2017-03-07 43 views
2

我想將Prolog謂詞轉換爲DCG代碼。即使我熟悉語法語言,我也會遇到一些麻煩,要了解DCG如何處理列表以及我應該如何使用它。在Prolog中使用列表DCG

其實,這是我的謂詞:

cleanList([], []). 
cleanList([H|L], [H|LL]) :- 
    number(H), 
    cleanList(L, LL), 
    !. 
cleanList([_|L], LL) :- 
    cleanList(L, LL). 

這是一個簡單的謂詞從而消除非數字元素。 我想在DCG中寫入相同的行爲。

我試過類似的東西(這並不明顯工作):

cleanList([]) --> []. 
cleanList([H]) --> {number(H)}. 
cleanList([H|T]) --> [H|T], {number(H)}, cleanList(T). 

是否可以解釋我什麼是錯或缺少什麼?

謝謝!

+0

一個大問題lem是'... - > [H | T],...'。您希望DCG讀取一個序列,並且'[H | T]'具有任意長度。不知道爲什麼你在這個詞中包含了'T'。對'cleanList(T)'的遞歸調用已經在輸入上掃描了'T'。 – lurker

+0

噢,我明白了!謝謝你的回覆,我不明白DCG如何讀取序列,現在沒問題。 – Naeoth

回答

1

DCG符號的目的正好是隱藏,或者更好的做出隱式的令牌列表。所以,你的代碼應該看起來像

cleanList([]) --> []. 
cleanList([H|T]) --> [H], {number(H)}, cleanList(T). 
cleanList(L) --> [H], {\+number(H)}, cleanList(L). 

,可以更加高效:

cleanList([]) --> []. 
cleanList([H|T]) --> [H], {number(H)}, !, cleanList(T). 
cleanList(L) --> [_], cleanList(L). 

樣式注:Prologgers做傾向於避免駱駝:)

clean_list([]) --> []. 
etc... 

另外,我寧願更簡潔的代碼:

clean_list([]) --> []. 
clean_list(R) --> [H], {number(H) -> R = [H|T] ; R = T}, clean_list(T). 
+0

我知道我接近答案,感謝您的精確和您的建議! – Naeoth