zoukankan      html  css  js  c++  java
  • 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).
    View Code

    我们可以做如下动作:

    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: (7) where_food(_G2943, kitchen)
     T Call: (8) location(_G2943, kitchen)
     T Exit: (8) location(apple, kitchen)
     T Call: (8) edible(apple)
     T Exit: (8) edible(apple)
     T Exit: (7) where_food(apple, kitchen)
    X = apple ;
     T Redo: (8) location(_G2943, kitchen)
     T Exit: (8) location(broccoli, kitchen)
     T Call: (8) edible(broccoli)
     T Fail: (8) edible(broccoli)
     T Redo: (8) location(_G2943, kitchen)
     T Exit: (8) location(crackers, kitchen)
     T Call: (8) edible(crackers)
     T Exit: (8) edible(crackers)
     T Exit: (7) 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(3),write(X),nl,fail.  
    
    /*列出所有和该房间相邻的房间*/
    list_connect(Place):-connect(Place,X),tab(3),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(3),write(X),nl,fail.
    list_things(_).                     
    list_connect(Place):-connect(Place,X),tab(3),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).
    View Code

    运行如下

    ?- look.
    You are in the kitchen
    You can see    apple
       broccoli
       crackers
    You can go to 
       office
       cellar
       dining room
    true.
  • 相关阅读:
    父亲的心
    英美主要报刊杂志网站整合【更新订正版】
    【更新】免费下载百度文库文档
    About Pull Strings 英语走后门议论文
    实验室安全事故读后感
    WorldWind上风羽线的显示
    传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确
    DevExpress的Web控件汉化方法
    安装rails卡住很慢 出现302 Moved Temporarily
    MSCRM4 在过滤后的LOOKUP框中实现查找
  • 原文地址:https://www.cnblogs.com/jijizhazha/p/6208399.html
Copyright © 2011-2022 走看看