prolog 规则
规则
规则由几个互相依赖的简单句(谓词)组成。用来描述事实之间的依赖关系,如:因果关系,蕴含关系,对应关系
规则的实质就是存储起来得查询
其语法结构如下:
head:-body
head 为谓词的定义部分,和事实一样,也包括谓词名和参数说明
:- 连接符 表示 蕴含
body 一个或多个目标,用“,”连接,表示 且
如上一章中的混合查询按规则保存下来即为:
where_food(X,Y):-location(X,Y),edible(X).
房间Y中,有可食事物的条件是:X位于Y 中,且X具有 edible属性
继续用上一章举例子,在文件的最后追加一个规则
where_food(X,Y):-location(X,Y),edible(X).
文件内容如下:
room(kitchen).
room(office).
room(hall).
room('dining room').
room(cellar).
location(nani,'washing mechine').
location(desk,office).
location(apple,kitchen).
location(broccoli,kitchen).
location(crackers,kitchen).
location(flashlight,desk).
location('washing mechine',cellar).
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). where_food(X,Y):-location(X,Y),edible(X).
我们可以做如下动作:
1、查找所有有可食食品的房间,和可食食品。
?- where_food(X,Y).
X = apple,
Y = kitchen ;
X = crackers,
Y = kitchen ;
false.
2、验证某个房间中是否存在某食物
?- where_food(apple,kitchen).
true .
3、查找某个房间中所有的可食用食物
?- where_food(X,kitchen).
X = apple ;
X = crackers.
4、查找可食用食物的所在的房间
?- where_food(apple,R).
R = kitchen.
综上所述,其实就是根据已经输入的事实,求解该规则的一个或两个变量的值。
规则的工作原理
首先prolog把目标和规则的子句的头部进行匹配,如果成功,那么prolog就把该规则的body部分作为新的目标进行匹配。
所以上面的 wherer_food 的debug信息如下:
?- where_food(X,kitchen).
T Call: () where_food(_G2943, kitchen)
T Call: () location(_G2943, kitchen)
T Exit: () location(apple, kitchen)
T Call: () edible(apple)
T Exit: () edible(apple)
T Exit: () where_food(apple, kitchen)
X = apple ;
T Redo: () location(_G2943, kitchen)
T Exit: () location(broccoli, kitchen)
T Call: () edible(broccoli)
T Fail: () edible(broccoli)
T Redo: () location(_G2943, kitchen)
T Exit: () location(crackers, kitchen)
T Call: () edible(crackers)
T Exit: () edible(crackers)
T Exit: () where_food(crackers, kitchen)
X = crackers.
对于 寻找Nani这个游戏,我们可以增添如下的规则:
/*定义两个房间相连*/
connect(X,Y):-door(X,Y).
connect(X,Y):-door(Y,X). /*列出该房间的所有物品*/
list_things(Place):-location(X,Place),tab(),write(X),nl,fail. /*列出所有和该房间相邻的房间*/
list_connect(Place):-connect(Place,X),tab(),write(X),nl,fail.
做一个测试:
?- list_things(kitchen).
apple
broccoli
crackers
false. ?- list_connect(kitchen).
office
cellar
dining room
false.
如图所示,list_things展示了该房间内的所有东西,list_connect显示了所有的和该房间相邻的所有房间。
但是这两个规则都有一个问题,都是 fail 结尾,如果我们把他们联用的时候,会由于fail,导致回溯。从而出现问题。
?- list_things(kitchen),list_connect(kitchen).
apple
broccoli
crackers
false.
list_connect(kitchen) 没有运行
所以我们要解决这个问题。
故我们在应该在添加两条事实,从而实现list_things和list_connect 都返回true。
list_things(_).
list_connect(_).
"_" 为空变量,表示我们不关心或者是暂时无法求值的变量。 这里取 我们不关心的意思。
?- list_things(kitchen),list_connect(kitchen).
apple
broccoli
crackers
office
cellar
dining room
true.
现在我们可以编写一条规则,查看小女孩所在的房间,并列出房间内所有的物品以及和该房间相邻的房间。
look:-here(Place),write('You are in the '),write(Place),nl,write('You can see '),list_things(Place),write('You can go to '),nl,list_connect(Place).
所以到目前位置,整个 test.pl 文件如下
room(kitchen).
room(office).
room(hall).
room('dining room').
room(cellar).
location(nani,'washing mechine').
location(desk,office).
location(apple,kitchen).
location(broccoli,kitchen).
location(crackers,kitchen).
location(flashlight,desk).
location('washing mechine',cellar).
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). where_food(X,Y):-location(X,Y),edible(X). connect(X,Y):-door(X,Y).
connect(X,Y):-door(Y,X). list_things(Place):-location(X,Place),tab(),write(X),nl,fail.
list_things(_).
list_connect(Place):-connect(Place,X),tab(),write(X),nl,fail.
list_connect(_). look:-here(Place),write('You are in the '),write(Place),nl,write('You can see '),list_things(Place),write('You can go to '),nl,list_connect(Place).
运行如下
?- look.
You are in the kitchen
You can see apple
broccoli
crackers
You can go to
office
cellar
dining room
true.
最新文章
- UVALive 4431 Fruit Weights --floyd,差分约束?
- AngularJS入门心得1——directive和controller如何通信
- SQL调优之排名优化
- 临时改GCC编译器,重启后失效
- hdu 4786 Fibonacci Tree (2013ACMICPC 成都站 F)
- cocos2d-x触摸分发器原理
- mysql root密码重置
- BizTalk 2010/2013 EDI B2B
- python中强大的format函数
- linux 添加ftp用户与登录配置详解
- 演示Eclipse插件实现代码提示和补全
- 定时调度系列之Quartz.Net详解
- Python网络编程(3)——SocketServer模块与简单并发服务器
- paddlepaddle
- linux(fedora) 第三课
- Python内建函数-callable
- Chapter3_操作符_方法调用中的别名问题
- pep8 &;&; pep20
- C语言四则运算编程
- Partition--使用分区切换来增加修改列的自增属性
热门文章
- servlet简单用法和配置示例及说明
- [原]JQuery mobile CSS 文件组织
- AJAX怎么用POST 传参数
- project euler 开坑
- [DFNews] Touch ID不是神话,指模依旧能搞定。
- sqlserver获取数据库表结构
- VS 远程调试之 “The visual studio remote debugger does not support this edition of windows”
- Andriod中textview垂直水平居中及LinearLayout内组件的垂直布局
- web 音频文件自动播放(兼容所有浏览器)
- 自制MFC消息响应定位器+原理分析