Удалить ведущие s(s(0)) в списке
(Это продолжение этого вопроса).
Как написать lead1(Xs,Ys)
что верно, если Ys
это суффикс Xs
со всеми ведущими s(s(0))
сроки удалены. Таким образом, вместо удаления ведущих 0
Теперь этот вопрос касается удаления ведущих s(s(0))
s.
По сравнению с первоначальным вопросом трудность заключается здесь в s(X)
а также s(s(X))
должным образом.
2 ответа
list_suffix([],[]).
list_suffix([X|Xs],S) :-
if_(X=s(s(0)), list_suffix(Xs,S), S=[X|Xs]).
Запросы с первым аргументом завершаются успешно:
?- list_suffix([s(0)],S).
S = [s(0)].
?- list_suffix([s(0),s(s(0))],S).
S = [s(0), s(s(0))].
?- list_suffix([s(s(0)),s(0),s(s(0))],S).
S = [s(0), s(s(0))].
?- list_suffix([s(s(0)), s(s(0)),s(0),s(s(0))],S).
S = [s(0), s(s(0))].
Если список состоит из термина, отличного от s/1, скажем, f(_)
второй список идентичен первому:
?- list_suffix([f(_)],S).
S = [f(_G201)].
?- list_suffix([f(_)],[]).
false.
Частично созданные списки работают также:
?- list_suffix([X, s(s(0)),s(0),s(s(0))],S).
X = s(s(0)),
S = [s(0), s(s(0))] ;
S = [X, s(s(0)), s(0), s(s(0))],
dif(X, s(s(0))).
Самый общий запрос также работает, но перечисляет ответ несправедливым образом:
?- list_suffix(X,Y).
X = Y, Y = [] ;
X = [s(s(0))],
Y = [] ;
X = [s(s(0)), s(s(0))],
Y = [] ;
X = [s(s(0)), s(s(0)), s(s(0))],
Y = [] ;
.
.
.
Однако это можно исправить, добавив префикс длины цели /2:
?- length(X,_), list_suffix(X,Y).
X = Y, Y = [] ;
X = [s(s(0))],
Y = [] ;
X = Y, Y = [_G155],
dif(_G155, s(s(0))) ;
X = [s(s(0)), s(s(0))],
Y = [] ;
X = [s(s(0)), _G79],
Y = [_G79],
dif(_G79, s(s(0))) ;
X = Y, Y = [_G155, _G158],
dif(_G155, s(s(0))) ;
X = [s(s(0)), s(s(0)), s(s(0))],
Y = [] ;
.
.
.
Hiere - это адаптация моего ответа на предыдущий вопрос. Он показывает использование когда / 2 вместо freeze/2. freeze/2 следует только условию nonvar/1 для первого аргумента. когда / 2 может следовать более сложным условиям.
lead(X, Y) :- var(X), !, freeze(X, lead(X,Y)).
lead([X|Y], Z) :- \+ ground(X), !, when(ground(X), lead([X|Y],Z)).
lead([s(s(0))|X], Y) :- !, lead(X, Y).
lead(X, X).
Вот несколько примеров, я выбираю похожие примеры, которые я дал в предыдущем ответе. Мы видим, как, когда / 2 адаптирует свое собственное условие, когда аргумент списка постепенно создается:
?- lead([s(0),s(s(0)),s(s(0)),s(0)],Y).
Y = [s(0), s(s(0)), s(s(0)), s(0)].
?- lead([s(s(0)),s(s(0)),s(s(0)),s(0)],Y).
Y = [s(0)].
?- lead([X,s(s(0)),s(s(0)),s(0)],Y), X=s(_).
X = s(_G3686),
when(ground(_G3686), lead([s(_G3686), s(s(0)), s(s(0)), s(0)], Y)).
?- lead([X,s(s(0)),s(s(0)),s(0)],Y), X=s(0).
X = s(0),
Y = [s(0), s(s(0)), s(s(0)), s(0)].
?- lead([X,s(s(0)),s(s(0)),s(0)],Y), X=s(s(_)).
X = s(s(_G3713)),
when(ground(_G3713), lead([s(s(_G3713)), s(s(0)), s(s(0)), s(0)], Y)).
?- lead([X,s(s(0)),s(s(0)),s(0)],Y), X=s(s(0)).
X = s(s(0)),
Y = [s(0)].
freeze / 2 и когда / 2 являются сопутствующими примитивами. Их чистота хорошо документирована в литературе. Согласно этому источнику, первой системой Пролог с сопроводительной структурой был Пролог-II с его примитивом гелер / 2. В источнике также упоминается важность сопряжения для загрузчиков, решающих ограничения.
Предположим, что чистота проверяется с коммутативностью, вот пример теста:
?- lead([X,s(s(0)),s(s(0)),s(0)],Y), X=s(s(0)).
X = s(s(0)),
Y = [s(0)].
?- X=s(s(0)), lead([X,s(s(0)),s(s(0)),s(0)],Y).
X = s(s(0)),
Y = [s(0)].
Но замораживание / 2 и когда / 2 необязательно гарантируют полноту, как я уже писал в своем первом ответе, нам может понадобиться что-то сделать "в конце". Значит, после запроса у нас может быть множество непослушных целей. В программировании с ограничением мы начинаем маркировку.
Также замораживайте / 2 и когда / 2 не может найти ранние сбои путем объединения целей, как это могут сделать решатели ограничений.
Приведенный выше пример работает с SWI-Prolog без какого-либо импорта, а в Jekejeke Prolog используется библиотека расширений Minlog и библиотека импорта (term/suspend).