1use fukurow_lite::model::{Class as OwlLiteClass, Property as OwlLiteProperty, Individual, OwlIri};
4use serde::{Deserialize, Serialize};
5use std::collections::HashSet;
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
9pub enum ClassExpression {
10 Named(OwlIri),
12
13 Thing,
15
16 Nothing,
18
19 IntersectionOf(Vec<ClassExpression>),
21
22 UnionOf(Vec<ClassExpression>),
24
25 ComplementOf(Box<ClassExpression>),
27
28 OneOf(Vec<Individual>),
30
31 SomeValuesFrom {
33 property: PropertyExpression,
34 class: Box<ClassExpression>,
35 },
36
37 AllValuesFrom {
39 property: PropertyExpression,
40 class: Box<ClassExpression>,
41 },
42
43 HasValue {
45 property: PropertyExpression,
46 individual: Individual,
47 },
48
49 MinCardinality {
51 cardinality: u32,
52 property: PropertyExpression,
53 class: Option<Box<ClassExpression>>, },
55
56 MaxCardinality {
58 cardinality: u32,
59 property: PropertyExpression,
60 class: Option<Box<ClassExpression>>, },
62
63 ExactCardinality {
65 cardinality: u32,
66 property: PropertyExpression,
67 class: Option<Box<ClassExpression>>, },
69}
70
71#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
73pub enum PropertyExpression {
74 ObjectProperty(OwlIri),
76
77 DataProperty(OwlIri),
79
80 InverseOf(Box<PropertyExpression>),
82}
83
84#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
86pub enum Axiom {
87 OwlLite(fukurow_lite::Axiom),
89
90 SubClassOf(ClassExpression, ClassExpression),
92
93 EquivalentClasses(Vec<ClassExpression>),
95
96 DisjointClasses(Vec<ClassExpression>),
98
99 SubPropertyOf(PropertyExpression, PropertyExpression),
101
102 EquivalentProperties(Vec<PropertyExpression>),
104
105 ObjectPropertyDomain(PropertyExpression, ClassExpression),
107
108 ObjectPropertyRange(PropertyExpression, ClassExpression),
110
111 FunctionalProperty(PropertyExpression),
113
114 InverseFunctionalProperty(PropertyExpression),
116
117 TransitiveProperty(PropertyExpression),
119
120 SymmetricProperty(PropertyExpression),
122
123 AsymmetricProperty(PropertyExpression),
125
126 ReflexiveProperty(PropertyExpression),
128
129 IrreflexiveProperty(PropertyExpression),
131
132 DisjointProperties(Vec<PropertyExpression>),
134
135 SameIndividual(Vec<Individual>),
137
138 DifferentIndividuals(Vec<Individual>),
140
141 ClassAssertion(ClassExpression, Individual),
143
144 ObjectPropertyAssertion(PropertyExpression, Individual, Individual),
146
147 NegativeObjectPropertyAssertion(PropertyExpression, Individual, Individual),
149
150 DataPropertyAssertion(OwlIri, Individual, String), NegativeDataPropertyAssertion(OwlIri, Individual, String),
155}
156
157#[derive(Debug, Clone, Serialize, Deserialize)]
159pub struct OwlDlOntology {
160 pub iri: Option<OwlIri>,
162
163 pub axioms: Vec<Axiom>,
165
166 pub classes: HashSet<OwlLiteClass>,
168
169 pub properties: HashSet<OwlLiteProperty>,
171
172 pub individuals: HashSet<Individual>,
174
175 pub class_expressions: HashSet<ClassExpression>,
177
178 pub property_expressions: HashSet<PropertyExpression>,
180}
181
182impl OwlDlOntology {
183 pub fn new() -> Self {
184 Self {
185 iri: None,
186 axioms: Vec::new(),
187 classes: HashSet::new(),
188 properties: HashSet::new(),
189 individuals: HashSet::new(),
190 class_expressions: HashSet::new(),
191 property_expressions: HashSet::new(),
192 }
193 }
194
195 pub fn with_iri(iri: OwlIri) -> Self {
196 Self {
197 iri: Some(iri),
198 axioms: Vec::new(),
199 classes: HashSet::new(),
200 properties: HashSet::new(),
201 individuals: HashSet::new(),
202 class_expressions: HashSet::new(),
203 property_expressions: HashSet::new(),
204 }
205 }
206
207 pub fn add_axiom(&mut self, axiom: Axiom) {
208 match &axiom {
210 Axiom::OwlLite(lite_axiom) => {
211 match lite_axiom {
213 fukurow_lite::Axiom::SubClassOf(c1, c2) => {
214 let ce1 = Self::owl_lite_class_to_expression(c1.clone());
215 let ce2 = Self::owl_lite_class_to_expression(c2.clone());
216 self.add_class_expression(&ce1);
217 self.add_class_expression(&ce2);
218 }
219 fukurow_lite::Axiom::EquivalentClasses(classes) => {
220 for class in classes {
221 let expr = Self::owl_lite_class_to_expression(class.clone());
222 self.add_class_expression(&expr);
223 }
224 }
225 fukurow_lite::Axiom::DisjointClasses(classes) => {
226 for class in classes {
227 let expr = Self::owl_lite_class_to_expression(class.clone());
228 self.add_class_expression(&expr);
229 }
230 }
231 fukurow_lite::Axiom::SubPropertyOf(p1, p2) => {
232 let pe1 = Self::owl_lite_property_to_expression(p1.clone());
233 let pe2 = Self::owl_lite_property_to_expression(p2.clone());
234 self.add_property_expression(&pe1);
235 self.add_property_expression(&pe2);
236 }
237 fukurow_lite::Axiom::EquivalentProperties(properties) => {
238 for prop in properties {
239 let expr = Self::owl_lite_property_to_expression(prop.clone());
240 self.add_property_expression(&expr);
241 }
242 }
243 fukurow_lite::Axiom::ObjectPropertyDomain(p, c) => {
244 let pe = Self::owl_lite_property_to_expression(p.clone());
245 let ce = Self::owl_lite_class_to_expression(c.clone());
246 self.add_property_expression(&pe);
247 self.add_class_expression(&ce);
248 }
249 fukurow_lite::Axiom::ObjectPropertyRange(p, c) => {
250 let pe = Self::owl_lite_property_to_expression(p.clone());
251 let ce = Self::owl_lite_class_to_expression(c.clone());
252 self.add_property_expression(&pe);
253 self.add_class_expression(&ce);
254 }
255 fukurow_lite::Axiom::FunctionalProperty(p) |
256 fukurow_lite::Axiom::InverseFunctionalProperty(p) |
257 fukurow_lite::Axiom::TransitiveProperty(p) |
258 fukurow_lite::Axiom::SymmetricProperty(p) => {
259 let pe = Self::owl_lite_property_to_expression(p.clone());
260 self.add_property_expression(&pe);
261 }
262 fukurow_lite::Axiom::SameIndividual(individuals) => {
263 self.individuals.extend(individuals.iter().cloned());
264 }
265 fukurow_lite::Axiom::DifferentIndividuals(individuals) => {
266 self.individuals.extend(individuals.iter().cloned());
267 }
268 fukurow_lite::Axiom::ClassAssertion(c, i) => {
269 let ce = Self::owl_lite_class_to_expression(c.clone());
270 self.add_class_expression(&ce);
271 self.individuals.insert(i.clone());
272 }
273 fukurow_lite::Axiom::ObjectPropertyAssertion(p, i1, i2) => {
274 let pe = Self::owl_lite_property_to_expression(p.clone());
275 self.add_property_expression(&pe);
276 self.individuals.insert(i1.clone());
277 self.individuals.insert(i2.clone());
278 }
279 fukurow_lite::Axiom::NegativeObjectPropertyAssertion(p, i1, i2) => {
280 let pe = Self::owl_lite_property_to_expression(p.clone());
281 self.add_property_expression(&pe);
282 self.individuals.insert(i1.clone());
283 self.individuals.insert(i2.clone());
284 }
285 }
286 }
287 Axiom::SubClassOf(ce1, ce2) => {
288 self.add_class_expression(ce1);
289 self.add_class_expression(ce2);
290 }
291 Axiom::EquivalentClasses(expressions) => {
292 for expr in expressions {
293 self.add_class_expression(expr);
294 }
295 }
296 Axiom::DisjointClasses(expressions) => {
297 for expr in expressions {
298 self.add_class_expression(expr);
299 }
300 }
301 Axiom::SubPropertyOf(pe1, pe2) => {
302 self.add_property_expression(pe1);
303 self.add_property_expression(pe2);
304 }
305 Axiom::EquivalentProperties(expressions) => {
306 for expr in expressions {
307 self.add_property_expression(expr);
308 }
309 }
310 Axiom::ObjectPropertyDomain(pe, ce) => {
311 self.add_property_expression(pe);
312 self.add_class_expression(ce);
313 }
314 Axiom::ObjectPropertyRange(pe, ce) => {
315 self.add_property_expression(pe);
316 self.add_class_expression(ce);
317 }
318 Axiom::FunctionalProperty(pe) |
319 Axiom::InverseFunctionalProperty(pe) |
320 Axiom::TransitiveProperty(pe) |
321 Axiom::SymmetricProperty(pe) |
322 Axiom::AsymmetricProperty(pe) |
323 Axiom::ReflexiveProperty(pe) |
324 Axiom::IrreflexiveProperty(pe) => {
325 self.add_property_expression(pe);
326 }
327 Axiom::DisjointProperties(expressions) => {
328 for expr in expressions {
329 self.add_property_expression(expr);
330 }
331 }
332 Axiom::SameIndividual(individuals) => {
333 self.individuals.extend(individuals.iter().cloned());
334 }
335 Axiom::DifferentIndividuals(individuals) => {
336 self.individuals.extend(individuals.iter().cloned());
337 }
338 Axiom::ClassAssertion(ce, i) => {
339 self.add_class_expression(ce);
340 self.individuals.insert(i.clone());
341 }
342 Axiom::ObjectPropertyAssertion(pe, i1, i2) |
343 Axiom::NegativeObjectPropertyAssertion(pe, i1, i2) => {
344 self.add_property_expression(pe);
345 self.individuals.insert(i1.clone());
346 self.individuals.insert(i2.clone());
347 }
348 Axiom::DataPropertyAssertion(_, i, _) |
349 Axiom::NegativeDataPropertyAssertion(_, i, _) => {
350 self.individuals.insert(i.clone());
351 }
352 }
353
354 self.axioms.push(axiom);
355 }
356
357 fn owl_lite_class_to_expression(class: OwlLiteClass) -> ClassExpression {
358 match class {
359 OwlLiteClass::Named(iri) => ClassExpression::Named(iri),
360 OwlLiteClass::Thing => ClassExpression::Thing,
361 OwlLiteClass::Nothing => ClassExpression::Nothing,
362 }
363 }
364
365 fn owl_lite_property_to_expression(property: OwlLiteProperty) -> PropertyExpression {
366 match property {
367 OwlLiteProperty::Object(iri) => PropertyExpression::ObjectProperty(iri),
368 OwlLiteProperty::Data(iri) => PropertyExpression::DataProperty(iri),
369 }
370 }
371
372 pub fn add_class_expression(&mut self, expr: &ClassExpression) {
373 self.collect_class_expressions(expr);
375 }
376
377 pub fn add_property_expression(&mut self, expr: &PropertyExpression) {
378 self.collect_property_expressions(expr);
380 }
381
382 fn collect_class_expressions(&mut self, expr: &ClassExpression) {
383 match expr {
384 ClassExpression::Named(iri) => {
385 self.classes.insert(OwlLiteClass::Named(iri.clone()));
386 }
387 ClassExpression::Thing => {
388 self.classes.insert(OwlLiteClass::Thing);
389 }
390 ClassExpression::Nothing => {
391 self.classes.insert(OwlLiteClass::Nothing);
392 }
393 ClassExpression::IntersectionOf(expressions) |
394 ClassExpression::UnionOf(expressions) => {
395 for expr in expressions {
396 self.collect_class_expressions(expr);
397 }
398 }
399 ClassExpression::ComplementOf(expr) => {
400 self.collect_class_expressions(expr);
401 }
402 ClassExpression::OneOf(individuals) => {
403 self.individuals.extend(individuals.iter().cloned());
404 }
405 ClassExpression::SomeValuesFrom { class, .. } |
406 ClassExpression::AllValuesFrom { class, .. } => {
407 self.collect_class_expressions(class);
408 }
409 ClassExpression::HasValue { individual, .. } => {
410 self.individuals.insert(individual.clone());
411 }
412 ClassExpression::MinCardinality { class, .. } |
413 ClassExpression::MaxCardinality { class, .. } |
414 ClassExpression::ExactCardinality { class, .. } => {
415 if let Some(class) = class {
416 self.collect_class_expressions(class);
417 }
418 }
419 }
420 self.class_expressions.insert(expr.clone());
421 }
422
423 fn collect_property_expressions(&mut self, expr: &PropertyExpression) {
424 match expr {
425 PropertyExpression::ObjectProperty(iri) => {
426 self.properties.insert(OwlLiteProperty::Object(iri.clone()));
427 }
428 PropertyExpression::DataProperty(iri) => {
429 self.properties.insert(OwlLiteProperty::Data(iri.clone()));
430 }
431 PropertyExpression::InverseOf(expr) => {
432 self.collect_property_expressions(expr);
433 }
434 }
435 self.property_expressions.insert(expr.clone());
436 }
437}