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

已查看 54 次
跳至第一个未读帖子

Pointer2VoidStar

未读,
2021年3月3日 09:29:482021/3/3
收件人 CLIPSESG

I am using fuzzyCLIPS 6.31 and I want to have a fact that is a collection (of other facts). Currently, I have something like this:

(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
 )

This could be an example of a simplistic expert system that attempt to predict the likelihood of a riot breaking out, based on some simplistic input variables and heuristics.

I have the following questions:

  1. Is "stringifying" facts (concatenating and then parsing/groking the resulting string) a good/acceptable way of dealing with lists (or collections) of facts ?
  2. How does one access and manipulate the string held in a slot of a fact?

CLIPS Support

未读,
2021年3月3日 13:41:172021/3/3
收件人 CLIPSESG
Create a unique id for each person fact and store that in your collection rather than the content of the fact.

         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> 

The general pattern then for doing something to each member of the collection is:

(defrule for-each-person
   (people (members $? ?id $?))
   (person (id ?id)
           (name ?name)
           (age ?age)
           (gender ?gender))
   =>
   ;; Action
   )
回复全部
回复作者
转发
0 个新帖子