I'd like to test whether a term has only one solution. (Understanding that this might be done in different ways) I've done the following and would like to understand why it doesn't work, if it can be made to work, and if not, what the appropriate implementation would be.
First, I have an "implies" operator (that has seemed to work elsewhere):
:- op(1050,xfy,'==>').
'==>'(A,B) :-·forall(call(A), call(B)).
next I have my singleSolution predicate:
singleSolution(G) :- copy_term(G,G2), (call(G), call(G2)) ==> (G = G2).
Here I'm trying to say: take a term G and make a copy of it, so I can solve them independently. Now if solving both independently implies they are equal, then there must be only one solution.
This works in some simple cases.
BUT.
I have a predicate foo(X,Y,Z)
(too large to share) which solves things properly, and for which singleSolution
can answer correctly. However, X,Y,Z are not fully ground after singleSolution(foo(X,Y,Z))
is called, even though they would be after directly calling foo(X,Y,Z)
.
I don't understand that. (As a sanity test: I've verified that I get the same results under swi-prolog and gprolog.)
EDIT: Here is an example of where this fails.
increasing([]).
increasing([_]).
increasing([X,Y|T]) :- X < Y, increasing([Y|T]).
increasingSublist(LL,L) :-·
sublist(L,LL),
length(L, Len),
Len > 1,
increasing(L).
then
| ?- findall(L, singleSolution(increasingSublist([1,2],L)),R).
R = [_]
yes
But we don't know what L
is.