owl_structural_model/
axiom.rs1use iri_rfc3987::Iri;
4
5use crate::{
6 AnnotationSubject,
7 AnnotationValue,
8 AxiomAnnotations,
9 ClassExpression,
10 Entity,
11 ObjectPropertyExpression,
12 StructuralModelError,
13};
14
15const KIND_AXIOM_OPERANDS: &str = "axiom operands";
16
17#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
19pub enum Axiom {
20 Declaration {
22 entity: Entity,
24 annotations: AxiomAnnotations,
26 },
27 SubClassOf {
29 sub_class: ClassExpression,
31 super_class: ClassExpression,
33 annotations: AxiomAnnotations,
35 },
36 EquivalentClasses {
38 classes: Vec<ClassExpression>,
40 annotations: AxiomAnnotations,
42 },
43 DisjointClasses {
45 classes: Vec<ClassExpression>,
47 annotations: AxiomAnnotations,
49 },
50 ObjectPropertyDomain {
52 property: ObjectPropertyExpression,
54 domain: ClassExpression,
56 annotations: AxiomAnnotations,
58 },
59 AnnotationAssertion {
61 property: Iri<String>,
63 subject: AnnotationSubject,
65 value: AnnotationValue,
67 annotations: AxiomAnnotations,
69 },
70}
71
72impl Axiom {
73 #[must_use]
75 pub fn declaration(entity: Entity) -> Self {
76 Self::Declaration { entity, annotations: AxiomAnnotations::empty() }
77 }
78
79 #[must_use]
81 pub fn sub_class_of(sub_class: ClassExpression, super_class: ClassExpression) -> Self {
82 Self::SubClassOf { sub_class, super_class, annotations: AxiomAnnotations::empty() }
83 }
84
85 pub fn equivalent_classes(classes: Vec<ClassExpression>) -> Result<Self, StructuralModelError> {
92 Self::require_pair(&classes)?;
93 Ok(Self::EquivalentClasses { classes, annotations: AxiomAnnotations::empty() })
94 }
95
96 pub fn disjoint_classes(classes: Vec<ClassExpression>) -> Result<Self, StructuralModelError> {
103 Self::require_pair(&classes)?;
104 Ok(Self::DisjointClasses { classes, annotations: AxiomAnnotations::empty() })
105 }
106
107 fn require_pair(classes: &[ClassExpression]) -> Result<(), StructuralModelError> {
108 if classes.len() < 2 {
109 return Err(StructuralModelError::InvalidFormat {
110 kind: KIND_AXIOM_OPERANDS,
111 value: classes.len().to_string(),
112 message: "requires at least two class expressions",
113 });
114 }
115 Ok(())
116 }
117}