Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在SWI-Prolog中编写可选_Prolog_Dcg - Fatal编程技术网

如何在SWI-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

我需要用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).
和“->”给出运算符的错误“:-”

这是我的密码


很抱歉给您带来不便,但我不是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,…出现次数。我会尝试,但我绝对不能肯定我会成功…谢谢你的帮助。)