You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jena.apache.org by Christophe FAGOT <fa...@intactile.com> on 2014/03/19 17:46:07 UTC

Removed RETERuleContext not fired to Builtin in rule head

Hi Jena folks,

since I need to use Jena with its RETEEngine, I’m actually investigating what is actually feasible / usable with this engine functionalities.

I would like to develop my own BuiltIn, used in the head of a forward rule, and doing some actions when a new rule context appears (due to triples adding) for the body rule, while doing some other actions when a rule context disappears (dur to triples removal) for this body rule.

It appears in the RETEConflictSet (line 180) that a BuiltIn can receive only … added RETERuleContext. Hence a BuiltIn action can only be called when a RETERuleContext is added, never when a RETERuleContext is removed.

Is their a reason for that ?

Would it be possible to add in the context whether it’s a context added or removed, and to call the BuiltIn head action in both cases ?

Thanks,

Chris.


: : . . . . . . . . . . . . . . . . . . . . . . . : :
Christophe FAGOT, PhD
Responsable R&D informatique

intactile DESIGN
: : Création d’interfaces subtiles : :
+33 (0)4 67 52 88 61
+33 (0)9 50 12 05 66
20 rue du carré du roi
34000 MONTPELLIER,  France
http://www.intactile.com

Hugh MacLeod : "It's not what the software does, it's what the user does"

Les informations contenues dans cet email et ses documents attachés sont confidentielles. Elles sont exclusivement adressées aux destinataires explicitement désignés ci-dessus et ne peuvent être divulguées sans consentement de son auteur. Si vous n'êtes pas le destinataire de cet email vous ne devez pas employer, révéler, distribuer, copier, imprimer ou transmettre le contenu de cet email et devez le détruire immédiatement.













Re: Removed RETERuleContext not fired to Builtin in rule head

Posted by "Sébastien Boulet [intactile DESIGN]" <bo...@intactile.com>.
Hello,

i just created a JIRA ticket and i attached a patch corresponding to the modifications discussed previously:

https://issues.apache.org/jira/browse/JENA-863 <https://issues.apache.org/jira/browse/JENA-863>

Regards

Seb

Sébastien BOULET
LEAD DÉVELOPPEUR

intactile DESIGN
Création d’interfaces + subtiles
04 67 52 88 61
09 50 12 05 66
20 rue du carré du roi
34000 MONTPELLIER
France
www.intactile.com <http://intactile.com/>

Les informations contenues dans cet email et ses documents attachés sont confidentielles. Elles sont exclusivement adressées aux destinataires explicitement désignés ci-dessus et ne peuvent être divulguées sans consentement de son auteur. Si vous n'êtes pas le destinataire de cet email vous ne devez pas employer, révéler, distribuer, copier, imprimer ou transmettre le contenu de cet email et devez le détruire immédiatement.

> Le 21 janv. 2015 à 12:34, Dave Reynolds <da...@gmail.com> a écrit :
> 
> No "red" in the plain text copy I received :) but I think I can see the changes you are proposing. They do look safe in principle (aside from some missing "{}").
> 
> As we discussed before, there is no guarantee you will receive all the removal messages so whether this facility will achieve what you desire is not clear to me. However, it does give an extension point for people who want to experiment in this area and should not affected existing usage.
> 
> Happy for you to submit a tested patched as a JIRA so people can check it. I'm about to go on leave so will not be able to look it instantly myself.
> 
> Dave
> 
> 
> On 21/01/15 10:50, Christophe FAGOT [intactile DESIGN] wrote:
>> Hi all, hi Dave,
>> 
>> back to this old discussion, in order to increase the BuiltIn behaviour by our side, but while preserving the actual behaviour of the existing BuiltIn of Jena and those developped by third parties, we would like to propose the following patches. Our aim is to be able to send the removed context to some rules handle by a RETE engine (while it's not possible for the time being).
>> 
>> First, we need an interface extending the current BuilIn one and provide a method called when removed contexts have to be indicated.
>> 
>> public interface ReversibleBuiltIn extends BuiltIn {
>> 	    /**
>>      * This method is invoked when the builtin is called in a rule head with a removed context.
>>      * Such a use is only valid in a forward rule.
>>      * @param args the array of argument values for the builtin, this is an array
>>      * of Nodes.
>>      * @param length the length of the argument list, may be less than the length of the args array
>>      * for some rule engines
>>      * @param context an removed context giving access to other relevant data
>>      */
>>     public void reverseHeadAction(Node[] args, int length, RuleContext context);
>> }
>> 
>> Then, when need to define when to call the reverseHeadAction method, we propose to complete RETEConflictSet::execute as following (changes are in bold red) :
>> 
>>     public static void execute(RETERuleContext context, boolean isAdd) {
>>         Rule rule = context.getRule();
>>         BindingEnvironment env = context.getEnv();
>>         ForwardRuleInfGraphI infGraph = (ForwardRuleInfGraphI)context.getGraph();
>>         if (infGraph.shouldTrace()) {
>>             logger.info("Fired rule: " + rule.toShortString());
>>         }
>>         RETEEngine engine = context.getEngine();
>>         engine.incRuleCount();
>>         List<Triple> matchList = null;
>>         if (infGraph.shouldLogDerivations() && isAdd) {
>>             // Create derivation record
>>             matchList = new ArrayList<>(rule.bodyLength());
>>             for (int i = 0; i < rule.bodyLength(); i++) {
>>                 Object clause = rule.getBodyElement(i);
>>                 if (clause instanceof TriplePattern) {
>>                     matchList.add(env.instantiate((TriplePattern)clause));
>>                 }
>>             }
>>         }
>>         for (int i = 0; i < rule.headLength(); i++) {
>>             Object hClause = rule.getHeadElement(i);
>>             if (hClause instanceof TriplePattern) {
>>                 Triple t = env.instantiate((TriplePattern) hClause);
>>                 // Used to filter out triples with literal subjects
>>                 // but this is not necessary
>>                 // if (!t.getSubject().isLiteral()) {
>>                     // Only add the result if it is legal at the RDF level.
>>                     // E.g. RDFS rules can create assertions about literals
>>                     // that we can't record in RDF
>>                     if (isAdd) {
>>                         if ( ! context.contains(t) ) {
>>                             engine.addTriple(t, true);
>>                             if (infGraph.shouldLogDerivations()) {
>>                                 infGraph.logDerivation(t, new RuleDerivation(rule, t, matchList, infGraph));
>>                             }
>>                         }
>>                     } else {
>>                         if ( context.contains(t)) {
>>                             // Remove the generated triple
>>                             engine.deleteTriple(t, true);
>>                         }
>>                     }
>>               // }
>>             } else if (hClause instanceof Functor && isAdd) {
>>                 Functor f = (Functor)hClause;
>>                 Builtin imp = f.getImplementor();
>>                 if (imp != null) {
>>                     imp.headAction(f.getBoundArgs(env), f.getArgLength(), context);
>>                 } else {
>>                     throw new ReasonerException("Invoking undefined Functor " + f.getName() +" in " + rule.toShortString());
>>                 }
>>         	  else if (hClause instanceof Functor && !isAdd) {
>>                 Functor f = (Functor)hClause;
>>                 BuiltIn imp = f.getImplementor();
>>                 if (imp != null && imp instanceOf ReversibleBuiltIn ) {
>>                     ((ReversibleBuiltIn)imp).reverseHeadAction(f.getBoundArgs(env), f.getArgLength(), context);
>>                 }
>>             } else if (hClause instanceof Rule) {
>>                 Rule r = (Rule)hClause;
>>                 if (r.isBackward()) {
>>                     if (isAdd) {
>>                         infGraph.addBRule(r.instantiate(env));
>>                     } else {
>>                         infGraph.deleteBRule(r.instantiate(env));
>>                     }
>>                 } else {
>>                     throw new ReasonerException("Found non-backward subrule : " + r);
>>                 }
>>             }
>>         }
>>     }
>> 
>> 
>> Does it sounds good for you ? If yes, we will do these improvements, and a ticket in Jira and send the patch for validation.
>> 
>> Best regards,
>> 
>> Chris.
>> 
>> Christophe FAGOT, PhD
>> RESPONSABLE R&D INFORMATIQUE
>> 
>> intactile DESIGN
>> Création d’interfaces + subtiles
>> +33 (0)4 67 52 88 61
>> +33 (0)9 50 12 05 66
>> 20 rue du carré du roi
>> 34000 MONTPELLIER
>> France
>> www.intactile.com
>> 
>> Hugh MacLeod : "It's not what the software does, it's what the user does"
>> 
>> Les informations contenues dans cet email et ses documents attachés sont confidentielles. Elles sont exclusivement adressées aux destinataires explicitement désignés ci-dessus et ne peuvent être divulguées sans consentement de son auteur. Si vous n'êtes pas le destinataire de cet email vous ne devez pas employer, révéler, distribuer, copier, imprimer ou transmettre le contenu de cet email et devez le détruire immédiatement.
>> 
>>> Le 20 mars 2014 à 16:20, Dave Reynolds <da...@gmail.com> a écrit :
>>> 
>>> 
>>> On 20/03/14 10:59, Christophe FAGOT wrote:
>>>> 
>>>> Le 20 mars 2014 à 11:20, Dave Reynolds <da...@gmail.com> a écrit :
>>>> 
>>>>> 
>>>>> On 20/03/14 09:46, Christophe FAGOT wrote:
>>>>>> 
>>>>>> Le 19 mars 2014 à 18:46, Dave Reynolds <da...@gmail.com> a écrit :
>>>>>> 
>>>>>>> 
>>>>>>> On 19/03/14 16:46, Christophe FAGOT wrote:
>>>>>>>> Hi Jena folks,
>>>>>>>> 
>>>>>>>> since I need to use Jena with its RETEEngine, I’m actually investigating what is actually feasible / usable with this engine functionalities.
>>>>>>>> 
>>>>>>>> I would like to develop my own BuiltIn, used in the head of a forward rule, and doing some actions when a new rule context appears (due to triples adding) for the body rule, while doing some other actions when a rule context disappears (dur to triples removal) for this body rule.
>>>>>>>> 
>>>>>>>> It appears in the RETEConflictSet (line 180) that a BuiltIn can receive only … added RETERuleContext. Hence a BuiltIn action can only be called when a RETERuleContext is added, never when a RETERuleContext is removed.
>>>>>>>> 
>>>>>>>> Is their a reason for that ?
>>>>>>> 
>>>>>>> The existing head builtins expect to only be fired when a potitive deduction is made. This is a legacy of the fact that the rule system was designed for monotonic inference and all the remove/non-monotonic processing is a hack.
>>>>>> 
>>>>>> I don’t see the relationship between monotonic inference and remove prohibited. A monotonic inference only means that when adding some facts in the knowledge base, the previous inferred data can’t be removed, while when removing some facts, new facts can’t be produced. And this is exactly what Jena Rete engine perfectly does with « standard » triple patterns. But when the head is a BuiltIn, that BuiltIn does not have a single chance to act the same way. The BuildIn can only react to added triples. And the only mandatory thing for a BuiltIn is to declare is it is monotonic or not. But it’s behavior and the triples it adds/removes in the inference graph are never verified to check if it really has a (non-)monotonic behavior. But this is another story.
>>>>> 
>>>>> The point is that builtins in the head are only useful if they have some side effect. Jena indeed handles removes when the rules are monotonic. As soon as you have side-effecting builtins then all bets are off. Even if a builtin's effect is reversible (which I take to be the case you are interested in) it's hard to guarantee all the necessary rules will fire in "remove" mode in the way you expect without the rule equivalent of reference counting.
>>>> 
>>>> Absolutely agree. Would you be open to some little modifications in the RETE classes source code, if that modifications improve the ability to extend the RETE behavior (or to correct the problem of memory consumption), while preserving the actual behavior of existing rules sets using BuiltIn (hence, receiving only added data) ?
>>> 
>>> Sure, patches welcome.
>>> 
>>> I believe the right workflow would be to open a jira entry/ies for your enhancement and attach the changes as patch fines.
>>> 
>>> Warning: I'm petty overloaded right now [*] so may need prompting to review any patches.
>>> 
>>> Dave
>>> 
>>> [*] For values of "right now" that seem to be depressingly permanent!
>> 
>> 


Re: Removed RETERuleContext not fired to Builtin in rule head

Posted by Dave Reynolds <da...@gmail.com>.
No "red" in the plain text copy I received :) but I think I can see the 
changes you are proposing. They do look safe in principle (aside from 
some missing "{}").

As we discussed before, there is no guarantee you will receive all the 
removal messages so whether this facility will achieve what you desire 
is not clear to me. However, it does give an extension point for people 
who want to experiment in this area and should not affected existing usage.

Happy for you to submit a tested patched as a JIRA so people can check 
it. I'm about to go on leave so will not be able to look it instantly 
myself.

Dave


On 21/01/15 10:50, Christophe FAGOT [intactile DESIGN] wrote:
> Hi all, hi Dave,
>
> back to this old discussion, in order to increase the BuiltIn behaviour by our side, but while preserving the actual behaviour of the existing BuiltIn of Jena and those developped by third parties, we would like to propose the following patches. Our aim is to be able to send the removed context to some rules handle by a RETE engine (while it's not possible for the time being).
>
> First, we need an interface extending the current BuilIn one and provide a method called when removed contexts have to be indicated.
>
> public interface ReversibleBuiltIn extends BuiltIn {
> 	    /**
>       * This method is invoked when the builtin is called in a rule head with a removed context.
>       * Such a use is only valid in a forward rule.
>       * @param args the array of argument values for the builtin, this is an array
>       * of Nodes.
>       * @param length the length of the argument list, may be less than the length of the args array
>       * for some rule engines
>       * @param context an removed context giving access to other relevant data
>       */
>      public void reverseHeadAction(Node[] args, int length, RuleContext context);
> }
>
> Then, when need to define when to call the reverseHeadAction method, we propose to complete RETEConflictSet::execute as following (changes are in bold red) :
>
>      public static void execute(RETERuleContext context, boolean isAdd) {
>          Rule rule = context.getRule();
>          BindingEnvironment env = context.getEnv();
>          ForwardRuleInfGraphI infGraph = (ForwardRuleInfGraphI)context.getGraph();
>          if (infGraph.shouldTrace()) {
>              logger.info("Fired rule: " + rule.toShortString());
>          }
>          RETEEngine engine = context.getEngine();
>          engine.incRuleCount();
>          List<Triple> matchList = null;
>          if (infGraph.shouldLogDerivations() && isAdd) {
>              // Create derivation record
>              matchList = new ArrayList<>(rule.bodyLength());
>              for (int i = 0; i < rule.bodyLength(); i++) {
>                  Object clause = rule.getBodyElement(i);
>                  if (clause instanceof TriplePattern) {
>                      matchList.add(env.instantiate((TriplePattern)clause));
>                  }
>              }
>          }
>          for (int i = 0; i < rule.headLength(); i++) {
>              Object hClause = rule.getHeadElement(i);
>              if (hClause instanceof TriplePattern) {
>                  Triple t = env.instantiate((TriplePattern) hClause);
>                  // Used to filter out triples with literal subjects
>                  // but this is not necessary
>                  // if (!t.getSubject().isLiteral()) {
>                      // Only add the result if it is legal at the RDF level.
>                      // E.g. RDFS rules can create assertions about literals
>                      // that we can't record in RDF
>                      if (isAdd) {
>                          if ( ! context.contains(t) ) {
>                              engine.addTriple(t, true);
>                              if (infGraph.shouldLogDerivations()) {
>                                  infGraph.logDerivation(t, new RuleDerivation(rule, t, matchList, infGraph));
>                              }
>                          }
>                      } else {
>                          if ( context.contains(t)) {
>                              // Remove the generated triple
>                              engine.deleteTriple(t, true);
>                          }
>                      }
>                // }
>              } else if (hClause instanceof Functor && isAdd) {
>                  Functor f = (Functor)hClause;
>                  Builtin imp = f.getImplementor();
>                  if (imp != null) {
>                      imp.headAction(f.getBoundArgs(env), f.getArgLength(), context);
>                  } else {
>                      throw new ReasonerException("Invoking undefined Functor " + f.getName() +" in " + rule.toShortString());
>                  }
>          	  else if (hClause instanceof Functor && !isAdd) {
>                  Functor f = (Functor)hClause;
>                  BuiltIn imp = f.getImplementor();
>                  if (imp != null && imp instanceOf ReversibleBuiltIn ) {
>                      ((ReversibleBuiltIn)imp).reverseHeadAction(f.getBoundArgs(env), f.getArgLength(), context);
>                  }
>              } else if (hClause instanceof Rule) {
>                  Rule r = (Rule)hClause;
>                  if (r.isBackward()) {
>                      if (isAdd) {
>                          infGraph.addBRule(r.instantiate(env));
>                      } else {
>                          infGraph.deleteBRule(r.instantiate(env));
>                      }
>                  } else {
>                      throw new ReasonerException("Found non-backward subrule : " + r);
>                  }
>              }
>          }
>      }
>
>
> Does it sounds good for you ? If yes, we will do these improvements, and a ticket in Jira and send the patch for validation.
>
> Best regards,
>
> Chris.
>
> Christophe FAGOT, PhD
> RESPONSABLE R&D INFORMATIQUE
>
> intactile DESIGN
> Création d’interfaces + subtiles
> +33 (0)4 67 52 88 61
> +33 (0)9 50 12 05 66
> 20 rue du carré du roi
> 34000 MONTPELLIER
> France
> www.intactile.com
>
> Hugh MacLeod : "It's not what the software does, it's what the user does"
>
> Les informations contenues dans cet email et ses documents attachés sont confidentielles. Elles sont exclusivement adressées aux destinataires explicitement désignés ci-dessus et ne peuvent être divulguées sans consentement de son auteur. Si vous n'êtes pas le destinataire de cet email vous ne devez pas employer, révéler, distribuer, copier, imprimer ou transmettre le contenu de cet email et devez le détruire immédiatement.
>
>> Le 20 mars 2014 à 16:20, Dave Reynolds <da...@gmail.com> a écrit :
>>
>>
>> On 20/03/14 10:59, Christophe FAGOT wrote:
>>>
>>> Le 20 mars 2014 à 11:20, Dave Reynolds <da...@gmail.com> a écrit :
>>>
>>>>
>>>> On 20/03/14 09:46, Christophe FAGOT wrote:
>>>>>
>>>>> Le 19 mars 2014 à 18:46, Dave Reynolds <da...@gmail.com> a écrit :
>>>>>
>>>>>>
>>>>>> On 19/03/14 16:46, Christophe FAGOT wrote:
>>>>>>> Hi Jena folks,
>>>>>>>
>>>>>>> since I need to use Jena with its RETEEngine, I’m actually investigating what is actually feasible / usable with this engine functionalities.
>>>>>>>
>>>>>>> I would like to develop my own BuiltIn, used in the head of a forward rule, and doing some actions when a new rule context appears (due to triples adding) for the body rule, while doing some other actions when a rule context disappears (dur to triples removal) for this body rule.
>>>>>>>
>>>>>>> It appears in the RETEConflictSet (line 180) that a BuiltIn can receive only … added RETERuleContext. Hence a BuiltIn action can only be called when a RETERuleContext is added, never when a RETERuleContext is removed.
>>>>>>>
>>>>>>> Is their a reason for that ?
>>>>>>
>>>>>> The existing head builtins expect to only be fired when a potitive deduction is made. This is a legacy of the fact that the rule system was designed for monotonic inference and all the remove/non-monotonic processing is a hack.
>>>>>
>>>>> I don’t see the relationship between monotonic inference and remove prohibited. A monotonic inference only means that when adding some facts in the knowledge base, the previous inferred data can’t be removed, while when removing some facts, new facts can’t be produced. And this is exactly what Jena Rete engine perfectly does with « standard » triple patterns. But when the head is a BuiltIn, that BuiltIn does not have a single chance to act the same way. The BuildIn can only react to added triples. And the only mandatory thing for a BuiltIn is to declare is it is monotonic or not. But it’s behavior and the triples it adds/removes in the inference graph are never verified to check if it really has a (non-)monotonic behavior. But this is another story.
>>>>
>>>> The point is that builtins in the head are only useful if they have some side effect. Jena indeed handles removes when the rules are monotonic. As soon as you have side-effecting builtins then all bets are off. Even if a builtin's effect is reversible (which I take to be the case you are interested in) it's hard to guarantee all the necessary rules will fire in "remove" mode in the way you expect without the rule equivalent of reference counting.
>>>
>>> Absolutely agree. Would you be open to some little modifications in the RETE classes source code, if that modifications improve the ability to extend the RETE behavior (or to correct the problem of memory consumption), while preserving the actual behavior of existing rules sets using BuiltIn (hence, receiving only added data) ?
>>
>> Sure, patches welcome.
>>
>> I believe the right workflow would be to open a jira entry/ies for your enhancement and attach the changes as patch fines.
>>
>> Warning: I'm petty overloaded right now [*] so may need prompting to review any patches.
>>
>> Dave
>>
>> [*] For values of "right now" that seem to be depressingly permanent!
>
>

Re: Removed RETERuleContext not fired to Builtin in rule head

Posted by "Christophe FAGOT [intactile DESIGN]" <fa...@intactile.com>.
Hi all, hi Dave,

back to this old discussion, in order to increase the BuiltIn behaviour by our side, but while preserving the actual behaviour of the existing BuiltIn of Jena and those developped by third parties, we would like to propose the following patches. Our aim is to be able to send the removed context to some rules handle by a RETE engine (while it's not possible for the time being).

First, we need an interface extending the current BuilIn one and provide a method called when removed contexts have to be indicated.

public interface ReversibleBuiltIn extends BuiltIn {
	    /**
     * This method is invoked when the builtin is called in a rule head with a removed context.
     * Such a use is only valid in a forward rule.
     * @param args the array of argument values for the builtin, this is an array 
     * of Nodes.
     * @param length the length of the argument list, may be less than the length of the args array
     * for some rule engines
     * @param context an removed context giving access to other relevant data
     */
    public void reverseHeadAction(Node[] args, int length, RuleContext context);
}

Then, when need to define when to call the reverseHeadAction method, we propose to complete RETEConflictSet::execute as following (changes are in bold red) :

    public static void execute(RETERuleContext context, boolean isAdd) {
        Rule rule = context.getRule();
        BindingEnvironment env = context.getEnv();
        ForwardRuleInfGraphI infGraph = (ForwardRuleInfGraphI)context.getGraph();
        if (infGraph.shouldTrace()) {
            logger.info("Fired rule: " + rule.toShortString());
        }
        RETEEngine engine = context.getEngine();
        engine.incRuleCount();
        List<Triple> matchList = null;
        if (infGraph.shouldLogDerivations() && isAdd) {
            // Create derivation record
            matchList = new ArrayList<>(rule.bodyLength());
            for (int i = 0; i < rule.bodyLength(); i++) {
                Object clause = rule.getBodyElement(i);
                if (clause instanceof TriplePattern) {
                    matchList.add(env.instantiate((TriplePattern)clause));
                } 
            }
        }
        for (int i = 0; i < rule.headLength(); i++) {
            Object hClause = rule.getHeadElement(i);
            if (hClause instanceof TriplePattern) {
                Triple t = env.instantiate((TriplePattern) hClause);
                // Used to filter out triples with literal subjects
                // but this is not necessary
                // if (!t.getSubject().isLiteral()) {
                    // Only add the result if it is legal at the RDF level.
                    // E.g. RDFS rules can create assertions about literals
                    // that we can't record in RDF
                    if (isAdd) {
                        if ( ! context.contains(t) ) {
                            engine.addTriple(t, true);
                            if (infGraph.shouldLogDerivations()) {
                                infGraph.logDerivation(t, new RuleDerivation(rule, t, matchList, infGraph));
                            }
                        }
                    } else {
                        if ( context.contains(t)) {
                            // Remove the generated triple
                            engine.deleteTriple(t, true);
                        }
                    }
              // }
            } else if (hClause instanceof Functor && isAdd) {
                Functor f = (Functor)hClause;
                Builtin imp = f.getImplementor();
                if (imp != null) {
                    imp.headAction(f.getBoundArgs(env), f.getArgLength(), context);
                } else {
                    throw new ReasonerException("Invoking undefined Functor " + f.getName() +" in " + rule.toShortString());
                }
        	  else if (hClause instanceof Functor && !isAdd) {
                Functor f = (Functor)hClause;
                BuiltIn imp = f.getImplementor();
                if (imp != null && imp instanceOf ReversibleBuiltIn ) {
                    ((ReversibleBuiltIn)imp).reverseHeadAction(f.getBoundArgs(env), f.getArgLength(), context);
                }
            } else if (hClause instanceof Rule) {
                Rule r = (Rule)hClause;
                if (r.isBackward()) {
                    if (isAdd) {
                        infGraph.addBRule(r.instantiate(env));
                    } else {
                        infGraph.deleteBRule(r.instantiate(env));
                    }
                } else {
                    throw new ReasonerException("Found non-backward subrule : " + r); 
                }
            }
        }        
    }


Does it sounds good for you ? If yes, we will do these improvements, and a ticket in Jira and send the patch for validation.

Best regards,

Chris.

Christophe FAGOT, PhD
RESPONSABLE R&D INFORMATIQUE

intactile DESIGN
Création d’interfaces + subtiles
+33 (0)4 67 52 88 61
+33 (0)9 50 12 05 66
20 rue du carré du roi
34000 MONTPELLIER
France
www.intactile.com

Hugh MacLeod : "It's not what the software does, it's what the user does"

Les informations contenues dans cet email et ses documents attachés sont confidentielles. Elles sont exclusivement adressées aux destinataires explicitement désignés ci-dessus et ne peuvent être divulguées sans consentement de son auteur. Si vous n'êtes pas le destinataire de cet email vous ne devez pas employer, révéler, distribuer, copier, imprimer ou transmettre le contenu de cet email et devez le détruire immédiatement.

> Le 20 mars 2014 à 16:20, Dave Reynolds <da...@gmail.com> a écrit :
> 
> 
> On 20/03/14 10:59, Christophe FAGOT wrote:
>> 
>> Le 20 mars 2014 à 11:20, Dave Reynolds <da...@gmail.com> a écrit :
>> 
>>> 
>>> On 20/03/14 09:46, Christophe FAGOT wrote:
>>>> 
>>>> Le 19 mars 2014 à 18:46, Dave Reynolds <da...@gmail.com> a écrit :
>>>> 
>>>>> 
>>>>> On 19/03/14 16:46, Christophe FAGOT wrote:
>>>>>> Hi Jena folks,
>>>>>> 
>>>>>> since I need to use Jena with its RETEEngine, I’m actually investigating what is actually feasible / usable with this engine functionalities.
>>>>>> 
>>>>>> I would like to develop my own BuiltIn, used in the head of a forward rule, and doing some actions when a new rule context appears (due to triples adding) for the body rule, while doing some other actions when a rule context disappears (dur to triples removal) for this body rule.
>>>>>> 
>>>>>> It appears in the RETEConflictSet (line 180) that a BuiltIn can receive only … added RETERuleContext. Hence a BuiltIn action can only be called when a RETERuleContext is added, never when a RETERuleContext is removed.
>>>>>> 
>>>>>> Is their a reason for that ?
>>>>> 
>>>>> The existing head builtins expect to only be fired when a potitive deduction is made. This is a legacy of the fact that the rule system was designed for monotonic inference and all the remove/non-monotonic processing is a hack.
>>>> 
>>>> I don’t see the relationship between monotonic inference and remove prohibited. A monotonic inference only means that when adding some facts in the knowledge base, the previous inferred data can’t be removed, while when removing some facts, new facts can’t be produced. And this is exactly what Jena Rete engine perfectly does with « standard » triple patterns. But when the head is a BuiltIn, that BuiltIn does not have a single chance to act the same way. The BuildIn can only react to added triples. And the only mandatory thing for a BuiltIn is to declare is it is monotonic or not. But it’s behavior and the triples it adds/removes in the inference graph are never verified to check if it really has a (non-)monotonic behavior. But this is another story.
>>> 
>>> The point is that builtins in the head are only useful if they have some side effect. Jena indeed handles removes when the rules are monotonic. As soon as you have side-effecting builtins then all bets are off. Even if a builtin's effect is reversible (which I take to be the case you are interested in) it's hard to guarantee all the necessary rules will fire in "remove" mode in the way you expect without the rule equivalent of reference counting.
>> 
>> Absolutely agree. Would you be open to some little modifications in the RETE classes source code, if that modifications improve the ability to extend the RETE behavior (or to correct the problem of memory consumption), while preserving the actual behavior of existing rules sets using BuiltIn (hence, receiving only added data) ?
> 
> Sure, patches welcome.
> 
> I believe the right workflow would be to open a jira entry/ies for your enhancement and attach the changes as patch fines.
> 
> Warning: I'm petty overloaded right now [*] so may need prompting to review any patches.
> 
> Dave
> 
> [*] For values of "right now" that seem to be depressingly permanent!


Re: Removed RETERuleContext not fired to Builtin in rule head

Posted by Dave Reynolds <da...@gmail.com>.
On 20/03/14 10:59, Christophe FAGOT wrote:
>
> Le 20 mars 2014 à 11:20, Dave Reynolds <da...@gmail.com> a écrit :
>
>>
>> On 20/03/14 09:46, Christophe FAGOT wrote:
>>>
>>> Le 19 mars 2014 à 18:46, Dave Reynolds <da...@gmail.com> a écrit :
>>>
>>>>
>>>> On 19/03/14 16:46, Christophe FAGOT wrote:
>>>>> Hi Jena folks,
>>>>>
>>>>> since I need to use Jena with its RETEEngine, I’m actually investigating what is actually feasible / usable with this engine functionalities.
>>>>>
>>>>> I would like to develop my own BuiltIn, used in the head of a forward rule, and doing some actions when a new rule context appears (due to triples adding) for the body rule, while doing some other actions when a rule context disappears (dur to triples removal) for this body rule.
>>>>>
>>>>> It appears in the RETEConflictSet (line 180) that a BuiltIn can receive only … added RETERuleContext. Hence a BuiltIn action can only be called when a RETERuleContext is added, never when a RETERuleContext is removed.
>>>>>
>>>>> Is their a reason for that ?
>>>>
>>>> The existing head builtins expect to only be fired when a potitive deduction is made. This is a legacy of the fact that the rule system was designed for monotonic inference and all the remove/non-monotonic processing is a hack.
>>>
>>> I don’t see the relationship between monotonic inference and remove prohibited. A monotonic inference only means that when adding some facts in the knowledge base, the previous inferred data can’t be removed, while when removing some facts, new facts can’t be produced. And this is exactly what Jena Rete engine perfectly does with « standard » triple patterns. But when the head is a BuiltIn, that BuiltIn does not have a single chance to act the same way. The BuildIn can only react to added triples. And the only mandatory thing for a BuiltIn is to declare is it is monotonic or not. But it’s behavior and the triples it adds/removes in the inference graph are never verified to check if it really has a (non-)monotonic behavior. But this is another story.
>>
>> The point is that builtins in the head are only useful if they have some side effect. Jena indeed handles removes when the rules are monotonic. As soon as you have side-effecting builtins then all bets are off. Even if a builtin's effect is reversible (which I take to be the case you are interested in) it's hard to guarantee all the necessary rules will fire in "remove" mode in the way you expect without the rule equivalent of reference counting.
>
> Absolutely agree. Would you be open to some little modifications in the RETE classes source code, if that modifications improve the ability to extend the RETE behavior (or to correct the problem of memory consumption), while preserving the actual behavior of existing rules sets using BuiltIn (hence, receiving only added data) ?

Sure, patches welcome.

I believe the right workflow would be to open a jira entry/ies for your 
enhancement and attach the changes as patch fines.

Warning: I'm petty overloaded right now [*] so may need prompting to 
review any patches.

Dave

[*] For values of "right now" that seem to be depressingly permanent!

Re: Removed RETERuleContext not fired to Builtin in rule head

Posted by Christophe FAGOT <fa...@intactile.com>.
Le 20 mars 2014 à 11:20, Dave Reynolds <da...@gmail.com> a écrit :

> 
> On 20/03/14 09:46, Christophe FAGOT wrote:
>> 
>> Le 19 mars 2014 à 18:46, Dave Reynolds <da...@gmail.com> a écrit :
>> 
>>> 
>>> On 19/03/14 16:46, Christophe FAGOT wrote:
>>>> Hi Jena folks,
>>>> 
>>>> since I need to use Jena with its RETEEngine, I’m actually investigating what is actually feasible / usable with this engine functionalities.
>>>> 
>>>> I would like to develop my own BuiltIn, used in the head of a forward rule, and doing some actions when a new rule context appears (due to triples adding) for the body rule, while doing some other actions when a rule context disappears (dur to triples removal) for this body rule.
>>>> 
>>>> It appears in the RETEConflictSet (line 180) that a BuiltIn can receive only … added RETERuleContext. Hence a BuiltIn action can only be called when a RETERuleContext is added, never when a RETERuleContext is removed.
>>>> 
>>>> Is their a reason for that ?
>>> 
>>> The existing head builtins expect to only be fired when a potitive deduction is made. This is a legacy of the fact that the rule system was designed for monotonic inference and all the remove/non-monotonic processing is a hack.
>> 
>> I don’t see the relationship between monotonic inference and remove prohibited. A monotonic inference only means that when adding some facts in the knowledge base, the previous inferred data can’t be removed, while when removing some facts, new facts can’t be produced. And this is exactly what Jena Rete engine perfectly does with « standard » triple patterns. But when the head is a BuiltIn, that BuiltIn does not have a single chance to act the same way. The BuildIn can only react to added triples. And the only mandatory thing for a BuiltIn is to declare is it is monotonic or not. But it’s behavior and the triples it adds/removes in the inference graph are never verified to check if it really has a (non-)monotonic behavior. But this is another story.
> 
> The point is that builtins in the head are only useful if they have some side effect. Jena indeed handles removes when the rules are monotonic. As soon as you have side-effecting builtins then all bets are off. Even if a builtin's effect is reversible (which I take to be the case you are interested in) it's hard to guarantee all the necessary rules will fire in "remove" mode in the way you expect without the rule equivalent of reference counting.

Absolutely agree. Would you be open to some little modifications in the RETE classes source code, if that modifications improve the ability to extend the RETE behavior (or to correct the problem of memory consumption), while preserving the actual behavior of existing rules sets using BuiltIn (hence, receiving only added data) ?

Chris.

> 
> Dave
> 

: : . . . . . . . . . . . . . . . . . . . . . . . : :

Christophe FAGOT, PhD

Responsable R&D informatique


intactile DESIGN
: : Création d’interfaces subtiles : :
+33 (0)4 67 52 88 61
+33 (0)9 50 12 05 66
20 rue du carré du roi
34000 MONTPELLIER,  France
http://www.intactile.com

Hugh MacLeod : "It's not what the software does, it's what the user does"

Les informations contenues dans cet email et ses documents attachés sont confidentielles. Elles sont exclusivement adressées aux destinataires explicitement désignés ci-dessus et ne peuvent être divulguées sans consentement de son auteur. Si vous n'êtes pas le destinataire de cet email vous ne devez pas employer, révéler, distribuer, copier, imprimer ou transmettre le contenu de cet email et devez le détruire immédiatement.













Re: Removed RETERuleContext not fired to Builtin in rule head

Posted by Dave Reynolds <da...@gmail.com>.
On 20/03/14 09:46, Christophe FAGOT wrote:
>
> Le 19 mars 2014 à 18:46, Dave Reynolds <da...@gmail.com> a écrit :
>
>>
>> On 19/03/14 16:46, Christophe FAGOT wrote:
>>> Hi Jena folks,
>>>
>>> since I need to use Jena with its RETEEngine, I’m actually investigating what is actually feasible / usable with this engine functionalities.
>>>
>>> I would like to develop my own BuiltIn, used in the head of a forward rule, and doing some actions when a new rule context appears (due to triples adding) for the body rule, while doing some other actions when a rule context disappears (dur to triples removal) for this body rule.
>>>
>>> It appears in the RETEConflictSet (line 180) that a BuiltIn can receive only … added RETERuleContext. Hence a BuiltIn action can only be called when a RETERuleContext is added, never when a RETERuleContext is removed.
>>>
>>> Is their a reason for that ?
>>
>> The existing head builtins expect to only be fired when a potitive deduction is made. This is a legacy of the fact that the rule system was designed for monotonic inference and all the remove/non-monotonic processing is a hack.
>
> I don’t see the relationship between monotonic inference and remove prohibited. A monotonic inference only means that when adding some facts in the knowledge base, the previous inferred data can’t be removed, while when removing some facts, new facts can’t be produced. And this is exactly what Jena Rete engine perfectly does with « standard » triple patterns. But when the head is a BuiltIn, that BuiltIn does not have a single chance to act the same way. The BuildIn can only react to added triples. And the only mandatory thing for a BuiltIn is to declare is it is monotonic or not. But it’s behavior and the triples it adds/removes in the inference graph are never verified to check if it really has a (non-)monotonic behavior. But this is another story.

The point is that builtins in the head are only useful if they have some 
side effect. Jena indeed handles removes when the rules are monotonic. 
As soon as you have side-effecting builtins then all bets are off. Even 
if a builtin's effect is reversible (which I take to be the case you are 
interested in) it's hard to guarantee all the necessary rules will fire 
in "remove" mode in the way you expect without the rule equivalent of 
reference counting.

Dave


Re: Removed RETERuleContext not fired to Builtin in rule head

Posted by Christophe FAGOT <fa...@intactile.com>.
Le 19 mars 2014 à 18:46, Dave Reynolds <da...@gmail.com> a écrit :

> 
> On 19/03/14 16:46, Christophe FAGOT wrote:
>> Hi Jena folks,
>> 
>> since I need to use Jena with its RETEEngine, I’m actually investigating what is actually feasible / usable with this engine functionalities.
>> 
>> I would like to develop my own BuiltIn, used in the head of a forward rule, and doing some actions when a new rule context appears (due to triples adding) for the body rule, while doing some other actions when a rule context disappears (dur to triples removal) for this body rule.
>> 
>> It appears in the RETEConflictSet (line 180) that a BuiltIn can receive only … added RETERuleContext. Hence a BuiltIn action can only be called when a RETERuleContext is added, never when a RETERuleContext is removed.
>> 
>> Is their a reason for that ?
> 
> The existing head builtins expect to only be fired when a potitive deduction is made. This is a legacy of the fact that the rule system was designed for monotonic inference and all the remove/non-monotonic processing is a hack.

I don’t see the relationship between monotonic inference and remove prohibited. A monotonic inference only means that when adding some facts in the knowledge base, the previous inferred data can’t be removed, while when removing some facts, new facts can’t be produced. And this is exactly what Jena Rete engine perfectly does with « standard » triple patterns. But when the head is a BuiltIn, that BuiltIn does not have a single chance to act the same way. The BuildIn can only react to added triples. And the only mandatory thing for a BuiltIn is to declare is it is monotonic or not. But it’s behavior and the triples it adds/removes in the inference graph are never verified to check if it really has a (non-)monotonic behavior. But this is another story.

> It was added due to requests on the user's list but was a mistake.
> 
> Note also that since there's no reference counting in the rule system it's notion of removal is not reliable.
> 
>> Would it be possible to add in the context whether it’s a context added or removed, and to call the BuiltIn head action in both cases ?
> 
> No because that would change behaviour for existing rules sets, especially any with custom builtins.

For sure, if some changes occurs, they have to fully respect and ensure the way the existing rules sets behave.

> 
> I guess you could have a custom sort of builtin which does support firing a head-action on a remove and modify RETEConflictSet to check for such builtins and allow those (and only those) to fire - passing the isAdd flag as part of the call.

That was exactly what I had in mind. Adding a flag to BuiltIn so that they declare if they need to receive the removals, set the default value to false in BaseBuiltIn, modify a little bit RETEConflictSet, and fire the remove only to the BuiltIn requiring it.

Chris.

> 
> Dave
> 

: : . . . . . . . . . . . . . . . . . . . . . . . : :

Christophe FAGOT, PhD

Responsable R&D informatique


intactile DESIGN
: : Création d’interfaces subtiles : :
+33 (0)4 67 52 88 61
+33 (0)9 50 12 05 66
20 rue du carré du roi
34000 MONTPELLIER,  France
http://www.intactile.com

Hugh MacLeod : "It's not what the software does, it's what the user does"

Les informations contenues dans cet email et ses documents attachés sont confidentielles. Elles sont exclusivement adressées aux destinataires explicitement désignés ci-dessus et ne peuvent être divulguées sans consentement de son auteur. Si vous n'êtes pas le destinataire de cet email vous ne devez pas employer, révéler, distribuer, copier, imprimer ou transmettre le contenu de cet email et devez le détruire immédiatement.













Re: Removed RETERuleContext not fired to Builtin in rule head

Posted by Dave Reynolds <da...@gmail.com>.
On 19/03/14 16:46, Christophe FAGOT wrote:
> Hi Jena folks,
>
> since I need to use Jena with its RETEEngine, I’m actually investigating what is actually feasible / usable with this engine functionalities.
>
> I would like to develop my own BuiltIn, used in the head of a forward rule, and doing some actions when a new rule context appears (due to triples adding) for the body rule, while doing some other actions when a rule context disappears (dur to triples removal) for this body rule.
>
> It appears in the RETEConflictSet (line 180) that a BuiltIn can receive only … added RETERuleContext. Hence a BuiltIn action can only be called when a RETERuleContext is added, never when a RETERuleContext is removed.
>
> Is their a reason for that ?

The existing head builtins expect to only be fired when a potitive 
deduction is made. This is a legacy of the fact that the rule system was 
designed for monotonic inference and all the remove/non-monotonic 
processing is a hack. It was added due to requests on the user's list 
but was a mistake.

Note also that since there's no reference counting in the rule system 
it's notion of removal is not reliable.

> Would it be possible to add in the context whether it’s a context added or removed, and to call the BuiltIn head action in both cases ?

No because that would change behaviour for existing rules sets, 
especially any with custom builtins.

I guess you could have a custom sort of builtin which does support 
firing a head-action on a remove and modify RETEConflictSet to check for 
such builtins and allow those (and only those) to fire - passing the 
isAdd flag as part of the call.

Dave