Testing Prolog Difference lists

Try:

dapp([1,2,3|X] - X,[4,5,6] - [],Y - []).
drotate([1,2,3|X] - X,Y - []).

Y is the answer for both predicates.


The definition of drotate can be simplified:

dapp( A-B, B-C, A-C). 
drotate( [H|T]-T1, R-S) :- % (* dapp( T-T1, [H|L]-L, R-S). 
       %%                       dapp( A-B , B    -C, A-C). 
       %% use the definition of dapp: *)
                             T = R, T1 = [H|L], L = S. 

In other words, simply,

drotate( [H|R]-[H|L], R-L).

Now, any difference list is usually written out as a pair, A-B. So a call to drotate might be drotate( [1,2,3|Z]-Z, R-L) with intent to see the output in R-L variables. But matching this call with the last definition, we get Z = [1|L], i.e. the logvar Z, presumably non-instantiated before the call, gets instantiated by it, actually adding 1 at the end of the open-ended list [1,2,3|Z]-Z, turning it into [1,2,3,1|L]-L. R just gets pointed at the 2nd element of the newly enlarged list by matching [H|R] with the list.

?- drotate( [1,2,3|Z]-Z, R-L).

Z = [1|_G345]
R = [2, 3, 1|_G345]
L = _G345 

Yes

But it could also be called with the truly circular data, A-A = [1,2,3|Z]-Z, drotate( A-Z, R-L):

?- A-A = [1,2,3|Z]-Z, drotate( A-Z, R-L).

A = [1, 2, 3, 1, 2, 3, 1, 2, 3|...]
Z = [1, 2, 3, 1, 2, 3, 1, 2, 3|...]
R = [2, 3, 1, 2, 3, 1, 2, 3, 1|...]
L = [2, 3, 1, 2, 3, 1, 2, 3, 1|...] 

Yes