现在学 Prolog 合一和证明搜索

本文深入探讨了Prolog中的合一概念,包括常量、变量和复合项的合一规则。文章通过示例解释了合一的过程,并介绍了Prolog的内置谓词= / 2如何测试两个项是否合一。此外,文章还介绍了Prolog的证明搜索策略,展示了如何通过搜索知识库来确定查询是否可满足。证明搜索涉及到目标列表、回溯和选择点的概念,通过图形表示法帮助理解搜索过程。
摘要由CSDN通过智能技术生成

转载自:https://mp.weixin.qq.com/s/SeMjK-_XR69jSQEQ-iRHMg

本章有两个主要目标:

1. 讨论Prolog中的合一,并解释Prolog合一与标准合一有何不同。在此过程中,我们将introduce/ 2,Prolog合一的内置谓词,并与check / 2合一,即标准合一的内置谓词。

2. 解释Prolog在尝试使用惯用方式从旧信息中推断出新信息时使用的搜索策略。

 

合一

在上一章中使用知识库KB4时,我们简要提到了合一的思想。例如,我们说过Prolog将woman(X)与woman(mia)进行合一,从而将变量X实例化为mia。现在是时候仔细研究合一了,因为它是Prolog中最基本的思想之一。

  回想一下,有三种项:

 

1.常数。这些可以是原子(如vincent)或数字(如24)。

2.变量。 (如X,Z3和List。)

3.复合项。它们具有以下形式:

   functor(term_1,…,term_n).

 

    我们将努力确定Prolog何时将两个项合一的绑定。我们的出发点将是以下绑定过程。它给出了基本的直觉,但在细节上略有改动:

    两个项是合一的,还是它们包含可以用项合一实例化的变量,使得结果的项相等。

 

例如,这意味着项mia和mia合一,因为它们是同一原子。类似地,项42和42合一(因为它们是相同的数字),项X和X合一(因为它们是相同的变量),而项woman(mia)和woman(mia)合一,因为它们是相同的复合项。但是,项woman(mia)和woman(vincent)并不合一,因为它们不相同(并且它们都不包含可以实例化以使其相同的变量)。

  现在,项mia和X呢?它们并不相同,但是变量X可以实例化为mia,这使它们相等。因此,根据我们的工作定义的第二部分,mia和X是合一的。类似地,项woman(X)和woman(mia)是合一的,因为可以通过将X实例化为mia来使它们相等。loves(vincent,X)和loves(X,mia)怎么样?不能。不可能找到使两个项相等的X的实例。你明白为什么吗?将X实例化为vincent会使我们得到loves(vincent,vincent)和loves(vincent,mia)这两个项,这显然是不相等的。但是,将X实例化为mia会产生loves(vincent,mia)和loves(mia,mia)项,两者也不相等。

  通常,我们不仅对两个项合一这一事实感兴趣,而且我们还想知道如何实例化变量才能使其相等。而Prolog向我们提供了这些信息。当Prolog合一两个项时,它将执行所有必要的实例化,因此之后这些项实际上是相等的。此功能以及允许我们构建复杂项(即递归结构的项)的事实,使合一成为一种强大的编程机制。

  基本直觉现在应该清楚了。这是使它们精确的定义。它不仅告诉我们Prolog将合一哪些项,而且还告诉我们变量将如何实现这一目标。

 

1.如果term1和term2是常数,则term1和term2当且仅当它们是相同的原子或相同的数字时才合一。

2.如果term1是变量,而term2是任何类型的项,则term1和term2合一,并且term1实例化为term2。同样,如果term2是变量,而term1是任何类型的term,则term1和term2合一,并且term2实例化为term1。 (因此,如果它们都是变量,则它们都将彼此实例化,并且我们说它们共享值。)

3.如果term1和term2是复合项,则只有在以下情况下它们才可以合一:

(a)它们具有相同的函子和元数,并且

(b)所有其相应的参数合一,并且

(c)变量实例是兼容的。 (例如,在合一一对参数时无法将变量X实例化为mia,而在合一另一对参数时则无法将变量X实例化为vincent。)

 

4.当且仅当这两个项是根据前三个条款的合一来合一的。

 

  让我们看看这个定义的形式。第一个条款告诉我们两个常量何时合一。第二个条款告诉我们何时两个项(其中一个是变量)合一(这些项将始终合一;变量与任何事物合一)。同样重要的是,该条款还告诉我们必须执行哪些实例化才能使两个项相同。最后,第三个条款告诉我们两个复合项何时合一。注意此定义的结构。它的前三个条款完美地反映了项的(递归)结构。

  第四条很重要:它说前三个条款告诉我们所有关于两个项合一的知识。如果使用1-3条无法显示两个项可以合一,那么它们就不能合一。例如,batman不与daughter(ink)合一。那么为什么呢?第一个项是一个常数,第二个项是一个复合项。但是前三条中没有一个告诉我们如何合一两个这样的项,因此(按第4条)它们不是合一的。

 

例子

为了确保我们完全理解此定义,让我们来看几个示例。在这些示例中,我们将使用一个重要的内置谓词= / 2谓词(回想一下,在末尾写/ 2表示该谓词带有两个参数)。

= / 2谓词测试其两个参数是否合一。例如,如果我们构成查询

 

?- =(mia,mia).

 

Prolog将回答true,如果我们提出查询

 

?- =(mia,vincent).

 

Prolog会回应 false.

但是我们通常不会以这种方式提出这些查询。面对现实吧,=(mia,mia)表示法是很不自然的。如果我们可以使用中缀表示法(即,可以将= / 2函子放在其参数之间)并编写类似以下内容,那就更好了:

 

?-mia = mia.

 

实际上,Prolog允许我们执行此操作,因此在以下示例中,我们将使用中缀表示法。

让我们回到第一个示例:

 

?- =(mia,mia).

true.

 

为什么Prolog会说true.?这似乎是一个愚蠢的问题:毫无疑问,x项的合一!是的,但是从上面给出的定义来看,这是怎么做的?重要的是要学会系统地思考合一(这对Prolog来说是根本的),而系统地思考意味着将示例与上述给出的合一定义联系起来。因此,让我们仔细考虑一下这个示例。

该定义包含三个条款。现在,条款2是针对一个参数是变量的情况,条款3是针对两个参数都是复合项的情况,因此在这里没有用。但是,条款1与我们的示例有关。这告诉我们两个常数在且仅当它们是完全相同的对象时才合一。由于mia和mia是同一原子,因此合一成功。

类似的参数解释了以下响应:

 

?- 2=2.

true.

 

?- mia = vincent.

false.

 

再次,条款1在这里是相关的(毕竟,2,mia和vincent都是常量)。由于2与2相同,并且mia与vincent是不同的原子,因此Prolog对第一个查询回答“true”,对第二个查询回答“false”。

但是,条款1确实给我们带来了一个小惊喜。考虑以下查询:

 

?- 'mia' = mia.

true.

 

这里发生了什么?为什么这两个项合一?好吧,就Prolog而言,“ mia”和mia是同一个原子。实际上,对于Prolog,任何形式为“符号”的原子都被视为与形式符号的原子相同的实体。在某些程序中,这可能是有用的功能,所以请不要忘记它。

另一方面,要查询

 

?- '2'=2.

false.

 

Prolog将回答false。而且,如果您考虑第1章中给出的定义,您将发现这必须是这样的工作方式。毕竟2是一个数字,而 ‘2’是一个原子。它们根本是不能相同的。

让我们尝试一个带有变量的示例:

 

?- mia = X.

X = mia.

 

再次,这是一个简单的示例:显然,变量X可以与常量mia合一,而Prolog可以这样做,并告诉我们它已经实现了合一。很好,但是从我们的定

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值