ontologos_core/
reasoner.rs1use crate::error::{Error, Result};
2use crate::ontology::Ontology;
3
4const MAX_PARALLELISM: usize = 64;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
8pub enum Profile {
9 #[default]
11 Auto,
12 Rdfs,
14 Rl,
16 El,
18}
19
20#[derive(Debug, Clone)]
22pub struct ReasonerConfig {
23 pub incremental: bool,
25 pub explanations: bool,
27 pub parallelism: usize,
29}
30
31impl Default for ReasonerConfig {
32 fn default() -> Self {
33 Self {
34 incremental: false,
35 explanations: false,
36 parallelism: 1,
37 }
38 }
39}
40
41#[derive(Debug, Default)]
43pub struct ReasonerBuilder {
44 profile: Profile,
45 config: ReasonerConfig,
46}
47
48impl ReasonerBuilder {
49 #[must_use]
51 pub fn new() -> Self {
52 Self::default()
53 }
54
55 #[must_use]
57 pub fn profile(mut self, profile: Profile) -> Self {
58 self.profile = profile;
59 self
60 }
61
62 #[must_use]
64 pub fn config(mut self, config: ReasonerConfig) -> Self {
65 self.config = config;
66 self
67 }
68
69 pub fn build(self, ontology: Ontology) -> Result<Reasoner> {
71 if self.config.parallelism == 0 || self.config.parallelism > MAX_PARALLELISM {
72 return Err(Error::Message(format!(
73 "parallelism must be in 1..={MAX_PARALLELISM}, got {}",
74 self.config.parallelism
75 )));
76 }
77 Ok(Reasoner {
78 ontology,
79 profile: self.profile,
80 config: self.config,
81 session: None,
82 })
83 }
84}
85
86#[derive(Debug)]
88pub struct Reasoner {
89 ontology: Ontology,
90 profile: Profile,
91 config: ReasonerConfig,
92 session: Option<Box<dyn crate::session::ReasonerSession>>,
93}
94
95impl Reasoner {
96 #[must_use]
98 pub fn builder() -> ReasonerBuilder {
99 ReasonerBuilder::new()
100 }
101
102 #[must_use]
104 pub fn profile(&self) -> Profile {
105 self.profile
106 }
107
108 #[must_use]
110 pub fn config(&self) -> &ReasonerConfig {
111 &self.config
112 }
113
114 #[must_use]
116 pub fn ontology(&self) -> &Ontology {
117 &self.ontology
118 }
119
120 pub fn ontology_mut(&mut self) -> &mut Ontology {
122 &mut self.ontology
123 }
124
125 #[must_use]
127 pub fn session(&self) -> Option<&dyn crate::session::ReasonerSession> {
128 self.session.as_deref()
129 }
130
131 pub fn session_mut(&mut self) -> Option<&mut dyn crate::session::ReasonerSession> {
133 self.session.as_deref_mut()
134 }
135
136 pub fn take_session(&mut self) -> Option<Box<dyn crate::session::ReasonerSession>> {
138 self.session.take()
139 }
140
141 pub fn set_session(&mut self, session: Box<dyn crate::session::ReasonerSession>) {
143 self.session = Some(session);
144 }
145
146 pub fn clear_session(&mut self) {
148 if let Some(session) = self.session.as_mut() {
149 session.clear();
150 }
151 self.session = None;
152 }
153
154 pub fn classify(&mut self) -> Result<()> {
161 if self.profile == Profile::Rdfs {
162 return Err(Error::Message(
163 "Profile::Rdfs: use ontologos_rdfs::classify_reasoner or \
164 ontologos_rdfs::materialize_reasoner; Reasoner::classify does not \
165 dispatch to profile engines"
166 .into(),
167 ));
168 }
169 if self.profile == Profile::Rl {
170 return Err(Error::Message(
171 "Profile::Rl: use ontologos_rl::classify_reasoner or \
172 ontologos_rl::materialize_reasoner; Reasoner::classify does not \
173 dispatch to profile engines"
174 .into(),
175 ));
176 }
177 Err(Error::NotImplemented)
178 }
179}