The CLIPS reference manual explains about do-for-fact
:
If a fact-set satisfies the query, the specified action is executed, and the function is immediately terminated. The return value is the evaluation of the action. If no fact-set satisfied the query, then the return value is the symbol FALSE.
However, I cannot find any details on what the "evaluation of the action" means in general.
Is it safe to assume that do-for-fact
always returns a value not equal to FALSE
if a fact has been found?
Is the following code snippet correct?
(if (not (do-for-fact ((?p1 girl boy woman man)
(?p2 girl boy woman man)
(?p3 girl boy woman man))
(and (= ?p1:age ?p2:age ?p3:age)
(neq ?p1 ?p2)
(neq ?p1 ?p3)
(neq ?p2 ?p3))
(printout t ?p1:name " " ?p2:name " " ?p3:name crlf)))
then
(printout t "Nobody found" crlf)
)
Action refers to the BNF description of the function syntax:
(do-for-fact <fact-set-template> <query> <action>*)
This action term is the same term used in the body of a deffunction:
(deffunction <name> [<comment>]
(<regular-parameter>* [<wildcard-parameter>]) <action>*)
The return value in both cases is the last action evaluated. If the last action evaluated returns the value FALSE, then the do-for-fact function will return the value FALSE just as it would if there was no fact-set that satisfied the query.
In your example, the printout function has no return value which is treated as a non-FALSE value by the not function, so it will work as you expect
CLIPS> (printout t)
CLIPS> (not (printout t))
FALSE
CLIPS>
If you had included the symbol FALSE after the printout call, then the return value of the do-for-fact call would always be FALSE regardless of whether any fact-set satisfied the query.
(printout t ?p1:name " " ?p2:name " " ?p3:name crlf)
FALSE))