我需要通过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 专家
最佳答案
根据您的描述
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 或多个(由 和
分隔)值。
请注意,此类解释器在处理任何大量输入时都会非常慢。我建议您使用 DCG 重写语法。
关于prolog - 如何在SWI-Prolog中编写可选,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13895668/