Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improving vocabulary module #67

Merged
merged 16 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
d63bfca
Vocabulary: introducing tests that are meant to pass but currently fail.
filippodebortoli Feb 15, 2023
4a0f5fc
Changes definition of vocab::IRIString, refactors vocab::WithIRI and …
filippodebortoli Feb 16, 2023
bc62c9e
Implements Meta::all() for vocab::Vocab and refactors io::rdf::reader…
filippodebortoli Feb 16, 2023
6e9f5a4
(refactor) deprecates IRIString.
filippodebortoli Feb 29, 2024
628bc93
(fix) extends vocab::to_built_in_entity() to return content for OWL::…
filippodebortoli Feb 29, 2024
d962487
(fix) corrects vocab::is_xsd_datatype to correctly identify initial X…
filippodebortoli Feb 29, 2024
842cdf7
(fix) resolves namespace checking for OWL entity types in vocab::enti…
filippodebortoli Feb 29, 2024
a6b53d1
(feat) adds standardised conversion traits for vocabulary enumerations.
filippodebortoli Mar 1, 2024
a251e75
(refactor) deprecates vocab::WithIRI in favor of Deref and TryFrom.
filippodebortoli Mar 2, 2024
9188216
(refactor) introduces vocabulary_type and vocabulary_traits declarati…
filippodebortoli Mar 4, 2024
7bc5f65
(feat) corrects macros to account for documentation of vocabulary types.
filippodebortoli Mar 6, 2024
40ae079
(refactor) removes vocab::WithIRI and vocab::IRIString.
filippodebortoli Mar 6, 2024
de6161e
(refactor) `vocab` has now a `test` module.
filippodebortoli Mar 8, 2024
ba77327
(fix) moves implementation of Borrow<str> inside of vocabulary_traits!.
filippodebortoli Mar 8, 2024
e739083
Merge branch 'phillord:devel' into fixes/vocabulary
filippodebortoli Mar 8, 2024
ace5888
Merge branch 'phillord:devel' into fixes/vocabulary
filippodebortoli Mar 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions src/io/owx/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ use quick_xml::name::ResolveResult::Bound;
use crate::error::*;
use crate::io::ParserConfiguration;
use crate::model::*;
use crate::vocab::Facet;
use crate::vocab::Namespace::*;
use crate::vocab::OWL2Datatype;
use crate::vocab::WithIRI;
use crate::{ontology::set::SetOntology, vocab::OWL};

use std::borrow::Cow;
use std::collections::BTreeSet;
use std::convert::TryFrom;
use std::io::BufRead;

use quick_xml::events::BytesEnd;
Expand Down Expand Up @@ -299,7 +300,7 @@ fn error_missing_element<A: ForIRI, R: BufRead>(tag: &[u8], r: &mut Read<A, R>)

fn is_owl(res: &ResolveResult) -> bool {
if let Bound(ns) = res {
ns.as_ref() == OWL.iri_b()
ns.as_ref() == OWL.as_bytes()
} else {
false
}
Expand Down Expand Up @@ -658,7 +659,7 @@ fn object_cardinality_restriction<A: ForIRI, R: BufRead>(
.map_err(|_s| HornedError::invalid("Failed to parse int"))?,
ope,
Box::new(match vce.len() {
0 => r.build.class(OWL::Thing.iri_str()).into(),
0 => r.build.class(OWL::Thing.as_ref()).into(),
1 => vce.remove(0),
_ => return Err(error_unexpected_tag(end_tag, r)),
}),
Expand All @@ -681,7 +682,7 @@ fn data_cardinality_restriction<A: ForIRI, R: BufRead>(
.map_err(|_s| HornedError::invalid("Failed to parse int"))?,
dp,
match vdr.len() {
0 => r.build.datatype(OWL2Datatype::RDFSLiteral.iri_str()).into(),
0 => r.build.datatype(OWL2Datatype::Literal.as_ref()).into(),
1 => vdr.remove(0),
_ => return Err(error_unexpected_tag(end_tag, r)),
},
Expand Down Expand Up @@ -994,16 +995,15 @@ from_start! {
from_start! {
FacetRestriction, r, e,
{
let f = get_attr_value_bytes(e, b"facet")?;
let f = f.ok_or_else(
|| error_missing_attribute("facet", r)
)?;
let f = get_attr_value_bytes(e, b"facet")?
.ok_or_else(|| error_missing_attribute("facet", r))?;

Ok(
FacetRestriction {
f: Facet::var_b(&f)
.ok_or_else(
|| error_unknown_entity("facet", &f, r))?,
f: Facet::try_from(f.as_ref())
.map_err(|_| error_unknown_entity("facet", &f, r))?,
// .ok_or_else(
// || error_unknown_entity("facet", &f, r))?,
l: from_next(r)?
}
)
Expand Down Expand Up @@ -1936,7 +1936,7 @@ pub mod test {
} = cl
{
assert!(match dr {
DataRange::Datatype(dt) => dt.is_s(&OWL2Datatype::RDFSLiteral.iri_s()[..]),
DataRange::Datatype(dt) => dt.is_s(OWL2Datatype::Literal.as_ref()),
_ => false,
});
} else {
Expand Down
7 changes: 4 additions & 3 deletions src/io/owx/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::model::Kinded;
use crate::model::*;
use crate::ontology::indexed::ForIndex;
use crate::vocab::Namespace::*;
use crate::{ontology::component_mapped::ComponentMappedOntology, vocab::WithIRI};
use crate::ontology::component_mapped::ComponentMappedOntology;

use quick_xml::events::BytesDecl;
use quick_xml::events::BytesEnd;
Expand Down Expand Up @@ -240,10 +240,11 @@ where

// let mut elem = BytesStart::owned_name("Ontology");
let mut elem = BytesStart::new("Ontology");
elem.push_attribute((b"xmlns" as &[u8], OWL.iri_b()));
elem.push_attribute((b"xmlns" as &[u8], OWL.as_bytes()));

let id = o.i().the_ontology_id_or_default();
iri_maybe(&mut elem, "xml:base", &id.iri);

// Render XML Namespaces.
for pre in m.mappings() {
elem.push_attribute((format!("xmlns:{}", pre.0).as_bytes(),pre.1.as_bytes()));
Expand Down Expand Up @@ -856,7 +857,7 @@ render! {
let mut open = BytesStart::new("FacetRestriction");
// Got the facet IRI from vocab
open.push_attribute(("facet",
&self.f.iri_s()[..]));
self.f.as_ref()));
self.l.within_tag(w, m, open)?;

Ok(())
Expand Down
79 changes: 47 additions & 32 deletions src/io/rdf/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ use rio_api::{
};
use Term::*;

use crate::{error::HornedError, io::ParserConfiguration};
use crate::{error::HornedError, io::ParserConfiguration, vocab::Facet};
use crate::model::*;
use crate::{model::Literal, ontology::component_mapped::ComponentMappedOntology};

use crate::ontology::indexed::ForIndex;
use crate::vocab::is_annotation_builtin;
use crate::vocab::WithIRI;
use crate::vocab::OWL as VOWL;
use crate::vocab::RDF as VRDF;
use crate::{
Expand Down Expand Up @@ -193,37 +192,53 @@ impl<A: ForIRI> From<Term<A>> for OrTerm<A> {
}
}

fn vocab_lookup<A: ForIRI>() -> HashMap<&'static str, Term<A>> {
let mut m = HashMap::default();
/// Creates a lookup [HashMap] for OWL, RDF, RDFS and Facet vocabularies.
fn vocab_lookup<A: ForIRI>() -> HashMap<String, Term<A>> {
// Preallocate capacity, as we know at compile-time how many elements will
// be stored in the hashmaps.
// 87 = #OWL variants - 1 + #RDF variants + #RDFS variants + #Facet variants
let mut lookup_map = HashMap::with_capacity(87);

for v in VOWL::all() {
match v {
// Skip the builtin properties or we have to treat them separately
VOWL::TopDataProperty => None,
_ => m.insert(v.iri_s().as_str(), Term::OWL(v)),
};
}
lookup_map.extend(
VOWL::all()
.into_iter()
.filter_map(|variant| match variant {
// Skip the builtin properties or we have to treat them separately
VOWL::TopDataProperty => None, // |
// VOWL::TopObjectProperty |
// VOWL::Thing |
// VOWL::Nothing => None,
_ => Some((variant.underlying(), Term::OWL(variant)))
})
);

for v in VRDFS::all() {
m.insert(v.iri_s().as_str(), Term::RDFS(v));
}
lookup_map.extend(
VRDFS::all()
.into_iter()
.map(|variant| (variant.underlying(), Term::RDFS(variant)))
);

for v in VRDF::all() {
m.insert(v.iri_s().as_str(), Term::RDF(v));
}
lookup_map.extend(
VRDF::all()
.into_iter()
.map(|variant| (variant.underlying(), Term::RDF(variant)))
);

for v in Facet::all() {
m.insert(v.iri_s().as_str(), Term::FacetTerm(v));
}
m
lookup_map.extend(
Facet::all()
.into_iter()
.map(|variant| (variant.underlying(), Term::FacetTerm(variant)))
);

lookup_map
}

fn to_term_nn<'a, A: ForIRI>(
nn: &'a NamedNode,
m: &HashMap<&str, Term<A>>,
m: &HashMap<String, Term<A>>,
b: &Build<A>,
) -> Term<A> {
if let Some(term) = m.get(&nn.iri) {
if let Some(term) = m.get(nn.iri) {
return term.clone();
}
Term::Iri(b.iri(nn.iri))
Expand Down Expand Up @@ -260,7 +275,7 @@ fn to_term_lt<'a, A: ForIRI>(lt: &'a rio_api::model::Literal, b: &Build<A>) -> T

fn to_term_nnb<'a, A: ForIRI>(
nnb: &'a Subject,
m: &HashMap<&str, Term<A>>,
m: &HashMap<String, Term<A>>,
b: &Build<A>,
) -> Term<A> {
match nnb {
Expand All @@ -270,7 +285,7 @@ fn to_term_nnb<'a, A: ForIRI>(
}
}

fn to_term<'a, A: ForIRI>(t: &'a RioTerm, m: &HashMap<&str, Term<A>>, b: &Build<A>) -> Term<A> {
fn to_term<'a, A: ForIRI>(t: &'a RioTerm, m: &HashMap<String, Term<A>>, b: &Build<A>) -> Term<A> {
match t {
rio_api::model::Term::NamedNode(iri) => to_term_nn(iri, m, b),
rio_api::model::Term::BlankNode(id) => to_term_bn(id),
Expand Down Expand Up @@ -641,11 +656,11 @@ impl<'a, A: ForIRI, AA: ForIndex<A>> OntologyParser<'a, A, AA> {
// We assume that anything passed to here is an
// annotation built in type
[s, RDFS(rdfs), b] => {
let iri = self.b.iri(rdfs.iri_str());
let iri = self.b.iri(rdfs.as_ref());
self.annotation(&[s.clone(), Term::Iri(iri), b.clone()])
}
[s, OWL(owl), b] => {
let iri = self.b.iri(owl.iri_str());
let iri = self.b.iri(owl.as_ref());
self.annotation(&[s.clone(), Term::Iri(iri), b.clone()])
}
[_, Iri(p), ob @ Term::Literal(_)] => Annotation {
Expand All @@ -659,7 +674,7 @@ impl<'a, A: ForIRI, AA: ForIndex<A>> OntologyParser<'a, A, AA> {
av: ob.clone().into(),
}
}
[s, Iri(p), Term::BNode(bnodeid)] => {
[_, Iri(p), Term::BNode(bnodeid)] => {
Annotation {
ap: AnnotationProperty(p.clone()),
av: AnonymousIndividual(bnodeid.0.clone()).into(),
Expand Down Expand Up @@ -1018,7 +1033,7 @@ impl<'a, A: ForIRI, AA: ForIndex<A>> OntologyParser<'a, A, AA> {
) -> Option<PropertyExpression<A>> {
match term {
Term::OWL(vowl) => {
let iri = self.b.iri(vowl.iri_str());
let iri = self.b.iri(vowl.as_ref());
self.find_property_kind(&Term::Iri(iri), ic)
}
Term::Iri(iri) => match self.find_declaration_kind(iri, ic) {
Expand Down Expand Up @@ -1196,7 +1211,7 @@ impl<'a, A: ForIRI, AA: ForIndex<A>> OntologyParser<'a, A, AA> {
{
n:self.fetch_u32(literal)?,
ope: pr.into(),
bce: self.b.class(VOWL::Thing.iri_str()).into()
bce: self.b.class(VOWL::Thing).into()
}
}
}
Expand All @@ -1223,7 +1238,7 @@ impl<'a, A: ForIRI, AA: ForIndex<A>> OntologyParser<'a, A, AA> {
{
n:self.fetch_u32(literal)?,
ope: pr.into(),
bce: self.b.class(VOWL::Thing.iri_str()).into()
bce: self.b.class(VOWL::Thing).into()
}
}
}
Expand All @@ -1250,7 +1265,7 @@ impl<'a, A: ForIRI, AA: ForIndex<A>> OntologyParser<'a, A, AA> {
{
n:self.fetch_u32(literal)?,
ope: pr.into(),
bce: self.b.class(VOWL::Thing.iri_str()).into()
bce: self.b.class(VOWL::Thing).into()
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/io/rdf/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
error::HornedError,
model::*,
ontology::component_mapped::ComponentMappedOntology,
vocab::{is_thing, Vocab, WithIRI, OWL, RDF, RDFS, XSD},
vocab::{Vocab, OWL, RDF, RDFS, XSD},
};

use crate::ontology::indexed::ForIndex;
Expand Down Expand Up @@ -70,7 +70,7 @@ impl<A: ForIRI> NodeGenerator<A> {

/// Return an cached version of PNamedNode value.
fn cache_rc<V: Into<Vocab>>(&mut self, v: V) -> A {
let voc: &str = v.into().iri_s();
let voc: &str = &v.into();
if let Some(rc) = self.b.get(voc) {
return rc.clone();
}
Expand Down Expand Up @@ -1105,7 +1105,7 @@ fn obj_cardinality<A: ForIRI, W: Write>(
);

if let ClassExpression::Class(ref cl) = *ce {
if is_thing(&cl.0) {
if cl.is_thing() {
triples!(f, bn.clone(), unqual, node_n);
return Ok(bn);
}
Expand Down
28 changes: 13 additions & 15 deletions src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ use std::ops::Deref;
use std::rc::Rc;
use std::sync::Arc;

use crate::vocab::Facet;

/// An
/// [IRI](https://en.wikipedia.org/wiki/Internationalized_Resource_Identifier)
/// is an internationalized version of an URI/URL.
Expand Down Expand Up @@ -531,6 +533,17 @@ named! {
NamedIndividual
}

impl<A: ForIRI> Class<A> {

pub fn is_thing(&self) -> bool {
self.0.as_ref() == crate::vocab::OWL::Thing.as_ref()
}

pub fn is_nothing(&self) -> bool {
self.0.as_ref() == crate::vocab::OWL::Nothing.as_ref()
}
}

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

Expand Down Expand Up @@ -1507,21 +1520,6 @@ pub struct FacetRestriction<A> {
pub l: Literal<A>,
}

#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum Facet {
Length,
MinLength,
MaxLength,
Pattern,
MinInclusive,
MinExclusive,
MaxInclusive,
MaxExclusive,
TotalDigits,
FractionDigits,
LangRange,
}

#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum DataRange<A> {
Datatype(Datatype<A>),
Expand Down
4 changes: 2 additions & 2 deletions src/ontology/declaration_mapped.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ mod test {
use super::DeclarationMappedIndex;
use crate::model::{AnnotatedComponent, Build, NamedEntity, NamedEntityKind, RcStr};
use crate::ontology::indexed::OntologyIndex;
use crate::vocab::{WithIRI, OWL};
use crate::vocab::OWL;
fn stuff() -> (
AnnotatedComponent<RcStr>,
AnnotatedComponent<RcStr>,
Expand Down Expand Up @@ -198,7 +198,7 @@ mod test {
let d = DeclarationMappedIndex::new_rc();
let b = Build::new_rc();
assert_eq!(
d.declaration_kind(&b.iri(OWL::TopDataProperty.iri_str())),
d.declaration_kind(&b.iri(OWL::TopDataProperty.as_ref())),
Some(NamedEntityKind::DataProperty)
);
}
Expand Down
1 change: 1 addition & 0 deletions src/visitor.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::model::*;
use crate::ontology::set::SetOntology;
use crate::vocab::Facet;
use std::collections::BTreeSet;
use std::marker::PhantomData;

Expand Down
Loading
Loading