Here is the API location.
[image: image.png]

As you suggested, I started to investigate the backward rules.  Here is
some experimental code I did

    // Useful constants
    Node p = NodeFactory.createURI("p");
    Node q = NodeFactory.createURI("q");
    Node r = NodeFactory.createURI("r");
    Node s = NodeFactory.createURI("s");
    Node t = NodeFactory.createURI("t");
    Node a = NodeFactory.createURI("a");
    Node b = NodeFactory.createURI("b");
    Node c = NodeFactory.createURI("c");
    Node d = NodeFactory.createURI("d");
    Node C1 = NodeFactory.createURI("C1");
    Node C2 = NodeFactory.createURI("C2");
    Node C3 = NodeFactory.createURI("C3");
    Node ty = RDF.Nodes.type;
    Node sC = RDFS.Nodes.subClassOf;

    List<Rule> ruleList = Rule.parseRules("""

            [r1: (?a p ?c) <- (?a p ?b), (?b p ?c)]

            # Print primitive
            [C2ForwardPrint: (?a C2 ?c) -> print("check check forward")]

            -> tableAll().
            """);

    public void testBackward() {
        Graph test = Factory.createGraphMem();
        test.add(Triple.create(a, p, b));
        test.add(Triple.create(b, p, c));

        GenericRuleReasoner reasoner = (GenericRuleReasoner)
GenericRuleReasonerFactory.theInstance().create(null);
        reasoner.setRules(ruleList);
        reasoner.setMode(GenericRuleReasoner.HYBRID);
        reasoner.setTransitiveClosureCaching(true);

        //Bind data
        FBRuleInfGraph infgraph = (FBRuleInfGraph)reasoner.bind(test);
        infgraph.prepare();


        // Add backward rule programatically.
        List<Rule> ruleList2 = Rule.parseRules("""
            [C2Print: print("check check") <- (?a C2 ?c)]
            [C1: (?a C2 ?c) <- (?a C1 ?c)]
            -> tableAll().
            """);
        infgraph.addBRules(ruleList2);
        // do not necessary to call prepare();
        //infgraph.prepare();
        // insert triple
        infgraph.performAdd(Triple.create(a, C1, t));

        // check if a C2 t is generated.
        Iterator it = infgraph.find(null, C2, null);
        while (it.hasNext()) {
            System.out.println("#####  " + it.next());
        }
    }

I.could successfully add a backward rule. Thanks for the suggestion.  When
adding triple (a C1 t) as below

infgraph.performAdd(Triple.create(a, C1, t));

I could see:  a @C2 t.  printed.     <--- backward rule triggered.

Regarding backward rule, I have a few questions:
1. It seems the backward rule does not support builtin primitives, such as
print()?  I did not see C2Print print anything.
2. I created a forward rule (C2ForwardPrint) at the very beginning.  If I
add triple as below

infgraph.performAdd(Triple.create(a, C2, t));

'check check forward'  will be printed

However, if I add above (a C1 t) triple, nothing happens. I assume (a C1
t)  generats (a C2 t) from backward rule C1, then recursively calls the
C2ForwardPrint rule to print something?

Is there anything wrong?


Dave Reynolds <[email protected]> 于2023年4月4日周二 02:20写道:

> Hi,
>
> Very mysterious. If I check the github repository as tagged for 4.2.0 I
> can't see an addRule method in BasicForwardRuleInfGraph. Clearly I'm
> missing something.
>
> You can add rules to a reasoner but you would then have to rebuild the
> InfGraph/InfModel.
>
> Like I say, you can add backward rules to a running hybrid engine, if
> that's any use but I don't believe there's any support for dynamically
> adding forward rules.
>
> Dave
>
> On 03/04/2023 19:52, L B wrote:
> > Hi Dave,
> >
> > Thanks for the update.
> >
> > The Jena version I am using is 4.2.0.
> > image.png
> >
> > Checked Jena version 4.5.0. This API seems gone.
> >
> > The system we are developing may have thousands of rules. To make the
> > engine more efficient,  we want some rules to be loaded/unloaded
> > dynamically.  For example, the driving related rules are loaded when the
> > user is driving. When the user gets home, those driving rules will be
> > unloaded.
> >
> > In Jena 4.5 API, the reasoner has addRules API, but I do not know how to
> > make it work.
> >
> > //inf is the InfModel created already.
> > GenericRuleReasoner reasoner = (GenericRuleReasoner) inf.getReasoner();
> > reasoner.setMode(GenericRuleReasoner.HYBRID);
> > reasoner.setDerivationLogging(true);
> > reasoner.setTraceOn(true);
> >
> > List<Rule> rules = Rule.parseRules(ruleStr);
> > reasoner.addRules(rules);
> > inf.prepare();
> >
> > The rule added is never triggered.  Is there any way we could add/remove
> > rules programmatically without cause to rebuild InfModal and recheck all
> > the existing rules?
> >
> >
> > Dave Reynolds <[email protected]
> > <mailto:[email protected]>> 于2023年3月30日周四 14:14写道:
> >
> >     There's no support for dynamically adding forward rules to a
> "running"
> >     reasoner that I recall.
> >
> >     You can dynamically add backward rules to a hybrid reasoner, but
> that's
> >     not relevant here.
> >
> >     Your code example suggests you are calling addRule on a
> >     BasicForwardRuleInfGraph but, unless I'm missing something, that
> method
> >     is not in the jena source. Is it something you have added?
> >
> >     You can add rules to a reasoner but then would essentially have to
> >     build
> >     a new InfGraph or reset the engine state of the current infgraph.
> >     Either
> >     way that's why you are seeing the original deduction retrigger.
> >
> >     If you need to fire some action when adding triples to a model, and
> >     dynamically change the processing, I'd suggest using the listener
> >     machinery rather than the rule system.
> >
> >     Dave
> >
> >     On 28/03/2023 18:43, L B wrote:
> >      > I am currently still trying to figure out the solution.
> >      >
> >      > 1. If I do not call coreInfModel.prepare(), nothing happens
> >     during the
> >      > triple update which is WAD, I believe.
> >      > 2. When one triple is updated, all the rules which have true
> >     condition will
> >      > be triggered, rather than the rules related. I am expecting the
> >     other rules
> >      > will not be triggered unless its related triplets are updated. Is
> it
> >      > possible?
> >      >
> >      >
> >      > L B <[email protected] <mailto:[email protected]>> 于2023年3
> >     月24日周五 16:10写道:
> >      >
> >      >>
> >      >> 1) Init code:
> >      >>
> >      >> GenericRuleReasoner reasoner = new GenericRuleReasoner(new
> >      >> ArrayList<Rule>());
> >      >>              reasoner.setMode(GenericRuleReasoner.FORWARD);
> >      >>              mCoreInfModel =
> ModelFactory.createInfModel(reasoner,
> >      >> mCoreModel);
> >      >>
> >      >> 2) Statement exits
> >      >>   (:A :B :C)
> >      >>
> >      >> 3) Rule exists and triggered before
> >      >>
> >      >>              [ alwaysTrue:
> >      >>                  (:A :B :C)
> >      >>                  -> triggerAction
> >      >>              ]
> >      >>
> >      >> 4) Now, I am trying to add rules at runtime.
> >      >>
> >      >>               [ rule2:
> >      >>                  (:X :Y :Z)
> >      >>                  -> triggerAction2
> >      >>              ]
> >      >>
> >      >>          InfModel infModel = getCoreInfModel();
> >      >>          BasicForwardRuleInfGraph infGraph =
> >     (BasicForwardRuleInfGraph)
> >      >> infModel.getGraph();          infGraph.addRule(rule)
> >      >>          coreInfModel.prepare()
> >      >>
> >      >> 5) add triple (:X :Y :Z)
> >      >>
> >      >>          val infGraph = infModel.graph as
> BasicForwardRuleInfGraph
> >      >>         infGraph.add(triple)
> >      >>
> >      >> *The problem comes, both "alwaysTrue" and "rule2" triggered.*
> >      >>
> >      >> *I am expecting only "rule2" is triggered. *
> >      >>
> >      >> Is there anyway that only "rule2" can be triggered since the
> updated
> >      >> triple is only X, Y Z?
> >      >>
> >      >> Many thanks
> >      >>
> >      >>
> >      >>
> >      >
> >
>

Reply via email to