This commit is contained in:
Alex Wied
2026-06-30 19:25:15 -04:00
parent 5cea8e8307
commit 2a6e9432d9
21 changed files with 1039 additions and 235 deletions
+60 -78
View File
@@ -1,10 +1,17 @@
use oxigraph::model::{Dataset, GraphName, NamedOrBlankNode, NamedOrBlankNodeRef, Quad, Term};
use oxigraph::sparql::{QueryResults, SparqlEvaluator};
use oxigraph::model::{Dataset, GraphName, NamedNodeRef, NamedOrBlankNode, NamedOrBlankNodeRef, Term};
use oxigraph::sparql::SparqlEvaluator;
use oxigraph::store::Store;
use tracing::{debug, debug_span};
use crate::error;
use crate::rdf::vocab::owl;
const INFERENCE_GRAPH: NamedNodeRef = NamedNodeRef::new_unchecked("https://graphofliberty.org/inference");
const RDF_SCHEMA: NamedNodeRef = NamedNodeRef::new_unchecked("http://www.w3.org/2000/01/rdf-schema#");
pub fn same_as(store: &mut Store) -> error::Result<()> {
let span = debug_span!("Materialize owl:sameAs");
let _enter = span.enter();
let additional_quads = store
.quads_for_pattern(None, Some(owl::SAME_AS), None, None)
.filter_map(Result::ok)
@@ -19,6 +26,7 @@ pub fn same_as(store: &mut Store) -> error::Result<()> {
None,
).filter_map(Result::ok) {
quad.subject = NamedOrBlankNode::NamedNode(y.clone());
quad.graph_name = GraphName::NamedNode(INFERENCE_GRAPH.into_owned());
new_dataset.insert(quad.as_ref());
}
@@ -29,6 +37,7 @@ pub fn same_as(store: &mut Store) -> error::Result<()> {
None,
).filter_map(Result::ok) {
quad.subject = NamedOrBlankNode::NamedNode(x.clone());
quad.graph_name = GraphName::NamedNode(INFERENCE_GRAPH.into_owned());
new_dataset.insert(quad.as_ref());
}
}
@@ -40,97 +49,70 @@ pub fn same_as(store: &mut Store) -> error::Result<()> {
let new_size = store.len()?;
if new_size > old_size {
same_as(store)
} else {
Ok(())
let difference = new_size - old_size;
debug!(?old_size, ?new_size, ?difference, "same_as");
same_as(store)?;
}
Ok(())
}
pub fn super_classes(store: &mut Store) -> error::Result<()> {
let query = SparqlEvaluator::new()
.parse_query(
r#"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
pub fn super_properties(store: &mut Store) -> error::Result<()> {
let span = debug_span!("Materialize rdfs:subPropertyOf");
let _enter = span.enter();
CONSTRUCT {
?item a ?parent
} WHERE {
?item a ?class .
?class rdfs:subClassOf ?parent .
}"#,
)
.expect("Unable to parse superclass query");
let mut additional_quads = Dataset::new();
if let QueryResults::Graph(graph) = query.on_store(&store).execute().unwrap()
{
additional_quads.extend(graph.filter_map(Result::ok).map(|triple| {
Quad::new(
triple.subject,
triple.predicate,
triple.object,
GraphName::DefaultGraph,
)
}));
let update = SparqlEvaluator::new()
.with_prefix("rdfs", RDF_SCHEMA.as_str())?
.with_prefix("inference", INFERENCE_GRAPH.as_str())?
.parse_update(r#"INSERT {
GRAPH inference: {
?property rdfs:subPropertyOf ?parent .
?subject ?parent ?object .
}
} WHERE {
GRAPH ?g1 { ?property rdfs:subPropertyOf+ ?parent }
OPTIONAL { GRAPH ?g2 { ?subject ?parent ?object } }
}"#)?;
let old_size = store.len()?;
store.extend(&additional_quads)?;
update.on_store(&store).execute()?;
let new_size = store.len()?;
if new_size > old_size {
super_classes(store)
} else {
Ok(())
let difference = new_size - old_size;
debug!(?old_size, ?new_size, ?difference, "super_properties");
super_properties(store)?;
}
Ok(())
}
/*fn iri_information(dataset: &Dataset) -> HashMap<NamedNode, IriInformation> {
let query = SparqlEvaluator::new()
.parse_query(
r#"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX gl: <https://graphofliberty.org/2026/04/ont/>
pub fn super_classes(store: &mut Store) -> error::Result<()> {
let span = debug_span!("Materialize rdfs:subClassOf");
let _enter = span.enter();
SELECT DISTINCT ?class ?subject ?label ?comment ?read_only {
VALUES ?class { rdf:Property rdfs:Class }
?subject a ?class .
OPTIONAL {
?subject rdfs:label ?label
FILTER (langMATCHES(LANG(?label), "en") || !hasLANG(?label))
let update = SparqlEvaluator::new()
.with_prefix("rdfs", RDF_SCHEMA.as_str())?
.with_prefix("inference", INFERENCE_GRAPH.as_str())?
.parse_update(r#"INSERT {
GRAPH inference: {
?class rdfs:subClassOf ?parent .
?item a ?parent .
}
OPTIONAL {
?subject rdfs:comment ?comment
FILTER (langMATCHES(LANG(?label), "en") || !hasLANG(?comment))
}
OPTIONAL { ?subject gl:readOnly ?read_only }
}"#,
)
.expect("Unable to parse property query");
} WHERE {
GRAPH ?g1 { ?item a ?class }
GRAPH ?g2 { ?class rdfs:subClassOf+ ?parent }
}"#)?;
let mut results = HashMap::new();
if let QueryResults::Solutions(solutions) =
query.on_queryable_dataset(dataset).execute().unwrap()
{
for solution in solutions.filter_map(Result::ok) {
let type_ = solution.get("class").and_then(crate::rdf::ontology::term_to_named_node);
let subject = solution.get("subject").and_then(crate::rdf::ontology::term_to_named_node);
let label = solution.get("label").and_then(crate::rdf::ontology::term_to_string);
let comment = solution.get("comment").and_then(crate::rdf::ontology::term_to_string);
let read_only = solution
.get("read_only")
.and_then(crate::rdf::ontology::term_to_boolean)
.unwrap_or(false);
let old_size = store.len()?;
update.on_store(&store).execute()?;
let new_size = store.len()?;
if let Some(subject) = subject && let Some(type_) = type_ {
let info = IriInformation {
type_: type_.clone(),
label: label.map(String::from),
comment: comment.map(String::from),
read_only,
};
results.insert(subject.to_owned(), info);
}
}
if new_size > old_size {
let difference = new_size - old_size;
debug!(?old_size, ?new_size, ?difference, "super_classes");
super_classes(store)?;
}
results
}*/
Ok(())
}