Prolog 人工智能语言中文论坛---打造优质Prolog学习交流园地

一个供Prolog爱好者学习与交流的地方


您没有登录。 请登录注册

关于DCG rules的几个问题

浏览上一个主题 浏览下一个主题 向下  留言 [第1页/共1页]

1 关于DCG rules的几个问题 于 周一 十一月 26, 2012 2:07 am

1. Give the Prolog code produced by the DCG rule:
a --> b, c. (Don’t worry about the names used for variables; you can use any names you like.)

2. Assume we have a grammar similar to the one above (i.e. a --> b, c.), however it is a complete grammar with definitions for b, c, and whatever else is needed. Write a Prolog predicate, parse_a(WordList), that succeeds when WordList is an ‘a’ phrase in the grammar, that is, when it matches whatever the “a -->” rules are, with no words left over.

3.Here’s a simple grammar for arithmetic expressions:
代码:
 expression --> term.
 expression --> term, [ '+' ], expression.
 term --> factor.
 term --> factor, [ '*' ], term.
 factor --> [ Number ], { integer(Number) }.
Modify the grammar so that it computes the value of the expression and returns it as an argument. That is, change “expression -->”, to “expression.(Value) -->”, etc., and modify the rules so that Value gets set to the value of the expression.

4. Given the following database:
代码:
meat(beef).
meat(chicken).
vegetable(carrots).
vegetable(broccoli).
carnivore(john).
carnivore(mary).
vegetarian(bruce).
Write Prolog rules for eats(Person, Food), and hates(Person, Food) that satisfy the following properties:
Carnivores only eat meat and cheese
Vegetarians, only eat vegetables and cheese
If someone isn’t carnivore or vegetarian, they’re an omnivore and so they eat anything.
Everybody either eats a food or hates it; there’s no inbetween.

5. Given the grammar:
代码:
assertion(LF) --> np(S), vp(S^LF).
np(john) --> [john].
np(mary) --> [mary].
np(bruce) --> [bruce].
np(jenny) --> [jenny].
np(carrots) --> [carrots].
np(broccoli) --> [broccoli].
np(chicken) --> [chicken].
np(beef) --> [beef].
np(cheese) --> [cheese].
vp(S^LF) --> v(S^O^LF), np(O).
v(S^O^eats(S, O)) --> [eats].
v(S^O^hates(S, O)) --> [hates].
And the database from question 4 (including your answers), give the code for a Prolog predicate, verify, that takes a word list, parses it as an assertion in the grammar above, and returns succeeds if its logical form is true (given the database), and otherwise fails. Thus, verify([john, eats, cheese]) should succeed, but verify([jenny, hates, carrots]) should fail.


上面几个问题我没有翻译成中文,如果需要的话,我再翻译吧

查阅用户资料

2 回复: 关于DCG rules的几个问题 于 周三 十一月 28, 2012 8:08 am

回答答一题,其他你慢慢练习:
xhdengfei 写道::1. Give the Prolog code produced by the DCG rule:
a --> b, c. (Don’t worry about the names used for variables; you can use any names you like.)

这蛮简单。明确子句语法DCG的用途就是读句子、分解句子。 Prolog中用来表达句子最简单的方式就是列表,譬如 [this,is,a,book,'.'] 。而上面的 a --> b, c. 是语法的一条规则,说 a 这一条规则,是在句子前面先找到一个 b 接着再找到一个 c 。所以可以用下面这个查询
代码:
?- a([hello,world,!], Rest).
......
查询之後,就看语法规则能不能读出hello和world两个词,如果能读出两个词,则Rest会是剩下的[!]。像这样要读hello和world,全部语法要写成
代码:
a --> b, c.
b --> [hello].
c --> [world].

这样来看, a --> b, c. 这一条规则对应到 Prolog 程序,会是以下这样:
代码:
a(Sentence, Rest) :- b(Sentence, S1), c(S1, Rest).
至於若要说b和c对应,则是
代码:
b([hello|Rest], Rest).
c([world|Rest], Rest).

查阅用户资料 http://yauhsien.wordpress.com

3 回复: 关于DCG rules的几个问题 于 周五 十一月 30, 2012 5:15 am

我可能还没太理解DCG,那个第三题:

代码:
 expression --> term.
 expression --> term, [ '+' ], expression.
 term --> factor.
 term --> factor, [ '*' ], term.
 factor --> [ Number ], { integer(Number) }.


改成

代码:
 expression(Value,[]) --> term(Value).
 expression(Value,Rest) --> term(Value), [ '+' ], expression(Rest).
 term(Number) --> factor(Number).
 term(Number,Rest) --> factor(Number), [ '*' ], term(Rest).
 factor(Number) --> [ Number ], { integer(Number) }.

这样可以么

yauhsien 写道::回答答一题,其他你慢慢练习:
xhdengfei 写道::1. Give the Prolog code produced by the DCG rule:
a --> b, c. (Don’t worry about the names used for variables; you can use any names you like.)

这蛮简单。明确子句语法DCG的用途就是读句子、分解句子。 Prolog中用来表达句子最简单的方式就是列表,譬如 [this,is,a,book,'.'] 。而上面的 a --> b, c. 是语法的一条规则,说 a 这一条规则,是在句子前面先找到一个 b 接着再找到一个 c 。所以可以用下面这个查询
代码:
?- a([hello,world,!], Rest).
......
查询之後,就看语法规则能不能读出hello和world两个词,如果能读出两个词,则Rest会是剩下的[!]。像这样要读hello和world,全部语法要写成
代码:
a --> b, c.
b --> [hello].
c --> [world].

这样来看, a --> b, c. 这一条规则对应到 Prolog 程序,会是以下这样:
代码:
a(Sentence, Rest) :- b(Sentence, S1), c(S1, Rest).
至於若要说b和c对应,则是
代码:
b([hello|Rest], Rest).
c([world|Rest], Rest).

查阅用户资料

4 回复: 关于DCG rules的几个问题 于 周日 十二月 02, 2012 3:35 pm

xhdengfei 写道::我可能还没太理解DCG,那个第三题:

代码:
 expression --> term.
 expression --> term, [ '+' ], expression.
 term --> factor.
 term --> factor, [ '*' ], term.
 factor --> [ Number ], { integer(Number) }.


改成

代码:
 expression(Value,[]) --> term(Value).
 expression(Value,Rest) --> term(Value), [ '+' ], expression(Rest).
 term(Number) --> factor(Number).
 term(Number,Rest) --> factor(Number), [ '*' ], term(Rest).
 factor(Number) --> [ Number ], { integer(Number) }.

这样可以么

看起来一部分是对的。你说,譬如找 expres​sion(A,B,[1,'+',2,'*',3],R) 通过的结果会分为 A, B 二部份,但是往第二句後段一看,它会查一个 expres​sion(B) --> ... 但你系统中并没有 expression/3 规则。同理, term/3 (即 term(Number) --> ... ) 会用到但是 term/4 (即 term(Number,Rest) --> ... ) 不会用到。於是,这些语法经过你改写之後并没有重现原本的功能。

题目的意思是要加一个参数,让语法通过的结果由新加的参数传回。那就照题目指定的
代码:
expression(Value) --> term.
看起来可行,可是 term 句子读走一些符号之後并没有传回,那就会改成
代码:
expression(Value) --> term(Value).
term(Value) --> factor(Value).
factor(Value) --> [Number], { integer(Number), Value = Number }.
这样看起来实现了一半,是正确的。

到此要确认它可以正确运作,可以给这个查询:
代码:
?- expression(V,[1,'+',2,'*',3],R).
结果 V = 1 而 R = ['+',2,'*',3] 。

接下实现分二半的句子。刚开始像这样写,
代码:
expression(Value) --> term(Value1), ['+'], expression(Value2).
看起来也正确,只是 term(Value1) 取走一个项目,接着 expres​sion(Value2) 取走另一个项目,然後你可以想得到重点就在这里,只要 Value = [Value1,'+',Value2] 就是结果。所以接着是怎麽写,你可以再试试看。提示:大括号 { } 中间可以写普通的 prolog 句子。

DCG学习,可参考本站学习资源区 ?- like(kathy, Person). 於今年三月13日发的帖子,简单明白。

查阅用户资料 http://yauhsien.wordpress.com

5 回复: 关于DCG rules的几个问题 于 周日 十二月 02, 2012 8:19 pm

谢啦,我后来想到怎么写了

代码:
expression(Value) --> term(Value).
 expression(Value) --> term(X), [ '+' ], expression(Y),{Value is X + Y}.

 term(Number) --> factor(Number).
 term(Number) --> factor(X), [ '*' ], term(Y),{Number is X * Y}.

 factor(Number) --> [ '+' ], factor(Number).
 factor(Number) --> [ Number ], { integer(Number) }.


yauhsien 写道::
xhdengfei 写道::我可能还没太理解DCG,那个第三题:

代码:
 expression --> term.
 expression --> term, [ '+' ], expression.
 term --> factor.
 term --> factor, [ '*' ], term.
 factor --> [ Number ], { integer(Number) }.


改成

代码:
 expression(Value,[]) --> term(Value).
 expression(Value,Rest) --> term(Value), [ '+' ], expression(Rest).
 term(Number) --> factor(Number).
 term(Number,Rest) --> factor(Number), [ '*' ], term(Rest).
 factor(Number) --> [ Number ], { integer(Number) }.

这样可以么

看起来一部分是对的。你说,譬如找 expres​sion(A,B,[1,'+',2,'*',3],R) 通过的结果会分为 A, B 二部份,但是往第二句後段一看,它会查一个 expres​sion(B) --> ... 但你系统中并没有 expression/3 规则。同理, term/3 (即 term(Number) --> ... ) 会用到但是 term/4 (即 term(Number,Rest) --> ... ) 不会用到。於是,这些语法经过你改写之後并没有重现原本的功能。

题目的意思是要加一个参数,让语法通过的结果由新加的参数传回。那就照题目指定的
代码:
expression(Value) --> term.
看起来可行,可是 term 句子读走一些符号之後并没有传回,那就会改成
代码:
expression(Value) --> term(Value).
term(Value) --> factor(Value).
factor(Value) --> [Number], { integer(Number), Value = Number }.
这样看起来实现了一半,是正确的。

到此要确认它可以正确运作,可以给这个查询:
代码:
?- expression(V,[1,'+',2,'*',3],R).
结果 V = 1 而 R = ['+',2,'*',3] 。

接下实现分二半的句子。刚开始像这样写,
代码:
expression(Value) --> term(Value1), ['+'], expression(Value2).
看起来也正确,只是 term(Value1) 取走一个项目,接着 expres​sion(Value2) 取走另一个项目,然後你可以想得到重点就在这里,只要 Value = [Value1,'+',Value2] 就是结果。所以接着是怎麽写,你可以再试试看。提示:大括号 { } 中间可以写普通的 prolog 句子。

DCG学习,可参考本站学习资源区 ?- like(kathy, Person). 於今年三月13日发的帖子,简单明白。

查阅用户资料

6 回复: 关于DCG rules的几个问题 于 周一 十二月 03, 2012 1:15 am

like(kathy, Person).....
y大太有创意了,哈哈。

yauhsien 写道::
xhdengfei 写道::我可能还没太理解DCG,那个第三题:

代码:
 expression --> term.
 expression --> term, [ '+' ], expression.
 term --> factor.
 term --> factor, [ '*' ], term.
 factor --> [ Number ], { integer(Number) }.


改成

代码:
 expression(Value,[]) --> term(Value).
 expression(Value,Rest) --> term(Value), [ '+' ], expression(Rest).
 term(Number) --> factor(Number).
 term(Number,Rest) --> factor(Number), [ '*' ], term(Rest).
 factor(Number) --> [ Number ], { integer(Number) }.

这样可以么

看起来一部分是对的。你说,譬如找 expres​sion(A,B,[1,'+',2,'*',3],R) 通过的结果会分为 A, B 二部份,但是往第二句後段一看,它会查一个 expres​sion(B) --> ... 但你系统中并没有 expression/3 规则。同理, term/3 (即 term(Number) --> ... ) 会用到但是 term/4 (即 term(Number,Rest) --> ... ) 不会用到。於是,这些语法经过你改写之後并没有重现原本的功能。

题目的意思是要加一个参数,让语法通过的结果由新加的参数传回。那就照题目指定的
代码:
expression(Value) --> term.
看起来可行,可是 term 句子读走一些符号之後并没有传回,那就会改成
代码:
expression(Value) --> term(Value).
term(Value) --> factor(Value).
factor(Value) --> [Number], { integer(Number), Value = Number }.
这样看起来实现了一半,是正确的。

到此要确认它可以正确运作,可以给这个查询:
代码:
?- expression(V,[1,'+',2,'*',3],R).
结果 V = 1 而 R = ['+',2,'*',3] 。

接下实现分二半的句子。刚开始像这样写,
代码:
expression(Value) --> term(Value1), ['+'], expression(Value2).
看起来也正确,只是 term(Value1) 取走一个项目,接着 expres​sion(Value2) 取走另一个项目,然後你可以想得到重点就在这里,只要 Value = [Value1,'+',Value2] 就是结果。所以接着是怎麽写,你可以再试试看。提示:大括号 { } 中间可以写普通的 prolog 句子。

DCG学习,可参考本站学习资源区 ?- like(kathy, Person). 於今年三月13日发的帖子,简单明白。

查阅用户资料 http://prolog.longluntan.net

浏览上一个主题 浏览下一个主题 返回页首  留言 [第1页/共1页]

您在这个论坛的权限:
不能在这个论坛回复主题