So how can you prove ambiguity? In Prolog, this is easily possible for concrete sentences:
?- length(Xs,N), bagof(t,phrase(s,Xs),[_,_|_]).
Xs = [0,0,1], N = 3
; Xs = [0,0,0,1], N = 4
; Xs = [0,0,0,0,1], N = 5
; Xs = [0,0,0,1,1], N = 5
; Xs = [0,0,0,0,0,1], N = 6
; Xs = [0,0,0,0,1,1], N = 6
; Xs = [0,0,0,0,0,0,1], N = 7
; ... .
This proves that there is ambiguity for concrete length and gives the relevant counterexample.
There is, however a caveat which might show only after some time: bagof/3
has to store the entire set of solutions somehow. So if this set is very large, bagof/3
might overflow. The following query avoids this bug at the price of getting redundant solutions:
?- length(Xs,N), phrase(s,Xs), bagof(t,phrase(s,Xs),[_,_|_]).
Xs = [0,0,1], N = 3
; Xs = [0,0,1], N = 3
; Xs = [0,0,0,1], N = 4
; Xs = [0,0,0,1], N = 4
; Xs = [0,0,0,1], N = 4
; Xs = [0,0,0,1,1], N = 5
; Xs = [0,0,0,1,1], N = 5
; Xs = [0,0,0,0,1], N = 5
; Xs = [0,0,0,1,1], N = 5
; Xs = [0,0,0,0,1], N = 5
; Xs = [0,0,0,0,1], N = 5
; Xs = [0,0,0,0,1], N = 5
; Xs = [0,0,0,0,1,1], N = 6
; ... .
with your improved grammar, the query loops. That means that the system cannot find a counterexample. At least not with a length below 1000 which is what I tested.
Some general remarks about writing DCGs in Prolog:
Try to put the recursive case last, this might save some space.
You might want to use double-quoted strings to represent terminals. See this answer for more.