慣用的解決方案:
swap(L,S) :-
%maplist(when_, [
append([X,C,Y],L), (C=[];C=[_]), same_length(X,Y),
reverse(X,U), reverse(Y,V), append([U,C,V],S)
%])
.
?- swap([1,2,3,4,5],S).
S = [2, 1, 3, 5, 4] ;
false.
它不是一個真正的關係,因爲它掛起如果調用模式swap(-,+)
,但它的行爲在取消對包圍,並提供該片段後更好:
:- meta_predicate when_(0).
when_(P) :-
strip_module(P,_,Q), Q =.. [_|As],
or_list(As, Exp), display(Exp),
when(Exp, P).
or_list([A], ground(A)) :- !.
or_list([A|As], (ground(A);Exp)) :- or_list(As, Exp).
編輯
@false'評論後,我試圖解釋這個答案的動機。所請求的swap/2'函數'似乎是展示Prolog數據模型特性的理想候選者,儘管請求的解釋(關於應用於列表的整數算術的適當句法用法)在這裏甚至沒有暗示。
從Prolog的一開始,我們就可以使用關係型和功能(遞歸)工具的獨特混合,這對新手來說可能毫無意義。至少,這仍然讓我感到意外......我喜歡這個事實。
現在,功能邏輯編程,例如Curry,嘗試通過「縮小」的解決方案。從鏈接頁面:
Narrowing is useful because it allows a function to be treated as a relation: its value can be computed "in both directions"
現在,when_/1它是一個簡單的方法來解決同一個問題。腳踏實地,swap/2被描述爲一個函數,但可能是是實現的作爲關係?
@false建議,將same_length(L,S)
作爲第一個目標,修復swap( - ,+)模式,但在swap( - , - )上循環。基於when_/1的方法反而報告不能對連詞進行研究。除了
編輯
終止的問題,我選擇的目標爲了真的是無效的。暗示這個答案another question,我突然想到一個很大的效率增益(至少,對於模式互換(+, - ))可得將限制第一:
3 ?- numlist(1,100,L), time((append([X,C,Y],L), (C=[];C=[_]), same_length(X,Y), append([Y,C,X], S))).
% 328,899 inferences, 0.125 CPU in 0.125 seconds (100% CPU, 2634422 Lips)
L = [1, 2, 3, 4, 5, 6, 7, 8, 9|...],
X = [1, 2, 3, 4, 5, 6, 7, 8, 9|...],
C = [],
Y = [51, 52, 53, 54, 55, 56, 57, 58, 59|...],
S = [51, 52, 53, 54, 55, 56, 57, 58, 59|...]
.
4 ?- numlist(1,100,L), time(((C=[];C=[_]), same_length(X,Y), append([X,C,Y],L), append([Y,C,X], S))).
% 3,273 inferences, 0.001 CPU in 0.001 seconds (100% CPU,999 Lips)
您建議的'swap/2'實現並沒有做OP想要做的事情。 – lurker
我是新來的prolog一般所以不能超清所有的措辭。感謝您對類型問題的澄清。我仍然堅持編程的必要心態。這是有道理的,我需要使用一個謂詞來獲取值,然後重新插入。還要感謝代碼建議。你能解釋最後一行嗎? –
@ lurker:哦,的確不是!原來,我看不懂。 – Amadan