在Prolog中递归成功

问题描述

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

我不知道这是怎么工作的。 如果我运行查询

add(succ(succ(succ(0))),succ(succ(0)),R)

它如何从第一个参数中删除succ?

如果我运行它:

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

这使身体满意。我们将它们输入头部:

add(succ(X),succ(Z)) %% becomes
add(succ(succ(succ(0))),succ(R))

即在我看来,它似乎只是添加succ,而不是将它们从第一个参数中删除?我看到还有关于此确切问题的另一篇文章,但这对我来说没有意义。

解决方法

当您调用目标$ persistent.playthrough = 1 $ persistent.anticheat = renpy.random.randint(100000,999999) $ renpy.save_persistent() $ delete_character("sayori") $ in_sayori_kill = True 时,Prolog尝试执行以add(succ(succ(succ(0))),succ(succ(0)),R)为首的子句时,发生统一。统一是Prolog的核心概念之一,重要的是要了解它。统一也是add(succ(X),Y,succ(Z))运算符执行的操作。执行该子句的开头时所发生的情况与执行以下等效查询时所发生的情况完全相同:

=

重要的是要理解,统一不仅是“解包”或“建立”术语,而且是同时

它可以从术语“提取”信息:

?- add(succ(succ(succ(0))),R) = add(succ(X),succ(Z)).

在这里我们发现?- X = f(a),Y = f(Z),X = Y. X = Y,Y = f(a),Z = a. af仿函数的参数。

它可以“构建”术语:

X

在这里,我们将术语?- X = f(Y),Y = g(h). X = f(g(h)),Y = g(h). “插入”到g(h)的“孔” Y中。

它也可以同时完成多个术语:

X

此处统一将两个?- X = f(a,B),Y = f(A,b),Y = f(a,B = b,A = a. 术语“拆包”,然后在每个术语中“填充”一个孔。

现在,有了这些知识,您的示例中的统一有什么用?

f

尤其是,当?- add(succ(succ(succ(0))),succ(Z)). R = succ(Z),X = Y,Y = succ(succ(0)). succ(succ(succ(0)))统一时,这会将succ(X)绑定到Xsucc(succ(0)) 绑定到整个术语X,而仅绑定到“内部”部分。这就是从参数中删除succ(succ(succ(0)))一级的原因。