嘗試用比較:
:- use_module(library(clpfd)).
insert([], X, [X]).
insert([X|Xs], New, Ys) :-
zcompare(Order, X, New),
insert(Order, X, New, Xs, Ys).
insert(>, X, New, Xs, [New,X|Xs]).
insert(=, X, _, Xs, [X|Xs]).
insert(<, X, New, Xs, [X|Ys]) :-
insert(Xs, New, Ys).
但也許你需要解釋嗎?令人奇怪的是,因爲你也可以只閱讀文檔,像我一樣,發現這是爲什麼足夠好實現,當然也許這是好事,說明更多的,以防萬一。
insert([], X, [X]).
當第一個參數爲空列表,第二個參數是結果列表的唯一元素。
insert([X|Xs], New, Ys) :-
zcompare(Order, X, New), ...
當第一個參數是清單至少有一個元素,取頭元素,並將其與新的元素。之後compare
或zcompare
第一個參數的買賣盤>
或=
或<
(但是這分別意味着什麼?也許猜到或者甚至閱讀文檔,如果它沒有太多的工作)。
insert(Order, X, New, Xs, Ys).
比較以訂單和變量的休息之後....
insert(>, X, New, Xs, [New,X|Xs]).
元素在列表的頭部比新元素大。這意味着結果列表應該有新的元素,然後頭,然後列表的其餘部分。
insert(=, X, _, Xs, [X|Xs]).
元素在列表的頭是完全一樣的新元素。我們完成了,不需要插入任何東西只是保留原始列表作爲結果。
insert(<, X, New, Xs, [X|Ys]) :-
insert(Xs, New, Ys).
元素在列表的頭部比新元素小:新的元素必須進來結果這個元素之後。因此,我們將當前元素放回列表中,並在列表的其餘部分中搜索New元素的位置。
這麼多的文字,但現在更容易理解什麼代碼說?也許或者不是?
有
?- insert([5, 6, 30, 60, 90], 40, L).
L = [5, 6, 30, 40, 60, 90].
?- insert([5, 6, 30, 60, 90], 6, L).
L = [5, 6, 30, 60, 90].
?- insert([5, 6, 30, 60, 90], 100, L).
L = [5, 6, 30, 60, 90, 100].
?- insert([5, 6, 30, 60, 90], 0, L).
L = [0, 5, 6, 30, 60, 90].
,但因爲它使用像zcompare/3
謂詞看起來有點像compare/3
但它知道整數約束,因此可以查詢還有更多有趣的事情做與此解決方案:
可以在列表[1,3,4]中插入什麼整數?
?- insert([1,3,4], X, R).
R = [X, 1, 3, 4],
X in inf..0 ;
X = 1,
R = [1, 3, 4] ;
X = 2,
R = [1, 2, 3, 4] ;
X = 3,
R = [1, 3, 4] ;
X = 4,
R = [1, 3, 4] ;
R = [1, 3, 4, X],
X in 5..sup.
因此,你可以在前面插入任何整數< 1,也可以「插入」 1即在那裏,或者可以插入2 1和3之間,也可以「插入」 3或4 ,或者你可以在列表末尾插入5或更大的東西。
你不恰當地使用匿名變量('_'),您應使用一個真正的命名變量。當你不關心它是如何綁定的時候,使用匿名變量。使用'insert([],X,[X])'以及'insert([H,Y | Rest],X,Result): - X
lurker
謝謝lurker爲你解釋,現在我意識到_有它自己的含義,當我需要綁定變量的值時,我需要使用以大寫字母開頭的字符串。 – Enoy