use crate::model::{AnnotatedAxiom, Axiom, ForIRI, MutableOntology, RcStr};
use crate::ontology::indexed::ForIndex;
use super::indexed::{OntologyIndex, ThreeIndexedOntology, TwoIndexedOntology};
use std::collections::HashMap;
use std::convert::AsRef;
use std::rc::Rc;
#[derive(Debug, Default)]
pub struct LogicallyEqualIndex<A, AA>(HashMap<Axiom<A>, AA>);
impl<A: ForIRI, AA: ForIndex<A>> LogicallyEqualIndex<A, AA> {
pub fn new() -> Self {
LogicallyEqualIndex(HashMap::new())
}
}
impl LogicallyEqualIndex<RcStr, Rc<AnnotatedAxiom<RcStr>>> {
pub fn new_rc() -> Self {
LogicallyEqualIndex::new()
}
}
impl<A: ForIRI, AA: ForIndex<A>> OntologyIndex<A, AA> for LogicallyEqualIndex<A, AA> {
fn index_insert(&mut self, ax: AA) -> bool {
self.0.insert(ax.borrow().axiom.clone(), ax).is_some()
}
fn index_remove(&mut self, ax: &AnnotatedAxiom<A>) -> bool {
self.0.remove(&ax.axiom).is_some()
}
}
impl<A: ForIRI, AA: ForIndex<A>> LogicallyEqualIndex<A, AA> {
pub fn logical_contains(&self, ax: &AnnotatedAxiom<A>) -> bool {
self.0.contains_key(&ax.axiom)
}
pub fn logical_get(&self, ax: &AnnotatedAxiom<A>) -> Option<&AnnotatedAxiom<A>> {
self.0.get(&ax.axiom).map(|fi| fi.borrow())
}
pub fn logical_get_rc(&self, ax: &AnnotatedAxiom<A>) -> Option<AA> {
self.0.get(&ax.axiom).cloned()
}
}
impl<A: ForIRI, AA: ForIndex<A>, I: OntologyIndex<A, AA>> AsRef<LogicallyEqualIndex<A, AA>>
for TwoIndexedOntology<A, AA, I, LogicallyEqualIndex<A, AA>>
{
fn as_ref(&self) -> &LogicallyEqualIndex<A, AA> {
self.j()
}
}
impl<A: ForIRI, AA: ForIndex<A>, I, J> AsRef<LogicallyEqualIndex<A, AA>>
for ThreeIndexedOntology<A, AA, I, J, LogicallyEqualIndex<A, AA>>
where
I: OntologyIndex<A, AA>,
J: OntologyIndex<A, AA>,
{
fn as_ref(&self) -> &LogicallyEqualIndex<A, AA> {
self.k()
}
}
pub fn update_or_insert_logically_equal_axiom<A: ForIRI, AA: ForIndex<A>, O>(
o: &mut O,
axiom: AnnotatedAxiom<A>,
) where
O: MutableOntology<A> + AsRef<LogicallyEqualIndex<A, AA>>,
{
if let Some(axiom) = update_logically_equal_axiom(o, axiom) {
o.insert(axiom);
}
}
pub fn update_logically_equal_axiom<A: ForIRI, AA: ForIndex<A>, O>(
o: &mut O,
mut axiom: AnnotatedAxiom<A>,
) -> Option<AnnotatedAxiom<A>>
where
O: MutableOntology<A> + AsRef<LogicallyEqualIndex<A, AA>>,
{
let lei: &LogicallyEqualIndex<_, _> = o.as_ref();
let src = lei.logical_get_rc(&axiom);
if let Some(fi) = src {
o.remove(fi.borrow());
let mut logical_axiom = fi.unwrap();
logical_axiom.ann.append(&mut axiom.ann);
o.insert(logical_axiom);
None
} else {
Some(axiom)
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::model::*;
use crate::ontology::indexed::*;
use crate::ontology::set::*;
#[test]
fn cons() {
let _lei = LogicallyEqualIndex::new_rc();
assert!(true);
}
#[test]
fn equal_retrieve() {
let build = Build::new_rc();
let mut o = LogicallyEqualIndex::new();
let decl1: AnnotatedAxiom<_> = DeclareClass(build.class("http://www.example.com#a")).into();
let decl2: AnnotatedAxiom<_> = DeclareClass(build.class("http://www.example.com#b")).into();
let decl3: AnnotatedAxiom<_> = DeclareClass(build.class("http://www.example.com#c")).into();
o.index_insert(Rc::new(decl1.clone()));
o.index_insert(Rc::new(decl2.clone()));
o.index_insert(Rc::new(decl3.clone()));
assert!(o.logical_contains(&decl1));
assert!(o.logical_contains(&decl2));
assert!(o.logical_contains(&decl3));
}
#[test]
fn annotation_not_equal_retrieve() {
let b = Build::new_rc();
let mut o = TwoIndexedOntology::new(
SetIndex::new_rc(),
LogicallyEqualIndex::new(),
OntologyID::default(),
);
let ann = Annotation {
ap: b.annotation_property("http://www.example.com/ap"),
av: b.iri("http://www.example.com/av").into(),
};
let decl1: AnnotatedAxiom<_> = DeclareClass(b.class("http://www.example.com#a")).into();
let decl2: AnnotatedAxiom<_> = DeclareClass(b.class("http://www.example.com#b")).into();
let decl3: AnnotatedAxiom<_> = DeclareClass(b.class("http://www.example.com#c")).into();
let mut decl1_a = decl1.clone();
decl1_a.ann.insert(ann.clone());
let mut decl2_a = decl2.clone();
decl2_a.ann.insert(ann);
o.insert(decl1_a.clone());
o.insert(decl2_a.clone());
o.insert(decl3.clone());
assert!(!o.i().contains(&decl1));
assert!(!o.i().contains(&decl2));
assert!(o.i().contains(&decl3));
assert!(o.j().logical_contains(&decl1));
assert!(o.j().logical_contains(&decl2));
assert!(o.j().logical_contains(&decl3));
}
#[test]
fn test_update_equal_axiom() {
let b = Build::new_rc();
{
let mut o = TwoIndexedOntology::new(
SetIndex::new_rc(),
LogicallyEqualIndex::new(),
OntologyID::default(),
);
let ne: NamedEntity<_> = b.class("http://www.example.com").into();
let ax: Axiom<_> = ne.into();
let mut dec: AnnotatedAxiom<_> = ax.into();
dec.ann.insert(Annotation {
ap: b.annotation_property("http://www.example.com/p1"),
av: b.iri("http://www.example.com/a1").into(),
});
let ne: NamedEntity<_> = b.class("http://www.example.com").into();
let ax: Axiom<_> = ne.into();
let mut dec2: AnnotatedAxiom<_> = ax.into();
dec2.ann.insert(Annotation {
ap: b.annotation_property("http://www.example.com/p1"),
av: b.iri("http://www.example.com/a2").into(),
});
o.insert(dec);
o.insert(dec2);
assert_eq!(o.i().into_iter().count(), 2);
}
{
let mut o = TwoIndexedOntology::new(
SetIndex::new_rc(),
LogicallyEqualIndex::new(),
OntologyID::default(),
);
let ne: NamedEntity<_> = b.class("http://www.example.com").into();
let ax: Axiom<_> = ne.into();
let mut dec: AnnotatedAxiom<_> = ax.into();
dec.ann.insert(Annotation {
ap: b.annotation_property("http://www.example.com/p1"),
av: b.iri("http://www.example.com/a1").into(),
});
let ne: NamedEntity<_> = b.class("http://www.example.com").into();
let ax: Axiom<_> = ne.into();
let mut dec2: AnnotatedAxiom<_> = ax.into();
dec2.ann.insert(Annotation {
ap: b.annotation_property("http://www.example.com/p1"),
av: b.iri("http://www.example.com/a2").into(),
});
o.insert(dec);
update_logically_equal_axiom(&mut o, dec2);
assert_eq!(o.i().into_iter().count(), 1);
let aa = o.i().into_iter().next().unwrap();
assert_eq!(aa.ann.len(), 2);
}
}
}