使用PROLOG进行逻辑编程:简单的例子


 

我们从第35页的例3.2中的家族关系开始。小知识库KB被编码没有谓词女性的事实作为图5.1中名为rel.plPROLOG程序。

可以使用该命令在PROLOG解释器中加载和编译该程序

 

– [rel]

1.  
简单例子69

图片

初始查询返回对话框

 

孩子(夏娃,奥斯卡,安妮)。

 

 

正确答案是的。这个答案是如何产生的?对于查询
child
eveoscaranne)。
在其条款标题中有六个事实和一个规则具有相同的谓词。现在,在查询与输入数据中的每个互补文字之间按照发生的顺序进行统一。如果其中一个替代方案失败,则会导致回溯到最后一个分支点,并测试下一个替代方案。因为统一在每个事实中都失败了,所以查询与第8行中的递归规则统一。现在系统尝试解决子目标子(eveanneoscar,这与第三种选择成功。查询

后代(XY)。X =奥斯卡

Y =凯伦是的

回答第一个找到的解决方案,原样

 

后裔(克莱德,Y)。Y =玛丽

 

查询

 

后裔(克莱德,卡伦)。

 

图片

然而,没有回答。其原因是第8行中的子句,它指定了子谓词的对称性。该子句以递归方式调用自身而不具有终止的可能性。这个问题可以通过以下新程序解决(这里省略了事实)。

 

 

 

1.
后代(XY):子(XYZ)。

2.
后代(XY):子(XZY)。

3.
后代(XY):子(XUV),后代(UY)。

但现在查询

 

孩子(夏娃,奥斯卡,安妮)。

 

图片

不再正确回答,因为不再给出最后两个变量中的对称性。该程序中找到了解决这两个问题的方法

 

 

4.  
child_fact(奥斯卡,克伦,弗朗兹)。

5.  
child_fact(玛丽,克伦,弗朗兹)。

6.  
child_factEVA,安,奥斯卡)。

7.  
child_fact(亨利,安,奥斯卡)。

8.  
child_fact(伊索尔德,安,奥斯卡)。

9.  
child_fact(克莱德,玛丽,oscarb)。7

10.     
childXZY): – child_factXYZ)。

11.     
childXZY): – child_factXZY)。10

12.
后代(XY):子(XYZ)。

13.
后代(XY):子(XUV),后代(UY)。

 

通过为事实引入新的谓词child_fact,谓词子节点不再是递归的。但是,该程序不再像第68 页的图5.1中的逻辑正确的第一个变体那样优雅和简单,这导致了无限循环。与其他语言一样,PROLOG程序员必须注意处理并避免无限循环。PROLOG只是一种编程语言,而不是一个定理证明者。

我们必须在这里区分PROLOG程序的声明程序语义。声明性语义由喇叭子句的逻辑解释给出。相反,程序语义是由PROLOG程序的执行定义的,我们希望现在更详细地观察它。使用查询子项(eveoscaranne执行第 68 页的图 5.1 中的程序,如第 71 页的图
5.2
所示,作为搜索

树。1执行从左上角开始查询。每条边代表一个位置

sible SLD解决步骤与互补的统一文字。当搜索树通过递归规则变得无限深时,PROLOG执行终止,因为事实发生在输入数据中的规则之前。

图片

相反,对于查询后代(clydekarenPROLOG执行不会终止。我们可以在第71 页的图5.3中显示的/或树中清楚地看到这一点。在这种表示中,由一个条款的头部引导到子目标的分支代表。因为必须解决子句的所有子目标,所以这些是和分支。所有其他分支是或分支,其中至少一个必须与其父节点一致。这两个概述的事实代表了

 

图片

1 常量缩写为节省空间。

2.  
执行控制和程序要素71

图片

 

图片图片

 

5.2 儿童的PROLOG搜索树(夏娃,奥斯卡,安妮)

 

图片

 

5.3 或树递减(克莱德,卡伦

 

查询的解决方案。然而,PROLOG解释器并没有在这里终止,因为它通过使用带有回溯的深度优先搜索(参见第6.2.2节)来工作,因此首先选择到最左边的无限深的路径。

 

图片


 


ETC注销ETC充值ETC客服ETC扣费查询


ETC发行合作

发表回复