Prolog查询 - 试图了解这种结果是如何发生的

时间:2013-11-25 04:14:47

标签: prolog

所以我试图从Prolog中找出一些东西,但我不确定为什么我得到的结果是我得到的。鉴于这个定义:

families(_, Smith, lucy, _, jeff, Smith).

和这个查询:

?- families(Ford, nancy, Ford, jeff, Smith, White).

为什么这是结果?:

Ford = lucy,
Smith = jeff,
White = nancy.

谢谢!

2 个答案:

答案 0 :(得分:3)

(注意:开场后和结束括号前不需要留空格。另外,如果这是作业,你应该这样说。)

families/6的定义,

families(_, Smith, lucy, _, jeff, Smith).

表示:

  1. 忽略第一个参数和第四个参数(下划线);
  2. 统一第二个和最后一个参数(两个参数由相同的变量名称​​ Smith 引用);
  3. 用原子lucy;
  4. 统一第三个参数
  5. 用原子jeff统一第五个参数。
  6. 现在您的查询,

    ?- families(Ford, nancy, Ford, jeff, Smith, White).
    

    问:

    • 你能用同一个变量 Ford 统一第一个和第三个参数吗?
      • 是的,你可以,现在Ford = lucy(来自定义中的3.)。
    • 第二个参数可以是原子nancy吗?
      • 是,White = nancy(来自定义中的2.)
    • 第四个参数可以是原子jeff吗?
      • 是的,但这没有任何影响(从定义中的1.)
    • 你能用变量 Smith 统一第五个参数吗?
      • 是,和Smith = jeff(定义中的4.)。

    现在应该清楚,假设你知道统一是如何运作的。重要的是定义和查询中的变量名称位于不同的上下文中,并且具有相同的名称意味着什么(如在定义中的位置2和6中的 Smith Smith 在查询中的第5位。)

    总而言之,这是一个复杂的例子,它使用变量和原子名称来试图混淆人类读者。它会强迫你注意,并且可以作为糟糕编程风格的一个例子。

答案 1 :(得分:2)

作为the answer by Boris的视觉辅助,我们可以将谓词和查询写在另一个旁边,

   families( _   , Smith, lucy, _   , jeff , Smith).
?- families( Ford, nancy, Ford, jeff, Smith, White).

现在,定义中的 Smith 和查询中的 Smith 相同!每个谓词都有自己的“namespace”,因为谓词的变量是在谓词的使用上重命名的。所以我们实际上在这里

   families( _   , A    , lucy, _   , jeff , A    ).
?- families( Ford, nancy, Ford, jeff, Smith, White).

匹配,产生替换

_=Ford, A=nancy, lucy=Ford, _=jeff, jeff=Smith, A=White.

Ford=lucy, Smith=jeff, White=nancy.

最后一个是 White=A A=nancy 的结果。 A 本身未报告,因为它不是查询的逻辑变量之一。