(這是對that question的後續處理)。刪除列表中的前導s(s(0))
如何編寫lead1(Xs,Ys)
這是真的,如果Ys
是Xs
的後綴,並刪除了所有前導s(s(0))
條款。因此,現在不是刪除前導0
,而是現在刪除前導s(s(0))
。
與原始問題相比,難點在於正確處理s(X)
和s(s(X))
的情況。
(這是對that question的後續處理)。刪除列表中的前導s(s(0))
如何編寫lead1(Xs,Ys)
這是真的,如果Ys
是Xs
的後綴,並刪除了所有前導s(s(0))
條款。因此,現在不是刪除前導0
,而是現在刪除前導s(s(0))
。
與原始問題相比,難點在於正確處理s(X)
和s(s(X))
的情況。
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是我對上一個問題的回答的改編。它顯示了使用when/2而不是freeze/2。凍結/ 2只在第一個參數上有一個非變量/ 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)].
凍結/ 2,當/ 2 corouting元。文獻中詳細記載了它們的純度。根據這個source,第一個Prolog系統帶有Corler/2原語的Prolog-II。消息來源還提到了Corouting對引導約束求解器的重要性。
假設純淨與交換性測試,這裏是一個樣本測試:
?- 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不necesserely保證完整性,因爲我已經在我的第一個答案寫了,我們可能需要做'最後'。意思是在查詢之後,我們可能會有一系列陷入困境的目標。在約束規劃中,我們將開始標記。
還凍結/ 2,當/ 2無法提前找到失敗時,通過組合目標,因爲約束求解器可以做到。
上述示例運行時沒有導入,而在Jekejeke Prolog中使用SWI-Prolog,並使用Minlog Extension和導入庫(term/suspend)。
所以你不再使用'freeze/2'。 – false
凍結/ 2仍被用在lead/2謂詞的第一個子句中。 freeze/2是when/2的特例,它可以定義爲'freeze(X,G): - when(nonvar(X),G).'。我在回答你的原始問題時已經提到過/ 2,你沒有注意到嗎? –
「正確處理s(X)和s(s(X))的情況」非常籠統,無助於理解謂詞的行爲,請考慮編輯回答r,添加更多信息... – coder
@coder:這不是規範的一部分。只是爲什麼這個最小的變化是有趣的理由。 – false
我也不明白問題出在哪裏。這個問題肯定需要一些例子來展示爲什麼@TopologicalSort建議是不夠的。 – Fatalize