我需要通过Prolog实现一些规则
例如:
S ---> A,[b],{c}.
其中:
[b]可能会发生一次或没有像0或1次
{c}可能发生0,1,2,......次
我怎么写呢?
修改 的
我用过这个:
:- op(700,xfx,--->).
s ---> [vp].
s ---> [vp,conj,vp].
s ---> [vp,conj,np].
vp ---> [feal_amr],
([mfoal_beh];[]),
([mfoal_beh];[]),
([bdl];[]),
[sefa_optional],
([hal];[]),
([shbh_gomla];[]),
([mfoal_motlk];[]).
它给了我一个错误“在句子体中完全停止?无法重新定义,/ 2”
在这一行的逗号“vp ---> [feal_amr],...”
修改 的
我用“--->”因为我有这个
parse_topdown(Category,String,Reststring,[Category|Subtrees]) :-
Category ---> RHS,
matches(RHS,String,Reststring,Subtrees).
和“ - >”操作员“: - ”给出错误?!!
这是我的代码 Arabic Parser Code
我很抱歉给您带来不便,但我不是Prolog的专家
答案 0 :(得分:1)
首先,你可能想要小写的S和A; Prolog使用变量名的初始上限。
允许'b'发生一次或根本不发生的一种方法是写下这样的东西:
s --> a, b_optional, {c}.
b_optional --> [b].
b_optional --> [].
如果您愿意,还有将b_optional的两个规则写为单一规则的语法;请参阅您最喜欢的Prolog文本中有关明确条款语法的章节。
我不知道你所说的0,1,2,......次是什么意思,所以我认为我不能帮助你。
答案 1 :(得分:1)
来自您的描述
s --> [a], ([b] ; []), c_1.
c_1 --> [c], c_1 ; [].
一些测试模式:
?- phrase(s, [a,b,c,c,c]).
true
?- phrase(s, [a]).
true
修改强>
关于您的代码:您应该使用-->
。为什么要声明--->
(而不是定义它)?这样你应该编写你自己的分析器,你不使用DCG。
请注意[vp,conj,vp]这是终端的列表,
不确定feal_amr,mfoal_beh等等,但是vp肯定是非终结(它被重写)。
然后我认为你应该写
s --> vp.
s --> vp,conj,vp.
s --> vp,conj,np.
vp -->
[feal_amr],
([mfoal_beh];[]),
([mfoal_beh];[]),
([bdl];[]),
[sefa_optional],
([hal];[]),
([shbh_gomla];[]),
([mfoal_motlk];[]).
% I hypotesize it's a comma.
conj --> [','].
编辑,如评论中所述,您不使用DCG,但您自己的解释器。我用最小的例子测试了它
:- op(700,xfx,--->).
s ---> [name,verb,names].
names ---> [name, conj, names].
names ---> [name].
names ---> [].
lex(anne, name).
lex(bob, name).
lex(charlie, name).
lex(call, verb).
lex(and, conj).
parse_topdown(Category,[Word|Reststring],Reststring,[Category,Word]) :-
lex(Word,Category).
parse_topdown(Category,String,Reststring,[Category|Subtrees]) :-
Category ---> RHS,
matches(RHS,String,Reststring,Subtrees).
matches([],String,String,[]).
matches([Category|Categories],String,RestString,[Subtree|Subtrees]) :-
parse_topdown(Category,String,String1,Subtree),
matches(Categories,String1,RestString,Subtrees).
并且该程序接受0,1或更多名称:
?- parse_topdown(s,[anne,call,bob,and,charlie],R,P).
R = [],
P = [s, [name, anne], [verb, call], [names, [name, bob], [conj, and], [names|...]]] ;
R = [charlie],
P = [s, [name, anne], [verb, call], [names, [name, bob], [conj, and], [names]]] ;
R = [and, charlie],
P = [s, [name, anne], [verb, call], [names, [name, bob]]] ;
R = [bob, and, charlie],
P = [s, [name, anne], [verb, call], [names]] ;
false.
注意我保留R自由,以检查部分匹配。回到原始问题,您可以看到非终结names
如何接受0,1或许多(由and
分隔)值。
请注意,这样的解释器在任何实质性输入上都会非常慢。我建议你用DCG重写你的语法。