Skip to content

Commit

Permalink
Update to make look more like the OWL API
Browse files Browse the repository at this point in the history
The spec and the OWL use different names as far as I can see. But the
OWL API looks more like the XML serialization.

Currently broken
  • Loading branch information
phillord committed Mar 12, 2024
1 parent 4b1a2ca commit 3e52acc
Show file tree
Hide file tree
Showing 13 changed files with 547 additions and 14 deletions.
21 changes: 18 additions & 3 deletions src/io/owx/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,6 @@ fn is_owl(res: &ResolveResult) -> bool {
} else {
false
}

}

fn is_owl_name(res: &ResolveResult, e: &BytesEnd, tag: &[u8]) -> bool {
Expand Down Expand Up @@ -366,7 +365,7 @@ from_start! {
let datatype_iri = get_iri_value_for(r, e, b"datatypeIRI")?;
let lang = get_attr_value_str(&mut r.reader, e, b"xml:lang")?;

// quick-xml only offers `r.reader.read_text()` for NsReader<'i &u8> as
// quick-xml only offers `r.reader.read_text()` for NsReader<'i &u8> as
// of version 0.26.0.
// So, we need to work around it.
//
Expand All @@ -379,7 +378,7 @@ from_start! {
if let Event::End(event) = r.reader.read_event_into(&mut buf)? {
if let b"Literal" = event.local_name().as_ref() { break; }
}

// This decoding step is not sufficient on its own.
// For instance, "A --> B" would yield "A --&gt; B".
let escaped_str = r.reader.decoder().decode(&buf)?;
Expand Down Expand Up @@ -587,6 +586,15 @@ fn axiom_from_start<A: ForIRI, R: BufRead>(
iri: from_next(r)?,
}
.into(),
b"DLSafeRule" => {
discard_till(r, b"Body")?;
let body = till_end(r, b"Body")?;
discard_till(r, b"Head")?;
Rule {
body,
head: till_end(r, b"Head")?
}
}.into(),
_ => {
return Err(error_unexpected_tag(axiom_kind, r));
}
Expand Down Expand Up @@ -2070,6 +2078,13 @@ pub mod test {
}
}

#[test]
fn swrl_rule_basic() {
let ont_s = include_str!("../../ont/owl-xml/swrl_rule_basic.owx");

let (_, _) = read_ok(&mut ont_s.as_bytes());
}

#[test]
fn family() {
let ont_s = include_str!("../../ont/owl-xml/family.owx");
Expand Down
4 changes: 3 additions & 1 deletion src/io/owx/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ fn tag_for_kind(axk: ComponentKind) -> &'static str {
ComponentKind::SubAnnotationPropertyOf => "SubAnnotationPropertyOf",
ComponentKind::AnnotationPropertyDomain => "AnnotationPropertyDomain",
ComponentKind::AnnotationPropertyRange => "AnnotationPropertyRange",
ComponentKind::Rule => todo!("SWRL"),
}
}

Expand Down Expand Up @@ -607,7 +608,8 @@ render! {
Component::AnnotationAssertion(ax) => ax.render(w, m)?,
Component::SubAnnotationPropertyOf(ax) => ax.render(w, m)?,
Component::AnnotationPropertyDomain(ax) => ax.render(w, m)?,
Component::AnnotationPropertyRange(ax) => ax.render(w, m)?
Component::AnnotationPropertyRange(ax) => ax.render(w, m)?,
Component::Rule(_) => todo!("SWRL"),
}
Ok(())
}
Expand Down
1 change: 1 addition & 0 deletions src/io/rdf/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,7 @@ impl<A: ForIRI> Render<A, Annotatable<A>> for Component<A> {
Component::AnnotationPropertyDomain(cmp) => cmp.render(f, ng)?.into(),
Component::AnnotationPropertyRange(cmp) => cmp.render(f, ng)?.into(),
Component::ClassAssertion(cmp) => cmp.render(f, ng)?.into(),
Component::Rule(_) => todo!("SWRL todo"),
})
}
}
Expand Down
21 changes: 11 additions & 10 deletions src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1727,20 +1727,21 @@ impl<A: ForIRI> From<Class<A>> for Box<ClassExpression<A>> {

#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum Atom<A>{
DescriptionAtom(IObject<A>),
DataRangeAtom(DObject<A>),
IndividualValuedPropertyID(IObject<A>, IObject<A>),
DataValuedPropertyID(IObject<A>, DObject<A>),
SameAsAtom(IObject<A>, IObject<A>),
DifferentFromAtom(IObject<A>, IObject<A>),
BuiltInAtom(IRI<A>, DObject<A>),
BuiltInAtom{pred: IRI<A>, arg: DArgument<A>},
ClassAtom{pred:ClassExpression<A>, arg: IArgument<A>},
DataPropertyAtom{pred: DataProperty<A>, args:(DArgument<A>, DArgument<A>)},
DataRangeAtom{pred: DataRange<A>, arg:DArgument<A>},
DifferentIndividualsAtom{pred:A, args:(IArgument<A>, IArgument<A>)},
ObjectPropertyAtom{pred:ObjectPropertyExpression<A>,args:(IArgument<A>,IArgument<A>)},
SameIndividualAtom{pred: A, args:(IArgument<A>, IArgument<A>)}
}


#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct IObject<A>(IRI<A>);
pub struct IArgument<A>(IRI<A>);

#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct DObject<A>(IRI<A>);
pub struct DArgument<A>(IRI<A>);

/// Access or change the `OntologyID` of an `Ontology`
pub trait Ontology<A> {
Expand Down Expand Up @@ -1948,7 +1949,7 @@ mod test {

let iri = b.iri("http://www.example.com");
let r = Rule{
head: vec![Atom::DescriptionAtom(IObject(iri))],
head: vec![Atom::DescriptionAtom(IObject(iri.clone()))],
body: vec![Atom::DescriptionAtom(IObject(iri))],
};

Expand Down
64 changes: 64 additions & 0 deletions src/ont/bubo/swrl_rule_basic.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
(clojure.core/load-file "ontology.clj")


(defclass A)
(defclass B)

(clojure.core/let [
df (owl-data-factory)

var (.getSWRLVariable
df
(iri-for-name o "x"))
]
(.applyChange
(owl-ontology-manager)
(org.semanticweb.owlapi.model.AddAxiom.
o
(.getSWRLRule
df
#{(.getSWRLClassAtom df A var)}
#{(.getSWRLClassAtom df B var)}))))

;; OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
;; // Let's create an ontology and name it
;; // "http://www.co-ode.org/ontologies/testont.owl" We need to set up a
;; // mapping which points to a concrete file where the ontology will be
;; // stored. (It's good practice to do this even if we don't intend to
;; // save the ontology).
;; IRI ontologyIRI = IRI.create("http://www.co-ode.org/ontologies/", "testont.owl");
;; // Create a document IRI which can be resolved to point to where our
;; // ontology will be saved.
;; IRI documentIRI = IRI.create("file:/tmp/", "SWRLTest.owl");
;; // Set up a mapping, which maps the ontology to the document IRI
;; SimpleIRIMapper mapper = new SimpleIRIMapper(ontologyIRI, documentIRI);
;; manager.getIRIMappers().add(mapper);
;; // Now create the ontology - we use the ontology IRI (not the physical
;; // IRI)
;; OWLOntology ontology = manager.createOntology(ontologyIRI);
;; OWLDataFactory factory = manager.getOWLDataFactory();
;; // Get hold of references to class A and class B. Note that the ontology
;; // does not contain class A or classB, we simply get referenc/mes to
;; // objects from a data factory that represent class A and class B
;; OWLClass classA = factory.getOWLClass(ontologyIRI + "#", "A");
;; OWLClass classB = factory.getOWLClass(ontologyIRI + "#", "B");
;; SWRLVariable var = factory.getSWRLVariable(ontologyIRI + "#", "x");
;; SWRLRule rule =
;; factory.getSWRLRule(Collections.singleton(factory.getSWRLClassAtom(classA, var)),
;; Collections.singleton(factory.getSWRLClassAtom(classB, var)));
;; manager.applyChange(new AddAxiom(ontology, rule));
;; OWLObjectProperty objProp = factory.getOWLObjectProperty(ontologyIRI + "#", "propA");
;; OWLObjectProperty propB = factory.getOWLObjectProperty(ontologyIRI + "#", "propB");
;; SWRLObjectPropertyAtom propAtom = factory.getSWRLObjectPropertyAtom(objProp, var, var);
;; SWRLObjectPropertyAtom propAtom2 = factory.getSWRLObjectPropertyAtom(propB, var, var);
;; Set<SWRLAtom> antecedent = new HashSet<SWRLAtom>();
;; antecedent.add(propAtom);
;; antecedent.add(propAtom2);
;; SWRLRule rule2 = factory.getSWRLRule(antecedent, Collections.singleton(propAtom));
;; manager.applyChange(new AddAxiom(ontology, rule2));
;; // Now save the ontology. The ontology will be saved to the location
;; // where we loaded it from, in the default ontology format
;; manager.saveOntology(ontology);


(save-all)
24 changes: 24 additions & 0 deletions src/ont/bubo/swrl_rule_two_variables.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
(clojure.core/load-file "ontology.clj")


(defclass A)
(defclass A1)
(defclass B)
(defclass B1)

(clojure.core/let [df (owl-data-factory)
var (.getSWRLVariable
df
(iri-for-name o "x"))]
(.applyChange
(owl-ontology-manager)
(org.semanticweb.owlapi.model.AddAxiom.
o
(.getSWRLRule
df
#{(.getSWRLClassAtom df A var)(.getSWRLClassAtom df A1 var)}
#{(.getSWRLClassAtom df B var)(.getSWRLClassAtom df B1 var)}))))



(save-all)
86 changes: 86 additions & 0 deletions src/ont/owl-rdf/swrl_rule_basic.owl
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?xml version="1.0"?>
<rdf:RDF xmlns="http://www.example.com/iri#"
xml:base="http://www.example.com/iri"
xmlns:o="http://www.example.com/iri#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:swrl="http://www.w3.org/2003/11/swrl#"
xmlns:swrlb="http://www.w3.org/2003/11/swrlb#">
<owl:Ontology rdf:about="http://www.example.com/iri">
<owl:versionIRI rdf:resource="http://www.example.com/viri"/>
</owl:Ontology>



<!--
///////////////////////////////////////////////////////////////////////////////////////
//
// Classes
//
///////////////////////////////////////////////////////////////////////////////////////
-->




<!-- http://www.example.com/iri#A -->

<owl:Class rdf:about="http://www.example.com/iri#A"/>



<!-- http://www.example.com/iri#B -->

<owl:Class rdf:about="http://www.example.com/iri#B"/>



<!--
///////////////////////////////////////////////////////////////////////////////////////
//
// Rules
//
///////////////////////////////////////////////////////////////////////////////////////
-->

<rdf:Description rdf:about="http://www.example.com/iri#x">
<rdf:type rdf:resource="http://www.w3.org/2003/11/swrl#Variable"/>
</rdf:Description>
<rdf:Description>
<rdf:type rdf:resource="http://www.w3.org/2003/11/swrl#Imp"/>
<swrl:body>
<rdf:Description>
<rdf:type rdf:resource="http://www.w3.org/2003/11/swrl#AtomList"/>
<rdf:first>
<rdf:Description>
<rdf:type rdf:resource="http://www.w3.org/2003/11/swrl#ClassAtom"/>
<swrl:classPredicate rdf:resource="http://www.example.com/iri#A"/>
<swrl:argument1 rdf:resource="http://www.example.com/iri#x"/>
</rdf:Description>
</rdf:first>
<rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
</rdf:Description>
</swrl:body>
<swrl:head>
<rdf:Description>
<rdf:type rdf:resource="http://www.w3.org/2003/11/swrl#AtomList"/>
<rdf:first>
<rdf:Description>
<rdf:type rdf:resource="http://www.w3.org/2003/11/swrl#ClassAtom"/>
<swrl:classPredicate rdf:resource="http://www.example.com/iri#B"/>
<swrl:argument1 rdf:resource="http://www.example.com/iri#x"/>
</rdf:Description>
</rdf:first>
<rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
</rdf:Description>
</swrl:head>
</rdf:Description>
</rdf:RDF>



<!-- Generated by the OWL API (version 4.5.19) https://github.com/owlcs/owlapi -->

Loading

0 comments on commit 3e52acc

Please sign in to comment.