Function to tell if a fact exists?

1,394 views
Skip to first unread message

baylor

unread,
Mar 29, 2011, 8:32:29 PM3/29/11
to CLIPSESG
Is there a function that, given the name of a fact (not template),
will return TRUE or FALSE?

There's fact-exists but it requires an index, not a name

any-factp does not work. If the fact is there, it returns TRUE but if
it's not it prints an error on the screen and then dies. Example:

(assert (x))
(any-factp ((?f x)) TRUE)
TRUE

(any-factp ((?f y)) TRUE)
[PRNTUTIL1] Unable to find deftemplate y.

There are workarounds, like not using facts and just using templates
and, of course, not using functions and handling things through rules,
but i'm curious as to whether i could make this work with facts

For the record, i'm testing an interactive application where the user
is asked the same questions over and over ("Current State=X, what
action will you take?") until some criteria is met (system is in state
Y). i honestly don't know how to do this using rules. Wine.clp stops
when it runs out of questions and it only asks a given question once
but that doesn't work in my situation. So instead i used a while loop
in a function. The while loop asks questions, asserts answers and then
(run). It stop when a flag is set by the rules and that's the part i
can't figure out. An easy answer is to ditch facts and switch to
templates but curiosity has the better of me

-baylor

CLIPS Support

unread,
Apr 2, 2011, 4:36:21 PM4/2/11
to CLIPSESG
All facts use an underlying deftemplate, but for ordered facts the
deftemplate is automatically created for you with a single multifield
slot to contain all of the values. The parser for the fact query
functions use the deftemplate to determine the list of slots which can
be referenced within its body, so you'll get an error if it's not
defined. In the example where you used (assert (x)), the assertion
automatically created the deftemplate before the fact was asserted, so
the subsequent any-factp had a deftemplate available. My
recommendation would be to use deftemplates, but what you can do to
get this to work is to use the eval function to allow you to defer the
parsing of the any-factp expression until after you've determined that
the deftemplate exists:

CLIPS> (and (member$ y (get-deftemplate-list)) (eval "(any-factp ((?f
y)) TRUE)"))
FALSE
CLIPS> (assert (y))
<Fact-1>
CLIPS> (and (member$ y (get-deftemplate-list)) (eval "(any-factp ((?f
y)) TRUE)"))
TRUE
CLIPS>

So if the deftemplate doesn't exists, there can't be any facts with
that relation name, otherwise at some point the fact existed, so parse
and execute the any-factp function to determine if it stil exists.
Reply all
Reply to author
Forward
0 new messages