Проблема с рекурсией, не затрагивающая базовый вариант

Я работаю над следующим 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
| ?-
Другие вопросы по тегам