快速注意你的現有代碼:
在你的定義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/2
或phrase/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
在手冊中還有更多與人物相關的謂詞。
非常感謝你,這真的很有幫助。 – user2895589
@ user2895589很高興聽到!謝謝。順便說一句,如果這也回答了另一個非常類似的問題,那麼您可能需要刪除另一個。這將有助於保持整潔。祝你的邏輯編程好運! –
+1非常好,宣言性的DCG!順便說一句:在SWI-Prolog中,在'? - set_prolog_flag(double_quotes,chars).'之後,你得到的是原子而不是字符代碼,例如:'? - Xs =「abc」.'產生:'Xs = [a,b, C]'。這使得使用字符串更加方便。 – mat