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
)