2012-04-25 99 views
4

有人可以向我解释为什么这个序言查询的工作方式。该定义是:如何使用succ通过递归查询运行prolog?

add(0,Y,Y). 
add(succ(X),Y,succ(Z)):- add(X,Y,Z). 

鉴于此:

?- add(succ(succ(succ(0))), succ(succ(0)), R). 

继承人的查询跟踪:

Call: (6) add(succ(succ(succ(0))), succ(succ(0)), R) 

Call: (7) add(succ(succ(0)), succ(succ(0)), _G648) 

Call: (8) add(succ(0), succ(succ(0)), _G650) 

Call: (9) add(0, succ(succ(0)), _G652) 

Exit: (9) add(0, succ(succ(0)), succ(succ(0))) 

Exit: (8) add(succ(0), succ(succ(0)), succ(succ(succ(0)))) 

Exit: (7) add(succ(succ(0)), succ(succ(0)), 
               succ(succ(succ(succ(0))))) 

Exit: (6) add(succ(succ(succ(0))), succ(succ(0)), 
               succ(succ(succ(succ(succ(0)))))) 

是困惑我最了解该教程是事实的一部分,在第一个参数,succ被剥离,并且它递归。虽然递归虽然,R获得succ ...如何?!另外,零在哪里从第一个出口(9)出发?我对prolog很陌生,我正在努力理解作业的语言。任何帮助非常感谢。先谢谢了。

注:有兴趣的人,链接,本教程是http://www.learnprolognow.org/lpnpage.php?pagetype=html&pageid=lpn-htmlse9

+0

通常,'succ/1'写成's/1'。请看标签[tag:successor-arithmetics]的答案。 – false 2012-04-25 07:24:35

回答

1

“哪里零来自在第一个出口(9)?”

呼叫add(0, succ(succ(0)), _G652)是统一的,说的是,如果add第一个参数是零,那么第二个和第三个是相同的第一条。在这个特定的情景变量_G652变成succ(succ(0))

“虽然递归,但R获得了成功......如何?!”

这是应用第二个子句的结果。本条款(粗略地)声明,您首先从第一个参数中剥离succ,然后递归地调用add,最后,向从此递归调用返回的第三个参数添加另一个“层”succ

谓词add不过在皮亚诺算术直接实现加:http://en.wikipedia.org/wiki/Peano_axioms#Addition

+0

我明白你在说什么了,我对此多了解一点。我不理解的是,规则的头也在做一些事情,我只是假设它没有做任何事情,直到尸体被证明。 – Andy 2012-04-25 19:19:27

4

你看,callexitverbs,行动的解释采取试图解决您提出的查询。然后跟踪将显示已完成的实际工作的详细信息,并让您以历史视角查看它。

当Prolog的必然选择规则(一call),它使用你给它name(所谓functor),并试图以unify在规则的头上,每种说法。然后我们通常会说Prolog也考虑了arity,即参数的数量,以供选择。

Unification试图使'等于'两个词,而值得注意的结果是所谓的bindings变量。您已经知道变量是从Uppercase开始的那些名称。这些名称标识规则中未指定的值,即参数为placeholders。为了避免混淆,当Prolog显示跟踪时,变量被重命名,以便我们可以识别它们,因为相关的细节是identities或证据期间建立的绑定。

然后你会看到跟踪中的这样的_G648符号。他们停留在尚未被实例化的被叫目标的论点,即RZ。 R是唯一的(只发生在顶级调用中),所以这个Prolog很好地保持用户友好的名称,但是Z来自程序,可能会多次出现,然后重新命名。

为了回答这个查询

?- add(succ(succ(succ(0))), succ(succ(0)), R). 

Prolog的第一次尝试,以匹配

add(0,Y,Y). 

和失败,因为SUCC(SUCC(SUCC(0))不能进行等于0 然后企图

add(succ(X),Y,succ(Z)) :- add(X,Y,Z). 

因此必须解决这些绑定(向左调用者的条款):

succ(succ(succ(0))) = succ(X) 
succ(succ(0)) = Y 
R = Z 

你可以看到为什么X变得succ(succ(0)),我们有一个新的目标来证明,即规则主体add(X,Y,Z)与刚成立的绑定:

加(SUCC(SUCC(0)),SUCC (SUCC(0)),_ G648)

等等......直到X变得0和目标相匹配

add(0,Y,Y).

然后Y变成succ(succ(0)),值得注意的是在调用规则中给出了Z的值。

HTH