public void nonMatchingAntecedentsAddsNoConsequents() { TripleStore store = new MemoryTripleStore(); SimpleRuleProcessor ruleProcessor = new SimpleRuleProcessor(); Rule rule = new Rule(); rule.AddAntecedent(new Pattern(new UriRef("http://example.com/subj"), new UriRef("http://example.com/pred"), new UriRef("http://example.com/obj"))); rule.AddConsequent(new Pattern(new UriRef("http://example.com/subj"), new UriRef("http://example.com/pred"), new UriRef("http://example.com/other"))); ruleProcessor.Process(rule, store); Assert.IsTrue(store.IsEmpty(), "Store is still empty"); }
public void noAntecedentsAutomaticallyAddsConsequents() { TripleStore store = new MemoryTripleStore(); SimpleRuleProcessor ruleProcessor = new SimpleRuleProcessor(); Rule rule = new Rule(); rule.AddConsequent(new Pattern(new UriRef("http://example.com/subj"), new UriRef("http://example.com/pred"), new UriRef("http://example.com/obj"))); ruleProcessor.Process(rule, store); Assert.IsFalse(store.IsEmpty(), "Store is non-empty"); Assert.IsTrue(store.Contains(new Statement(new UriRef("http://example.com/subj"), new UriRef("http://example.com/pred"), new UriRef("http://example.com/obj"))), "Destination contains consequent"); }
public void consequentsAreAddedUsingAntecedentSolutionBindings() { TripleStore store = new MemoryTripleStore(); SimpleRuleProcessor ruleProcessor = new SimpleRuleProcessor(); store.Add(new Statement(new UriRef("http://example.com/subj"), new UriRef("http://example.com/pred"), new UriRef("http://example.com/obj"))); Rule rule = new Rule(); rule.AddAntecedent(new Pattern(new Variable("var1"), new UriRef("http://example.com/pred"), new Variable("var2"))); rule.AddConsequent(new Pattern(new Variable("var1"), new UriRef("http://example.com/newPred"), new Variable("var2"))); ruleProcessor.Process(rule, store); Assert.IsFalse(store.IsEmpty(), "Destination is non-empty"); Assert.IsTrue(store.Contains(new Statement(new UriRef("http://example.com/subj"), new UriRef("http://example.com/newPred"), new UriRef("http://example.com/obj"))), "Destination contains consequent"); }
public void allAntecedentMatchesAreProcessed() { TripleStore store = new MemoryTripleStore(); SimpleRuleProcessor ruleProcessor = new SimpleRuleProcessor(); store.Add(new Statement(new UriRef("http://example.com/subj1"), new UriRef("http://example.com/pred"), new UriRef("http://example.com/obj1"))); store.Add(new Statement(new UriRef("http://example.com/subj2"), new UriRef("http://example.com/pred"), new UriRef("http://example.com/obj2"))); Rule rule = new Rule(); rule.AddAntecedent(new Pattern(new Variable("var1"), new UriRef("http://example.com/pred"), new Variable("var2"))); rule.AddConsequent(new Pattern(new Variable("var1"), new UriRef("http://example.com/newPred"), new Variable("var2"))); ruleProcessor.Process(rule, store); Assert.IsFalse(store.IsEmpty(), "Destination is non-empty"); Assert.IsTrue(store.Contains(new Statement(new UriRef("http://example.com/subj1"), new UriRef("http://example.com/newPred"), new UriRef("http://example.com/obj1"))), "Destination contains first match onsequent"); Assert.IsTrue(store.Contains(new Statement(new UriRef("http://example.com/subj2"), new UriRef("http://example.com/newPred"), new UriRef("http://example.com/obj2"))), "Destination contains second match consequent"); }
private Rule MakeAxioms() { Rule axioms = new Rule(); axioms.AddConsequent(new Pattern(Schema.rdfs.comment, Schema.rdfs.domain, Schema.rdfs.Resource)); axioms.AddConsequent(new Pattern(Schema.rdfs.comment, Schema.rdfs.range, Schema.rdfs.Literal)); axioms.AddConsequent(new Pattern(Schema.rdfs.domain, Schema.rdfs.domain, Schema.rdf.Property)); axioms.AddConsequent(new Pattern(Schema.rdfs.domain, Schema.rdfs.range, Schema.rdfs.Class)); axioms.AddConsequent(new Pattern(Schema.rdf.first, Schema.rdf.type, Schema.rdf.Property)); axioms.AddConsequent(new Pattern(Schema.rdf.first, Schema.rdfs.domain, Schema.rdf.List)); axioms.AddConsequent(new Pattern(Schema.rdf.first, Schema.rdfs.range, Schema.rdfs.Resource)); axioms.AddConsequent(new Pattern(Schema.rdfs.isDefinedBy, Schema.rdfs.domain, Schema.rdfs.Resource)); axioms.AddConsequent(new Pattern(Schema.rdfs.isDefinedBy, Schema.rdfs.range, Schema.rdfs.Resource)); axioms.AddConsequent(new Pattern(Schema.rdfs.label, Schema.rdfs.domain, Schema.rdfs.Resource)); axioms.AddConsequent(new Pattern(Schema.rdfs.label, Schema.rdfs.range, Schema.rdfs.Literal)); axioms.AddConsequent(new Pattern(Schema.rdfs.member, Schema.rdfs.domain, Schema.rdfs.Resource)); axioms.AddConsequent(new Pattern(Schema.rdfs.member, Schema.rdfs.range, Schema.rdfs.Resource)); axioms.AddConsequent(new Pattern(Schema.rdf.nil, Schema.rdf.type, Schema.rdf.Property)); axioms.AddConsequent(new Pattern(Schema.rdf.object_, Schema.rdf.type, Schema.rdf.Property)); axioms.AddConsequent(new Pattern(Schema.rdf.object_, Schema.rdfs.domain, Schema.rdf.Statement)); axioms.AddConsequent(new Pattern(Schema.rdf.object_, Schema.rdfs.range, Schema.rdfs.Resource)); axioms.AddConsequent(new Pattern(Schema.rdf.predicate, Schema.rdf.type, Schema.rdf.Property)); axioms.AddConsequent(new Pattern(Schema.rdf.predicate, Schema.rdfs.domain, Schema.rdf.Statement)); axioms.AddConsequent(new Pattern(Schema.rdf.predicate, Schema.rdfs.range, Schema.rdfs.Resource)); axioms.AddConsequent(new Pattern(Schema.rdfs.range, Schema.rdfs.domain, Schema.rdf.Property)); axioms.AddConsequent(new Pattern(Schema.rdfs.range, Schema.rdfs.range, Schema.rdfs.Class)); axioms.AddConsequent(new Pattern(Schema.rdf.rest, Schema.rdf.type, Schema.rdf.Property)); axioms.AddConsequent(new Pattern(Schema.rdf.rest, Schema.rdfs.domain, Schema.rdf.List)); axioms.AddConsequent(new Pattern(Schema.rdf.rest, Schema.rdfs.range, Schema.rdf.List)); axioms.AddConsequent(new Pattern(Schema.rdfs.seeAlso, Schema.rdfs.domain, Schema.rdfs.Resource)); axioms.AddConsequent(new Pattern(Schema.rdfs.seeAlso, Schema.rdfs.range, Schema.rdfs.Resource)); axioms.AddConsequent(new Pattern(Schema.rdf.subject, Schema.rdf.type, Schema.rdf.Property)); axioms.AddConsequent(new Pattern(Schema.rdf.subject, Schema.rdfs.domain, Schema.rdf.Statement)); axioms.AddConsequent(new Pattern(Schema.rdf.subject, Schema.rdfs.range, Schema.rdfs.Resource)); axioms.AddConsequent(new Pattern(Schema.rdfs.subClassOf, Schema.rdfs.domain, Schema.rdfs.Class)); axioms.AddConsequent(new Pattern(Schema.rdfs.subClassOf, Schema.rdfs.range, Schema.rdfs.Class)); axioms.AddConsequent(new Pattern(Schema.rdfs.subPropertyOf, Schema.rdfs.domain, Schema.rdf.Property)); axioms.AddConsequent(new Pattern(Schema.rdfs.subPropertyOf, Schema.rdfs.range, Schema.rdf.Property)); axioms.AddConsequent(new Pattern(Schema.rdf.type, Schema.rdf.type, Schema.rdf.Property)); axioms.AddConsequent(new Pattern(Schema.rdf.type, Schema.rdfs.domain, Schema.rdfs.Resource)); axioms.AddConsequent(new Pattern(Schema.rdf.type, Schema.rdfs.range, Schema.rdfs.Class)); axioms.AddConsequent(new Pattern(Schema.rdf.value, Schema.rdf.type, Schema.rdf.Property)); axioms.AddConsequent(new Pattern(Schema.rdf.value, Schema.rdfs.domain, Schema.rdfs.Resource)); axioms.AddConsequent(new Pattern(Schema.rdf.value, Schema.rdfs.range, Schema.rdfs.Resource)); axioms.AddConsequent(new Pattern(Schema.rdf.Alt, Schema.rdfs.subClassOf, Schema.rdfs.Container)); axioms.AddConsequent(new Pattern(Schema.rdf.Bag, Schema.rdfs.subClassOf, Schema.rdfs.Container)); axioms.AddConsequent(new Pattern(Schema.rdf.Seq, Schema.rdfs.subClassOf, Schema.rdfs.Container)); axioms.AddConsequent(new Pattern(Schema.rdfs.ContainerMembershipProperty, Schema.rdfs.subClassOf, Schema.rdf.Property)); axioms.AddConsequent(new Pattern(Schema.rdfs.isDefinedBy, Schema.rdfs.subPropertyOf, Schema.rdfs.seeAlso)); axioms.AddConsequent(new Pattern(Schema.rdf.XMLLiteral, Schema.rdf.type, Schema.rdfs.Datatype)); axioms.AddConsequent(new Pattern(Schema.rdf.XMLLiteral, Schema.rdfs.subClassOf, Schema.rdfs.Literal)); axioms.AddConsequent(new Pattern(Schema.rdfs.Datatype, Schema.rdfs.subClassOf, Schema.rdfs.Class)); for (int listIndex = 1; listIndex < 16; ++listIndex) { UriRef listIndexProperty = new UriRef(Schema.rdf._nsprefix + "_" + listIndex); axioms.AddConsequent(new Pattern(listIndexProperty, Schema.rdf.type, Schema.rdf.Property)); axioms.AddConsequent(new Pattern(listIndexProperty, Schema.rdf.type, Schema.rdfs.ContainerMembershipProperty)); axioms.AddConsequent(new Pattern(listIndexProperty, Schema.rdfs.domain, Schema.rdfs.Resource)); axioms.AddConsequent(new Pattern(listIndexProperty, Schema.rdfs.range, Schema.rdfs.Resource)); } return(axioms); }
/// <summary>Applies inference rules to assertions in the KnowledgeBase.</summary> public virtual void Think() { // Implementation of this method has not been optimised for efficiency. Focus is on correctness for now itsInferences = (TripleStore)itsAssertions.Clone(); itsInferences.Add(itsSchemas); Rule axioms = MakeAxioms(); itsInferences.Evaluate(axioms); int previousStatementCount = 0; ArrayList rules = new ArrayList(); Rule rdf1 = new Rule(); rdf1.AddAntecedent(new Pattern(new Variable("uuu"), new Variable("aaa"), new Variable("yyy"))); rdf1.AddConsequent(new Pattern(new Variable("aaa"), Schema.rdf.type, Schema.rdf.Property)); rules.Add(rdf1); Rule rdfs2 = new Rule(); rdfs2.AddAntecedent(new Pattern(new Variable("aaa"), Schema.rdfs.domain, new Variable("xxx"))); rdfs2.AddAntecedent(new Pattern(new Variable("uuu"), new Variable("aaa"), new Variable("yyy"))); rdfs2.AddConsequent(new Pattern(new Variable("uuu"), Schema.rdf.type, new Variable("xxx"))); rules.Add(rdfs2); Rule rdfs3 = new Rule(); rdfs3.AddAntecedent(new Pattern(new Variable("aaa"), Schema.rdfs.range, new Variable("xxx"))); rdfs3.AddAntecedent(new Pattern(new Variable("uuu"), new Variable("aaa"), new Variable("vvv"))); rdfs3.AddConsequent(new Pattern(new Variable("vvv"), Schema.rdf.type, new Variable("xxx"))); rules.Add(rdfs3); Rule rdfs4 = new Rule(); rdfs4.AddAntecedent(new Pattern(new Variable("uuu"), new Variable("aaa"), new Variable("xxx"))); rdfs4.AddConsequent(new Pattern(new Variable("uuu"), Schema.rdf.type, Schema.rdfs.Resource)); rdfs4.AddConsequent(new Pattern(new Variable("xxx"), Schema.rdf.type, Schema.rdfs.Resource)); rules.Add(rdfs4); Rule rdfs5 = new Rule(); rdfs5.AddAntecedent(new Pattern(new Variable("uuu"), Schema.rdf.type, Schema.rdf.Property)); rdfs5.AddConsequent(new Pattern(new Variable("uuu"), Schema.rdfs.subPropertyOf, new Variable("uuu"))); rules.Add(rdfs5); Rule rdfs6 = new Rule(); rdfs6.AddAntecedent(new Pattern(new Variable("uuu"), Schema.rdfs.subPropertyOf, new Variable("vvv"))); rdfs6.AddAntecedent(new Pattern(new Variable("vvv"), Schema.rdfs.subPropertyOf, new Variable("xxx"))); rdfs6.AddConsequent(new Pattern(new Variable("uuu"), Schema.rdfs.subPropertyOf, new Variable("xxx"))); rules.Add(rdfs6); Rule rdfs7 = new Rule(); rdfs7.AddAntecedent(new Pattern(new Variable("aaa"), Schema.rdfs.subPropertyOf, new Variable("bbb"))); rdfs7.AddAntecedent(new Pattern(new Variable("uuu"), new Variable("aaa"), new Variable("yyy"))); rdfs7.AddConsequent(new Pattern(new Variable("uuu"), new Variable("bbb"), new Variable("yyy"))); rules.Add(rdfs7); Rule rdfs8and10 = new Rule(); rdfs8and10.AddAntecedent(new Pattern(new Variable("uuu"), Schema.rdf.type, Schema.rdfs.Class)); rdfs8and10.AddConsequent(new Pattern(new Variable("uuu"), Schema.rdfs.subClassOf, Schema.rdfs.Resource)); rdfs8and10.AddConsequent(new Pattern(new Variable("uuu"), Schema.rdfs.subClassOf, new Variable("uuu"))); rules.Add(rdfs8and10); Rule rdfs9 = new Rule(); rdfs9.AddAntecedent(new Pattern(new Variable("uuu"), Schema.rdfs.subClassOf, new Variable("xxx"))); rdfs9.AddAntecedent(new Pattern(new Variable("vvv"), Schema.rdf.type, new Variable("uuu"))); rdfs9.AddConsequent(new Pattern(new Variable("vvv"), Schema.rdf.type, new Variable("xxx"))); rules.Add(rdfs9); Rule rdfs11 = new Rule(); rdfs11.AddAntecedent(new Pattern(new Variable("uuu"), Schema.rdfs.subClassOf, new Variable("vvv"))); rdfs11.AddAntecedent(new Pattern(new Variable("vvv"), Schema.rdfs.subClassOf, new Variable("xxx"))); rdfs11.AddConsequent(new Pattern(new Variable("uuu"), Schema.rdfs.subClassOf, new Variable("xxx"))); rules.Add(rdfs11); Rule rdfs12 = new Rule(); rdfs12.AddAntecedent(new Pattern(new Variable("uuu"), Schema.rdf.type, Schema.rdfs.ContainerMembershipProperty)); rdfs12.AddConsequent(new Pattern(new Variable("uuu"), Schema.rdfs.subPropertyOf, Schema.rdfs.member)); rules.Add(rdfs12); Rule rdfs13 = new Rule(); rdfs13.AddAntecedent(new Pattern(new Variable("uuu"), Schema.rdf.type, Schema.rdfs.Datatype)); rdfs13.AddConsequent(new Pattern(new Variable("uuu"), Schema.rdfs.subClassOf, Schema.rdfs.Literal)); rules.Add(rdfs13); /* * Can also add following OWL entailment rules * (after Herman J. ter Horst, Extending the RDFS Entailment Lemma, Proceedings of 3rd International Semantic Web Conference) * * rdfp1: (?p rdf:type owl:FunctionalProperty) (?u ?p ?v) (?u ?p ?w) where v is URI or BlankNode then add (?v owl:sameAs ?w) * rdfp2: (?p rdf:type owl:InverseFunctionalProperty) (?u ?p ?w) (?v ?p ?w) then add (?u owl:sameAs ?v) * rdfp3: (?p rdf:type owl:SymmetricProperty) (?v ?p ?w) where w is URI or BlankNode then add (?w ?p ?v) * rdfp4: (?p rdf:type owl:TransitiveProperty) (?u ?p ?v) (?v ?p ?w) then add (?u ?p ?w) * rdfp5a: (?v ?p ?w) then add (?v owl:sameAs ?v) * rdfp5b: (?v ?p ?w) where w is URI or BlankNode then add (?w owl:sameAs ?w) * rdfp6: (?v owl:sameAs ?w) where w is URI or BlankNode then add (?w owl:sameAs ?v) * rdfp7: (?u owl:sameAs ?v) (?v owl:sameAs ?w) then add (?u owl:sameAs ?w) * rdfp8a: (?p owl:inverseOf ?q) (?v ?p ?w) where w is URI or BlankNode and q is URI then add (?w ?q ?v) * rdfp8b: (?p owl:inverseOf ?q) (?v ?q ?w) where w is URI or BlankNode and q is URI then add (?w ?p ?v) * rdfp9: (?v rdf:type rdfs:Class) (?v owl:sameAs ?w) then add (?v rdfs:subClassOf ?w) * rdfp10: (?p rdf:type rdf:Property) (?p owl:sameAs ?q) then add (?p rdfs:subPropertyOf ?q) * * */ while (previousStatementCount != itsInferences.StatementCount) { previousStatementCount = itsInferences.StatementCount; foreach (Rule rule in rules) { itsInferences.Evaluate(rule); } } }