2012-11-15 81 views
1

所以我試圖通過直接在分割內使用排序庫謂詞擺脫包裝子句。什麼拆分只是從列表中產生一個數字列表,如下所示:[1:2,3:2,4:6] - split - > [1,2,3,2,4,6 ]。但生成的列表包含重複項,我不想這樣做,所以我使用包裝器將split和sort結合起來,然後生成所需的結果:[1,2,3,4,6]。序言:擺脫遞歸助手謂詞

我真的很想擺脫包裝,只是在拆分內使用排序,但我不斷收到「錯誤:排序/ 2:參數沒有充分實例化。」有任何想法嗎?謝謝:)

split([],[]). 
split([H1:H2|T],[H1,H2|NT]) :- 
    split(T,NT). 

wrapper(L,Processed) :- 
    split(L,L2), 
    sort(L2,Processed). 
+0

'[1:2,3:2,4:6]'這個詞對我來說很古怪,它是爲了什麼?這個'ins(T,NT)'是什麼? – false

+0

ins應該被遞歸分割,我的不好:)。固定。 [1:2 ..]是圖中邊緣的列表。 –

+1

你將永遠不會因爲你的split/2的定義而得到這個錯誤信息。這不可能! – false

回答

1

I'd really like to get rid of the wrapper and just use sort within split

然後用複雜的目標使用findall

split(Edges, NodeSet) :- 
    findall(Node, 
      (member(Edge, Edges), (Edge = (Node:_); Edge = (_:Node))), 
      NodeList), 
    sort(NodeList, NodeSet). 

然而,一旦你開始使用聚合謂詞,你也可以同樣跳過sort和使用setof

split(Edges, NodeSet) :- 
    setof(Node, Edge^Pair^(member(Edge, Edges), 
          Edge =.. [:|Pair], 
          member(Node,Pair)), 
      NodeSet). 

閱讀原文:get the set of全部Node s.t.存在Edge並且存在Pair s.t. (等),並稱NodeSet

=..(「univ」)運算符解構一對:Edge =.. [:, Left, Right]。在嘗試這種辦法,看到這個答案是否這是比OP的一個更好的主意下面的討論

% endpoint(Edge, Node) is true iff Node is an endpoint of Edge 
endpoint(Node:_, Node). 
endpoint(_:Node, Node). 

split(Edges, NodeSet) :- 
    setof(Node, Edge^(member(Edge, Edges), endpoint(Edge, Node)), NodeSet). 

編輯:爲了更好的可讀性,你可以寫一個獨立的謂語從邊緣得到節點原始代碼。

+0

與原來的split/2相比,你在這裏獲得了什麼?除非變量存在,否則您的解決方案不起作用。 – false

+0

謝謝larsmans :) –

+0

@false:無論如何,您無法從包含變量的列表中找到一組元素。你所獲得的是,你現在有一個目標或一對目標,你可以插入一個更大的子句中間,而不必命名它們,因爲遞歸現在是隱含的。這就是這些謂詞存在的原因。 –