1use serde::{Deserialize, Serialize};
4use std::collections::HashSet;
5
6#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Serialize, Deserialize)]
8pub struct OwlIri(pub String);
9
10impl OwlIri {
11 pub fn new(s: String) -> Self {
12 Self(s)
13 }
14
15 pub fn as_str(&self) -> &str {
16 &self.0
17 }
18}
19
20impl std::fmt::Display for OwlIri {
21 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22 write!(f, "{}", self.0)
23 }
24}
25
26#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
28pub enum Class {
29 Named(OwlIri),
31 Thing,
33 Nothing,
35}
36
37#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
39pub enum Property {
40 Object(OwlIri),
42 Data(OwlIri),
44}
45
46#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
48pub struct Individual(pub OwlIri);
49
50#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
52pub enum Axiom {
53 SubClassOf(Class, Class),
55
56 EquivalentClasses(Vec<Class>),
58
59 DisjointClasses(Vec<Class>),
61
62 SubPropertyOf(Property, Property),
64
65 EquivalentProperties(Vec<Property>),
67
68 ObjectPropertyDomain(Property, Class),
70
71 ObjectPropertyRange(Property, Class),
73
74 FunctionalProperty(Property),
76
77 InverseFunctionalProperty(Property),
79
80 TransitiveProperty(Property),
82
83 SymmetricProperty(Property),
85
86 SameIndividual(Vec<Individual>),
88
89 DifferentIndividuals(Vec<Individual>),
91
92 ClassAssertion(Class, Individual),
94
95 ObjectPropertyAssertion(Property, Individual, Individual),
97
98 NegativeObjectPropertyAssertion(Property, Individual, Individual),
100}
101
102#[derive(Debug, Clone, Serialize, Deserialize)]
104pub struct Ontology {
105 pub iri: Option<OwlIri>,
107
108 pub axioms: Vec<Axiom>,
110
111 pub classes: HashSet<Class>,
113
114 pub properties: HashSet<Property>,
116
117 pub individuals: HashSet<Individual>,
119}
120
121impl Ontology {
122 pub fn new() -> Self {
123 Self {
124 iri: None,
125 axioms: Vec::new(),
126 classes: HashSet::new(),
127 properties: HashSet::new(),
128 individuals: HashSet::new(),
129 }
130 }
131
132 pub fn with_iri(iri: OwlIri) -> Self {
133 Self {
134 iri: Some(iri),
135 axioms: Vec::new(),
136 classes: HashSet::new(),
137 properties: HashSet::new(),
138 individuals: HashSet::new(),
139 }
140 }
141
142 pub fn add_axiom(&mut self, axiom: Axiom) {
143 match &axiom {
145 Axiom::SubClassOf(c1, c2) => {
146 self.classes.insert(c1.clone());
147 self.classes.insert(c2.clone());
148 }
149 Axiom::EquivalentClasses(classes) => {
150 self.classes.extend(classes.iter().cloned());
151 }
152 Axiom::DisjointClasses(classes) => {
153 self.classes.extend(classes.iter().cloned());
154 }
155 Axiom::SubPropertyOf(p1, p2) => {
156 self.properties.insert(p1.clone());
157 self.properties.insert(p2.clone());
158 }
159 Axiom::EquivalentProperties(properties) => {
160 self.properties.extend(properties.iter().cloned());
161 }
162 Axiom::ObjectPropertyDomain(p, c) => {
163 self.properties.insert(p.clone());
164 self.classes.insert(c.clone());
165 }
166 Axiom::ObjectPropertyRange(p, c) => {
167 self.properties.insert(p.clone());
168 self.classes.insert(c.clone());
169 }
170 Axiom::FunctionalProperty(p) |
171 Axiom::InverseFunctionalProperty(p) |
172 Axiom::TransitiveProperty(p) |
173 Axiom::SymmetricProperty(p) => {
174 self.properties.insert(p.clone());
175 }
176 Axiom::SameIndividual(individuals) => {
177 self.individuals.extend(individuals.iter().cloned());
178 }
179 Axiom::DifferentIndividuals(individuals) => {
180 self.individuals.extend(individuals.iter().cloned());
181 }
182 Axiom::ClassAssertion(c, i) => {
183 self.classes.insert(c.clone());
184 self.individuals.insert(i.clone());
185 }
186 Axiom::ObjectPropertyAssertion(p, i1, i2) |
187 Axiom::NegativeObjectPropertyAssertion(p, i1, i2) => {
188 self.properties.insert(p.clone());
189 self.individuals.insert(i1.clone());
190 self.individuals.insert(i2.clone());
191 }
192 }
193
194 self.axioms.push(axiom);
195 }
196}