2013-10-19 85 views
3

你好,我是新的Prolog和DGC.I想寫一個DCG來解析時間表達式,如10.20或12點。我怎麼能檢查10.20是否有效的表達式或不爲Olcock寫了一些代碼。PROLOG - DCG解析

oclock --> digit1,phrase1. 

digit1 --> [T],{digit1(T)}. 
digit1(1). 
digit1(2). 
digit1(3). 
digit1(4). 
digit1(5). 
digit1(6). 
digit1(7). 
digit1(8). 
digit1(9). 
digit1(10). 
digit1(11). 
digit1(12). 

phrase1 --> [P],{phrase1(P)}. 
phrase1(Oclock). 

我是個被查詢

oclock([1,oclock],[]). 

檢查有人可以幫助我在此。

回答

2

快速注意你的現有代碼:

在你的定義phrase1(Oclock)Oclock留下完全不確定的,這意味着什麼算作phrase1。因此,對於phrase1\\0您的DCG規則將是真實的任何單元素列表:

?- phrase(phrase1, X). 
X = [_G481]. 

?- phrase(phrase1, [a]). 
true. 

?- phrase(phrase1, [abababab]). 
true. 

?- phrase(phrase1, [[aba,dbdi,dbdi]]). 
true. 

?- phrase(phrase1, []). 
false. 

一個可能的解決你的問題

這裏是一個可能的解決方案:

time --> hours, suffix. 

suffix --> sep, minutes, meridiem. 
suffix --> ['oclock']. 

hours --> {between(1,12,H)}, [H]. 
sep  --> ['.']. 
minutes --> {between(1,60,M)}, [M]. 

meridiem --> [am]. 
meridiem --> [pm]. 

用以下查詢測試:

?- phrase(time, [1,'.',10,am]). 
true. 

phrase/2phrase/3是調用DCG規則的標準謂詞。您也可以查詢phrase(time, X)並查看X使用所有可能的時間實例化。

爲防萬一有任何混淆,這個解決方案和你自己的將只適用於原子串,但不是字符串。所以,如果你試圖通過閱讀文件來解析自然語言,你必須做一些工作,把字符輸入轉換成原子,或者讓dcg處理字符。例如,

time --> hours, suffix. 

suffix --> sep, minutes, meridiem. 
suffix --> " oclock". 

hours --> {hours(H)}, H. 
sep  --> ".". 
minutes --> {minutes(M)}, M. 

meridiem --> " am". 
meridiem --> " pm". 

hours(H) :- 
    between(1,12,N), 
    atom_codes(N,H). 
minutes(M) :- 
    between(1,60,N), 
    atom_codes(N,M). 

已將原子列表交換爲字符代碼列表;自?- A = "aaa". A = [97, 97, 97].在SWI-Prolog中,原子和代碼字符之間的轉換可以通過以下列出的謂詞來實現:file:///opt/local/lib/swipl-6.4.1/doc/Manual/manipatom.html#atom_chars/2

在手冊中還有更多與人物相關的謂詞。

+1

非常感謝你,這真的很有幫助。 – user2895589

+0

@ user2895589很高興聽到!謝謝。順便說一句,如果這也回答了另一個非常類似的問題,那麼您可能需要刪除另一個。這將有助於保持整潔。祝你的邏輯編程好運! –

+1

+1非常好,宣言性的DCG!順便說一句:在SWI-Prolog中,在'? - set_prolog_flag(double_quotes,chars).'之後,你得到的是原子而不是字符代碼,例如:'? - Xs =「abc」.'產生:'Xs = [a,b, C]'。這使得使用字符串更加方便。 – mat