Skip to content

Commit

Permalink
feat(structure): Track ResourceIds on assertions for better reification
Browse files Browse the repository at this point in the history
  • Loading branch information
hobofan committed Jul 5, 2023
1 parent 544ece6 commit 6c74c22
Show file tree
Hide file tree
Showing 21 changed files with 1,279 additions and 697 deletions.
9 changes: 7 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ wasm-bindgen = { version = "0.2", features = [
js-sys = "0.3"
web-sys = { version = "0.3", features = ["console"] }
# harriet = { git = "https://github.com/field33/harriet" }
harriet = "0.3"
harriet = "0.3.1"
# Toggle on the serde support of harriets dependency
snowflake = { version = "1.3.0", features = ["serde_support"] }
oxsdatatypes = "0.1.1"
time = { version = "0.3", features = ["formatting"] }
# The `console_error_panic_hook` crate provides better debugging of panics by
Expand Down
56 changes: 55 additions & 1 deletion src/api/ontology.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

use crate::owl::{Axiom, Declaration, IRIBuilder, IRI};
use crate::owl::{AnnotationAssertion, Axiom, Declaration, IRIBuilder, ResourceId, IRI};

#[cfg(feature = "wasm")]
#[wasm_bindgen::prelude::wasm_bindgen]
Expand Down Expand Up @@ -59,6 +59,60 @@ impl Ontology {
pub fn axioms(&self) -> &Vec<Axiom> {
&self.owl.axioms
}

/// Finds all annotations assertions for a given `ResourceId`.
pub fn annotation_assertions_for_resource_id(
&self,
resource_id: &ResourceId,
) -> Vec<AnnotationAssertion> {
let mut annotations = vec![];
// Add annotations that are on the axiom directly
for axiom in self.axioms() {
if let Some(axiom_annotations) = match axiom {
Axiom::AnnotationAssertion(apa) => {
if apa.resource_ids.contains(resource_id) {
Some(apa.annotations.clone())
} else {
None
}
}
Axiom::DataPropertyAssertion(dpa) => {
if dpa.resource_ids.contains(resource_id) {
Some(dpa.annotations.clone())
} else {
None
}
}
Axiom::ObjectPropertyAssertion(opa) => {
if opa.resource_ids.contains(resource_id) {
Some(opa.annotations.clone())
} else {
None
}
}
_ => {
None
// unimplemented!("`annotationsForResourceId` is only implemented for assertions right now")
}
} {
for annotation in &axiom_annotations {
annotations.push(annotation.clone().to_assertion(resource_id.to_owned()));
}
}
}
// Find additional AnnotationAssertions via matching their subject to resource_id
for axiom in self.axioms() {
if let Axiom::AnnotationAssertion(annotation_assertion) = axiom {
if &annotation_assertion.subject == resource_id {
annotations.push(annotation_assertion.clone());
}
}
}

// HACK: This may not remove all duplicates, as we can't order the Vec before deduping.
annotations.dedup();
annotations
}
}

/// mutation api
Expand Down
22 changes: 21 additions & 1 deletion src/api/wasm.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![allow(non_snake_case)]

use crate::owl::Literal;
use crate::owl::{AnnotationAssertion, Axiom, Literal, ResourceId as OwlResourceId};

use super::Ontology;
use js_sys::{Array, Number, JSON};
Expand Down Expand Up @@ -114,6 +114,21 @@ impl Ontology {
}
array.unchecked_into()
}

#[wasm_bindgen(js_name = "annotationsForResourceId")]
pub fn wasm_annotations_for_resource_id(&self, resource_id: &ResourceId) -> AnnotationAssertionArray {
let owl_resource_id: OwlResourceId = serde_json::from_str(&JSON::stringify(resource_id).unwrap().as_string().unwrap()).unwrap();

let array = Array::new();
for a in self.annotation_assertions_for_resource_id(&owl_resource_id) {
if let Ok(s) = serde_json::to_string(&a) {
if let Ok(value) = JSON::parse(&s) {
array.push(&value);
}
}
}
array.unchecked_into()
}
}

#[wasm_bindgen]
Expand All @@ -124,6 +139,9 @@ extern "C" {
pub type DeclarationArray;
#[wasm_bindgen(typescript_type = "Array<Computation>")]
pub type ComputationArray;

#[wasm_bindgen(typescript_type = "Array<AnnotationAssertion>")]
pub type AnnotationAssertionArray;
}

#[wasm_bindgen(typescript_custom_section)]
Expand Down Expand Up @@ -401,6 +419,8 @@ export function matchValue<R>(value: Value, matcher: ValueMatcher<R>): R;
extern "C" {
#[wasm_bindgen(typescript_type = "IRI")]
pub type IRI;
#[wasm_bindgen(typescript_type = "ResourceId")]
pub type ResourceId;
#[wasm_bindgen(typescript_type = "Value")]
pub type Value;
#[wasm_bindgen(typescript_type = "Triple")]
Expand Down
5 changes: 4 additions & 1 deletion src/examples/family.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,10 @@ pub fn family() -> ApiOntology {
vec![
Axiom::AnnotationAssertion(AnnotationAssertion::new(
wk::rdfs_comment(),
iri.new("Person"),
iri.new::<IRI>("Person"),
LiteralOrIRI::from("Represents the set of all people"),
vec![],
vec![],
)),
Axiom::SubObjectPropertyOf(SubObjectPropertyOf::new(
iri.new::<ObjectPropertyIRI>("hasWife").into(),
Expand Down Expand Up @@ -648,6 +649,7 @@ pub fn family() -> ApiOntology {
iri.new("John"),
iri.new("Mary"),
vec![],
vec![],
)),
Axiom::NegativeObjectPropertyAssertion(NegativeObjectPropertyAssertion::new(
iri.new("hasWife"),
Expand All @@ -666,6 +668,7 @@ pub fn family() -> ApiOntology {
iri.new("John"),
Literal::from(51u8),
vec![],
vec![],
)),
Axiom::NegativeDataPropertyAssertion(NegativeDataPropertyAssertion::new(
iri.new("hasAge"),
Expand Down
10 changes: 9 additions & 1 deletion src/owl/axiom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,15 @@ impl Axiom {

pub fn subject(&self) -> Option<&IRI> {
match self {
Axiom::AnnotationAssertion(a) => Some(&a.subject),
Axiom::AnnotationAssertion(a) => {
// TODO: This seems like it could be a source for confusion (silently not having a subject if it's a BlankNode
match &a.subject {
ResourceId::IRI(iri_subject) => {
Some(&iri_subject)
}
ResourceId::BlankNode(_) => {None}
}
},
Axiom::AnnotationPropertyRange(a) => Some(a.iri.as_iri()),
Axiom::AnnotationPropertyDomain(a) => Some(a.iri.as_iri()),
Axiom::SubObjectPropertyOf(a) => match &a.object_property {
Expand Down
7 changes: 6 additions & 1 deletion src/owl/datatypes/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::owl::{IndividualIRI, IRI};
use crate::owl::{IndividualIRI, IRI, ResourceId};

mod constructors;
pub use constructors::*;
Expand Down Expand Up @@ -36,6 +36,9 @@ impl DataPropertyIRI {

#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
pub struct DataPropertyAssertion {
/// Known IDs of reifications of this assertion.
#[serde(rename = "resourceIds")]
pub resource_ids: Vec<ResourceId>,
#[serde(rename = "dataPropertyIRI")]
pub iri: DataPropertyIRI,
#[serde(rename = "subjectIRI")]
Expand All @@ -58,12 +61,14 @@ impl DataPropertyAssertion {
subject: IndividualIRI,
value: Literal,
annotations: Vec<Annotation>,
resource_ids: Vec<ResourceId>,
) -> Self {
Self {
iri,
subject,
value,
annotations,
resource_ids
}
}
}
Expand Down
Loading

0 comments on commit 6c74c22

Please sign in to comment.