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
> > >>
> > >>
> > >>
> > >
> >
>