#| http://lists.mindswap.org/pipermail/pellet-users/2006-April/000595.html Hi All, We're experimenting with an extension to Pellet that would allow for reasoning with DL-safe rules. The algorithm for reasoning is tableaux-based and it is a simple extension of the current one used for OWL-DL. Our approach is described in [1] and DL-safe rules are introduced in [2]. The important thing to remember about DL-safe rules is that they are applicable to explicictly asserted individuals only. In order to use this, you need to provide an input file in the form of an ontology extended with rules. The rules have to be in SWRL RDF/XML syntax. An example input file is available at http://www.mindswap.org/~kolovski/rules.owl Then, you only need to add -dlsafe to the command line arguments to use the rules algorithm. Example command line args: -inputFile http://www.mindswap.org/~kolovski/rules.owl -dlsafe You could also query the ontology: -inputFile http://www.mindswap.org/~kolovski/rules.owl -dlsafe -queryFile "query.owl" -queryFormat RDQL -dlsafe There are a couple of reasons this is not an official Pellet release yet: 1) It is slow - further optimizations are needed on algorithm. This is where pellet users can help us: if you already have any sample rules, or an idea of what kinds of rules you'd want to run, we can work with them and see what optimizations are possible. 2) No support for datatype properties at the moment The rules code is part of the Pellet svn now. Also note that rules.jar has been included in lib folder (needed for parsing). Regards, Vlad [1] http://www.mindswap.org/papers/2006/dlsafe.pdf [2] http://www.fzi.de/KCMS/kcms_file.php?action=link&id=404 |# (in-package :cl-user) (defparameter *rulefile-field* (load-time-value (let ((it (find "rulesFile" (#"getDeclaredFields" (find-java-class 'pellet)) :key #"toString" :test 'search))) (#"setAccessible" it t) it))) (defparameter *kb-rules-field* (load-time-value (let ((it (find "rules" (#"getDeclaredFields" (find-java-class 'knowledgebase)) :key #"toString" :test 'search))) (#"setAccessible" it t) it))) (defun parse-rules (uri) (let ((pellet (new 'pellet))) (#"set" *rulefile-field* pellet uri) (#"parseRules" pellet))) ;; (defun test-rule () ;; (let ((f (new 'OWLRuleDataFactoryImpl)) ;; (f2 (#"getInstance" 'OWLDataFactoryImpl (new 'OWLConnectionImpl)))) ;; (let ((varx (#"getOWLRuleIVariable" f (#"create" 'java.net.URI "x" ))) ;; (vary (#"getOWLRuleIVariable" f (#"create" 'java.net.URI "y" )))) ;; (let ((antec (#"getOWLRuleClassAtom" f (new 'owlclassimpl f2 (new 'java.net.uri "http://www.biopax.org/release/biopax-level2.owl#protein")) varx)) ;; (conseq (#"getOWLRuleClassAtom" f (new 'owlclassimpl f2 (new 'java.net.uri "http://www.biopax.org/release/biopax-level2.owl#physicalEntity")) vary)) ;; (eq (#"getOWLRuleEqualityAtom" f varx vary)) ;; (antecs (new 'hashset)) ;; (conseqs (new 'hashset))) ;; (#"add" antecs antec) ;; (#"add" antecs (#"getOWLRuleObjectPropertyAtom" f varx (new 'owlobjectpropertyimpl f2 (new 'java.net.uri "http://www.biopax.org/release/biopax-level2.owl#UNIFICATION-XREF")) vary )) ;; (#"add" antecs eq) ;; (#"add" conseqs conseq) ;; (#"toString" (#"getOWLRule" f antecs conseqs)) ;; )))) ;; (rule ;; (!friend ?x ?y) ;; (!person ?x) ;; (!person ?y) ;; => ;; (!knows ?x ?y)) (defvar *rule-ontology*) (defun make-rule (antecedents consequents) (let ((rfactory (new 'OWLRuleDataFactoryImpl)) (dfactory (#"getInstance" 'OWLDataFactoryImpl (new 'OWLConnectionImpl))) (made (make-hash-table))) (setq @ made) (labels ((variable-p (s) (and (symbolp s) (char= (char (string s) 0) #\?))) (make-variable (name) (or (gethash name made) (setf (gethash name made) (#"getOWLRuleIVariable" rfactory (#"create" 'java.net.URI (string-downcase (subseq (string name) 1))))))) (make-class (name) (or (gethash name made) (setf (gethash name made) (if (boundp '*rule-ontology*) (#"getClass" *rule-ontology* (new 'java.net.uri (uri-full name))) (new 'owlclassimpl dfactory (new 'java.net.uri (uri-full name))))))) (make-property (name) (or (gethash name made) (setf (gethash name made) (if (boundp '*rule-ontology*) (#"getProperty" *rule-ontology* (new 'java.net.uri (uri-full name))) (new 'owlobjectpropertyimpl dfactory (new 'java.net.uri (uri-full name))))))) (parse-one (clause) (cond ((and (= (length clause) 3) (uri-p (car clause)) (variable-p (second clause)) (variable-p (third clause))) (#"getOWLRuleObjectPropertyAtom" rfactory (make-variable (second clause)) (make-property (car clause)) (make-variable (third clause)))) ((and (= (length clause) 3) (member (first clause) '(= /=))) (case (first clause) (/= (#"getOWLRuleInequalityAtom" rfactory (make-variable (second clause)) (make-variable (third clause)))) (= (#"getOWLRuleEqualityAtom" rfactory (make-variable (second clause)) (make-variable (third clause)))))) ((and (= (length clause) 2) (uri-p (car clause)) (variable-p (second clause))) (#"getOWLRuleClassAtom" rfactory (make-class (car clause)) (make-variable (second clause)))) (t (error "don't know how yet"))))) (let ((aset (new 'hashset)) (cset (new 'hashset))) (loop for clause in antecedents do (#"add" aset (parse-one clause))) (loop for clause in consequents do (#"add" cset (parse-one clause))) (#"getOWLRule" rfactory aset cset))))) (defmacro rule (&rest clauses) (setq clauses (eval-uri-reader-macro clauses)) (loop with antecedents and consequents for clause in clauses with state = :antecedent do (cond ((and (symbolp clause) (equal (string clause) "=>")) (setq state :consequent)) ((eq state :antecedent) (push clause antecedents)) (t (push clause consequents))) finally (return `(make-rule ',antecedents ',consequents)))) (defun list-to-hashset (elements) (let ((s (new 'hashset))) (loop for el in elements do (#"add" s el)) s)) #| (with-ontology ruletest (:rules (list (rule (!a ?x) => (!b ?x)))) ((class !a :partial) (class !b :partial) (individual !a1 (type !a))) (princ (abstract-syntax ruletest )) (princ (#"toString" (car (rules ruletest)))) (check ruletest)) (with-ontology ruletest (:rules (list (rule (!a ?x) => (!b ?x)))) ((class !a :partial) (class !b :partial) (individual !a1 (type !a))) (describe !a1)) ;; getOWLRuleDataValue(OWLDataValue) ;; getOWLRuleDVariable(java.net.URI) ;; getOWLRuleIndividual(OWLIndividual) ;; getOWLRuleIVariable(java.net.URI) ;; getOWLRule(java.util.Set,java.util.Set) ;; getOWLRuleInequalityAtom(OWLRuleIObject,OWLRuleIObject) ;; getOWLRuleEqualityAtom(OWLRuleIObject,OWLRuleIObject) ;; getOWLRuleObjectPropertyAtom(OWLRuleIObject,OWLObjectProperty,OWLRuleIObject) ;; getOWLRuleDataPropertyAtom(OWLRuleIObject,OWLDataProperty,OWLRuleDObject) ;; getOWLRuleClassAtom(OWLDescription,OWLRuleIObject) ;; OWLRule ;; OWLRuleAtom ;; OWLRuleClassAtom ;; OWLRuleDataFactory ;; OWLRuleDataPropertyAtom ;; OWLRuleObjectPropertyAtom ;; OWLRuleDataValue ;; OWLRuleDObject ;; OWLRuleDVariable ;; OWLRuleEqualityAtom ;; OWLRuleIndividual ;; OWLRuleInequalityAtom ;; OWLRuleIObject ;; OWLRuleIVariable ;; OWLRuleVariable (defun describe-rules (rules) (map nil (lambda(r) (princ (#"toString" r))) (set-to-list rules))) (describe-rules (parse-rules "http://www.mindswap.org/~kolovski/rules.owl")) ; jena: (#"parseRules" 'rulesys.rule (#"rulesParserFromReader" 'rulesys.rule (new 'BufferedReader (new 'StringReader "[title: (?x http://ddddd ?y) <- (?x uri ?y)]"))))) From: andrea@pasteur.fr Subject: Rules Date: April 5, 2006 6:45:07 PM EDT To: alanruttenberg@gmail.com [title: (?x http://ddddd ?y) <- (?x uri ?y)()()()] private void makePostProcessedKnowledge() { /** * This is a shortcut */ if(postRuleList.size()==0) { myKnowledge=myOntoKnowledge; status=4; validStatus=4; System.out.println("This was pretty easy..."); return; } String[] namespaces=commonMemory.getNamespaces(); String ruleBlock=new String(); for (int i = 0; i < namespaces.length; i++) { String tempPrefix=commonMemory.getNamespacePrefix(namespaces[i]); if(tempPrefix!=null) ruleBlock=ruleBlock.concat("@prefix "+tempPrefix+": "+"<"+namespaces[i]+">\n"); } ruleBlock=ruleBlock.concat("\n\n"); for (Iterator iter = postRuleList.iterator(); iter.hasNext();) { InfRuleObject rule = (InfRuleObject) iter.next(); if(rule.isActive()) { ruleBlock=ruleBlock.concat(rule.getRule()+"\n\n"); } } System.out.println("Your rules...\n"+ruleBlock); List tempRules; try { tempRules=Rule.parseRules(Rule.rulesParserFromReader(new BufferedReader(new StringReader(ruleBlock)))); } catch(Exception e) { System.out.println("Parser Error :\n"+e); return; } //OntModelSpec rulesSpec=new OntModelSpec(getJenaMode()); OntModelSpec rulesSpec=getJenaMode(); GenericRuleReasoner reasoner=new GenericRuleReasoner(tempRules,rulesSpec.getReasonerFactory()); rulesSpec.setReasoner(reasoner); myKnowledge=ModelFactory.createOntologyModel(rulesSpec,myOntoKnowledge); /* myPreProcessedKnowledge=myBasicKnowledge; */ status=4; validStatus=4; //String header="@include <"+getSelectedBaseReasonerLevel()+">\n"; /* String header=new String(); String[] namespaces=commonMemory.getNamespaces(); for (int i = 0; i < namespaces.length; i++) { String tempPrefix=commonMemory.getNamespacePrefix(namespaces[i]); if(tempPrefix!=null) header=header.concat("@prefix "+tempPrefix+": "+"<"+namespaces[i]+">\n"); } header=header.concat("\n\n"); for(int i=0;i"+header); List tempRules; try { tempRules=Rule.parseRules(Rule.rulesParserFromReader(new BufferedReader(new StringReader(header)))); } catch(Exception e) { System.out.println("Parser Error :\n"+e); return; } //OntModelSpec rulesSpec=new OntModelSpec(getJenaMode()); OntModelSpec rulesSpec=getJenaMode(); GenericRuleReasoner reasoner=new GenericRuleReasoner(tempRules,rulesSpec.getReasonerFactory()); rulesSpec.setReasoner(reasoner); myKnowledge=ModelFactory.createOntologyModel(rulesSpec,myOntoKnowledge); */ } (rule (!headOf ?st ?de) (!FullProfessor ?st) (!teacherOf ?st ?co) :-> (!SpecialCourse ?co)) "headOf(?st,?de), FullProfessor(?st), teacherOf(?st,?co) -> SpecialCourse(?co)." |#