1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
use serde::{Deserialize, Serialize};

use crate::owl::*;

#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub enum Axiom {
    // Annotations
    AnnotationAssertion(AnnotationAssertion),
    AnnotationPropertyRange(AnnotationPropertyRange),
    AnnotationPropertyDomain(AnnotationPropertyDomain),
    // Properties
    SubObjectPropertyOf(SubObjectPropertyOf),
    SubDataPropertyOf(SubDataPropertyOf),
    SubAnnotationPropertyOf(SubAnnotationPropertyOf),
    EquivalentObjectProperties(EquivalentObjectProperties),
    EquivalentDataProperties(EquivalentDataProperties),
    InverseObjectProperties(InverseObjectProperties),
    DisjointObjectProperties(DisjointObjectProperties),
    ObjectPropertyDomain(ObjectPropertyDomain),
    ObjectPropertyRange(ObjectPropertyRange),
    DataPropertyDomain(DataPropertyDomain),
    DataPropertyRange(DataPropertyRange),
    SymmetricObjectProperty(SymmetricObjectProperty),
    AsymmetricObjectProperty(AsymmetricObjectProperty),
    ReflexiveObjectProperty(ReflexiveObjectProperty),
    IrreflexiveObjectProperty(IrreflexiveObjectProperty),
    FunctionalObjectProperty(FunctionalObjectProperty),
    InverseFunctionalObjectProperty(InverseFunctionalObjectProperty),
    TransitiveObjectProperty(TransitiveObjectProperty),
    FunctionalDataProperty(FunctionalDataProperty),
    // Classes
    SubClassOf(SubClassOf),
    EquivalentClasses(EquivalentClasses),
    DisjointClasses(DisjointClasses),
    // Datatypes
    DatatypeDefinition(DatatypeDefinition),
    // Individuals
    ClassAssertion(ClassAssertion),
    SameIndividual(SameIndividual),
    DifferentIndividuals(DifferentIndividuals),
    // ObjectProperties
    ObjectPropertyAssertion(ObjectPropertyAssertion),
    NegativeObjectPropertyAssertion(NegativeObjectPropertyAssertion),
    // DataProperties
    DataPropertyAssertion(DataPropertyAssertion),
    NegativeDataPropertyAssertion(NegativeDataPropertyAssertion),
    // Other
    HasKey(HasKey),
}

impl Axiom {
    pub fn annotations_mut(&mut self) -> &mut Vec<Annotation> {
        match self {
            Axiom::AnnotationAssertion(a) => &mut a.annotations,
            Axiom::AnnotationPropertyDomain(a) => &mut a.annotations,
            Axiom::AnnotationPropertyRange(a) => &mut a.annotations,
            Axiom::SubObjectPropertyOf(a) => &mut a.annotations,
            Axiom::SubAnnotationPropertyOf(a) => &mut a.annotations,
            Axiom::SubDataPropertyOf(a) => &mut a.annotations,
            Axiom::EquivalentObjectProperties(a) => &mut a.annotations,
            Axiom::EquivalentDataProperties(a) => &mut a.annotations,
            Axiom::InverseObjectProperties(a) => &mut a.annotations,
            Axiom::DisjointObjectProperties(a) => &mut a.annotations,
            Axiom::ObjectPropertyDomain(a) => &mut a.annotations,
            Axiom::ObjectPropertyRange(a) => &mut a.annotations,
            Axiom::DataPropertyDomain(a) => &mut a.annotations,
            Axiom::DataPropertyRange(a) => &mut a.annotations,
            Axiom::SymmetricObjectProperty(a) => &mut a.annotations,
            Axiom::AsymmetricObjectProperty(a) => &mut a.annotations,
            Axiom::ReflexiveObjectProperty(a) => &mut a.annotations,
            Axiom::IrreflexiveObjectProperty(a) => &mut a.annotations,
            Axiom::FunctionalObjectProperty(a) => &mut a.annotations,
            Axiom::InverseFunctionalObjectProperty(a) => &mut a.annotations,
            Axiom::TransitiveObjectProperty(a) => &mut a.annotations,
            Axiom::FunctionalDataProperty(a) => &mut a.annotations,
            Axiom::SubClassOf(a) => &mut a.annotations,
            Axiom::EquivalentClasses(a) => &mut a.annotations,
            Axiom::DisjointClasses(a) => &mut a.annotations,
            Axiom::DatatypeDefinition(a) => &mut a.annotations,
            Axiom::ClassAssertion(a) => &mut a.annotations,
            Axiom::SameIndividual(a) => &mut a.annotations,
            Axiom::DifferentIndividuals(a) => &mut a.annotations,
            Axiom::ObjectPropertyAssertion(a) => &mut a.annotations,
            Axiom::NegativeObjectPropertyAssertion(a) => &mut a.annotations,
            Axiom::DataPropertyAssertion(a) => &mut a.annotations,
            Axiom::NegativeDataPropertyAssertion(a) => &mut a.annotations,
            Axiom::HasKey(a) => &mut a.annotations,
        }
    }

    pub fn subject(&self) -> Option<&IRI> {
        match self {
            Axiom::AnnotationAssertion(a) => Some(&a.subject),
            Axiom::AnnotationPropertyRange(a) => Some(a.iri.as_iri()),
            Axiom::AnnotationPropertyDomain(a) => Some(a.iri.as_iri()),
            Axiom::SubObjectPropertyOf(a) => match &a.object_property {
                ObjectPropertyConstructor::IRI(iri) => Some(iri.as_iri()),
                ObjectPropertyConstructor::ObjectInverseOf(_) => None,
                ObjectPropertyConstructor::ObjectPropertyChain(_) => None,
            },
            Axiom::SubDataPropertyOf(a) => Some(a.subject_iri.as_iri()),
            Axiom::SubAnnotationPropertyOf(a) => Some(a.subject_iri.as_iri()),
            Axiom::EquivalentObjectProperties(a) => Some(a.object_property_iri_1.as_iri()),
            Axiom::EquivalentDataProperties(a) => Some(a.data_property_iri_1.as_iri()),
            Axiom::InverseObjectProperties(a) => Some(a.object_property_iri_1.as_iri()),
            Axiom::DisjointObjectProperties(a) => Some(a.object_property_iri_1.as_iri()),
            Axiom::ObjectPropertyDomain(a) => Some(a.iri.as_iri()),
            Axiom::ObjectPropertyRange(a) => Some(a.iri.as_iri()),
            Axiom::DataPropertyDomain(a) => Some(a.iri.as_iri()),
            Axiom::DataPropertyRange(a) => Some(a.iri.as_iri()),
            Axiom::SymmetricObjectProperty(a) => Some(a.object_property_iri.as_iri()),
            Axiom::AsymmetricObjectProperty(a) => Some(a.object_property_iri.as_iri()),
            Axiom::ReflexiveObjectProperty(a) => Some(a.object_property_iri.as_iri()),
            Axiom::IrreflexiveObjectProperty(a) => Some(a.object_property_iri.as_iri()),
            Axiom::FunctionalObjectProperty(a) => Some(a.object_property_iri.as_iri()),
            Axiom::InverseFunctionalObjectProperty(a) => Some(a.object_property_iri.as_iri()),
            Axiom::TransitiveObjectProperty(a) => Some(a.object_property_iri.as_iri()),
            Axiom::FunctionalDataProperty(a) => Some(a.data_property_iri.as_iri()),
            Axiom::SubClassOf(a) => match a.cls.as_ref() {
                ClassConstructor::IRI(iri) => Some(iri.as_iri()),
                _ => None,
            },
            Axiom::EquivalentClasses(a) => Some(a.class_iri.as_iri()),
            Axiom::DisjointClasses(_) => None,
            Axiom::DatatypeDefinition(a) => Some(a.data_property_iri.as_iri()),
            Axiom::ClassAssertion(a) => Some(a.individual.as_iri()),
            Axiom::SameIndividual(a) => Some(a.individual1.as_iri()),
            Axiom::DifferentIndividuals(a) => Some(a.individual1.as_iri()),
            Axiom::ObjectPropertyAssertion(a) => Some(a.subject.as_iri()),
            Axiom::NegativeObjectPropertyAssertion(a) => Some(a.subject.as_iri()),
            Axiom::DataPropertyAssertion(a) => Some(a.subject.as_iri()),
            Axiom::NegativeDataPropertyAssertion(a) => Some(a.subject.as_iri()),
            Axiom::HasKey(a) => Some(a.iri.as_iri()),
        }
    }
}

impl From<SubObjectPropertyOf> for Axiom {
    fn from(s: SubObjectPropertyOf) -> Self {
        Self::SubObjectPropertyOf(s)
    }
}

impl From<SubAnnotationPropertyOf> for Axiom {
    fn from(s: SubAnnotationPropertyOf) -> Self {
        Self::SubAnnotationPropertyOf(s)
    }
}

impl From<SubDataPropertyOf> for Axiom {
    fn from(s: SubDataPropertyOf) -> Self {
        Self::SubDataPropertyOf(s)
    }
}