JESS: run-query* and rule LHS

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

JESS: run-query* and rule LHS

Nguyen, Son
run-query* and rule LHS

Hi,

I observed some strange behaviors of run-query* from the LHS of rules.

The first issue has to do with the location of the defquery relative to the rule that uses the query.
I have a simple Java Bean, a clp and the test program. The template is derived from the Java Bean.
A few functions are used to query the working memory.

Java class:

public class Model {
        private String name;
        public String getName() {
                return name;
        }
        public void setName(String name) {
                this.name = name;
        }
}

Clp file:

(import Model)
(deftemplate Model
(declare (from-class Model)))

(deffunction getQueryFirstResult (?queryResult)
    (bind ?result nil)
    (while (?queryResult next)
        (bind ?result (?queryResult getObject modelObject))
        (printout t ">< found: " (?result getName) crlf)
        (return ?result)
    ); while
    (printout t "getQueryFirstResult returns nil " crlf)
    (return ?result)
)

(deffunction queryNamedDataModelParameter (?query ?parameter ?caller)
    (printout t ?caller " -- current-module: " (get-current-module) " focus: " (get-focus) crlf)
    (facts)
    (printout t "query working memory... for model name: " ?parameter crlf)
    (bind ?result (run-query* ?query ?parameter))
    (bind ?matched (getQueryFirstResult ?result))
    (return ?matched)
)


(defrule rule1
        (Model (OBJECT ?_Model &:(eq (?_Model getName) "super")))
        (test (eq nil (queryNamedDataModelParameter query1 "super" "rule1 is caller" )))
        =>
        (printout t ">>> rule1 OOOOPPPPSSSS!  I am not supposed to be here !!!" crlf)
        (queryNamedDataModelParameter query1 "super" "rule1 RHS")
)

(defquery query1
        "Finds models with a given parameter name"
        (declare (variables ?parameter))
        (Model (OBJECT ?modelObject &:(eq (?modelObject getName) ?parameter))))


The test program:

        Rete rete = new Rete();
        rete.batch("src/q1.clp");
        rete.reset();
        Model model = new Model();
        model.setName(parameterName);
        rete.add(model);
        rete.run();

If the defquery is physically located above the defrule, things work fine and the query from the rule LHS found the matched model.

However, when the defquery is moved below the defrule, which is illutrated in the above clp, the query does not find anything.

The rule RHS is then executed and the query from the rule RHS finds the model. There is something going on here...

The second issue is about multiple identical defquery with different names in different clp files.
I made a copy of the included clp and renamed the rule and query to rule2 and query2. All queries in the new clp target query2 as well.

I made sure that the defquery are above the deftule.

I ran the two clp files:

        Rete rete = new Rete();
        rete.batch("src/q1.clp");
        rete.batch("src/q2.clp");
        rete.reset();
        Model model = new Model();
        String parameterName = "super";
        model.setName(parameterName);
        rete.add(model);
        rete.run();

I got the following output:

rule1 is caller -- current-module: MAIN focus: MAIN
f-0   (MAIN::initial-fact)
f-1   (MAIN::Model (class <Java-Object:java.lang.Class>) (name "super") (OBJECT <Java-Object:Model>))
For a total of 2 facts in module MAIN.
query working memory... for model name: super
>< found: super
rule2 is caller -- current-module: MAIN focus: MAIN
f-0   (MAIN::initial-fact)
f-1   (MAIN::Model (class <Java-Object:java.lang.Class>) (name "super") (OBJECT <Java-Object:Model>))
For a total of 2 facts in module MAIN.
query working memory... for model name: super
getQueryFirstResult returns nil
>>> rule2 OOOOPPPPSSSS!  I am not supposed to be here !!!
rule2 RHS -- current-module: MAIN focus: MAIN
f-0   (MAIN::initial-fact)
f-1   (MAIN::Model (class <Java-Object:java.lang.Class>) (name "super") (OBJECT <Java-Object:Model>))
For a total of 2 facts in module MAIN.
query working memory... for model name: super
>< found: super

Rule2 LHS query did not find the model, which I did not expect.
However, its RHS does find it.

If I create a single query and reference it from the rules, then the issue not not there.

Any insight will be greatly appreciated.

Son Nguyen

Reply | Threaded
Open this post in threaded view
|

JESS: RE: run-query* and rule LHS

Friedman-Hill, Ernest
run-query* and rule LHS
Hi,
 
The bottom line is that you can't run queries, directly or indirectly, from the LHS of rules. The results are unpredictable and, as you've seen, generally bad.


From: [hidden email] [mailto:[hidden email]] On Behalf Of Nguyen, Son
Sent: Tuesday, August 16, 2011 12:03 PM
To: jess-users
Subject: JESS: run-query* and rule LHS


Hi,

I observed some strange behaviors of run-query* from the LHS of rules.