用 clips 模拟生态第0.2步:随机觅食
刚开始用随机函数增减能量时,就发现 这个费解问题。
简言之,使用 modify 时,如果新值和旧值相等,则无任何操作、原事实不变且不再次触发匹配的规则,即不等于 retract加assert。以后要小心这个坑。
于是暂时用只增加能量(+ ?能量 (random 1 3))
,来规避(+ ?能量 (random -3 3))
时随机到增量为0导致停止觅食的情况。
之后添加规则:当能量大于某值时,能量重置为0并产生新个体。但发现仅有新生成的个体进行觅食,之前的个体停止更新能量,应该是觅食规则一直被新个体对应的事实激活的缘故。
想到 之前请教的回复,把之前的出生时间
改为了经历时间
并让所有个体同步‘觅食’。
(deftemplate 某种
(slot 编号)
(slot 能量)
(slot 经历时间))
(deftemplate 世界
(slot 时间)
)
(defrule 开始
=>
(println "开天辟地")
(assert (世界 (时间 0)))
(assert (某种 (编号 0) (能量 0) (经历时间 0))))
; 当无优先级声明时,规则编写顺序决定了执行的优先级!
(defrule 时间流逝
?环境 <- (世界 (时间 ?时间))
=>
(modify ?环境 (时间 (+ ?时间 1)))
)
(defrule 觅食
(declare (salience 5))
(世界 (时间 ?时间))
?个体 <- (某种 (能量 ?能量) (经历时间 ?经历时间&:(< ?经历时间 ?时间)))
=>
(modify ?个体 (能量 (+ ?能量 (random 1 3))) (经历时间 (+ 1 ?经历时间)))
)
; 待解决:新生命的 fact index 从2跳到几千
(defrule 繁衍
(declare (salience 10))
(世界 (时间 ?时间))
?长辈 <- (某种 (编号 ?编号) (能量 ?能量&:(> ?能量 10000)))
=>
(modify ?长辈 (能量 0))
; 编号可能重复
(assert (某种 (编号 (+ 1 ?编号)) (能量 0) (经历时间 ?时间)))
)
感觉(世界 (时间 ?时间))
这种写法有点累赘。考虑在命名上作些改进。
写文章的时候发现有经历时间
属性的修改,即便能量加0也不会和原事实相同,于是改为(random -3 3)
后,果然可行,但仍有个体消失的情况发生如下(能量阈值改用 1000)。也许是编号重复后与其他事实内容完全相同导致的,但为何事实会消失呢?待研究。
腾出3G内存后,screenshot app录屏产生mov,https://cloudconvert.com/mov-to-gif 生成gif