2013-05-15 21 views
0

我在Prolog中使用Ivan Bratko书籍“人工智能编程”研究DCG语法,并发现一些问题以了解Prolog如何自动转换DCG语法进入一套Prolog规则。关于Prolog如何自动将DCG语法转换为一组规则的疑问

例如我有以下的DCG语法:

move --> step. 
move --> step, move. 

step --> [up]. 
step --> [down]. 

其中:

moove是不可能性mooves的列表,并一步是一个单一的举动,可能是down

因此,它说一个动作列表可以是一个动作(一个步骤)或一个列表,一个由更多动作组成的列表,可以看作是一个动作(一个步骤),然后是一个动作列表(动作)。

所以这个语法可以生成词组,如下面的列表:向上,向下,向下,向上,向下]或类似:[高达]

这是非常简单的

然后,他展示了如何Prolog的自动前面的DCG语法转换成一套标准的序言规则(我已经改名为MOVE2和第二步,只是因为我已经在前面的DCG文法的同一个文件把这段代码):

/* move2 it is TRUE if the difference from the lists List and Rest is an 
    acceptable move. 
*/ 

/* BASE CASE: A moves list can be a single move (a step that can be "up" or "down") 
    It is TRUE that the difference from the lists List and Rest is an acceptable move 
    if it is TRUE that the head of the list is an acceptable move 
*/ 
move2(List, Rest) :- step2(List, Rest). 

/* GENERAL CASE: A moves list can be a single move followed by a list of moves. 
    The difference of List1 and Rest is a valid move if it is TRUE that: 
    the difference between List1 and List 2 is a step 
    the difference between List2 and Rest is a move 
*/ 
move2(List1, Rest) :- step2(List1, List2), 
         move2(List2, Rest). 

/* step predicate extract a single step ("up" or "down") from a list 
*/ 
step2([up|Rest], Rest). 

step2([down|Rest], Rest). 

我试图解释这些规则的意义,正如我写在评论,但我不太清楚我的解释...

你能给我一些提示,以便理解它吗?

TNX

安德烈

回答

0

我不认为有什么不对的代码或你的解释,但我觉得你看它“声明”不看它作为DCG。我可能会写这样的代码来代替:

step --> [up]. 
step --> [down]. 

move --> []. 
move --> step, move. 

这应该等价工作,但是这将是一个更容易扩展和维护比你的,因为它没有明确地保持差异列表。

越接近你可以让你的Prolog自然语言表达你的意图越好。如果需要大量的文字来解释你的代码是如何工作的,那么你就是在程序上编程。上面的Prolog与我们可以开箱即用的接近。我们可以通过创建一些助手走得更远:

one_or_more(_, []) --> []. 
one_or_more(R, [V|Vs]) --> 
    { Rule =.. [R, V] }, 
    Rule, 
    one_or_more(R, Vs). 

step(up) --> [up]. 
step(down) --> [down]. 

moves(Steps) --> one_or_more(step, Steps). 

(上面的代码是未经测试)的一点是要说明声明性编程的力量。编写诸如one_or_more//2这样的谓词可能会有更多的工作,但是一旦拥有它,程序的其余部分就会被提升为更具说明性的风格。有些评论可能需要在one_or_more//2左右,因为它不是很明显它如何工作如果它甚至可以工作)。上述的陈述性阅读是“移动(步骤)匹配一个或多个步骤”。这与我的原始版本的陈述性阅读以及对你的陈述性阅读是一样的。不同之处在于每个代码更接近显而易见的陈述性阅读。

+0

您的'移动// 0'不等于OP张贴的内容,因为它也接受空列表,但是OP的定义没有。另外'one_or_more // 2'应该被称为'zero_or_more // 2'来反映这一点。 – mat

+0

mmm我对这行代码有一些怀疑:Rule = .. [R,V] 什么是= ..? – AndreaNobili

+0

这是“univ”运算符,它构造了术语。尝试一下。 –