上文,加条规则年龄到10繁衍:

(defrule 繁衍
  (某种 (年龄 10))
  =>
  (assert (某种 (年龄 0)))
)

仍旧只有一个个体递增年龄。加了 暂停,仍无效:

(defrule 繁衍
  (某种 (年龄 10))
  =>
  (assert (某种 (年龄 0)))
  (halt)
)

尝试各种发现,如果把规则编写先后反过来,就生成了第二个个体:

(defrule 繁衍
  (某种 (年龄 10))
  =>
  (assert (某种 (年龄 0)))
  (halt)
)

(defrule 时间流逝
  ?个体 <- (某种 (年龄 ?年龄))
  =>
  (modify ?个体 (年龄 (+ ?年龄 1))))

想起 入门时看到的规则优先级 ,看来在优先级相同时排序靠前的先执行?

于是加高优先级(顺便:salience 这句好像必须是第一句):

(defrule 繁衍
  (declare (salience 10))
...

即便规则放在后面也可触发了。但是,去掉 (halt) 后,又只有单体年龄递增,不见第二个单体生成。

加大繁衍年龄:

(defrule 繁衍
  (declare (salience 10))
  (某种 (年龄 10000000))
  =>
  (assert (某种 (年龄 0)))
)

从事实(Facts)浏览器发现,fact 1 的年龄到千万时,会产生 fact 2,而且 fact 2中的年龄开始递增而 1 的年龄暂停,待 fact 2 的年龄到千万时,fact 2 消失,fact 1 从千万开始继续递增。

因此之前繁衍年龄小时,fact 2 一闪而过因此看不到。

至于年龄相同时为何消失,也许和 这里 的重复事实有关。

于是为区别单体添加编号:

(deftemplate 某种
  (slot 编号)
  (slot 年龄))

(defrule 开始
  =>
  (println "开天辟地")
  (assert (某种 (编号 0) (年龄 0))))

(defrule 时间流逝
  ?个体 <- (某种 (编号 ?编号) (年龄 ?年龄))
  =>
  (modify ?个体 (年龄 (+ ?年龄 1))))

(defrule 繁衍
  (declare (salience 10))
  (某种 (编号 ?编号) (年龄 10000000))
  =>
  (assert (某种 (编号 (+ 1 ?编号)) (年龄 0)))
)

现在每个单体递增到繁衍年龄时,就会增加一个编号递增的单体,部分成功。剩下就是解决繁衍后的单体的年龄不再递增的问题。

从议程(agenda)看,所有的单体都在排队,应该只有排在最先的最新单体的年龄递增得到执行:

CLIPS> (agenda)
0      时间流逝: f-11
0      时间流逝: f-10
0      时间流逝: f-9
0      时间流逝: f-8
0      时间流逝: f-7
0      时间流逝: f-6
0      时间流逝: f-5
0      时间流逝: f-4
0      时间流逝: f-3
0      时间流逝: f-2
0      时间流逝: f-1

论坛发问 后,确认需加其他条件实现比如年龄同步。

鉴于模拟环境中新生单体的年龄不同,决定试用另一思路,即不在个体中保留年龄信息,而改为保存出生时间:

(deftemplate 某种
  (slot 编号)
  (slot 出生时间))

(deftemplate 世界
  (slot 时间)
)

(defrule 开始
  =>
  (println "开天辟地")
  (assert (世界 (时间 0)))
  (assert (某种 (编号 0) (出生时间 0))))

; 当无优先级声明时,规则编写顺序决定了执行的优先级!

(defrule 时间流逝
  ?环境 <- (世界 (时间 ?时间))
  =>
  (modify ?环境 (时间 (+ ?时间 1)))
)

(defrule 繁衍
  (declare (salience 10))
  (世界 (时间 ?时间))
  (某种 (编号 ?编号) (出生时间 ?出生时间))
  (test (= 10000000 (- ?时间 ?出生时间)))
  =>
  (assert (某种 (编号 (+ 1 ?编号)) (出生时间 ?时间)))
)

运行后,可见世界时间戳递增,初始单体在时间戳 10000000 时,生成第二个单体,时间戳 20000000 时生成第三个,符合预期。

接下去添加能量值。