Skip to main content

v_common_onto/
onto.rs

1use crate::individual::*;
2use std::collections::{HashMap, HashSet};
3use std::fmt;
4
5// TODO: Load ontology individuals to have them by hand at runtime.
6
7#[derive(PartialEq, Debug)]
8pub enum RelType {
9    Sub,
10    Super,
11}
12
13#[derive(Debug)]
14pub struct Onto {
15    pub relations: HashMap<String, HashMap<String, RelType>>,
16    pub prefixes: HashMap<String, String>,
17}
18
19impl fmt::Display for Onto {
20    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21        write!(f, "{:#?}", self.relations)
22    }
23}
24
25impl Default for Onto {
26    fn default() -> Self {
27        Onto {
28            relations: HashMap::new(),
29            prefixes: HashMap::new(),
30        }
31    }
32}
33
34impl Onto {
35    pub fn update(&mut self, indv: &mut Individual) -> bool {
36        if let Some(vtype) = indv.get_first_literal("rdf:type") {
37            if vtype == "owl:Class"
38                || vtype == "rdfs:Class"
39                || vtype == "rdf:Property"
40                || vtype == "rdfs:Datatype"
41                || vtype == "owl:ObjectProperty"
42                || vtype == "owl:DatatypeProperty"
43            {
44                let subs = if vtype == "owl:Class" || vtype == "rdfs:Class" {
45                    if let Some(_subclasses) = indv.get_literals("rdfs:subClassOf") {
46                        _subclasses
47                    } else {
48                        Vec::new()
49                    }
50                } else if vtype == "rdf:Property" || vtype == "owl:ObjectProperty" || vtype == "owl:DatatypeProperty" {
51                    if let Some(_subproperties) = indv.get_literals("rdfs:subPropertyOf") {
52                        _subproperties
53                    } else {
54                        Vec::new()
55                    }
56                } else {
57                    Vec::new()
58                };
59
60                // if subs.len() > 0 {
61                let onto_el = self.relations.entry(indv.obj.uri.clone()).or_default();
62
63                for sub in subs.clone() {
64                    let rel_type = onto_el.entry(sub).or_insert(RelType::Super);
65                    *rel_type = RelType::Super;
66                }
67
68                for sub in subs {
69                    let onto_el = self.relations.entry(sub).or_default();
70                    let rel_type = onto_el.entry(indv.obj.uri.clone()).or_insert(RelType::Sub);
71                    *rel_type = RelType::Sub;
72                }
73            //}
74            } else if vtype == "owl:Ontology" {
75                if let Some(full_url) = indv.get_first_literal("v-s:fullUrl") {
76                    debug!("prefix : {} -> {}", indv.get_id(), full_url);
77                    self.prefixes.insert(indv.get_id().to_owned(), full_url);
78                }
79            } else {
80                debug!("is not onto element: {}", indv.obj.uri)
81            }
82        }
83        true
84    }
85
86    pub fn is_some_entered(&mut self, el: &str, subs: &[&str]) -> bool {
87        for sub in subs {
88            if self.relations.contains_key(*sub) {
89                let onto_el = self.relations.entry((*sub).to_string()).or_default();
90                if let Some(rtype) = onto_el.get(el) {
91                    if *rtype == RelType::Sub {
92                        return true;
93                    }
94                }
95            }
96        }
97
98        false
99    }
100
101    pub fn is_some_entered_it<'a, I>(&mut self, el: &str, subs: I) -> bool
102    where
103        I: Iterator<Item = &'a String>,
104    {
105        for sub in subs {
106            if self.relations.contains_key(sub) {
107                let onto_el = self.relations.entry((*sub).to_string()).or_default();
108                if let Some(rtype) = onto_el.get(el) {
109                    if *rtype == RelType::Sub {
110                        return true;
111                    }
112                }
113            }
114        }
115
116        false
117    }
118
119    pub fn get_subs(&self, el: &str, collector: &mut HashSet<String>) {
120        if self.relations.contains_key(el) {
121            let mut buf = Vec::new();
122            if let Some(qqq) = self.relations.get(el) {
123                for (x, t) in qqq {
124                    if *t == RelType::Sub && !collector.contains(x) {
125                        collector.insert(x.to_string());
126                        buf.push(x.to_string());
127                    }
128                }
129            }
130
131            for x in buf {
132                self.get_subs(&x, collector);
133            }
134        }
135    }
136
137    pub fn get_supers(&self, el: &str, collector: &mut HashSet<String>) {
138        if self.relations.contains_key(el) {
139            let mut buf = Vec::new();
140            if let Some(qqq) = self.relations.get(el) {
141                for (x, t) in qqq {
142                    if *t == RelType::Super && !collector.contains(x) {
143                        collector.insert(x.to_string());
144                        buf.push(x.to_string());
145                    }
146                }
147            }
148
149            for x in buf {
150                self.get_supers(&x, collector);
151            }
152        }
153    }
154
155    pub fn update_subs(&mut self, el: &str, subs: &mut HashSet<String>) {
156        if self.relations.contains_key(el) {
157            let onto_el = self.relations.entry(el.to_string()).or_default();
158
159            for sub in subs.iter() {
160                let rel_type = onto_el.entry(sub.to_string()).or_insert(RelType::Sub);
161                *rel_type = RelType::Sub;
162            }
163        }
164    }
165
166    pub fn get_full_prefix(&self, short_prefix: &str) -> Option<&String> {
167        self.prefixes.get(short_prefix)
168    }
169}