Files
tools/inference/src/logic.rs
T
2026-08-12 14:11:47 -04:00

58 lines
1.8 KiB
Rust

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<usize> {
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)
}
}