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

Documentation for ontology::iri_mapped #122

Draft
wants to merge 3 commits into
base: devel
Choose a base branch
from
Draft
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
82 changes: 53 additions & 29 deletions src/ontology/iri_mapped.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//! Access `AnnotatedComponent` by iri.
//! An index to access all the [annotated components](crate::model::AnnotatedComponent) referencing a given [IRI](crate::model::IRI).

//! # Overview
//!
//! This module provides an `IRIMappedIndex` which provides rapid
//! access to all components associated with a given IRI.
//! This module provides [IRIMappedIndex], which provides rapid
//! access to all components associated with a given IRI, and the concrete ontology implementation [IRIMappedOntology] using this index.
//!
use super::indexed::ForIndex;
use super::set::SetOntology;
Expand All @@ -25,6 +25,36 @@ use super::set::SetIndex;

use std::collections::HashSet;

/// Implements an ontology index that stores for each IRI a set of annotated components in which this IRI occurs.
///
/// # Examples
///
/// The following snippet shows the effect of adding an axiom involving two IRIs to a new index.
/// ```
/// # use horned_owl::ontology::iri_mapped::IRIMappedIndex;
/// # use horned_owl::{model::*, ontology::indexed::OntologyIndex};
/// # use std::rc::Rc;
/// # fn test_index_example() {
/// let build: Build<Rc<str>> = Build::new();
/// let mut idx = IRIMappedIndex::new();
///
/// // We create a component to add to the index.
/// let cmp = AnnotatedComponent {
/// component: Component::DisjointClasses(DisjointClasses(vec![
/// ClassExpression::Class(build.class("http://www.example.com/#A")),
/// ClassExpression::Class(build.class("http://www.example.com/#B")),
/// ])),
/// ann: Default::default(),
/// };
///
/// // We insert the annotated component that we just created in the index.
/// idx.index_insert(cmp);
///
/// // The index now lists the annotated component for both entities occurring in it.
/// assert!(idx.component_for_iri(&build.iri("http://www.example.com/#A")).next().is_some());
/// assert!(idx.component_for_iri(&build.iri("http://www.example.com/#B")).next().is_some());
/// # }
/// ```
#[derive(Debug, Eq, PartialEq)]
pub struct IRIMappedIndex<A, AA> {
irindex: RefCell<BTreeMap<IRI<A>, BTreeSet<AA>>>,
Expand All @@ -38,7 +68,8 @@ impl<A: ForIRI, AA: ForIndex<A>> IRIMappedIndex<A, AA> {
}
}

fn aa_to_iris(&self, cmp: &AnnotatedComponent<A>) -> HashSet<IRI<A>> {
/// Helper that visits an annotated component and extract all the occurring IRIs.
fn iris_from_component(cmp: &AnnotatedComponent<A>) -> HashSet<IRI<A>> {
let mut w = Walk::new(IRIExtract::default());
w.annotated_component(cmp);

Expand Down Expand Up @@ -66,20 +97,9 @@ impl<A: ForIRI, AA: ForIndex<A>> IRIMappedIndex<A, AA> {
unsafe { (*self.components_as_ptr(iri)).get_mut(iri).unwrap() }
}

/*
/// Gets an iterator that visits the annotated components of the ontology.
pub fn iter(&self) -> IRIMappedIter<A, AA> {
IRIMappedIter {
ont: self,
inner: None,
iris: unsafe { (*self.irindex.as_ptr()).keys().collect() },
}
}
*/

/// Fetch the AnnotatedComponent for a given IRI
/// Iterates over the annotated components associated to `iri` by the index.
///
/// See also `component` for access to the `Component` without annotations.
/// Use [`component()`](Self::component) to iterate over components without annotations.
pub fn component_for_iri(&self, iri: &IRI<A>) -> impl Iterator<Item = &AnnotatedComponent<A>> {
self.set_for_iri(iri)
// Iterate over option
Expand All @@ -89,8 +109,9 @@ impl<A: ForIRI, AA: ForIndex<A>> IRIMappedIndex<A, AA> {
.map(|rc| rc.borrow())
}

/// Fetch the Component set iterator for a given iri
/// Iterates over the components (without annotations) associated to `iri` by the index.
///
/// Use [`component_for_iri()`](Self::component_for_iri) to iterate over annotated components.
pub fn component(&self, iri: &IRI<A>) -> impl Iterator<Item = &Component<A>> {
self.component_for_iri(iri).map(|ann| &ann.component)
}
Expand Down Expand Up @@ -187,7 +208,7 @@ impl<'a, A: ForIRI, AA: ForIndex<A>> IntoIterator for &'a IRIMappedIndex<A,AA> {

impl<A: ForIRI, AA: ForIndex<A>> OntologyIndex<A, AA> for IRIMappedIndex<A, AA> {
fn index_insert(&mut self, cmp: AA) -> bool {
let iris = self.aa_to_iris(cmp.borrow());
let iris = Self::iris_from_component(cmp.borrow());
if !iris.is_empty() {
for iri in iris.iter() {
self.mut_set_for_iri(iri).insert(cmp.clone());
Expand All @@ -199,17 +220,21 @@ impl<A: ForIRI, AA: ForIndex<A>> OntologyIndex<A, AA> for IRIMappedIndex<A, AA>
}

fn index_take(&mut self, cmp: &AnnotatedComponent<A>) -> Option<AnnotatedComponent<A>> {
self.aa_to_iris(cmp).iter().fold(None, |val, iri| {
self.mut_set_for_iri(iri)
.take(cmp)
.map_or(val, |c| Some(c.unwrap()))
})
Self::iris_from_component(cmp)
.iter()
.fold(None, |val, iri| {
self.mut_set_for_iri(iri)
.take(cmp)
.map_or(val, |c| Some(c.unwrap()))
})
}

fn index_remove(&mut self, cmp: &AnnotatedComponent<A>) -> bool {
self.aa_to_iris(cmp).iter().fold(false, |val, iri| {
self.mut_set_for_iri(iri).remove(cmp) || val
})
Self::iris_from_component(cmp)
.iter()
.fold(false, |val, iri| {
self.mut_set_for_iri(iri).remove(cmp) || val
})
}
}

Expand Down Expand Up @@ -330,7 +355,6 @@ mod test {
#[test]
fn test_ontology_cons() {
let _ = IRIMappedOntology::new_arc();
assert!(true);
}

#[test]
Expand Down Expand Up @@ -445,7 +469,7 @@ mod test {

let mut v: Vec<_> = irindex
.iter()
.flat_map(|(i, s)| s.into_iter().map(move |c| (i.clone(), c.clone())))
.flat_map(|(i, s)| s.iter().map(move |c| (i.clone(), c.clone())))
.collect();
v.sort();

Expand Down
Loading