use std::collections::{BTreeMap, HashSet};
use ontologos_core::{AxiomId, EntityId, InferenceTrace};
use serde::Serialize;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum RlRule {
EqClassSub,
EqPropSub,
CharPropagate,
ExistentialSubProp,
ExistentialSubsumption,
TypeDomain,
TypeRange,
TypeSubclass,
TypeEquivalent,
PropSub,
PropInverse,
PropSymmetric,
PropTransitive,
SameAsClass,
SameAsProp,
PropReflexive,
}
impl RlRule {
#[must_use]
pub fn as_str(self) -> &'static str {
match self {
Self::EqClassSub => "eq_class_sub",
Self::EqPropSub => "eq_prop_sub",
Self::CharPropagate => "char_propagate",
Self::ExistentialSubProp => "existential_sub_prop",
Self::ExistentialSubsumption => "existential_subsumption",
Self::TypeDomain => "type_domain",
Self::TypeRange => "type_range",
Self::TypeSubclass => "type_subclass",
Self::TypeEquivalent => "type_equivalent",
Self::PropSub => "prop_sub",
Self::PropInverse => "prop_inverse",
Self::PropSymmetric => "prop_symmetric",
Self::PropTransitive => "prop_transitive",
Self::SameAsClass => "same_as_class",
Self::SameAsProp => "same_as_prop",
Self::PropReflexive => "prop_reflexive",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct InferenceRecord {
pub rule: RlRule,
pub premises: Vec<AxiomId>,
pub conclusion: AxiomId,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct MaterializationReport {
pub initial_axiom_count: usize,
pub final_axiom_count: usize,
pub rdfs_inferred: usize,
pub inferred_by_rule: BTreeMap<RlRule, usize>,
#[serde(skip_serializing_if = "trace_is_empty")]
pub trace: InferenceTrace,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub clashes: Vec<String>,
#[serde(skip)]
pub disjoint_clash_keys: HashSet<(EntityId, EntityId, EntityId)>,
#[serde(skip)]
pub same_as_clash_keys: HashSet<(EntityId, EntityId)>,
}
fn trace_is_empty(trace: &InferenceTrace) -> bool {
trace.steps.is_empty()
}
impl MaterializationReport {
#[must_use]
pub fn inferred_total(&self) -> usize {
self.final_axiom_count
.saturating_sub(self.initial_axiom_count)
}
}