PROLOG - DCG解析

3

你好,我是新手Prolog和DCG。我想编写一个DCG来解析时间表达式,比如10.20 am或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],[]).

有人能帮我解决这个问题吗?

1个回答

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

手册中还有许多与字符相关的述语。


@user2895589 听到这个消息非常高兴!谢谢。顺便说一下,如果这个回答也解决了你另一个非常相似的问题,你可能想要删除那个问题。这将有助于保持事情的整洁。祝你在逻辑编程方面好运! - Shon
1
非常好的声明式 DCG!顺便说一下,在 SWI-Prolog 中,执行 ?- set_prolog_flag(double_quotes, chars). 后,你会得到原子而不是字符编码,例如:?- Xs = "abc". 会产生 Xs = [a,b,c]。这使得处理字符串更加方便。 - mat
@mat 谢谢!这非常鼓舞人心。我已经采纳了您关于double_quotes标志的建议,并享受了其带来的好处。 - Shon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接