I am working with lists of facts that represent XML trees. I need to gather
up all the child elements that meet certain conditions, i. e., they all have
a particular tree node as a parent.
When I set up a rule to do this, Jess naturally fires for each child
element. Instead of this natural behavior, I want to gather up all the results
into a list or vector of some kind.
I believe I need a defquery but I am not sure that I am approaching this
situation in the optimum fashion. (Two solutions that did not work
are shown below.)
The following shows the problem. This shows how the Jess Facts might look
for a particular tree with one root element and three first level children.
If I write a rule for this, it fires three times, once for each child.
(deftemplate tag
(slot text)
(slot value)
(slot elementid)
(slot parent)
)
(assert (tag (text "root") (value "blah") (elementid 1) (parent 0)))
(assert (tag (text "FirstLevel") (value "abc") (elementid 2) (parent 1)))
(assert (tag (text "FirstLevel") (value "def") (elementid 2) (parent 1)))
(assert (tag (text "FirstLevel") (value "ghi") (elementid 2) (parent 1)))
(defrule exrule
"show Problem"
(tag (text "root") (value "blah") (elementid ?start) (parent 0))
(tag (text "FirstLevel") (value ?v) (parent ?start))
=>
(assert (processing ?v))
)
(watch all)
(run)
(facts)
(exit)
What I want is a rule that will fire once, passing a vector of all the children
to the right hand side. (In this simple example, we assert a fact. I would
want that fact to be (processing [abc,def,ghi])
where [abc,def,ghi] represents a Vector, multilist or other type of collection
containing abc,def, and ghi.
Generally, I would want one function for this.
Note that I need a general solution. This is because I have an engine that
sits on top of Jess to enable it to manipulate and transform XML.
It interprets rules about XML loaded into the database,
where the rules themselves are written in XML.
If you are interested in this XML work, you may look at the following
information:
1) My proposal for standardization of such rules, submitted to Legal XML
and the Rule ML initiative.
Legal XML: WorkingDraft: Standardization of Rule-Based Processing,
Transformation, and Generation of Legal XML Documents
http://www.wiu.edu/users/mflll/UN_100XX_2001_05_05.html
2) A document on the MIT Electronic Commerce Architecture Project server,
which explains how the underlying rules work:
http://ecitizen.mit.edu/ecap3.html
http://www.wiu.edu/users/mflll/ecap3.html (sometimes the latest version is hereuntil
it gets moved to the server.)
3) Documents explaining how this is useful in Legal Work
"Automated Reasoning with Legal XML Documents,"
Proceedings of the International Conference on Artificial Intelligence and Law
St. Louis, May 21-25, 2001., Association of Computing Machinery, New York, 2001.
"Rule-Processing in the Legal XML Context,"
Proceedings of the ICAIL-2001 Workshop:
Legal Knowledge Systems in Action: Practical AI in Today's Law Office"
St. Louis, May 21, 2001.
also, see http://www.wiu.edu/users/mflll/AILAW.PDF for an extended version.
--- FAILED ATTEMPT AT SOLUTION ONE (using a query)
(deftemplate tag
(slot text)
(slot value)
(slot elementid)
(slot parent)
(slot date)
)
(assert (tag (text "root") (value "blah") (elementid 1) (parent 0) ) )
(assert (tag (text "FirstLevel") (value "abc") (elementid 2) (parent 1)))
(assert (tag (text "FirstLevel") (value "def") (elementid 3) (parent 1)))
(assert (tag (text "FirstLevel") (value "ghi") (elementid 4) (parent 1)))
(assert (tag (text "root") (value "blah") (elementid 5) (parent 0) ) )
(assert (tag (text "FirstLevel") (value "abc") (elementid 6) (parent 5)))
(assert (tag (text "FirstLevel") (value "def") (elementid 7) (parent 5)))
(assert (tag (text "FirstLevel") (value "ghi") (elementid 8) (parent 5)))
(defrule exrule
"show Problem"
(declare (salience 1))
(tag (text "root") (value "blah") (elementid ?start) (parent 0) )
(tag (text "FirstLevel") (value ?v) (parent ?start) )
=>
(assert (processing ?v ?start))
)
(defquery search
"Finds processing with a given start"
(declare (variables ?start))
(processing ?v ?start)
)
(defrule exrule1
"show Problem"
(tag (text "root") (value "blah") (elementid ?start) (parent 0) )
=>
(bind ?e (run-query search ?start))
(while (?e hasMoreElements)
(printout t (call (call ?e nextElement) fact 1))
)
)
(watch all)
(run)
(facts)
(exit)
This generates an error from java:
Jess reported an error in routine call
while executing (call ?e hasMoreElements)
while executing (while (call ?e hasMoreElements) (printout t (call (call ?e
nextElement) fact 1)))
while executing defrule exrule1
while executing (run).
Message: No method named 'hasMoreElements' found in class java.util.AbstractList$Itr.
Program text: ( run ) at line 40.
at jess.Call.call(ReflectFunctions.java:414)
at jess.FunctionHolder.call(FunctionHolder.java:37)
at jess.Funcall.execute(Funcall.java:247)
at jess.FuncallValue.resolveValue(FuncallValue.java:33)
at jess.While.call(Funcall.java:636)
-- FAILED ATTEMPT TWO (USING MODIFY command )
This does not work, because I don't see a test condition that will
see if a multislot contains a values
(deftemplate tag
(slot text)
(slot value)
(slot elementid)
(slot parent)
(slot date)
)
(watch all)
(assert (tag (text "root") (value "blah") (elementid 1) (parent 0) ) )
(assert (tag (text "FirstLevel") (value "abc") (elementid 2) (parent 1)))
(assert (tag (text "FirstLevel") (value "def") (elementid 3) (parent 1)))
(assert (tag (text "FirstLevel") (value "ghi") (elementid 4) (parent 1)))
(assert (tag (text "root") (value "blah") (elementid 5) (parent 0) ) )
(assert (tag (text "FirstLevel") (value "abc") (elementid 6) (parent 5)))
(assert (tag (text "FirstLevel") (value "def") (elementid 7) (parent 5)))
(assert (tag (text "FirstLevel") (value "ghi") (elementid 8) (parent 5)))
(deftemplate processing (slot parent) (multislot value))
(defrule exrule
"Create First Entry"
(declare (salience 1))
(tag (text "root") (value "blah") (elementid ?start) (parent 0) )
(tag (text "FirstLevel") (value ?v) (parent ?start) )
(not (processing (parent ?start) ))
=>
(assert (processing (parent ?start) (value (create$ ?v))))
(assert (fired 0 ?v ?start))
)
(defrule exrule1
"show Problem"
(declare (salience 1))
(tag (text "root") (value "blah") (elementid ?start) (parent 0) )
(tag (text "FirstLevel") (value ?v) (parent ?start) )
?u <- (processing (parent ?start) (value ?vold)) ***
=>
(modify ?u (value (create$ ?vold ?v)))
(assert (fired modified ?v))
)
(defrule exrule2
"show Problem"
(tag (text "root") (value "blah") (elementid ?start) (parent 0) )
(processing (parent ?start ) (value ?vold))
=>
(printout t ?vold)
)
(run)
(facts)
(exit)
** I need a condition here that says ?v is not a member of ?vold
I tried the following in in Jess6.0a7 with no luck!
(test (or (and (multifieldp ?vold)(not(member$ ?v ?vold)))
(and (not (multifieldp ?vold)) (neq ?vold ?v))))
I noticed that (assert (processing(parent ?start)(value (create$ ?v))) would not
create a multifield for the value slot if ?v was an atom.
Thus, I had to have a two-pronged to check to see if the
content of procesing was a multifield.
Then, when the assert created the Jess fact
(processing (parent 5) (value "ghi" "def")), the activation for
the value "abc" would disappear.
Is there something suble about test I am not understanding?
---------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users [EMAIL PROTECTED]'
in the BODY of a message to [EMAIL PROTECTED], NOT to the
list (use your own address!) List problems? Notify [EMAIL PROTECTED]
---------------------------------------------------------------------