2014-12-04 15 views
1

如果我有一個這樣的程序,並且我想要一個人的最後一個項目沒有後面的逗號,我該怎麼做?最好使用DCG嗎?這將如何工作?文件輸出的DCG

male(bob). 
male(dave). 
male(fred). 
male(dereck). 


likes(bob,cake). 
likes(bob, pie). 
likes(bob, apple). 

likes(dave, fish). 
likes(dave, meat). 
likes(dave, potato). 
likes(dave, pear). 

likes(fred, water). 
likes(fred, beer). 

likes(dereck, wine). 
likes(dereck, cake). 



print:- 
    forall(
     male(Person), 
     (
      format("~w, ",[Person]), 
      forall(
      likes(Person,Item), 
      format("~w, ",[Item]) 
     ), 
      format("~n~n",[]) 
     ) 
    ). 

的出來說就是:

bob, cake, pie, apple, 

dave, fish, meat, potato, pear, 

fred, water, beer, 

dereck, wine, cake, %<I dont want these last commas 
+1

爲什麼你需要打印?這是某種報告嗎?或者僅僅是爲了看看事實數據庫中的內容? – 2014-12-04 13:33:31

+1

這是寫入文件作爲輸入到程序treeliker http://ida.felk.cvut.cz/treeliker/TreeLiker.html – user27815 2014-12-04 14:14:07

回答

4

首先考慮一個純粹的解決方案,採用DCG中翻譯的事情列出來一個人喜歡的,稍後解釋格式化指令列表:

person_likes(Who, Whats) --> 
    atom(Who), atom(': '), 
    likes_(Whats). 

likes_([])   --> [newline]. 
likes_([X])  --> atom(X), [newline]. 
likes_([X,Y|Rest]) --> atom(X), atom(', '), likes_([Y|Rest]). 

atom(A) --> [atom(A)]. 

正如你所看到的,關鍵的想法是根據列表中的元素數來區分這些情況。這向你展示瞭如何非常普遍地解決這些問題。

您已經可以使用它像這樣:

?- phrase(person_likes(bob, [cake,pie]), Instrs). 
Instrs = [atom(bob), atom(': '), atom(cake), atom(', '), atom(pie), newline]. 

對於所需的輸出,你簡單地解釋這些格式的說明。例如:

output(newline) :- nl. 
output(atom(A)) :- format("~w", [A]). 

樣品查詢,你的榜樣事實:

?- male(M), findall(W, likes(M,W), Whats), 
    phrase(person_likes(M,Whats), Ts), 
    maplist(output, Ts), false. 

產量:

bob: cake, pie, apple 
dave: fish, meat, potato, pear 
fred: water, beer 
dereck: wine, cake 

當然,你可以用相同的模式,以獲得更短的,不純版本(使用副作用)。但是你不能在另一個方向使用它!所以,研究純粹的版本是值得的。

+0

感謝您的這一點,它不太正確..它合併一些答案? pieapple應該是餡餅,蘋果 – user27815 2014-12-04 14:12:51

+0

謝謝,我也研究過如何改變它。 – user27815 2014-12-04 14:33:32

+2

這麼幹淨! – false 2014-12-04 15:38:07