取最近目标

之前 选取食物时并未取最短距离。开始在想怎么写按照属性找最小值的循环,还要遍历事实列表。后找到此帖,于是:

觅食规则中添加如下条件:

?最近食物 <- (食物 ... (x ?最近位置))

(not (食物 (x ?其他位置&:(< (取距离 ?其他位置 ?个体位置) (取距离 ?最近位置 ?个体位置)))))

即:「有某个食物,其他食物的距离没有比它的近」。这个实现思路相比手写循环比较距离更接近业务一些。

加调试开关

在初始化时内置事实:

(deffacts 运行环境
  (调试 TRUE))

并在显示详情规则中加条件(调试 TRUE)即可。

终于找到如何取事实的属性值

类似根据struct地址取值:fact-slot-value,于是把显示提取到功用,不需置于业务部分:

(deffunction 显示 (?首个)
  (print (fact-slot-value ?首个 速度) " "))

用户手册(user guide)中居然没有提此函数,好奇是有其他的选择或者推荐方法吗?

报错很大改进空间

代码段:

(deffunction 取距离 (位置1 位置2)
  (abs (- 位置1 位置2)))

语法错误如下:

[PRNTUTIL2] 功用.clp, Line 14: Syntax Error:  Check appropriate syntax for parameter list.

ERROR:
(deffunction MAIN::取距离
   (位置1

原因是函数形参必须问号开头:

(deffunction 取距离 (?位置1 ?位置2)
  (abs (- ?位置1 ?位置2)))

有一说一,参考手册 P371~409 近四十页列出了所有错误信息、解释和例子,很不错!

查询事实

发现了按条件查询的函数,像 SQL 的 select,不需自行逐个计数了:

(deffunction 事实个数 (?模版)
  (length$ (find-all-facts ((?各事实 ?模版)) TRUE)))

还有 any-factp(有否满足条件的fact,这个命名里的p不知何意)find-fact 等。

OO特性待研究

下面要添加狼、羊、草等类型,虽然可以添加个「物种」属性实现,仍打算有空看看 OO 相关章节。看文档说它同时支持多种范式,但感觉事实(Fact)已经有对象的味道。看看结合的多自然吧。