Prolog - 证明树错过了可能性

时间:2017-03-23 14:04:19

标签: prolog logic-programming

我有以下Prolog计划:

p(f(X), Y) :- p(g(X), g(Y)).
p(g(X), Y) :- p(f(Y), f(X)).
p(f(a), g(b)).

必须为谓词p(X, Y)绘制prolog证明树。

Prolog - proof tree

问题

  • 为什么YY1/Y匹配而不与Y/Y1匹配?为什么Y会进一步使用?
  • 如果我匹配谓词(例如p(X, Y)),我会得到一个新的谓词(例如p(g(X1), g(Y))) - 为什么只包含p(g(X1), g(Y))一个子树?我的意思是,它不应该有3因为知识库包含3个语句 - 而不仅仅是1?
  • 为什么树的每一层都与X2 / X1等相匹配?而不是以前的谓词? 不应该是g(X1)/fX5, g(Y1)/Y5

注意:也许我似乎从未做过教程或其他什么。但是我做到了......我感谢每一个帮助。

2 个答案:

答案 0 :(得分:4)

说实话,我很少看到一个更差的方法来解释Prolog而不是你在这里展示的方法。

,我希望在这两种情况下,作者都会使用Y/Y1而不是Y1/Y,否则符号会非常不一致。

关于您的其他问题:您正面临着在采用Prolog的极其操作视图时出现的常见问题。核心问题是这种方法不能扩展:你没有心智能力来实现这种方法。不要把这个看成是个人:一般来说,人类不能保持执行树的所有细节都成倍地呈指数级增长。这使得整个方法非常麻烦且容易出错。为了比较,考虑一下人类大师们多年前已停止与国际象棋计算机竞争的原因。在这个具体案例中,请注意例如最右边的分支在实际的Prolog执行中甚至没有出现,但图表错误地暗示它确实存在!

此处的部分问题是术语的混淆:请注意Prolog使用统一(不是“匹配”,这是片面统一)。当统一目标 head 并且统一成功时,您会获得变量的绑定。您继续使用这些绑定

要使整个方法远程可行,请考虑您的程序的片段

例如,假设我为您提供以下事实

p(f(a), g(b)).

然后你查询:

?- p(X, Y).
X = f(a),
Y = g(b).

此答案显示XY绑定。首先要确保你理解这一点,并理解这些绑定与“新谓词”之间的区别(不会出现!)。

此外,没有“声明”,但有3个条款,这是合乎逻辑的替代

现在,再次简化整个任务,请考虑您的程序的以下片段,其中我查看两个规则

p(f(X), Y) :- p(g(X), g(Y)).
p(g(X), Y) :- p(f(Y), f(X)).

已经有了这个程序,我们得到:

?- p(X, Y).
nontermination

添加另一个纯子句不能阻止这种不确定。因此,我建议您从程序的缩减版本开始,并更深入地考虑它。

从那里,您可以再次添加剩余的事实,并考虑差异。

答案 1 :(得分:2)

非常好的问题!

  

为什么YY1/Y匹配而不与Y/Y1匹配?为什么Y会进一步使用?

此处的命名似乎有些随意,因为可以使用Y/Y1,但随后需要进一步使用Y1。在这种情况下,他们选择Y1/Y并进一步使用Y。虽然这个表达式树的作者在它们的约定中是不一致的,但我不会过于关注命名,就像它们是否正确地在树下跟踪变量一样。

  

如果我匹配谓词(例如p(X, Y)),我会得到一个新的谓词(例如p(g(X1), g(Y))) - 为什么只包含p(g(X1), g(Y))一个子树?我的意思是,它不应该有3因为知识库包含3个语句 - 而不仅仅是1个?

首先关于术语谓词的关联词。术语只是Head :- Body上下文中的谓词,在这种情况下,Head是构成谓词子句头部的术语。如果术语是谓词的参数(例如,p(g(X1), g(Y)),则g(X1)g(Y)不是谓词。它们只是术语。

更具体地说,在这种情况下,术语p(g(X1), g(Y))只有一个子树,因为它只匹配3个谓词子句中的一个的头部,这是一个头部p(g(X), Y)(与X = X1Y = g(Y)匹配)。其他两个无法匹配,因为它们的格式为p(f(...), ...)f(...)字词与g(X1)字词不匹配。

  

为什么树的每一层都与X2/X1之类的东西相匹配?而不是以前的谓词?   不应该是g(X1)/fX5, g(Y1)/Y5

我不确定我是否正在关注此问题,但遵循的原则是树正在尝试使用相同的变量名称,如果它适用于相同内存中的变量,而如果它是不同的 {{1},则使用不同的变量名称(例如X1X) }。例如,如果我有X而我foo(X, Y) :- <some code>, bar(f(X), Y).,那么bar(X, Y) :- blah(X), ...谓词中引用的Xbar中引用的X不同{1}}谓词。我们可以说,在致电foo时,我们正在调用foo(X, Y),或者bar(f(X), Y)调用bar(X1, Y)