Skip to main content

strixonomy_reasoner/
adapter.rs

1use crate::error::{ReasonerError, Result};
2use crate::input::ReasonerInput;
3use crate::result::{
4    ClassificationResult, ConsistencyDetail, ConsistencyResult, ExplanationRequest,
5    ExplanationResult, InferredAssertions, InstanceCheckResult, RealizationResult,
6};
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
10#[serde(rename_all = "snake_case")]
11pub enum ReasonerId {
12    El,
13    Rl,
14    Rdfs,
15    Dl,
16    Auto,
17}
18
19impl ReasonerId {
20    pub fn parse(s: &str) -> Result<Self> {
21        match s.to_ascii_lowercase().as_str() {
22            "el" => Ok(Self::El),
23            "rl" => Ok(Self::Rl),
24            "rdfs" => Ok(Self::Rdfs),
25            "dl" => Ok(Self::Dl),
26            "auto" => Ok(Self::Auto),
27            _ => Err(ReasonerError::UnsupportedProfile(s.to_string())),
28        }
29    }
30
31    pub fn as_str(&self) -> &'static str {
32        match self {
33            Self::El => "el",
34            Self::Rl => "rl",
35            Self::Rdfs => "rdfs",
36            Self::Dl => "dl",
37            Self::Auto => "auto",
38        }
39    }
40
41    pub fn is_available(&self) -> bool {
42        true
43    }
44}
45
46#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
47#[serde(rename_all = "snake_case")]
48pub enum ReasonerProfile {
49    OwlEl,
50    OwlRl,
51    Rdfs,
52    OwlDl,
53    Auto,
54}
55
56impl From<ReasonerId> for ReasonerProfile {
57    fn from(id: ReasonerId) -> Self {
58        match id {
59            ReasonerId::El => Self::OwlEl,
60            ReasonerId::Rl => Self::OwlRl,
61            ReasonerId::Rdfs => Self::Rdfs,
62            ReasonerId::Dl => Self::OwlDl,
63            ReasonerId::Auto => Self::Auto,
64        }
65    }
66}
67
68pub trait ReasonerAdapter: Send + Sync {
69    fn id(&self) -> ReasonerId;
70    fn profile(&self) -> ReasonerProfile;
71    fn classify(&self, input: &ReasonerInput) -> Result<ClassificationResult>;
72    fn check_consistency(&self, input: &ReasonerInput) -> Result<ConsistencyResult> {
73        let result = self.classify(input)?;
74        let detail =
75            crate::abox::check_full_consistency(&input.ontology, self.id(), &result.unsatisfiable)?;
76        Ok(ConsistencyResult {
77            consistent: detail.consistent,
78            unsatisfiable: result.unsatisfiable.clone(),
79            detail: Some(detail),
80        })
81    }
82    fn realize(&self, input: &ReasonerInput) -> Result<RealizationResult> {
83        crate::abox::realize(&input.ontology, self.id())
84    }
85    fn check_instance(
86        &self,
87        input: &ReasonerInput,
88        individual_iri: &str,
89        class_iri: &str,
90    ) -> Result<InstanceCheckResult> {
91        crate::abox::check_instance(&input.ontology, self.id(), individual_iri, class_iri)
92    }
93    fn inferred_assertions(&self, input: &ReasonerInput) -> Result<InferredAssertions> {
94        crate::abox::inferred_assertions(&input.ontology, self.id())
95    }
96    fn consistency_detail(
97        &self,
98        input: &ReasonerInput,
99        unsatisfiable: &[String],
100    ) -> Result<ConsistencyDetail> {
101        crate::abox::check_full_consistency(&input.ontology, self.id(), unsatisfiable)
102    }
103    fn explain(
104        &self,
105        input: &ReasonerInput,
106        request: &ExplanationRequest,
107    ) -> Result<ExplanationResult>;
108}