I'm working on the following DCG:
zero(1) -->
[0],
!.
zero(N) -->
{
N < 1
},
[],
!.
zero(N) -->
zero(1),
{
M is N - 1
},
zero(M).
It works properly for positive test cases, eg
?- phrase(zero(5), A).
A = [0, 0, 0, 0, 0].
?- phrase(zero(2), [0,0]).
true.
But when I ran negative cases (typically something like phrase(zero(5), [0,0]).
), it goes into oblivian. Curiously, during tracing, it seems whenever it goes to the zero(1) line in the third clause during recursion, it doesn't go to the basecase (first clause), instead jumps to the second one and fails because N = 1. Any guesses?
I think your problem is over-specified, and you don't want the cuts. In particular, you don't need the "negative" case:
zero(N) -->
{
N < 1
},
[],
!.
This will SUCCEED on what you consider to be a failure case.
Instead, try something a little simpler:
zero(1) --> [0].
zero(N) --> { N > 1, M is N - 1 }, [0], zero(M).
This defines only the positive cases. All other cases fail. So:
| ?- phrase(zero(5), A).
A = [0,0,0,0,0]
yes
| ?- phrase(zero(2), [0,0]).
yes
| ?- phrase(zero(5), [0,0]).
no
| ?-