Selecting all facts

1,468 views
Skip to first unread message

Fabrizio J Bonsignore

unread,
Jan 24, 2011, 3:11:30 AM1/24/11
to CLIPSESG
I want to print all facts derived by the rulebase. This is for very
small occasional systems with a single deffacts construction; I am
using CLIPS 6.0, wxCLIPS 1.64. The deffacts construction includes a
single type of relation, say, (child ...), then the rulebase infers
other any number of other fact relations, say, grandchild, final-node,
goal-candidate... whatever the rulebase produces. The natural
construction

(defrule R
?o<-(not (child $?))
=>
(printout t (some-function ?o) crlf))

fails to parse after (not (. It should select all facts not beginning
with child. Of course the difficulty comes from the impossibility to
take the first field as variable to capture a fact address. So

(defrule R-2
?o<-(?ff&:(neq ?ff child) $?)
=>
(printout t (some-function ?o) crlf))

fails to parse too after (?ff though it is a natural syntax
construction also.

Some LHS construction mixing (find-fact), (forall ()) or (find-index)
seem possible too, but the difficulty is to bind a ?variable to the
unknown fact relations other than the original child relation. How can
this be achieved? Note that it is possible with more facts-rules
infrastructure, but a simple solution is most desirable so that data
can take the simple form (known-relation data) and any rule derived
new facts become the (printable ?solution).

Danilo J Bonsignore

Fabrizio J Bonsignore

unread,
Jan 25, 2011, 2:39:06 AM1/25/11
to CLIPSESG
Incidentally, to (find-all-facts), this version reports:
[EXPRNPSR3] Missing function declaration for find-all-facts,
so that functionality is no solution.

Danilo J Bonsignore

CLIPS Support

unread,
Jan 25, 2011, 9:11:42 AM1/25/11
to CLIPSESG
Use get-fact-list to retrieve the list of facts and progn$ to iterate
over those values. You can use the functions fact-relation, fact-slot-
names, and fact-slot-value to examine the individual facts.

CLIPS> (deftemplate point (slot x) (slot y))
CLIPS> (deftemplate circle (slot x) (slot y) (slot radius))
CLIPS> (assert (point (x 1) (y 1)) (point (x 2) (y 2)) (circle (x 1)
(y 3) (radius 2)) (circle (x 5) (y 9) (radius 4)))
<Fact-3>
CLIPS>
(progn$ (?f (get-fact-list))
(if (eq (fact-relation ?f) circle)
then
(progn$ (?s (fact-slot-names ?f))
(printout t (fact-slot-value ?f ?s) " "))
(printout t crlf)))
1 3 2
5 9 4
CLIPS>

Fabrizio J Bonsignore

unread,
Jan 26, 2011, 8:30:22 PM1/26/11
to CLIPSESG
On Jan 25, 9:11 am, CLIPS Support <gdronline2...@swbell.net> wrote:
> Use get-fact-list to retrieve the list of facts and progn$ to iterate
> over those values. You can use the functions fact-relation, fact-slot-
> names, and fact-slot-value to examine the individual facts.

(get-fact-list) feels very memory intensive, these factbases reach
80000+ facts in memory normally. The solution I found does go through
(fact-index) and (fact-relation) though I still have to mark the end
of the fact list. To run my function I add a special empty rule with
negative salience to trigger at the end of the matching process.

What I was thinking of was a LHS matching pattern. My solution is
working well with ordered fact only factbases, no deftemplates, but it
would be better to have LHS pattern selection rather than a list
traversing function. All in all I have to carry one deffunction and
one rule over rulebases and ensure salience is the last negative index
to ensure last-ness. With a matched pattern solution the solution is
in the language so there is no carry over, only a syntax idiom.

Danilo J Bonsignore

CLIPS Support

unread,
Jan 26, 2011, 10:43:28 PM1/26/11
to CLIPSESG
This is very straight forward to do if you use instances rather than
facts.

Fabrizio J Bonsignore

unread,
Jan 27, 2011, 10:35:30 PM1/27/11
to CLIPSESG
On Jan 26, 10:43 pm, CLIPS Support <gdronline2...@swbell.net> wrote:
> This is very straight forward to do if you use instances rather than
> facts.

The problem is still the same, generating ordered facts is simple and
direct and need no further code to carry beyond writing ad hoc rules,
particularly if code is generated. Otherwise have to generate classes
and deftemplates and carry defined deffunctions to process it besides
the specific rules written for it. Code generating ordered facts is
straightforward, otherwise have to pay attention to field definitions
and nested parenthesis. Of course if the usefulness of the factbase
goes beyond the immediate rulebase, it pays to add more structure and
reuse, but that is not always the case. I already have a deffunction
that cribs to file ordered facts added by the rulebase not in the
original factbase, using fact-index and fact-relation, but still miss
a way to say: **match all not (child $?) facts**.

Danilo J Bonsignore

notam

unread,
Mar 26, 2011, 12:40:55 AM3/26/11
to CLIPSESG


On Jan 27, 11:35 pm, Fabrizio J Bonsignore <synto...@gmail.com> wrote:
> On Jan 26, 10:43 pm, CLIPS Support <gdronline2...@swbell.net> wrote:
>
[snip]
> original factbase, using fact-index and fact-relation, but still miss
> a way to say: **match all not (child $?) facts**.

But there is I think.

To enumerate all facts that do NOT start with (child ...) Why not use
something like:

(do-for-all-facts ((?x (delete-member$ (get-deftemplate-list) child)))
TRUE (ppfact ?x) ; or some other function instead of ppfact for
example

Or:
(bind ?list (find-all-facts ((?x (delete-member$ (get-deftemplate-
list) child))) TRUE)) to just get them in a multifield ?list.

The "ordered facts" are returned in the get-deftemplate-list as well,
so it isn't only for deftemplates.
The slot value for an ordered fact is "implied", so if you only wanted
to see
which members were "ordered facts" you could. The list would need to
be filtered by (deftemplate-slot-existp <member> implied)
with something like:

(deffunction ordered-fact-deftemplates ()
(bind ?ordered (create$))
(progn$ (?name (get-deftemplate-list))
(if (deftemplate-slot-existp ?name implied) then (bind ?ordered
(insert$ ?ordered 999999 ?name))))
?ordered)

Which could be used in place of (get-deftemplate-list) in my previous
do-for-all-facts call to get ONLY ordered facts that aren't "child"
ones.

Cheers,
jsfb
Reply all
Reply to author
Forward
0 new messages