use oxigraph::model::GraphNameRef; use oxigraph::sparql::{SparqlEvaluator}; use oxigraph::store::Store; use tracing::debug_span; const RDF_SCHEMA_PREFIX: &str = "http://www.w3.org/2000/01/rdf-schema#"; const GL_PREFIX: &str = "https://graphofliberty.org/"; /// `prp-spo1` const SUB_PROPERTY_OF_UPDATE: &str = r#"INSERT { ?x ?p2 ?y . } WHERE { GRAPH gl:ontology { ?p1 rdfs:subPropertyOf ?p2 . } ?x ?p1 ?y . }"#; /// `cax-sco` const SUB_CLASS_OF_UPDATE: &str = r#"INSERT { ?x a ?c2 . } WHERE { GRAPH gl:ontology { ?c1 rdfs:subClassOf ?c2 . } ?x a ?c1 . }"#; /// `prp-dom` const DOMAIN_UPDATE: &str = r#"INSERT { ?x a ?c . } WHERE { GRAPH gl:ontology { ?p rdfs:domain ?c . } ?x ?p ?y . }"#; fn run_update(query_name: &str, query: &str, store: &Store, graph_name: GraphNameRef<'_>) -> crate::error::Result<()> { let _span = debug_span!("Update", name = query_name).entered(); SparqlEvaluator::new() .with_prefix("rdfs", RDF_SCHEMA_PREFIX)? .with_prefix("gl", GL_PREFIX)? .parse_update(&format!("WITH {graph_name} {query}"))? .on_store(store).execute()?; Ok(()) } pub(crate) fn infer(inferences: usize, store: &Store, graph_name: GraphNameRef<'_>) -> crate::error::Result { let old_count = store.quads_for_pattern(None, None, None, Some(graph_name)).count(); run_update("rdfs:subPropertyOf", SUB_PROPERTY_OF_UPDATE, &store, graph_name)?; run_update("rdfs:subClassOf", SUB_CLASS_OF_UPDATE, &store, graph_name)?; run_update("rdfs:domain", DOMAIN_UPDATE, &store, graph_name)?; let new_count = store.quads_for_pattern(None, None, None, Some(graph_name)).count(); let new_inferences_total = inferences + (new_count - old_count); if new_count > old_count { infer(new_inferences_total, store, graph_name) } else { Ok(new_inferences_total) } }