Clips笔记 2

变量

Clips中,变量是一个?接一个变量名实现的,比如?speed等。

变量的第一个作用是保存输入的槽值,给出代码示例:

(deftemplate person
    (slot name)
    (slot eyes)
)
(defrule BuleEyes
    (person (name ?name) (eyes blue))
=>
    (printout t ?name " has bule eyes." crlf)
)

(deffacts persons
    (person (name Jane) (eyes blue))
    (person (name Tom) (eyes green))
    (person (name Lily) (eyes blue))
)

(reset)
(run)

一个变量首次约束于某一值时,该变量在此规则内便保持该值,其他同名变量必须约束为这第一个变量的值,代码示例:

(undefrule *)

(deftemplate find
    (slot eyes)
)

(deftemplate person
    (slot name)
    (slot eyes)
)

(defrule find-eyes
    (find (eyes ?eyes))
    (person (name ?name) (eyes ?eyes))
=>
    (printout t ?name " has" ?eyes " eyes." crlf)
)

(deffacts persons
    (person (name Jane) (eyes blue))
    (person (name Tom) (eyes green))
    (person (name Lily) (eyes blue))
)

(reset)
(assert (find(eyes blue)))
(run)

上述代码中,因为对find中的eyes进行了蓝色约束,那么在规则find-eyes中,eyes将一直是蓝色的,所以这里就相当于是查找蓝色眼睛的同学。

Clips中,使用<-来作为取地址的操作,取地址操作时,相当于是<==的过程。

代码示例:

(clear)

(deftemplate person
    (slot name)
    (slot address)
)

(deftemplate moved
    (slot name)
    (slot address)
)

(defrule process-moved-information
    ?f1 <- (moved (name ?name) (address ?address))
    ?f2 <- (person (name ?name))
=>
    (retract ?f1) ; 在这里删除中间的事实
    (modify ?f2 (address ?address))
)

(deffacts example
    (person (name John) (address Lodon))
    (moved (name John) (address NewYork))
)

(reset)
(watch rules)
(watch facts)
(run)

如果删除(retract ?f1),之后程序进入死循环。理由如下:一个modify命令可以视为一个retract命令和一个assert命令。删除retract命令后,modify会先提取出person,之后再加入一个新的person结构,原来的moved结构没有被删除,此时又会满足规则,如此往复,造成无限循环。

如果要输入多个变量,那么可以使用$符号来表示1个或者多个变量。同时,也可以利用这个特性来匹配第一个或者最后一个数据等,给出代码示例:

(deftemplate person
    (multislot name)
)

(defrule print-name
    (person (name ?first $? ?last))
=>
    (printout t "Person first and last name are " ?first ", " ?last crlf)
)

(assert (person (name John Q. Lamg Smith)))
(facts)
(run)

此时,(run)的结果只会输出JohnSmith。注意,$只需要在LHS中即可,RHS不需要使用该符号。

字段约束

非约束~符号,相当于一个取反操作,代码示例:

(deftemplate person
    (slot name)
    (slot hair)
)
(defrule hair-rule
    (person (name ?name) (hair ~brown))
=>
    (printout t ?name " doesn't has brown hair" crlf)    
)

(deffacts persons
    (person (name Tom) (hair black))
    (person (name Sam) (hair brown))
    (person (name Amy) (hair red))
)

(reset)
(run)

或约束|符号,或操作:

(deftemplate person
    (slot name)
    (slot hair)
)
(defrule hair-rule
    (person (name ?name) (hair brown | black))
=>
    (printout t ?name " has dark hair" crlf)    
)

(deffacts persons
    (person (name Tom) (hair black))
    (person (name Sam) (hair brown))
    (person (name Amy) (hair red))
)

(reset)
(run)

与约束&符号,一般与其它符号联合使用,比如判别一个人有黑色或者红色的头发。

(deftemplate person
    (slot name)
    (slot hair)
)
(defrule dark-hair-rule
    (person (name ?name) (hair ?hair & brown | black))
=>
    (printout t ?name " has dark hair" crlf)    
)

(defrule no-dark-hair-rule
    (person (name ?name) (hair ?hair & ~brown & ~black))
=>
    (printout t ?name " has no dark hair" crlf)    
)

(assert (person (name Tom) (hair black)))
(assert (person (name Sam) (hair white)))
(run)

更强大的规则约束:

(deftemplate person
    (slot name)
    (slot hair)
)

(defrule myrule
    (person (name ?name)
            (hair ?hair & ~black & ~brown))
    (person (name ?name1 & ~?name)
            (hair ?hair1 & black | red))
=>
    (printout t "OK" crlf)
)

(watch facts)
(watch rule)
(assert (person (name Tom) (hair red)))
(assert (person (name Sam) (hair black)))
(run)

输出OK

数学表达式和规则求和

Lisp风格的前缀表达式,优先级同C语言,而且只能由括号确定。

(+ 2 2)
(- 2 3 4)
(+ 2 (* 3 4 5))

以一个矩形求和为例:

(deftemplate rectangle
    (slot width)
    (slot height)
)

(defrule sum-rectangle
    (rectangle (height ?height) (width ?width))
=>
    (assert (add-to-sum (* ?width ?height)))
)

(defrule sum-areas
    ?sum <- (sum ?total)  ; 为了取出地址,然后从facts中删除即可
    ?new-area <- (add-to-sum ?area)
=>
    (retract ?sum ?new-area)  ; 清空原来的列表数据
    (assert (sum (+ ?total ?area)))
)

(deffacts initial-data
    (rectangle (width 10) (height 10))
    (rectangle (width 30) (height 10))
    (rectangle (width 22) (height 14))
    (rectangle (width 11) (height 71))
    (sum 0)
)

(watch facts)
(watch activations)
(watch rules)
(reset)
(run)
(facts)

输出结果是:

CLIPS> (watch facts)
CLIPS> (watch activations)
CLIPS> (watch rules)
<== f-0     (initial-fact)
==> f-0     (initial-fact)
==> f-1     (rectangle (width 10) (height 10))
==> Activation 0      sum-rectangle: f-1
==> f-2     (rectangle (width 30) (height 10))
==> Activation 0      sum-rectangle: f-2
==> f-3     (rectangle (width 22) (height 14))
==> Activation 0      sum-rectangle: f-3
==> f-4     (rectangle (width 11) (height 71))
==> Activation 0      sum-rectangle: f-4
==> f-5     (sum 0)
CLIPS> (reset)
FIRE    1 sum-rectangle: f-4
==> f-6     (add-to-sum 781)
<== f-8     (add-to-sum 308)
==> f-9     (sum 1089)
FIRE    5 sum-rectangle: f-2
==> f-10    (add-to-sum 300)
==> Activation 0      sum-areas: f-9,f-10
FIRE    6 sum-areas: f-9,f-10
<== f-9     (sum 1089)
<== f-10    (add-to-sum 300)
==> f-11    (sum 1389)
FIRE    7 sum-rectangle: f-1
==> f-12    (add-to-sum 100)
==> Activation 0      sum-areas: f-11,f-12
FIRE    8 sum-areas: f-11,f-12
<== f-11    (sum 1389)
<== f-12    (add-to-sum 100)
==> f-13    (sum 1489)
CLIPS> (run)
(facts)
f-0     (initial-fact)
f-1     (rectangle (width 10) (height 10))
f-2     (rectangle (width 30) (height 10))
f-3     (rectangle (width 22) (height 14))
f-4     (rectangle (width 11) (height 71))
f-13    (sum 1489)
For a total of 6 facts.

这是使用中间变量的方式执行推导。而且,Clips编程中,没有循环的语法,一切操作都是函数式处理。

bind绑定函数

该函数核心作用是使用临时变量存储结果,防止重复计算。基本的语法结构是:

(bind <variable> <value>)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值