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

Feature/generic return owx reader #115

Merged
merged 5 commits into from
Jul 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ repos:
entry: make pre-commit
pass_filenames: false
stages: [pre-commit, pre-push]
- id: Compile Benches
name: Compile Benches
language: system
entry: cargo bench --no-run --quiet
pass_filenames: false
stages: [pre-commit, pre-push]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
Expand Down
7 changes: 6 additions & 1 deletion benches/io.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use criterion::{criterion_group, AxisScale, BenchmarkId, Criterion, PlotConfiguration};
use horned_owl::model::RcStr;
use horned_owl::ontology::set::SetOntology;
use std::fs::File;
use std::io::BufReader;
use std::time::Duration;
Expand All @@ -20,7 +22,10 @@ fn io_read(c: &mut Criterion) {
b.iter(|| {
let f = File::open(format!("benches/ont/o{}.owx", n)).ok().unwrap();
let mut f = BufReader::new(f);
let _ = horned_owl::io::owx::reader::read(&mut f, Default::default()).ok();
let _: (SetOntology<RcStr>, _) =
horned_owl::io::owx::reader::read(&mut f, Default::default())
.ok()
.unwrap();
})
});
}
Expand Down
10 changes: 5 additions & 5 deletions benches/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::rc::Rc;

use criterion::{criterion_group, AxisScale, BenchmarkId, Criterion, PlotConfiguration};

use horned_owl::io::rdf::reader::RDFOntology;
use horned_owl::io::rdf::reader::ConcreteRDFOntology;
use horned_owl::model::*;
use horned_owl::ontology::component_mapped::ComponentMappedOntology;
use horned_owl::ontology::declaration_mapped::DeclarationMappedIndex;
Expand Down Expand Up @@ -237,7 +237,7 @@ fn food_to_vec() -> Vec<u8> {
std::fs::read("./benches/ont/food.owl").unwrap()
}

fn read_vec<A: ForIRI, AA: ForIndex<A>>(v: &Vec<u8>, b: Build<A>) -> RDFOntology<A, AA> {
fn read_vec<A: ForIRI, AA: ForIndex<A>>(v: &Vec<u8>, b: Build<A>) -> ConcreteRDFOntology<A, AA> {
let mut c = Cursor::new(v.clone());
horned_owl::io::rdf::reader::read_with_build(&mut c, &b, Default::default())
.unwrap()
Expand All @@ -253,21 +253,21 @@ fn food(c: &mut Criterion) {
group.bench_function("food_rc_str_rc_comp", |b| {
b.iter(|| {
let b: Build<RcStr> = Build::new();
let _: RDFOntology<RcStr, RcAnnotatedComponent> = read_vec(&food, b);
let _: ConcreteRDFOntology<RcStr, RcAnnotatedComponent> = read_vec(&food, b);
})
});

group.bench_function("food_arc_str_arc_comp", |b| {
b.iter(|| {
let b: Build<ArcStr> = Build::new();
let _: RDFOntology<ArcStr, ArcAnnotatedComponent> = read_vec(&food, b);
let _: ConcreteRDFOntology<ArcStr, ArcAnnotatedComponent> = read_vec(&food, b);
})
});

group.bench_function("food_string_direct_comp", |b| {
b.iter(|| {
let b: Build<String> = Build::new();
let _: RDFOntology<String, AnnotatedComponent<String>> = read_vec(&food, b);
let _: ConcreteRDFOntology<String, AnnotatedComponent<String>> = read_vec(&food, b);
})
});
}
Expand Down
4 changes: 2 additions & 2 deletions horned-bin/src/bin/horned_unparsed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use clap::ArgMatches;

use horned_bin::config::{parser_app, parser_config};
use horned_owl::error::HornedError;
use horned_owl::io::rdf::reader::RDFOntology;
use horned_owl::io::rdf::reader::ConcreteRDFOntology;
use horned_owl::model::{RcAnnotatedComponent, RcStr};

use std::{fs::File, io::BufReader, path::Path};
Expand Down Expand Up @@ -38,7 +38,7 @@ pub(crate) fn matcher(matches: &ArgMatches) -> Result<(), HornedError> {
HornedError::CommandError("Command requires an INPUT argument".to_string())
})?;

let (_ont, incomplete): (RDFOntology<RcStr, RcAnnotatedComponent>, _) =
let (_ont, incomplete): (ConcreteRDFOntology<RcStr, RcAnnotatedComponent>, _) =
horned_owl::io::rdf::reader::read(
&mut BufReader::new(File::open(Path::new(input))?),
parser_config(matches),
Expand Down
6 changes: 3 additions & 3 deletions src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub mod rdf;

use curie::PrefixMapping;

use self::rdf::reader::{IncompleteParse, RDFOntology};
use self::rdf::reader::{ConcreteRDFOntology, IncompleteParse};
use crate::ontology::indexed::ForIndex;
use crate::{
model::ForIRI,
Expand All @@ -23,7 +23,7 @@ pub enum ResourceType {
pub enum ParserOutput<A: ForIRI, AA: ForIndex<A>> {
OFNParser(SetOntology<A>, PrefixMapping),
OWXParser(SetOntology<A>, PrefixMapping),
RDFParser(RDFOntology<A, AA>, IncompleteParse<A>),
RDFParser(ConcreteRDFOntology<A, AA>, IncompleteParse<A>),
}

impl<A: ForIRI, AA: ForIndex<A>> ParserOutput<A, AA> {
Expand All @@ -35,7 +35,7 @@ impl<A: ForIRI, AA: ForIndex<A>> ParserOutput<A, AA> {
ParserOutput::OWXParser(sop.0, sop.1)
}

pub fn rdf(rop: (RDFOntology<A, AA>, IncompleteParse<A>)) -> ParserOutput<A, AA> {
pub fn rdf(rop: (ConcreteRDFOntology<A, AA>, IncompleteParse<A>)) -> ParserOutput<A, AA> {
ParserOutput::RDFParser(rop.0, rop.1)
}
}
Expand Down
118 changes: 61 additions & 57 deletions src/io/ofn/reader/from_pair.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::BTreeSet;
use std::marker::PhantomData;
use std::str::FromStr;

use curie::Curie;
Expand All @@ -8,7 +9,6 @@ use pest::iterators::Pair;

use crate::error::HornedError;
use crate::model::*;
use crate::ontology::set::SetOntology;
use crate::vocab::{Facet, OWL2Datatype, OWL};

use super::Context;
Expand Down Expand Up @@ -941,63 +941,62 @@ impl<A: ForIRI> FromPair<A> for ObjectPropertyExpression<A> {
}

// ---------------------------------------------------------------------------
pub(crate) struct MutableOntologyWrapper<A: ForIRI, O: MutableOntology<A> + Ontology<A> + Default>(
pub(crate) O,
PhantomData<A>,
);

macro_rules! impl_ontology {
($ty:ident) => {
impl<A: ForIRI> FromPair<A> for $ty<A> {
const RULE: Rule = Rule::Ontology;
fn from_pair_unchecked(pair: Pair<Rule>, ctx: &Context<'_, A>) -> Result<Self> {
debug_assert!(pair.as_rule() == Rule::Ontology);
let mut pairs = pair.into_inner();
let mut pair = pairs.next().unwrap();

let mut ontology = $ty::default();
let mut ontology_id = OntologyID::default();

// Parse ontology IRI and Version IRI if any
if pair.as_rule() == Rule::OntologyIRI {
let inner = pair.into_inner().next().unwrap();
ontology_id.iri = Some(IRI::from_pair(inner, ctx)?);
pair = pairs.next().unwrap();
if pair.as_rule() == Rule::VersionIRI {
let inner = pair.into_inner().next().unwrap();
ontology_id.viri = Some(IRI::from_pair(inner, ctx)?);
pair = pairs.next().unwrap();
}
}
ontology.insert(ontology_id);
impl<A: ForIRI, O: MutableOntology<A> + Ontology<A> + Default> FromPair<A>
for MutableOntologyWrapper<A, O>
{
const RULE: Rule = Rule::Ontology;
fn from_pair_unchecked(pair: Pair<Rule>, ctx: &Context<'_, A>) -> Result<Self> {
debug_assert!(pair.as_rule() == Rule::Ontology);
let mut pairs = pair.into_inner();
let mut pair = pairs.next().unwrap();

// Process imports
for p in pair.into_inner() {
ontology.insert(Import::from_pair(p, ctx)?);
}
let mut ontology: O = Default::default();
let mut ontology_id = OntologyID::default();

// Process ontology annotations
for pair in pairs.next().unwrap().into_inner() {
ontology.insert(OntologyAnnotation::from_pair(pair, ctx)?);
}
// Parse ontology IRI and Version IRI if any
if pair.as_rule() == Rule::OntologyIRI {
let inner = pair.into_inner().next().unwrap();
ontology_id.iri = Some(IRI::from_pair(inner, ctx)?);
pair = pairs.next().unwrap();
if pair.as_rule() == Rule::VersionIRI {
let inner = pair.into_inner().next().unwrap();
ontology_id.viri = Some(IRI::from_pair(inner, ctx)?);
pair = pairs.next().unwrap();
}
}
ontology.insert(ontology_id);

// Process axioms, ignore SWRL rules
for pair in pairs.next().unwrap().into_inner() {
let inner = pair.into_inner().next().unwrap();
match inner.as_rule() {
Rule::Axiom => {
ontology.insert(AnnotatedComponent::from_pair(inner, ctx)?);
}
rule => {
unreachable!("unexpected rule in Ontology::from_pair: {:?}", rule);
}
}
}
// Process imports
for p in pair.into_inner() {
ontology.insert(Import::from_pair(p, ctx)?);
}

// Process ontology annotations
for pair in pairs.next().unwrap().into_inner() {
ontology.insert(OntologyAnnotation::from_pair(pair, ctx)?);
}

Ok(ontology)
// Process axioms, ignore SWRL rules
for pair in pairs.next().unwrap().into_inner() {
let inner = pair.into_inner().next().unwrap();
match inner.as_rule() {
Rule::Axiom => {
ontology.insert(AnnotatedComponent::from_pair(inner, ctx)?);
}
rule => {
unreachable!("unexpected rule in Ontology::from_pair: {:?}", rule);
}
}
}
};
}

impl_ontology!(SetOntology);
// impl_ontology!(AxiomMappedOntology);
Ok(MutableOntologyWrapper(ontology, Default::default()))
}
}

// ---------------------------------------------------------------------------

Expand Down Expand Up @@ -1035,17 +1034,18 @@ impl<A: ForIRI> FromPair<A> for PrefixMapping {

// ---------------------------------------------------------------------------

impl<A, O> FromPair<A> for (O, PrefixMapping)
impl<A, O> FromPair<A> for (MutableOntologyWrapper<A, O>, PrefixMapping)
where
A: ForIRI,
O: Ontology<A> + FromPair<A>,
O: Default + MutableOntology<A> + Ontology<A>,
{
const RULE: Rule = Rule::OntologyDocument;
fn from_pair_unchecked(pair: Pair<Rule>, ctx: &Context<'_, A>) -> Result<Self> {
let mut pairs = pair.into_inner();
let prefixes = PrefixMapping::from_pair(pairs.next().unwrap(), ctx)?;
let context = Context::new(ctx.build, &prefixes);
O::from_pair(pairs.next().unwrap(), &context).map(|ont| (ont, prefixes))
MutableOntologyWrapper::from_pair(pairs.next().unwrap(), &context)
.map(|ont| (ont, prefixes))
}
}

Expand Down Expand Up @@ -1117,6 +1117,7 @@ mod tests {

use super::*;
use crate::io::ofn::reader::lexer::OwlFunctionalLexer;
use crate::ontology::set::SetOntology;

use test_generator::test_resources;

Expand Down Expand Up @@ -1244,8 +1245,10 @@ mod tests {
.next()
.unwrap();

let doc: (SetOntology<String>, PrefixMapping) =
FromPair::from_pair(pair, &Context::new(&build, &prefixes)).unwrap();
let doc: (
MutableOntologyWrapper<_, SetOntology<String>>,
PrefixMapping,
) = FromPair::from_pair(pair, &Context::new(&build, &prefixes)).unwrap();
assert_eq!(
doc.1.mappings().collect::<HashSet<_>>(),
expected.mappings().collect::<HashSet<_>>()
Expand Down Expand Up @@ -1291,7 +1294,8 @@ mod tests {
let build = Build::new();
let prefixes = PrefixMapping::default();
let ctx = Context::new(&build, &prefixes);
let item: (SetOntology<Rc<str>>, _) = FromPair::from_pair(pair, &ctx).unwrap();
let item: (MutableOntologyWrapper<_, SetOntology<Rc<str>>>, _) =
FromPair::from_pair(pair, &ctx).unwrap();

let path = resource
.replace("owl-functional", "owl-xml")
Expand All @@ -1301,6 +1305,6 @@ mod tests {
crate::io::owx::reader::read(&mut Cursor::new(&owx), Default::default()).unwrap();

// pretty_assertions::assert_eq!(item.1, expected.1);
pretty_assertions::assert_eq!(item.0, expected.0);
pretty_assertions::assert_eq!(item.0 .0, expected.0);
}
}
17 changes: 10 additions & 7 deletions src/io/ofn/reader/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ use crate::error::HornedError;
use crate::io::ParserConfiguration;
use crate::model::Build;
use crate::model::ForIRI;
use crate::model::RcStr;
use crate::ontology::set::SetOntology;
use crate::model::MutableOntology;
use crate::model::Ontology;

mod from_pair;
mod lexer;

use self::from_pair::FromPair;
use self::from_pair::MutableOntologyWrapper;
use self::lexer::OwlFunctionalLexer;
use self::lexer::Rule;

Expand All @@ -27,18 +28,18 @@ impl<'a, A: ForIRI> Context<'a, A> {
}
}

pub fn read<R: BufRead>(
pub fn read<A: ForIRI, O: MutableOntology<A> + Ontology<A> + Default, R: BufRead>(
bufread: R,
_config: ParserConfiguration,
) -> Result<(SetOntology<RcStr>, PrefixMapping), HornedError> {
) -> Result<(O, PrefixMapping), HornedError> {
let b = Build::new();
read_with_build(bufread, &b)
}

pub fn read_with_build<A: ForIRI, R: BufRead>(
pub fn read_with_build<A: ForIRI, O: MutableOntology<A> + Ontology<A> + Default, R: BufRead>(
mut bufread: R,
build: &Build<A>,
) -> Result<(SetOntology<A>, PrefixMapping), HornedError> {
) -> Result<(O, PrefixMapping), HornedError> {
let prefixes = PrefixMapping::default();
let ctx = Context::new(build, &prefixes);

Expand All @@ -49,5 +50,7 @@ pub fn read_with_build<A: ForIRI, R: BufRead>(
.next()
.unwrap();

FromPair::from_pair(pair, &ctx)
let wrapper: Result<(MutableOntologyWrapper<A, O>, PrefixMapping), HornedError> =
FromPair::from_pair(pair, &ctx);
wrapper.map(|r| (r.0 .0, r.1))
}
7 changes: 3 additions & 4 deletions src/io/ofn/writer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,11 @@ mod test {
let reader = std::fs::File::open(&resource)
.map(std::io::BufReader::new)
.unwrap();
let (ont, prefixes) = crate::io::ofn::reader::read(reader, Default::default()).unwrap();
let (ont, prefixes): (ComponentMappedOntology<RcStr, AnnotatedComponent<RcStr>>, _) =
crate::io::ofn::reader::read(reader, Default::default()).unwrap();

let component_mapped: ComponentMappedOntology<RcStr, AnnotatedComponent<RcStr>> =
ont.clone().into();
let mut writer = Vec::new();
crate::io::ofn::writer::write(&mut writer, &component_mapped, Some(&prefixes)).unwrap();
crate::io::ofn::writer::write(&mut writer, &ont, Some(&prefixes)).unwrap();

let (ont2, prefixes2) =
crate::io::ofn::reader::read(std::io::Cursor::new(&writer), Default::default())
Expand Down
Loading
Loading