如何在SWI-Prolog中编写可选
我需要用Prolog实现一些规则 例:如何在SWI-Prolog中编写可选,prolog,dcg,Prolog,Dcg,我需要用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];[]), ([mfoa
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).
和“->”给出运算符的错误“:-”
这是我的密码
很抱歉给您带来不便,但我不是Prolog方面的专家首先,您可能需要小写S和A;Prolog对变量名使用首字母大写 允许“b”出现一次或根本不出现的一种方法是这样写:
s --> a, b_optional, {c}.
b_optional --> [b].
b_optional --> [].
如果您愿意,还可以将b_的两条规则作为一条规则编写为可选的语法;查阅你最喜欢的序言文本中关于定冠词语法的章节
我不知道你说的c发生在0,1,2。。。好几次了,所以我想我帮不了你 根据您的描述
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自由地检查部分匹配。回到原始问题,您可以看到非终结符名称如何接受0、1或多个(由和分隔)值
请注意,这种解释器在任何实质性输入上都会非常慢。我建议你用DCG重写语法。谢谢你的回答。关于{c}。。我的意思是它只能是(a,b)或(a,b,c)或(a,b,c,c)或(a,b,c,c)。。。还有一个问题,如果我有s-->a,b,c,其中b,c是可选的,它们中的任何一个都可能出现一次或没有。。我怎样才能展示它?我将写入s-->a、b_可选、c_可选。b_可选-->[b]。b_可选-->[]。c_可选-->[c]。c_可选-->[]。或者什么?对不起,我误解了你对[]和{}的用法。我猜你现在用[b]
来表示“可选的b”,用{c}
来表示“可选的可重复的c”。这种混淆是因为方括号和花括号在定冠词语法中都有意义;在DCG中,{c}
在语法规则的该点插入对谓词c
的调用,当且仅当c
成功且与输入中的任何内容均不匹配时,该调用才会成功。当我在代码中使用它时,它会给我一个错误“子句体中的句号?无法重新定义,/2”感谢您的回复,忘了“conj”吧我只放了一部分代码。。很抱歉,关于'-->'我使用它,因为我有这样一个:parse_-top-down(Category,String,Reststring,[Category,Subtrees]):-Category-->RHS,matches(RHS,String,Reststring,Subtrees)。
所以如果我使用“->”而不是“-->”与运算符一起使用“:-”它会给出一个错误,很抱歉给您带来不便,但我不是Prolog方面的专家:(我为代码添加了一个链接,你能帮我吗?提前谢谢我的原始答案不合适。我可以看出-->是由parse_top down解释的。然后你应该尝试一种最小语法,使用这种形式接受0,1,…出现次数。我会尝试,但我绝对不能肯定我会成功…谢谢你的帮助。)