2014-04-30 6 views
0

이것은 작성한 코드이지만 새로운 내장 기능은 작동하지 않는 것 같습니다. 오류가 발생합니다.Jena에 내장 된 사용자 정의

Exception in thread "main" com.hp.hpl.jena.reasoner.rulesys.impl.LPRuleSyntaxException: Syntax error in backward rule: matematica Unknown builtin operation 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

내 오류 : 스레드 "main"의 예외 com.hp.hpl.jena.reasoner.rulesys.impl.LPRuleSyntaxException : 역순 규칙의 구문 오류 : matematica 알 수없는 기본 제공 작업 mysum. 추론자를 설정하여 새로운 내장 기능을 인식 할 수있게하는 방법을 모르겠습니다. – user3563844

답변

0

사용자가 제공 한 코드를 사용하고, 아파치 예나 2.11.1 : 여기 내 코드입니다. BuiltinRegistry.theRegistry.register(...)으로 전화 할 때 으로, 내장자가 있음을 알립니다.

솔루션

당신의 실제 코드에서, 당신은 이전에 Rule.parseRules(Rule.rulesParserFromReader(src));를 호출하기 BuiltinRegistry.theRegistry.register(...)를 호출되지 않습니다 때문에 있습니다 점점 가능성이 높습니다 예외, 지금까지 규칙 파서에 관한 한, 존재하지 않는 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이 지원하지 않기 때문에 메서드를 구현하지 않았다고 가정합니다. 장난감 문제에서 예제 구현 을 룰 헤드에 사용할 수 없으므로 이것은 올바른 동작입니다.

+1

흥미 롭습니다. "** backward rule **의 구문 오류 : matematica Unknown builtin operation mysum". 규칙이 전제가되는 질문 (신체의 한 가지와 머리의 다섯 가지)으로 쓰여진 것이 아닙니까? –

+0

당신은 절대적으로 옳습니다. 제공된 장난감 예제는 실제 규칙을 반영하지 않는 것 같습니다. –

+0

안녕 여러분! 귀하의 기여에 대해 감사드립니다.덕분에 문제가 해결되었습니다. 사용자 정의 내장 기능을 내장했습니다! – user3563844