删除列表中的前导 s(s(0))
Remove leading s(s(0)) in list
(这是 的后续)。
如何写 lead1(Xs,Ys)
这是真的,当且仅当 Ys
是 Xs
的后缀,所有前导 s(s(0))
项都被删除。因此,这个问题现在不是删除前导 0
s,而是关于删除前导 s(s(0))
s.
相对于原题,难点在于s(X)
和s(s(X))
的情况处理得当
Hiere 是我对上一个问题的回答的改编版。它显示了使用 when/2 而不是 freeze/2。 freeze/2 仅在第一个参数上遵循 nonvar/1 条件。 when/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).
这里有一些示例运行,我选择的示例与我对上一个答案的回答类似。当列表参数逐渐实例化时,我们看到 when/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 和 when/2 是协程原语。它们的纯度在文献中有详细记载。根据这个 source 第一个具有协程的 Prolog 系统是具有 geler/2 原语的 Prolog-II。消息来源还提到协程对 bootstrap 约束求解器的重要性。
假设纯度是用交换性来检验的,这里是一个样本检验:
?- 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)].
但是 freeze/2 和 when/2 不一定能保证完整性,正如我在第一个回答中所写的那样,我们可能需要做一些事情 'at the end'。意味着在查询之后我们可能有一组挣扎的目标。在约束规划中,我们将开始标记。
freeze/2 和 when/2 也无法像约束求解器那样通过组合目标发现早期失败。
上面的 eexample 使用 SWI-Prolog without some import, and in Jekejeke Prolog use the Minlog Extension 和导入库(term/suspend)运行。
这是 if_/3 and =/3 的版本:
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 = [] ;
.
.
.
但是,可以通过在目标前加上前缀来解决这个问题 length/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 = [] ;
.
.
.
(这是
如何写 lead1(Xs,Ys)
这是真的,当且仅当 Ys
是 Xs
的后缀,所有前导 s(s(0))
项都被删除。因此,这个问题现在不是删除前导 0
s,而是关于删除前导 s(s(0))
s.
相对于原题,难点在于s(X)
和s(s(X))
的情况处理得当
Hiere 是我对上一个问题的回答的改编版。它显示了使用 when/2 而不是 freeze/2。 freeze/2 仅在第一个参数上遵循 nonvar/1 条件。 when/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).
这里有一些示例运行,我选择的示例与我对上一个答案的回答类似。当列表参数逐渐实例化时,我们看到 when/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 和 when/2 是协程原语。它们的纯度在文献中有详细记载。根据这个 source 第一个具有协程的 Prolog 系统是具有 geler/2 原语的 Prolog-II。消息来源还提到协程对 bootstrap 约束求解器的重要性。
假设纯度是用交换性来检验的,这里是一个样本检验:
?- 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)].
但是 freeze/2 和 when/2 不一定能保证完整性,正如我在第一个回答中所写的那样,我们可能需要做一些事情 'at the end'。意味着在查询之后我们可能有一组挣扎的目标。在约束规划中,我们将开始标记。
freeze/2 和 when/2 也无法像约束求解器那样通过组合目标发现早期失败。
上面的 eexample 使用 SWI-Prolog without some import, and in Jekejeke Prolog use the Minlog Extension 和导入库(term/suspend)运行。
这是 if_/3 and =/3 的版本:
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 = [] ;
.
.
.
但是,可以通过在目标前加上前缀来解决这个问题 length/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 = [] ;
.
.
.