2013-11-01 53 views
1

我是Prolog的新手,試圖實現一種深度方形謂詞,它將列表中的所有數字以及子列表中的所有數字正方形。我寫了一些工作代碼,但它沒有給我預期的輸出。在列表中包含子列表Prolog中的所有成員不使用maplist

代碼:

dsquare([],S). 
dsquare([H|T],[R|S]):- number(H), dsquare(T,S), R is H*H, !. 
dsquare([H|T],S):- isList(H), dsquare(H,S). 
dsquare([H|T],[R|S]) :- dsquare(T,S), R = H, !. 

電流輸出:

2?- dsquare([[2],4,a],X). 

X = [4| _VDHV] ; 

X = [[2], 16, a| _VDNM] ; 

fail. 

預期輸出:

X = [[4],16,]

另外我想知道爲什麼我在輸出中獲得'_VDHV'和'_VDNM'。 任何幫助將不勝感激。

編輯: 行,所以我更新了我的代碼:

dsquare([],[]). 
dsquare([H|T],[R|S]):- number(H), R is H*H, dsquare(T,S). 
dsquare([H|T],[R|S]):- isList(H), dsquare(H,R), dsquare(T,S). 
dsquare([H|T],[R|S]) :- R=H, dsquare(T,S). 

,但我得到的輸出是:

13?- dsquare([a,3,[[2]],b,4],X). 

X = [a, 9, [[4]], b, 16] ; 

X = [a, 9, [[4]], b, 4] ; 

X = [a, 9, [[2]], b, 16] ; 

X = [a, 9, [[2]], b, 4] ; 

X = [a, 9, [[2]], b, 16] ; 

X = [a, 9, [[2]], b, 4] ; 

X = [a, 9, [[2]], b, 16] ; 

X = [a, 9, [[2]], b, 4] ; 

X = [a, 3, [[4]], b, 16] ; 

X = [a, 3, [[4]], b, 4] ; 

X = [a, 3, [[2]], b, 16] ; 

X = [a, 3, [[2]], b, 4] ; 

X = [a, 3, [[2]], b, 16] ; 

X = [a, 3, [[2]], b, 4] ; 

X = [a, 3, [[2]], b, 16] ; 

X = [a, 3, [[2]], b, 4] ; 

fail. 

我不知道它是如何獲得這麼多的結果。

編輯 最後的工作方案是

dsquare([],[]). 
dsquare([H|T],[R|S]) :- number(H), !, R is H*H, dsquare(T,S). 
dsquare([H|T],[R|S]) :- isList(H), !, dsquare(H,R), dsquare(T,S). 
dsquare([H|T],[H|S]) :- dsquare(T,S). 
+0

@CapelliC:只需重新啓動我的程序讓它運行。 –

+0

@Nicholas Carey:你的解釋對我有幫助 –

回答

0

您的Prolog應該提醒你注意你的第一個和第三個規則「單身」。

嘗試

dsquare([],[]). 
... 
dsquare([H|T],[S|R]):- isList(H), dsquare(H,S), dsquare(T,R). 

OT不要放置沒有動機理由削減。

編輯你會得到更多結果,因爲最後一條規則會在回溯時被解僱。現在可以放置削減在需要的時間(後即輸入的代碼由條件把守的一個分支):

dsquare([],[]). 
dsquare([H|T],[R|S]) :- number(H), !, R is H*H, dsquare(T,S). 
dsquare([H|T],[R|S]) :- isList(H), !, dsquare(H,R), dsquare(T,S). 
dsquare([H|T],[R|S]) :- R=H, dsquare(T,S). 

或考慮佔了重複代碼重構:

dsquare([],[]). 
dsquare([H|T],[R|S]) :- 
    ( number(H) 
    -> R is H*H 
    ; isList(H) 
    -> dsquare(H,R) 
    ; R=H 
), 
    dsquare(T,S). 

編輯上面的定義(我測試了用 '的if/then/else語句')似乎很動聽:

1 ?- dsquare([[2],4,a],X). 
X = [[4], 16, a]. 

2 ?- dsquare([a,[3],[[[5]]],[2],a],X). 
X = [a, [9], [[[25]]], [4], a]. 
+0

我明白你在說什麼,並將其納入我的代碼中。我在問題和我得到的輸出中發佈我的新更新的代碼。 –

+0

好吧,'cut'是我現在明白的更好的東西。但現在我得到一個非常有趣的輸出。 dsquare(並[a,[3],[[[5]]],[2],A],X)。 X = [a,「」,[[[25]]],[4],a]; 對於一些'深'的情況下,我得到一個空白的空間,如圖所示。除了這一切看起來不錯。 –

+0

它仍然給我一個專門[3]的空白空間,但否則它的一切都很好。感謝您的幫助。我會看看我能爲空白做些什麼,也許試着在另一個prolog編譯器上運行它。 –

0

_Vxxx位是prolog在結果中表示未綁定變量的表示形式。基本上,它是符號表中的關鍵或地址。

  • 在你的第一條規則,

    dsquare([],S). 
    

    你永遠結合什麼的第二個參數。這意味着如果您將其作爲dsquare([],X)調用,則X將保持不受限制。如果作爲dsquare([1,2,3],X)被調用(假設其他一切正常工作,則產生的列表結構將被破壞,並且X將類似於[1,2,3|_VD3DC],因爲最後的項目將不是原型[](空列表)或./2,結構是一個非空列表。

  • 在你的第二個規則,

    dsquare([H|T],[R|S]):- number(H), dsquare(T,S), R is H*H, !. 
    
    • 切割(!)是不必要的
    • 您在運營商的順序不正確。首先是Square H,然後緩解下來。這完成了兩件事:它(A)提前失敗(如果結果是綁定的),並且(B)允許應用尾遞歸優化。
  • 在你的第三個規則,

    dsquare([H|T],S):- isList(H), dsquare(H,S). 
    

    你是遞歸下來,即源列表的開頭的子表,但是根本未評估的源列表的尾部,而不是簡單地丟棄它。

  • 在你的第4個規則,

    dsquare([H|T],[R|S]) :- dsquare(T,S), R = H, !. 
    

    再次,在你的第二個規則,剪裁上更是不必要的和操作的順序顛倒。

我會寫這樣的事:

deep_square([]  , [] ) % squaring an empty list produces an empty list 
    . 
deep_square([X|Xs] , [Y|Ys]) :- % otherwise... 
    number(X) ,      % if the head is a number, 
    Y is X*X ,      % square it 
    deep_square(Xs,Ys)    % and recurse down 
    .        % 
deep_square([X|Xs] , [Y|Ys]) :- % otherwise... 
    nonvar(X) ,      % if the head is bound, 
    X = [_|_] ,      % and is a non-empty list. 
    deep_square(X , Y) ,   % deep square the head 
    deep_square(Xs , Ys)   % and then recurse down 
    . 
deep_square([X|Xs] , [X|Ys]) :- % otherwise the head is unbound or something other than a number or a non-empty list... 
    deep_square(Xs , Ys)   % recurse down. 
    .        % Easy! 

你會發現,有統一magick和類似的很多這種情況發生在序言中的條款的頭謂詞。

+0

很好的解釋。我遵循你的意見並相應地修改了我的代碼。我也使用你的給定片段,但它沒有給我預期的輸出。這是我使用你的代碼時的輸出結果.21 - deep_square([a,2,[[3]],r],X)。 X = [a,4,[「」],r]; X = [a,4,[[3]],r]; X = [a,4,[[3]],r]; X = [a,4,[[3]],r]; X = [a,2,[「」],r]; X = [a,2,[[3]],r]; X = [a,2,[[3]],r]; X = [a,2,[[3]],r]; 失敗。 –

相關問題