Определение drotate
можно упростить:
dapp(A-B,B-C,A-C).
drotate([H|T]-T1,R-S) :- % dapp(T-T1,[H|L]-L,R-S).
%% use the definition of dapp:
T=R, T1=[H|L], L=S.
IOW, просто,
drotate([H|R]-[H|L],R-L).
Теперь любой список различий обычно записывается в виде пары, A-B
. Таким образом, вызов drotate
может быть drotate([1,2,3|Z]-Z,R-L)
с намерением увидеть вывод в R-L
переменных. Но сопоставив этот вызов с последним определением, мы получим Z=[1|L]
, т. Е. Логвар Z, предположительно неинстанцированный до вызова, инстанцируется им, фактически добавляя 1
в конец открытого списка [1,2,3|Z]-Z
, превращая его в [1,2,3,1|L]-L
. R
просто указывается на 2-й элемент нового расширенного списка, сопоставляя [H|R]
со списком.
?- drotate([1,2,3|Z]-Z,R-L).
Z = [1|_G345]
R = [2, 3, 1|_G345]
L = _G345
Yes
Но это также может быть вызвано с действительно круговыми данными, 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