Проблема с рекурсией, не затрагивающая базовый вариант
Я работаю над следующим DCG:
zero(1) -->
[0],
!.
zero(N) -->
{
N < 1
},
[],
!.
zero(N) -->
zero(1),
{
M is N - 1
},
zero(M).
Он работает правильно для положительных тестовых случаев, например
?- phrase(zero(5), A).
A = [0, 0, 0, 0, 0].
?- phrase(zero(2), [0,0]).
true.
Но когда я запускал отрицательные случаи (как правило, что-то вроде phrase(zero(5), [0,0]).
), он уходит в забвение. Любопытно, что во время трассировки кажется, что всякий раз, когда он идет к нулевой (1) строке в третьем предложении во время рекурсии, он не переходит в базовый регистр (первое предложение), а вместо этого переходит на второй и завершается неудачей, потому что N = 1. Есть догадки?
1 ответ
Я думаю, что ваша проблема слишком конкретна, и вы не хотите сокращений. В частности, вам не нужен "отрицательный" случай:
zero(N) -->
{
N < 1
},
[],
!.
Это будет УСПЕШНО в том, что вы считаете случаем неудачи.
Вместо этого попробуйте что-нибудь попроще:
zero(1) --> [0].
zero(N) --> { N > 1, M is N - 1 }, [0], zero(M).
Это определяет только положительные случаи. Все остальные случаи терпят неудачу. Так:
| ?- phrase(zero(5), A).
A = [0,0,0,0,0]
yes
| ?- phrase(zero(2), [0,0]).
yes
| ?- phrase(zero(5), [0,0]).
no
| ?-