Reputation: 591
I've been reading about how great difference lists are and I was hoping to test some examples from the books. But it seems that you can't pass lists as input in just the same way as, for instance append([1,2,3], [4,5], X), where X=[1,2,3,4,5]. Strangely, no book I've consulted ever mentions this.
I'm running the code on swipl and I'm interested in testing out a difference append predicate:
dapp(A-B,B-C,A-C).
and a "rotate first element of list" predicate:
drotate([H|T]-T1,R-S) :- dapp(T-T1,[H|L]-L,R-S).
Any ideas, how I can test these predicates in swipl?
Upvotes: 7
Views: 1331
Reputation: 71065
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
Upvotes: 2
Reputation: 9340
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.
Upvotes: 7