3

您好,我是新的 Prolog 和 DGC。我想编写一个 DCG 来解析时间表达式,例如上午 10.20 或 12 点。我如何检查 10.20 am 是否是有效的表达方式对于 Olcock 我写了一些代码。

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],[]).

有人可以帮我解决这个问题。

4

1 回答 1

2

关于现有代码的快速说明:

在您的定义phrase1(Oclock)中,Oclock完全未确定,这意味着任何内容都将被视为短语 1。因此,您的 DCG 规则对于任何单个元素列表phrase1\\0都是正确的:

?- 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。

以防万一有任何混淆,这个解决方案和您自己的解决方案都只适用于atom 字符串,而不适用于字符串。因此,如果您尝试通过读入文件来解析自然语言,则必须做一些工作,要么将输入的字符转换为原子,要么让 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

手册中还有更多与字符相关的谓词。

于 2013-10-19T09:47:24.483 回答