Чтобы увидеть, что ваша программа будет цикл, достаточно рассмотреть следующие failure-slice:
adjacent(X,Y,L):-
append(L1,[X,Y],T1), false,
append(T1,T2,L).
Если эта программа будет цикл, то исходная программа будет цикл тоже. Это может преуспеть, но все равно это будет цикл.
В вашей первой цели оба L1
и T1
являются неосвещенными переменными - это легко увидеть, потому что они не используются нигде в этом фрагменте. Как следствие, эта программа будет всегда петля, независимо от того, что X
, Y
или L
может быть. Чтобы исправить это, вам нужно что-то изменить в видимой части.
Одна из возможностей заключается в обмене двух целей. Но есть еще более простой выход:
adjacent(X,Y,L) :-
append(_,[X,Y|_],L)
Однако обратите внимание, что это не гарантирует, что L
действительно хорошо сформирован список. Фактически, adjacent(1,2,[1,2|nonlist])
преуспевает. В случае, если он должен быть список:
adjacent(X,Y,L) :-
append(_,[X,Y|R],L),
append(R,[],R).
failure-slice Посмотреть больше.
Это то же самое, первое решение @false предложил в своем ответе (он использовал '_' для одноэлементных переменных). – lurker