Search code examples
clips

What's the return value of CLIPS' do-for-fact if fact has been found?


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

Solution

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