问题
I have to find if two members of a list are adjacent. The restriction is to use the append/3
predicate. So far I've done the below, it works if it's true, otherwise I get no answer, it's like it runs eternally.
adjacent(X,Y,L):-
append(L1,[X,Y],T1),append(T1,T2,L).
回答1:
To see that your program will loop, it suffices to consider the following failure-slice:
adjacent(X,Y,L):- append(L1,[X,Y],T1), false,append(T1,T2,L).
If this program will loop, then the original program will loop too. It might succeed, but still it will loop.
In your first goal both L1
and T1
are uninstantiated variables - that's easy to see, because they are not used anywhere else in this fragment. As a consequence, this program will always loop, no matter what X
, Y
or L
might be. To fix this, you have to modify something in the visible part.
One possibility would be to exchange the two goals. But there is an even easier way out:
adjacent(X,Y,L) :-
append(_,[X,Y|_],L)
Note however, that this does not ensure that L
is really a well formed list. In fact, adjacent(1,2,[1,2|nonlist])
succeeds. In case it should be a list:
adjacent(X,Y,L) :-
append(_,[X,Y|R],L),
append(R,[],R).
See failure-slice for more.
回答2:
This might not be the best answer, but you can also try:
adjacent(X,Y,Zs):- append(As,[X,Y|Ys],Zs).
For example:
3 ?- adjacent(1,2,[1,2,3]).
true .
1 ?- adjacent(1,3,[1,2,3]).
false.
来源:https://stackoverflow.com/questions/23516616/find-adjacent-members