如何在 CLIPS 中实现集合(例如列表)以及如何查询这样的集合

How to implement collections (e.g. list) in CLIPS and how to interrogate such a collection

我正在使用 fuzzyCLIPS 6.31,我想要一个事实,它是(其他事实的)集合。 目前,我有这样的东西:

(deftemplate person "attributes of a person"
   (multislot name (type STRING) )
   (slot age (type FLOAT) (range 0.0 129.9) (default 0) )
   (slot gender (type SYMBOL) (allowed-symbols male female) )
   ; .. other attributes
)

(def template people "collection of people"
    ; terminating char separated string of string representation of person
    ; e.g. "John Frederick Handel, 42.5, male, ....;Homer Jay Simpson, 45.2, male, ..."
    (slot members (type STRING) )
)

(defrule make-person-and-add-to-group
    ; make a person fact
    ; amend previously asserted people fact by adding "stringified" person to people fact
)

(defrule predict-a-riot 
    ; IF we have (fuzzy) "too" many males in a group AND
    ; the males are above the age of 'X' AND
    ; some other salient facts
    ; => THEN
    ; assert riot prediction with CF
)

这可能是一个简单的专家系统的例子,它试图根据一些简单的输入变量和试探法来预测暴乱爆发的可能性。

我有以下问题:

  1. “字符串化”事实(连接然后 parsing/groking 结果字符串)是一种 good/acceptable 处理事实列表(或集合)的方式吗?
  2. 如何访问和操作事实槽中的字符串?

为每个人的事实创建一个唯一的 ID,并将其存储在您的集合中,而不是事实的内容。

         CLIPS (6.31 6/12/19)
CLIPS> 
(deftemplate person
   (slot id (type SYMBOL))
   (slot name (type STRING))
   (slot age (type INTEGER) (range 0 130) (default 0))
   (slot gender (type SYMBOL) (allowed-symbols male female)))
CLIPS> 
(deftemplate people 
   (multislot members (type SYMBOL)))
CLIPS>    
(deffacts initial
   (people)
   (add-person))
CLIPS> 
(deffunction add-person ()
   (printout t "Name: ")
   (bind ?name (readline))
   (printout t "Age: ")
   (bind ?age (read))
   (printout t "Gender: ")
   (bind ?gender (read))
   (bind ?id (gensym*))
   (assert (person (id ?id)
                   (name ?name)
                   (age ?age)
                   (gender ?gender)))
   (return ?id))
CLIPS>                    
(defrule make-person-and-add-to-group
   ?p <- (people (members $?people))
   ?a <- (add-person)
   =>
   (retract ?a)
   (printout t "Add Person? ")
   (bind ?response (lowcase (read)))
   (if (or (eq ?response y) (eq ?response yes))
      then
      (bind ?id (add-person))
      (modify ?p (members ?id ?people))
      (assert (add-person))))
CLIPS> (reset)
CLIPS> (run)
Add Person? yes
Name: Fred Smith
Age: 38
Gender: male
Add Person? yes
Name: Sally Jones
Age: 23
Gender: female
Add Person? no
CLIPS> (facts)
f-0     (initial-fact)
f-3     (person (id gen1) (name "Fred Smith") (age 38) (gender male))
f-6     (person (id gen2) (name "Sally Jones") (age 23) (gender female))
f-7     (people (members gen2 gen1))
For a total of 4 facts.
CLIPS> 

对集合中的每个成员做某事的一般模式是:

(defrule for-each-person
   (people (members $? ?id $?))
   (person (id ?id)
           (name ?name)
           (age ?age)
           (gender ?gender))
   =>
   ;; Action
   )