Избегая всех частей X, Y и Z, что мы можем сказать о работающем коде:
- Вы начинаете с запроса, подобного
shuffle([1,2],[a,b],L).
, и Пролог пытается решить его, решая три правила shuffle
.
- Одно правило тасования может быть решено само по себе, но только для пустых списков, остальные два зависят от решения другого случая правила
shuffle
.
- Какое бы решение ни было найдено должно перейти
shuffle -> shuffle -> [shuffle....] -> empty lists
. Это должно. Если он вообще не может соответствовать ни одному шаффлу, он ответит «ложь», и ваш код не будет работать. Если он перебрасывается между шаффами вечно, он будет бесконечным циклом и не даст ответов, и ваш код не будет работать. Он работает, поэтому он должен с самого начала объединяться в цепочку с пустыми списками.
Пролог постарается решить из верхней части правила:
From the top:
A) shuffle([1,2],[a,b],L). -no-> shuffle([],[],[]).
B) shuffle([1,2],[a,b],L). -??-> shuffle([X|Xs],Ys,[X|Zs]):- shuffle(Xs,Ys,Zs).
B) shuffle([1,2],[a,b],L). -??-> shuffle([X=1|Xs=[2]],Ys=[a,b],[X=1|Zs=??]) :- shuffle(Xs=[2],Ys=[a,b],Zs).
% A) fails as [1,2] does not match with []
% B) partially binds but is missing Zs. Solving to try and find the Zs is now:
shuffle(Xs=[2],Ys=[a,b],Zs).
From the top:
A) shuffle([2],[a,b],Zs). -no-> shuffle([],[],[]).
B) shuffle([2],[a,b],Zs). -??-> shuffle([X|Xs],Ys,[X|Zs]):- shuffle(Xs,Ys,Zs).
B) shuffle([2],[a,b],Zs). -??-> shuffle([X=2|Xs=[]],Ys=[a,b],[X=2|Zs=??]):- shuffle(Xs,Ys,Zs).
% A) fails as [2] does not match with []
% B) partially binds but is missing Zs. Solving to try and find the Zs is now:
shuffle(Xs=[],Ys=[a,b],Zs).
From the top:
A) shuffle([],[a,b],Zs). -no-> shuffle([],[],[]).
B) shuffle([],[a,b],Zs). -no-> shuffle([X|Xs],Ys,[X|Zs]):- shuffle(Xs,Ys,Zs).
C) shuffle([],[a,b],Zs). -??-> shuffle(Xs,[Y|Ys],[Y|Zs]):- shuffle(Xs,Ys,Zs).
C) shuffle([],[a,b],Zs). -??-> shuffle(Xs=[],[Y=a|Ys=[b]],[Y=a|Zs=??]):- shuffle(Xs,Ys,Zs).
% A) fails as [a,b] does not match with the second []
% B) fails as [] does not match with [X|Xs]
% C) partially binds but is missing Zs. Solving to try and find the Zs is now:
shuffle([],[b],Zs).
From the top:
A) shuffle([],[b],Zs). -no-> shuffle([],[],[]).
B) shuffle([],[b],Zs). -no-> shuffle([X|Xs],Ys,[X|Zs]):- shuffle(Xs,Ys,Zs).
C) shuffle([],[b],Zs). -??-> shuffle(Xs,[Y|Ys],[Y|Zs]):- shuffle(Xs,Ys,Zs).
C) shuffle([],[b],Zs). -??-> shuffle(Xs=[],[Y=b|Ys=[]],[Y=b|Zs=??]):- shuffle(Xs,Ys,Zs).
% A) fails as [b] does not match with the second []
% B) fails as [] does not match with [X|Xs]
% C) partially binds but is missing Zs. Solving to try and find the Zs is now:
shuffle([],[],Zs).
From the top:
A) shuffle([],[],Zs). -no-> shuffle([],[],[]).
% A) succeeds. Zs can be []
Это законченная цепочка от источника через четыре шаффла до пустых списков. Во время этой цепочки Zs был построен как [1|?]
, затем [1|[2|?]]
, затем [1|[2|[a|?]]]
, затем [1|[2|[a|[b|?]]]]
, затем [1|[2|[a|[b|[]]]]]
, что завершено, ничего не пропуская. Это связано с вашим L
вводом для первого результата.
Он прошел через перемешивание B B C C
.
Но пространство поиска не исчерпано, возможно, будет больше ответов. Если вы попросите их, он развернется обратно по цепочке к месту, где он мог бы пойти другим путем. Вместо решения shuffle([X|Xs]..
он может пропустить его и нырнуть вниз shuffle(Xs
.
Два предиката shuffle
с большим количеством значений работают вместе, образуя шаблон отказов, который заканчивается тремя пустыми списками:
[1,2],[a,b],Unknown
\
\
\ ? shuffle shuffle shuffle
/
/
\
[],[],[]
Одна цепочка логических соединений - B B C C A
. Другая цепочка - B C B C A
, что приводит к следующему ответу L=[1,a,2,b]
.
[1,2],[a,b],Unknown
/ \
/ \
\ \ B C B A
B B C C\ /
| /
| \
[],[],[]
Как только он вернется назад, при каждом выборе поменяйте местами перетасовку для другого и проследуйте вниз по цепочке до пустых списков, он найдет 6 путей, 6 способов отскочить через перетасовки.
Чем длиннее списки, тем длиннее цепочки. Когда он начинает возвращаться по цепочке, расстегивая шаги, ища другие пути, их становится больше. Больше точек выбора, поэтому он найдет больше решений - пропорционально длине входов.