定制内置在耶拿

时间:2014-04-30 09:20:48

标签: java eclipse jena built-in jena-rules

这是我编写的代码,但新的内置似乎不起作用。我收到错误:

  

线程中的异常“main”com.hp.hpl.jena.reasoner.rulesys.impl.LPRuleSyntaxException:向后规则中的语法错误:matematica未知的内置操作mysum

谁能告诉我错误在哪里?这是我的代码:

package JenaRules;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;

import org.semanticweb.owlapi.model.OWLOntologyCreationException;
import org.semanticweb.owlapi.model.OWLOntologyStorageException;

import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.ResultSetFormatter;
import com.hp.hpl.jena.rdf.model.InfModel;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.reasoner.Reasoner;
import com.hp.hpl.jena.reasoner.rulesys.*;
import com.hp.hpl.jena.reasoner.rulesys.builtins.BaseBuiltin;
import com.hp.hpl.jena.util.FileManager;
import com.hp.hpl.jena.vocabulary.RDFS;
import com.hp.hpl.jena.vocabulary.ReasonerVocabulary;

public class RulesOntology_MT {

    public static void main(String[] args) throws OWLOntologyStorageException,
    OWLOntologyCreationException, IOException  {

        BuiltinRegistry.theRegistry.register(new BaseBuiltin() {
             @Override
             public String getName() {
                    return "mysum";
                }
             @Override
                public int getArgLength() {
                    return 2;
                }
             @Override
                public boolean bodyCall(Node[] args, int length, RuleContext context) {
                    checkArgs(length, context);
                    BindingEnvironment env = context.getEnv();
                    Node n1 = getArg(0, args, context);
                    Node n2 = getArg(1, args, context);
                    if (n1.isLiteral() && n2.isLiteral()) {
                        Object v1 = n1.getLiteralValue();
                        Object v2 = n2.getLiteralValue();
                        Node sum = null;
                        if (v1 instanceof Number && v2 instanceof Number) {
                            Number nv1 = (Number)v1;
                            Number nv2 = (Number)v2;
                            int sumInt = nv1.intValue()+nv2.intValue();
                            sum = Util.makeIntNode(sumInt);
                            return env.bind(args[2], sum);
                        }
                    }
                    return false;
                }

        });

        // NON SERVE

        //      final String exampleRuleString2 =
        //              "[mat1: equal(?s ?p )\n\t-> print(?s ?p ?o),\n\t   (?s ?p ?o)\n]"+
        //                      "";

        final String exampleRuleString =    
                "[matematica:"+
                        "(?p http://www.semanticweb.org/prova_rules_M#totale_crediti ?x)"+
                        " -> " +
                        "(?p rdf:type  http://www.semanticweb.org/prova_rules_M#:Persona)"+
                        "(?e rdf:type  http://www.semanticweb.org/prova_rules_M#:Esame)"+
                        "(?p  http://www.semanticweb.org/prova_rules_M#:haSostenutoEsameDi ?e)"+
                        "(?e http://www.semanticweb.org/prova_rules_M/persona#crediti_esame ?cr)"+
                        "mysum(?cr,2)"+
                        "]";

        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  */
        // create an empty non-inferencing model

        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.
         */

        InfModel infModel = ModelFactory.createInfModel(reasoner, ModelFactory.createDefaultModel());
        infModel.prepare();
        infModel.createResource(RDFS.Class);

        //write down the result in RDFXML form
        infModel.write(System.out);

    }
}

1 个答案:

答案 0 :(得分:0)

使用您提供的代码和Apache Jena 2.11.1,我无法复制您获得的异常。请注意,当您致电BuiltinRegistry.theRegistry.register(...)时,您 告诉推理人内置网存在。

<强>解决方案

获取的例外可能是因为,在您的实际代码中,您在调用BuiltinRegistry.theRegistry.register(...)之前没有调用Rule.parseRules(Rule.rulesParserFromReader(src));,因此,就规则解析器而言,您使用的是不存在的Builtin。要修复它,只需在解析规则之前调用register。提供的玩具示例没有这个问题。

使用提供的示例

我还注意到,提供的代码示例中没有包含任何会刺激规则的内容,因此,代替infModel.createResource(RDFS.Class);,我添加了以下几行:

final Resource s = infModel.createResource();
final Property p = infModel.createProperty("http://www.semanticweb.org/prova_rules_M#totale_crediti");
final Resource o = infModel.createResource();
infModel.add(s,p,o);

这刺激了规则的触发,并导致以下异常追踪:

com.hp.hpl.jena.reasoner.rulesys.BuiltinException: Error in clause of rule (matematica) mysum: builtin mysum not usable in rule heads
    at com.hp.hpl.jena.reasoner.rulesys.builtins.BaseBuiltin.headAction(BaseBuiltin.java:86)
    at com.hp.hpl.jena.reasoner.rulesys.impl.RETEConflictSet.execute(RETEConflictSet.java:184)
    at com.hp.hpl.jena.reasoner.rulesys.impl.RETEConflictSet.add(RETEConflictSet.java:81)
    at com.hp.hpl.jena.reasoner.rulesys.impl.RETEEngine.requestRuleFiring(RETEEngine.java:249)
    at com.hp.hpl.jena.reasoner.rulesys.impl.RETETerminal.fire(RETETerminal.java:80)
    at com.hp.hpl.jena.reasoner.rulesys.impl.RETEClauseFilter.fire(RETEClauseFilter.java:227)
    at com.hp.hpl.jena.reasoner.rulesys.impl.RETEEngine.inject(RETEEngine.java:469)
    at com.hp.hpl.jena.reasoner.rulesys.impl.RETEEngine.runAll(RETEEngine.java:451)
    at com.hp.hpl.jena.reasoner.rulesys.impl.RETEEngine.add(RETEEngine.java:174)
    at com.hp.hpl.jena.reasoner.rulesys.FBRuleInfGraph.performAdd(FBRuleInfGraph.java:654)
    at com.hp.hpl.jena.graph.impl.GraphBase.add(GraphBase.java:202)
    at com.hp.hpl.jena.rdf.model.impl.ModelCom.add(ModelCom.java:1138)
    at SO.test(SO.java:108)

作为备注:我的测试类为SO.java,第108行是我们称之为infModel.add(s,p,o)的位置。

我得到的异常与您遇到的异常不同,但值得解释。您提供的实现实现Builtin#bodyCall(...),但不实现Builtin#headAction(...)。我们可以看到BaseBuiltin#headAction(...)抛出异常。此默认行为假定您未实现该方法,因为Builtin不支持该方法。在玩具问题中,这是正确的行为,因为示例实现不能在规则头中使用。