CLIPS 初学者:CLIPS 规则如何解释事实顺序?
CLIPS beginner: How CLIPS rules interpret the facts order?
我想知道我每天都做了哪些活动,所以我构造了以下代码:
(deftemplate schedule
(slot activity)
(slot starthour)
(slot endhour)
)
(defrule r1
(schedule (activity ?a) (starthour ?start) (endhour ?end))
(not (busy ?start ?a))
=>
(assert (busy ?start ?a))
)
(defrule r2
(busy ?d ?a)
(schedule (activity ?a) (starthour ?start) (endhour ?end))
(test (< ?d ?end))
=>
(assert (busy ( + ?d 1) ?a))
)
CLIPS> (assert (schedule (activity reading) (starthour 3) (endhour 5)))
<Fact-1>
CLIPS> (assert (schedule (activity music) (starthour 4) (endhour 7)))
<Fact-2>
对于我插入的事实,我得到了一个不按日期排序的结果。
CLIPS 如何解释事实的顺序?
有没有办法让我在一天内合并超过 1activity?
非常感谢!
默认情况下,CLIPS 使用深度优先策略来确定接下来要执行的规则,因此通常下一个执行的规则将由最后断言或撤回的事实激活。 Basic Programming Guide 中的第 5.3 节,冲突解决策略更详细地描述了这个过程。
只要规则生成了正确的事实,您就不必特别关心它们在事实列表中的排列顺序,因为 1) 使用事实是不切实际的-显示程序输出的列表和 2) 强制执行特定的放置顺序可能很困难且过于复杂。
相反,要在程序输出中对事实进行排序,请使用一个事实查询函数收集所有相关事实,然后使用带有自定义比较器的排序函数在打印之前对事实进行排序:
CLIPS (6.4 2/9/21)
CLIPS>
(deftemplate schedule
(slot activity)
(slot starthour)
(slot endhour))
CLIPS>
(deftemplate busy
(slot activity)
(slot hour))
CLIPS>
(defrule r1
(schedule (activity ?a) (starthour ?start) (endhour ?end))
(not (busy (activity ?a) (hour ?start)))
=>
(assert (busy (activity ?a) (hour ?start))))
CLIPS>
(defrule r2
(busy (activity ?a) (hour ?d))
(schedule (activity ?a) (starthour ?start) (endhour ?end))
(test (< ?d ?end))
=>
(assert (busy (activity ?a) (hour (+ ?d 1)))))
CLIPS>
(deffacts schedules
(schedule (activity reading) (starthour 3) (endhour 5))
(schedule (activity music) (starthour 4) (endhour 7)))
CLIPS>
(deffunction busy-compare (?f1 ?f2)
;; Sort by hour
(if (> (fact-slot-value ?f2 hour) (fact-slot-value ?f1 hour))
then (return FALSE))
(if (< (fact-slot-value ?f2 hour) (fact-slot-value ?f1 hour))
then (return TRUE))
;; And then sort by activity
(if (> (str-compare (fact-slot-value ?f2 activity)
(fact-slot-value ?f1 activity)) 0)
then (return FALSE)
else (return TRUE)))
CLIPS>
(defrule print
(declare (salience -10))
=>
(bind ?schedule (find-all-facts ((?f busy)) TRUE))
(bind ?schedule (sort busy-compare ?schedule))
(foreach ?s ?schedule
(format t "%2d %s%n" (fact-slot-value ?s hour) (fact-slot-value ?s activity))))
CLIPS> (reset)
CLIPS> (run)
3 reading
4 music
4 reading
5 music
5 reading
6 music
7 music
CLIPS> (facts)
f-1 (schedule (activity reading) (starthour 3) (endhour 5))
f-2 (schedule (activity music) (starthour 4) (endhour 7))
f-3 (busy (activity music) (hour 4))
f-4 (busy (activity music) (hour 5))
f-5 (busy (activity music) (hour 6))
f-6 (busy (activity music) (hour 7))
f-7 (busy (activity reading) (hour 3))
f-8 (busy (activity reading) (hour 4))
f-9 (busy (activity reading) (hour 5))
For a total of 9 facts.
CLIPS>
这是在每个繁忙事实中存储多个活动的另一种方法:
CLIPS> (clear)
CLIPS>
(deftemplate schedule
(slot activity)
(slot starthour)
(slot endhour))
CLIPS>
(deftemplate busy
(multislot activity)
(slot hour))
CLIPS>
(defrule r1
(schedule (activity ?a) (starthour ?start) (endhour ?end))
=>
(loop-for-count (?hour ?start ?end)
(assert (busy (activity ?a) (hour ?hour)))))
CLIPS>
(defrule combine
?b1 <- (busy (activity $?a) (hour ?d))
?b2 <- (busy (activity ?n&:(not (member$ ?n ?a))) (hour ?d))
=>
(modify ?b1 (activity ?a ?n))
(retract ?b2))
CLIPS>
(deffacts schedules
(schedule (activity reading) (starthour 3) (endhour 5))
(schedule (activity music) (starthour 4) (endhour 7)))
CLIPS>
(deffunction busy-compare (?f1 ?f2)
(if (> (fact-slot-value ?f2 hour) (fact-slot-value ?f1 hour))
then (return FALSE))
(if (< (fact-slot-value ?f2 hour) (fact-slot-value ?f1 hour))
then (return TRUE))
(return FALSE))
CLIPS>
(defrule print
(declare (salience -10))
=>
(bind ?schedule (find-all-facts ((?f busy)) TRUE))
(bind ?schedule (sort busy-compare ?schedule))
(foreach ?s ?schedule
(format t "%2d %s%n" (fact-slot-value ?s hour) (implode$ (fact-slot-value ?s activity)))))
CLIPS> (reset)
CLIPS> (run)
3 reading
4 reading music
5 reading music
6 music
7 music
CLIPS> (facts)
f-1 (schedule (activity reading) (starthour 3) (endhour 5))
f-2 (schedule (activity music) (starthour 4) (endhour 7))
f-5 (busy (activity music) (hour 6))
f-6 (busy (activity music) (hour 7))
f-7 (busy (activity reading) (hour 3))
f-8 (busy (activity reading music) (hour 4))
f-9 (busy (activity reading music) (hour 5))
For a total of 7 facts.
CLIPS>
我想知道我每天都做了哪些活动,所以我构造了以下代码:
(deftemplate schedule
(slot activity)
(slot starthour)
(slot endhour)
)
(defrule r1
(schedule (activity ?a) (starthour ?start) (endhour ?end))
(not (busy ?start ?a))
=>
(assert (busy ?start ?a))
)
(defrule r2
(busy ?d ?a)
(schedule (activity ?a) (starthour ?start) (endhour ?end))
(test (< ?d ?end))
=>
(assert (busy ( + ?d 1) ?a))
)
CLIPS> (assert (schedule (activity reading) (starthour 3) (endhour 5)))
<Fact-1>
CLIPS> (assert (schedule (activity music) (starthour 4) (endhour 7)))
<Fact-2>
对于我插入的事实,我得到了一个不按日期排序的结果。 CLIPS 如何解释事实的顺序? 有没有办法让我在一天内合并超过 1activity?
非常感谢!
默认情况下,CLIPS 使用深度优先策略来确定接下来要执行的规则,因此通常下一个执行的规则将由最后断言或撤回的事实激活。 Basic Programming Guide 中的第 5.3 节,冲突解决策略更详细地描述了这个过程。
只要规则生成了正确的事实,您就不必特别关心它们在事实列表中的排列顺序,因为 1) 使用事实是不切实际的-显示程序输出的列表和 2) 强制执行特定的放置顺序可能很困难且过于复杂。
相反,要在程序输出中对事实进行排序,请使用一个事实查询函数收集所有相关事实,然后使用带有自定义比较器的排序函数在打印之前对事实进行排序:
CLIPS (6.4 2/9/21)
CLIPS>
(deftemplate schedule
(slot activity)
(slot starthour)
(slot endhour))
CLIPS>
(deftemplate busy
(slot activity)
(slot hour))
CLIPS>
(defrule r1
(schedule (activity ?a) (starthour ?start) (endhour ?end))
(not (busy (activity ?a) (hour ?start)))
=>
(assert (busy (activity ?a) (hour ?start))))
CLIPS>
(defrule r2
(busy (activity ?a) (hour ?d))
(schedule (activity ?a) (starthour ?start) (endhour ?end))
(test (< ?d ?end))
=>
(assert (busy (activity ?a) (hour (+ ?d 1)))))
CLIPS>
(deffacts schedules
(schedule (activity reading) (starthour 3) (endhour 5))
(schedule (activity music) (starthour 4) (endhour 7)))
CLIPS>
(deffunction busy-compare (?f1 ?f2)
;; Sort by hour
(if (> (fact-slot-value ?f2 hour) (fact-slot-value ?f1 hour))
then (return FALSE))
(if (< (fact-slot-value ?f2 hour) (fact-slot-value ?f1 hour))
then (return TRUE))
;; And then sort by activity
(if (> (str-compare (fact-slot-value ?f2 activity)
(fact-slot-value ?f1 activity)) 0)
then (return FALSE)
else (return TRUE)))
CLIPS>
(defrule print
(declare (salience -10))
=>
(bind ?schedule (find-all-facts ((?f busy)) TRUE))
(bind ?schedule (sort busy-compare ?schedule))
(foreach ?s ?schedule
(format t "%2d %s%n" (fact-slot-value ?s hour) (fact-slot-value ?s activity))))
CLIPS> (reset)
CLIPS> (run)
3 reading
4 music
4 reading
5 music
5 reading
6 music
7 music
CLIPS> (facts)
f-1 (schedule (activity reading) (starthour 3) (endhour 5))
f-2 (schedule (activity music) (starthour 4) (endhour 7))
f-3 (busy (activity music) (hour 4))
f-4 (busy (activity music) (hour 5))
f-5 (busy (activity music) (hour 6))
f-6 (busy (activity music) (hour 7))
f-7 (busy (activity reading) (hour 3))
f-8 (busy (activity reading) (hour 4))
f-9 (busy (activity reading) (hour 5))
For a total of 9 facts.
CLIPS>
这是在每个繁忙事实中存储多个活动的另一种方法:
CLIPS> (clear)
CLIPS>
(deftemplate schedule
(slot activity)
(slot starthour)
(slot endhour))
CLIPS>
(deftemplate busy
(multislot activity)
(slot hour))
CLIPS>
(defrule r1
(schedule (activity ?a) (starthour ?start) (endhour ?end))
=>
(loop-for-count (?hour ?start ?end)
(assert (busy (activity ?a) (hour ?hour)))))
CLIPS>
(defrule combine
?b1 <- (busy (activity $?a) (hour ?d))
?b2 <- (busy (activity ?n&:(not (member$ ?n ?a))) (hour ?d))
=>
(modify ?b1 (activity ?a ?n))
(retract ?b2))
CLIPS>
(deffacts schedules
(schedule (activity reading) (starthour 3) (endhour 5))
(schedule (activity music) (starthour 4) (endhour 7)))
CLIPS>
(deffunction busy-compare (?f1 ?f2)
(if (> (fact-slot-value ?f2 hour) (fact-slot-value ?f1 hour))
then (return FALSE))
(if (< (fact-slot-value ?f2 hour) (fact-slot-value ?f1 hour))
then (return TRUE))
(return FALSE))
CLIPS>
(defrule print
(declare (salience -10))
=>
(bind ?schedule (find-all-facts ((?f busy)) TRUE))
(bind ?schedule (sort busy-compare ?schedule))
(foreach ?s ?schedule
(format t "%2d %s%n" (fact-slot-value ?s hour) (implode$ (fact-slot-value ?s activity)))))
CLIPS> (reset)
CLIPS> (run)
3 reading
4 reading music
5 reading music
6 music
7 music
CLIPS> (facts)
f-1 (schedule (activity reading) (starthour 3) (endhour 5))
f-2 (schedule (activity music) (starthour 4) (endhour 7))
f-5 (busy (activity music) (hour 6))
f-6 (busy (activity music) (hour 7))
f-7 (busy (activity reading) (hour 3))
f-8 (busy (activity reading music) (hour 4))
f-9 (busy (activity reading music) (hour 5))
For a total of 7 facts.
CLIPS>