test.pl文件
room(kitchen). room(office). room(hall). room('dining room'). room(cellar). location(desk,office). location(apple,kitchen). location(flashlight,desk). location('washing mechine',cellar). location(nani,'washing mechine'). location(broccoli,kitchen). location(crackers,kitchen). location(computer,office). door(office,hall). door(kitchen,office). door(hall,'dining room'). door(kitchen,cellar). door('dining room',kitchen). edible(apple). edible(crackers). tastes_yucky(broccoli). turned_off(flashlight). here(kitchen).
localtion() 和 door() 中的变量是区分顺序的,如:
?-location(desk,office).
true
?-location(office,desk).
false
?-door('dining room',kitchen).
true
?-door(kitchen,'dining room').
false
prolog程序的运行机理
1、自由变量 约束变量
prolog中无值的变量称之为自由变量,有值的变量称之为约束变量。
一个变量取了某值,就称该变量约束于某值,或者该变量被某值约束,或者该变量被某值实例化了。
在程序运行过程中,自由变量可以被实例化成为约束变量;一个约束变量也可以解除其值成为自由变量。
2、匹配合一
两个谓词可以匹配合一,指两个谓词的名相同,参量项的个数相同,参量类型相同,并且对应参量项还满足如下条件之一:
①如果两个都是常量,则必须完全相同。
②如果两个都是约束变量,则两个约束值必须相同
③如果一个是常量,一个是约束变量,那么常量和约束值必须相同。
④至少有一个是自由变量。(个人理解,如果至少有一个自由变量,其实是给用另一个相应的值,把这个自由变量约束起来,成为一个约束变量,最后是实现相等)
prolog的匹配合一操作,可以使两个能匹配的谓词合一起来。即为参加匹配的自由变量和常量,或者是两个自由变量建立一种对应关系。使得常量作为变量的约束值,两个对应的自由变量始终保持一致,即若其中一个值被约束,则另一个值也被约束,反之,解除一个值的约束,另外一个值也会被解除约束。
test.pl文件
room(kitchen). room(office). room(hall). room('dining room'). room(cellar). location(desk,office). location(apple,kitchen). location(flashlight,desk). location('washing mechine',cellar). location(nani,'washing mechine'). location(broccoli,kitchen). location(crackers,kitchen). location(computer,office). door(office,hall). door(kitchen,office). door(hall,'dining room'). door(kitchen,cellar). door('dining room',kitchen). edible(apple). edible(crackers). tastes_yucky(broccoli). turned_off(flashlight). here(kitchen).
localtion() 和 door() 中的变量是区分顺序的,如:
?-location(desk,office).
true
?-location(office,desk).
false
?-door('dining room',kitchen).
true
?-door(kitchen,'dining room').
false
prolog程序的运行机理
1、自由变量 约束变量
prolog中无值的变量称之为自由变量,有值的变量称之为约束变量。
一个变量取了某值,就称该变量约束于某值,或者该变量被某值约束,或者该变量被某值实例化了。
在程序运行过程中,自由变量可以被实例化成为约束变量;一个约束变量也可以解除其值成为自由变量。
2、匹配合一
两个谓词可以匹配合一,指两个谓词的名相同,参量项的个数相同,参量类型相同,并且对应参量项还满足如下条件之一:
①如果两个都是常量,则必须完全相同。
②如果两个都是约束变量,则两个约束值必须相同
③如果一个是常量,一个是约束变量,那么常量和约束值必须相同。
④至少有一个是自由变量。(个人理解,如果至少有一个自由变量,其实是给用另一个相应的值,把这个自由变量约束起来,成为一个约束变量,最后是实现相等)
prolog的匹配合一操作,可以使两个能匹配的谓词合一起来。即为参加匹配的自由变量和常量,或者是两个自由变量建立一种对应关系。使得常量作为变量的约束值,两个对应的自由变量始终保持一致,即若其中一个值被约束,则另一个值也被约束,反之,解除一个值的约束,另外一个值也会被解除约束。
简单查询
prolog的查询工作是靠模式匹配完成的,查询的模版叫做目标,如果有某个事实与目标想匹配,那么查询成功,prolog的解释器会显示true(有的prolog IDE 会显示yes),否则显示false(有的prolog IDE显示no)。
我们把prolog的模式匹配工作叫做联合。
?-room(office). true ?-room(fdafd). false
?-location(desk,office).
true
?-location(office,desk).
false
在查询目标中,我们可以使用使用变量。变量可以和任何条目匹配。
当联合成功之后,变量的值将和它所匹配的条目的值相同,这叫做变量的绑定(binding),当带变量的目标成功和数据库中的事实匹配之后,prolog将返回变量绑定的值。
?-room(X). X = kitchen; X = office; X = hall; X = 'dining room'; X = cellar. no % 有的prolog 程序会显示no 但是SWI-prolog不会显示任何提示,只会默默的退出查询 ?-
由于目标可以和多个条目匹配所有,变量可以绑定多个值。在prolog每次回答之后,输入“;”,可以让prolog继续查询,
?- location(Thing,Place). Thing = nani, Place = 'washing mechine' ; % 一次成功的查询 Thing = broccoli, Place = kitchen ; %又一次成功的查询 Thing = crackers, Place = kitchen ; Thing = desk, Place = office ; Thing = apple, Place = kitchen ; Thing = flashlight, Place = desk ; Thing = 'washing mechine', Place = cellar ; Thing = computer, Place = office.
查询的工作原理
当prolog试图与某一个目标相匹配时,例如 location/2,它就在数据库中搜索所有用location/2定义的子句。当找到一条与目标匹配的子句时,它就会为这条子句做上记号,当用户需要更多答案时,它就从那条做了记号的子句开始向下查询。
prolog的目标有四个端口来控制运行的流程。调用(call),退出(exit),重试(redo),失败(fail)。使用call进入目标,如果匹配成功,就到exit端口,如果失败就到fail端口,如果用户输入“;”(分号),那就又从redo端口进入目标。
call 开始使用目标搜寻子句
exit 目标匹配成功,在成功的子句上作记号,并绑定变量
redo 视图重新满足目标,首先释放变量,并从上次开始的记号开始搜索
fail 表示再找不到更多满足目标的子句
但是SWI-log进入调试模式(最后补上)
1 ?- % location/2: [call,redo,exit,fail] % The graphical front-end will be used for subsequent tracing 1 ?- location(X,kitchen). T Call: (7) location(_G161, kitchen) T Exit: (7) location(broccoli, kitchen) X = broccoli ; T Redo: (7) location(_G161, kitchen) T Exit: (7) location(crackers, kitchen) X = crackers ; T Redo: (7) location(_G161, kitchen) T Exit: (7) location(apple, kitchen) X = apple.
我感觉这个SWI-prolog 的调试信息不能很好的把顺序说明白,所以就复制一下文档中的debug信息。
?- location(X, kitchen). CALL: - location(X, kitchen) EXIT:(2) location(apple, kitchen) X = apple; REDO: location(X, kitchen) EXIT:(6) location(broccoli, kitchen) X = broccoli REDO: location(X, kitchen) EXIT:(7) location(crackers, kitchen) X = crackers FAIL - location(X, kitchen) no %括号中的数字表正在考虑的子句
SWI-prolgo进入调试模式方式:
菜单栏--debug--Edit spy points
第一步:在predicate栏输入自己想debug 的 谓词
第二步:点击输入栏右侧的 眼睛 图标。
第三步:点击 右上角的 debug 选框
第四步:像往常一样在SWI-prolog 输入想要查询的信息。继续查询的话使用“;”。
第二种:
两种调试方式