我有以下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证明树。
问题:
Y
与Y1/Y
匹配而不与Y/Y1
匹配?为什么Y
会进一步使用?p(X, Y)
),我会得到一个新的谓词(例如p(g(X1), g(Y))
) - 为什么只包含p(g(X1), g(Y))
一个子树?我的意思是,它不应该有3因为知识库包含3个语句 - 而不仅仅是1?g(X1)/fX5, g(Y1)/Y5
?注意:也许我似乎从未做过教程或其他什么。但是我做到了......我感谢每一个帮助。
答案 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).
此答案显示X
和Y
的绑定。首先要确保你理解这一点,并理解这些绑定与“新谓词”之间的区别(不会出现!)。
此外,没有“声明”,但有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)
非常好的问题!
为什么
Y
与Y1/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 = X1
和Y = g(Y)
匹配)。其他两个无法匹配,因为它们的格式为p(f(...), ...)
且f(...)
字词与g(X1)
字词不匹配。
为什么树的每一层都与
X2/X1
之类的东西相匹配?而不是以前的谓词? 不应该是g(X1)/fX5, g(Y1)/Y5
?
我不确定我是否正在关注此问题,但遵循的原则是树正在尝试使用相同的变量名称,如果它适用于相同内存中的变量,而如果它是不同的 {{1},则使用不同的变量名称(例如,X1
与X
) }。例如,如果我有X
而我foo(X, Y) :- <some code>, bar(f(X), Y).
,那么bar(X, Y) :- blah(X), ...
谓词中引用的X
与bar
中引用的X
不同{1}}谓词。我们可以说,在致电foo
时,我们正在调用foo(X, Y)
,或者bar(f(X), Y)
调用bar(X1, Y)
。