Prolog Past Paper
fail:- x=y
Lists
take/3
, perm/2
It commits any parts of the rule that have done so far, removing all the choice points which come before the cut in the rule body and that caused you to try that instance of the rule in the first place.
They maintain a variable at the tail of each list, achieving more efficient append in O(1) rather than O(n).
y1996p6q7
[l0, l1, l2] ~rotate~ [l1, l2, l0]
= [l0|l1, l2]
% rotate outputs a list L, which put the first element of the input list at the end.
rotate ([H|T0], L0) : - append(T0,[H],L0).
% To transform into difference list version, now
% T is a list T0 and an extra T1 at the tail
T = [ ... , T1] = T0 + T1
% L is a list L0 and an extra L1 at the tail
L = [ ... , L1] = L0 + L1
rotate2([H|T]-T1, L-L1) :- append(T-T1, [H|A]-A, L-L1).
A-B, B-C, A-C
> L=T, T1=[H|A], A=L1.
rotate2([H|T]-[H|A], T-A).
Why?
T = [ ..., T1] = T0 + T1 = T0 + [H|A], thus
T-A = T0 + [H|A] - A.
y1997p6q7
enum(0, [0|A]-A, B-B).
enum(1, A-A, [1|B]-B).
% A is the original list A0 + A1
enum(n(L,R), A-A1, B-B1) :- enum(L, AL-AL1, BL-BL1), enum(R, AR-AR1 , BR-BR1).
enum(n(L,R), AL-A1, BL-B1) :- enum(L, AL-AR, BL-BR), enum(R, AR-A1 , BR-B1).