刚开始用随机函数增减能量时,就发现 这个费解问题

简言之,使用 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