2

I have written a custom builtin to use in my Project but I do not really know how I can use it. I have written two classes. In one of them there is the builtin I have made (using BaseBuiltin) and in the other one I have registered the new builtin (using BuiltinRegistry).

I have already tried to use default builtins, writing rules that use them in a text file readable from Eclipse using Java. In this case I do not have any problems. How can I use the builtin I have built? Should I import (or include) something in some files?

Stanislav Kralin
  • 11,070
  • 4
  • 35
  • 58
user3563844
  • 113
  • 1
  • 8

1 Answers1

3

First you define a Builtin, usually by extending BaseBuiltin, and then you use BuiltinRegistry.theRegistry.register(Builtin) to make it available to Jena rule-based inference.

Once you've done that, you need to actually use a rule that will reference your Builtin in order to trigger it.

BuiltinRegistry.theRegistry.register( new BaseBuiltin() {
    @Override
    public String getName() {
        return "example";
    }
    @Override
    public void headAction( final Node[] args, final int length, final RuleContext context ) {
        System.out.println("Head Action: "+Arrays.toString(args));
    }
} );

final String exampleRuleString =
    "[mat1: (?s ?p ?o)\n\t-> print(?s ?p ?o),\n\t   example(?s ?p ?o)\n]"+
    "";
System.out.println(exampleRuleString);

/* I tend to use a fairly verbose syntax for parsing out my rules when I construct them
 * from a string. You can read them from whatever other sources.
 */
final List<Rule> rules;
try( final BufferedReader src = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(exampleRuleString.getBytes()))) ) {
    rules = Rule.parseRules(Rule.rulesParserFromReader(src));
}

/* Construct a reasoner and associate the rules with it  */
final GenericRuleReasoner reasoner = (GenericRuleReasoner) GenericRuleReasonerFactory.theInstance().create(null);
reasoner.setRules(rules);

/* Create & Prepare the InfModel. If you don't call prepare, then
 * rule firings and inference may be deferred until you query the
 * model rather than happening at insertion. This can make you think
 * that your Builtin is not working, when it is.
 */
final InfModel infModel = ModelFactory.createInfModel(reasoner, ModelFactory.createDefaultModel());
infModel.prepare();

/* Add a triple to the graph: 
* [] rdf:type rdfs:Class
*/
infModel.createResource(RDFS.Class);

The output of this code will be:

  • The string of the forward-chaining rule
  • The result of calling the print Builtin
  • The result of calling the example Builtin

... which is exactly what we see:

[mat1: (?s ?p ?o)
    -> print(?s ?p ?o),
       example(?s ?p ?o)
]
-2b47400d:14593fc1564:-7fff rdf:type rdfs:Class 
Head Action: [-2b47400d:14593fc1564:-7fff, http://www.w3.org/1999/02/22-rdf-syntax-ns#type, http://www.w3.org/2000/01/rdf-schema#Class]
Rob Hall
  • 2,693
  • 16
  • 22
  • Hello again! I have tried the code. I have just one question. Where can I use the Head Action method ? I mean, my program print: 1) The string of the forward-chaining rule 2) The result of calling the print Builtin How can I print the last result ? Cheers! – user3563844 Apr 29 '14 at 12:07
  • 1
    [`HeadAction`](http://jena.apache.org/documentation/javadoc/jena/com/hp/hpl/jena/reasoner/rulesys/Builtin.html#headAction%28com.hp.hpl.jena.graph.Node[],%20int,%20com.hp.hpl.jena.reasoner.rulesys.RuleContext%29) is called if your `Builtin` is in the consequence/result of a forward-chaining rule. It is fired whenever the rule itself is triggered (ie: all of the antecedents are satisfied). The 'result' _is_ the firing of the rule and the subsequent output `Head Action:...`. – Rob Hall Apr 29 '14 at 13:34
  • If this answer was satisfactory in helping you solve your problem, you may wish to consider [marking it as accepted](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work). This reduces the number of unanswered questions. – Rob Hall Aug 29 '14 at 14:36