typr_core/components/context/
graph.rs1use crate::components::context::Context;
2use crate::components::r#type::type_system::TypeSystem;
3use serde::Deserialize;
4use serde::Serialize;
5use std::collections::HashMap;
6use std::collections::HashSet;
7use std::fmt::Debug;
8use std::ops::Add;
9
10#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
11#[serde(bound = "T: Serialize + for<'a> Deserialize<'a>")]
12pub struct Graph<T: TypeSystem> {
13 memory: HashSet<T>,
14 root: Node<T>,
15 #[serde(skip)]
16 subtype_cache: HashMap<(T, T), bool>,
17}
18
19impl<T: TypeSystem> Default for Graph<T> {
20 fn default() -> Self {
21 Self::new()
22 }
23}
24
25impl<T: TypeSystem> Graph<T> {
26 pub fn new() -> Self {
27 Graph {
28 memory: HashSet::new(),
29 root: Node::new(),
30 subtype_cache: HashMap::new(),
31 }
32 }
33
34 pub fn check_subtype_cache(&self, t1: &T, t2: &T) -> Option<bool> {
36 self.subtype_cache.get(&(t1.clone(), t2.clone())).copied()
37 }
38
39 pub fn cache_subtype(self, t1: T, t2: T, result: bool) -> Self {
41 let mut new_cache = self.subtype_cache.clone();
42 new_cache.insert((t1, t2), result);
43 Graph {
44 subtype_cache: new_cache,
45 ..self
46 }
47 }
48
49 pub fn add_type(self, typ: T, context: &Context) -> Self {
50 if self.memory.contains(&typ) {
51 self
52 } else {
53 let new_memory = self
54 .memory
55 .iter()
56 .chain([typ.clone()].iter())
57 .cloned()
58 .collect();
59 let new_root = self.root.add_type(typ.clone(), context);
60 Graph {
61 memory: new_memory,
62 root: new_root,
63 subtype_cache: self.subtype_cache,
64 }
65 }
66 }
67
68 pub fn get_hierarchy(&self) -> String {
69 self.root.get_hierarchy()
70 }
71
72 pub fn get_supertypes(&self, typ: &T, context: &Context) -> Vec<T> {
73 self.root
74 .get_supertypes(typ, context)
75 .iter()
76 .cloned()
77 .collect::<HashSet<_>>()
78 .iter()
79 .cloned()
80 .collect::<Vec<_>>()
81 }
82
83 pub fn get_ordered_supertypes(&self, typ: &T, context: &Context) -> Vec<T> {
84 let raw = self.root.get_supertypes(typ, context);
85 let mut seen = HashSet::new();
86 let mut result = Vec::new();
87 for item in raw {
88 if seen.insert(item.clone()) {
89 result.push(item);
90 }
91 }
92 result
93 }
94
95 pub fn add_types(self, typs: &[T], context: &Context) -> Self {
96 typs.iter()
97 .cloned()
98 .fold(self, |acc, x| acc.add_type(x, context))
99 }
100}
101
102#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
103#[serde(bound = "T: Serialize + for<'a> Deserialize<'a>")]
104pub struct Node<T: TypeSystem> {
105 value: T,
106 subtypes: Vec<Node<T>>,
107}
108
109impl<T: TypeSystem> From<T> for Node<T> {
110 fn from(val: T) -> Self {
111 Node {
112 value: val,
113 subtypes: vec![],
114 }
115 }
116}
117
118impl<T: TypeSystem> Default for Node<T> {
119 fn default() -> Self {
120 Self::new()
121 }
122}
123
124impl<T: TypeSystem> Node<T> {
125 pub fn new() -> Self {
126 Node {
127 value: T::default(),
128 subtypes: vec![],
129 }
130 }
131
132 pub fn propagate(self, typ: T, context: &Context) -> Self {
133 let graph = Node {
134 value: self.value.clone(),
135 subtypes: self
136 .subtypes
137 .iter()
138 .cloned()
139 .map(|x| x.add_type(typ.clone(), context))
140 .collect(),
141 };
142 if graph == self {
143 self.add_subtype(typ)
144 } else {
145 graph
146 }
147 }
148
149 pub fn add_subtype(self, typ: T) -> Self {
150 Node {
151 value: self.value,
152 subtypes: self
153 .subtypes
154 .iter()
155 .chain([Node::from(typ)].iter())
156 .cloned()
157 .collect(),
158 }
159 }
160
161 pub fn set_subtypes(self, subtypes: Vec<Node<T>>) -> Self {
162 Node {
163 value: self.value,
164 subtypes,
165 }
166 }
167
168 fn switch_if_reverse_subtype(self, typ: T, context: &Context) -> Self {
169 if self.value.is_subtype_raw(&typ, context) {
170 Node {
171 value: typ,
172 subtypes: vec![Node::from(self.value).set_subtypes(self.subtypes)],
173 }
174 } else {
175 self
176 }
177 }
178
179 pub fn add_type(self, typ: T, context: &Context) -> Self {
180 if self.value == typ {
181 self
182 } else {
183 match (
184 typ.is_subtype_raw(&self.value, context),
185 self.subtypes.len(),
186 ) {
187 (true, 0) => self.add_subtype(typ),
188 (true, _) => self.propagate(typ, context),
189 _ => self.switch_if_reverse_subtype(typ, context),
190 }
191 }
192 }
193
194 pub fn get_supertypes(&self, target_type: &T, context: &Context) -> Vec<T> {
195 if target_type == &self.value {
196 vec![]
197 } else if target_type.is_subtype_raw(&self.value, context) {
198 self.subtypes
199 .iter()
200 .flat_map(|x| x.get_supertypes(target_type, context))
201 .chain([self.value.clone()].iter().cloned())
202 .collect::<Vec<T>>()
203 } else {
204 vec![]
205 }
206 }
207
208 pub fn get_hierarchy(&self) -> String {
209 self.get_hierarchy_helper(0)
210 }
211
212 fn tabulation_from_level(level: i32) -> String {
213 (0..level).map(|_| " ").collect::<Vec<_>>().join("")
214 }
215
216 pub fn get_hierarchy_helper(&self, level: i32) -> String {
217 let tab = Node::<T>::tabulation_from_level(level);
218 let children = self
219 .subtypes
220 .iter()
221 .map(|x| x.get_hierarchy_helper(level + 1))
222 .collect::<Vec<_>>()
223 .join("\n");
224 tab + &self.value.pretty() + "\n" + &children
225 }
226}
227
228use std::fmt;
229impl<T: TypeSystem> fmt::Display for Node<T> {
230 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
231 write!(f, "{}", self.get_hierarchy())
232 }
233}
234
235impl<T: TypeSystem> Add for Graph<T> {
236 type Output = Self;
237
238 fn add(self, other: Self) -> Self {
239 let context = Context::default(); let merged = other
241 .memory
242 .iter()
243 .cloned()
244 .fold(self.clone(), |acc, typ| acc.add_type(typ, &context));
245 let mut new_cache = self.subtype_cache;
247 new_cache.extend(other.subtype_cache);
248 Graph {
249 subtype_cache: new_cache,
250 ..merged
251 }
252 }
253}