1use std::collections::{HashMap, HashSet};
2use log::{info, warn};
3use crate::{algorithm::simulation, utils::logger::init_global_logger_once};
6
7use graph_base::interfaces::{edge::{DirectedHyperedge, Hyperedge}, graph::SingleId, hypergraph::{ContainedDirectedHyperedge, ContainedHyperedge, DirectedHypergraph, Hypergraph}, typed::{Type, Typed}};
8
9pub trait LMatch {
10 type Edge;
11 fn new() -> Self;
13 fn l_match_with_node_mut(&mut self, e: &Self::Edge, e_prime: &Self::Edge, u: usize) -> &HashSet<usize>;
14 fn l_match_with_node(&self, e: &Self::Edge, e_prime: &Self::Edge, u: usize) -> &HashSet<usize>;
15 fn dom(&self, e: &Self::Edge, e_prime: &Self::Edge) -> impl Iterator<Item = &usize>;
16}
17
18pub struct SematicCluster<'a, E: Hyperedge> {
19 id: usize,
20 hyperedges: Vec<&'a E>,
21}
22
23impl<'a, E: Hyperedge> SematicCluster<'a, E> {
24
25 pub fn new(id: usize, hyperedges: Vec<&'a E>) -> Self {
26 Self {
27 id,
28 hyperedges,
29 }
30 }
31
32 pub fn id(&self) -> usize {
33 self.id
34 }
35
36 pub fn hyperedges(&self) -> &Vec<&'a E> {
37 &self.hyperedges
38 }
39}
40
41pub trait Delta<'a> {
42 type Node;
43 type Edge: Hyperedge;
44 fn get_sematic_clusters(&'a self, u: &'a Self::Node, v: &'a Self::Node) -> &'a Vec<(SematicCluster<'a, Self::Edge>, SematicCluster<'a, Self::Edge>)>;
45}
46
47pub trait DMatch<'a> {
48 type Edge: Hyperedge;
49 fn d_match(&self, e: &SematicCluster<'a, Self::Edge>, e_prime: &SematicCluster<'a, Self::Edge>) -> &HashSet<(usize, usize)>;
51}
52
53pub trait LPredicate<'a>: Hypergraph<'a> {
54 fn l_predicate_node(&'a self, u: &'a Self::Node, v: &'a Self::Node) -> bool;
55 fn l_predicate_edge(&'a self, e: &'a Self::Edge, e_prime: &'a Self::Edge) -> bool;
56 fn l_predicate_set(&'a self, x: &HashSet<&'a Self::Node>, y: &HashSet<&'a Self::Node>) -> bool;
57}
58
59pub trait HyperSimulation<'a>: Hypergraph<'a> {
60 fn get_simulation_fixpoint(&'a self, other: &'a Self, l_match: &mut impl LMatch<Edge = Self::Edge>) -> HashMap<&'a Self::Node, HashSet<&'a Self::Node>>;
61 fn get_simulation_recursive(&'a self, other: &'a Self, l_match: &mut impl LMatch<Edge = Self::Edge>) -> HashMap<&'a Self::Node, HashSet<&'a Self::Node>>;
62 fn get_simulation_naive(&'a self, other: &'a Self, l_match: &mut impl LMatch<Edge = Self::Edge>) -> HashMap<&'a Self::Node, HashSet<&'a Self::Node>>;
63 fn get_soft_simulation_naive(&'a self, other: &'a Self, l_match: &mut impl LMatch<Edge = Self::Edge>) -> HashMap<&'a Self::Node, HashSet<&'a Self::Node>>;
64 fn get_hyper_simulation_naive(&'a self, other: &'a Self, delta: &'a impl Delta<'a, Node = Self::Node, Edge = Self::Edge>, d_match: & impl DMatch<'a, Edge = Self::Edge>) -> HashMap<&'a Self::Node, HashSet<&'a Self::Node>>;
65}
66
67impl<'a, H> HyperSimulation<'a> for H
86where H: Hypergraph<'a> + Typed<'a> + LPredicate<'a> + ContainedHyperedge<'a> {
87 fn get_simulation_fixpoint(&'a self, other: &'a Self, l_match: &mut impl LMatch<Edge = Self::Edge>) -> HashMap<&'a Self::Node, HashSet<&'a Self::Node>> {
88 todo!()
89 }
90
91 fn get_simulation_recursive(&'a self, other: &'a Self, l_match: &mut impl LMatch<Edge = Self::Edge>) -> HashMap<&'a Self::Node, HashSet<&'a Self::Node>> {
92 todo!()
93 }
94
95 fn get_simulation_naive(&'a self, other: &'a Self, l_match: &mut impl LMatch<Edge = Self::Edge>) -> HashMap<&'a Self::Node, HashSet<&'a Self::Node>> {
96
97 init_global_logger_once("hyper-simulation.log");
109
110 info!("Start Naive Hyper Simulation");
111
112 let self_contained_hyperedge = self.get_hyperedges_list();
113 let other_contained_hyperedge = other.get_hyperedges_list();
114
115 let mut simulation: HashMap<&Self::Node, HashSet<&Self::Node>> = self.nodes().map(|u| {
116 let res = other.nodes().filter(|v| {
117 if self.type_same(u, *v) {
118 let mut l_match_intersection: Option<HashSet<usize>> = None;
121 for e in self.contained_hyperedges(&self_contained_hyperedge, u) {
122 let mut l_match_union: HashSet<usize> = HashSet::new();
123 for e_prime in other.contained_hyperedges(&other_contained_hyperedge, v) {
124 if self.l_predicate_edge(e, e_prime) {
125 let id_set = l_match.l_match_with_node(e, e_prime, u.id());
127 l_match_union = l_match_union.union(&id_set).copied().collect();
128 }
129 }
130 l_match_intersection = match l_match_intersection {
131 Some(ref acc) => Some(acc.intersection(&l_match_union).copied().collect()),
132 None => Some(l_match_union),
133 };
134 }
135 if let Some(l_match_intersection) = l_match_intersection {
136 if l_match_intersection.contains(&v.id()){
137 return true;
138 }
139 }
140 }
141 false
142 }).collect();
143 (u, res)
144 }).collect();
145
146 info!("END Initial, sim: is ");
147 for (u, v_set) in &simulation {
148 info!("\tsim({}) = {:?}", u.id(), v_set.iter().map(|v| v.id()).collect::<Vec<_>>());
149 }
150
151
152 let mut changed = true;
153 while changed {
154 changed = false;
155 for u in self.nodes() {
156 let mut need_delete = Vec::new();
157 for v in simulation.get(u).unwrap() {
158 info!("Checking {} -> {}", u.id(), v.id());
159 let mut _delete = true;
160 for e in self.contained_hyperedges(&self_contained_hyperedge, u) {
161 if !_delete {
162 break;
163 }
164 for e_prime in other.contained_hyperedges(&other_contained_hyperedge, v) {
165 if self.l_predicate_edge(e, e_prime) {
166 if l_match.dom(e, e_prime).all(|u_prime| {
167 l_match.l_match_with_node(e, e_prime, u_prime.clone()).iter().map(|id| {other.get_node_by_id(*id)}).any(|v_prime| {
168 if let Some(v_prime) = v_prime {
169 return simulation.get(u).unwrap().contains(v_prime);
170 } else {
171 return false;
172 }
173 })
174 }) {
175 info!("Keeping {} -> {}", u.id(), v.id());
176 _delete = false;
177 break;
178 }
179 }
180 }
181 }
182 if _delete {
183 info!("Deleting {} -> {}", u.id(), v.id());
184 need_delete.push(v.clone());
185 }
186 }
187 for v in need_delete {
188 simulation.get_mut(u).unwrap().remove(v);
189 changed = true;
190 }
191 }
192 }
193
194 simulation
195 }
196
197 fn get_soft_simulation_naive(&'a self, other: &'a Self, l_match: &mut impl LMatch<Edge = Self::Edge>) -> HashMap<&'a Self::Node, HashSet<&'a Self::Node>> {
198 init_global_logger_once("hyper-simulation.log");
199
200 info!("Start Naive Hyper Simulation");
201
202 let mut l_predicate_edges: HashMap<(usize, usize), Vec<(&Self::Edge, &Self::Edge)>> = HashMap::new();
206 for e in self.hyperedges() {
207 for e_prime in other.hyperedges() {
208 if self.l_predicate_edge(e, e_prime) {
209 for u in e.id_set() {
210 for v in e_prime.id_set() {
211 l_predicate_edges.entry((u, v)).or_default().push((e, e_prime));
212 }
213 }
214 }
215 }
216 }
217
218 let mut simulation: HashMap<&'a Self::Node, HashSet<&'a Self::Node>> = self.nodes().map(|u| {
219 let res = other.nodes().filter(|v| {
220 if self.type_same(u, *v) {
221 if let Some(edge_pairs) = l_predicate_edges.get(&(u.id(), v.id())) {
222 for (e, e_prime) in edge_pairs {
223 let id_set = l_match.l_match_with_node(e, e_prime, u.id());
224 if !id_set.contains(&v.id()) {
225 return false;
226 }
227 }
228 return true;
229 } else {
230 return true;
231 }
232 }
233 false
234 }).collect();
235 (u, res)
236 }).collect();
237
238 info!("END Initial, sim: is ");
239 for (u, v_set) in &simulation {
240 info!("\tsim({}) = {:?}", u.id(), v_set.iter().map(|v| v.id()).collect::<Vec<_>>());
241 }
242
243
244 let mut changed = true;
245 while changed {
246 changed = false;
247 for u in self.nodes() {
248 let mut need_delete = Vec::new();
249 for v in simulation.get(u).unwrap() {
250 info!("Checking {} -> {}", u.id(), v.id());
251 let mut _delete = false;
252
253 if let Some(edge_pairs) = l_predicate_edges.get(&(u.id(), v.id())) {
254 for (e, e_prime) in edge_pairs {
255 if l_match.dom(e, e_prime).all(|u_prime| {
256 l_match.l_match_with_node(e, e_prime, u_prime.clone()).iter().map(|id| {other.get_node_by_id(*id)}).any(|v_prime| {
257 if let Some(v_prime) = v_prime {
258 return simulation.get(u).unwrap().contains(v_prime);
259 } else {
260 return false;
261 }
262 })
263 }) {
264 info!("Keeping {} -> {}", u.id(), v.id());
265 _delete = true;
266 break;
267 }
268 }
269 }
270
271 if _delete {
272 info!("Deleting {} -> {}", u.id(), v.id());
273 need_delete.push(v.clone());
274 }
275 }
276
277 for v in need_delete {
278 simulation.get_mut(u).unwrap().remove(v);
279 changed = true;
280 }
281 }
282 }
283
284 simulation
285
286 }
287
288 fn get_hyper_simulation_naive(&'a self, other: &'a Self, delta: &'a impl Delta<'a, Node = Self::Node, Edge = Self::Edge>, d_match: & impl DMatch<'a, Edge = Self::Edge>) -> HashMap<&'a Self::Node, HashSet<&'a Self::Node>> {
289 init_global_logger_once("hyper-simulation.log");
290
291 let mut simulation: HashMap<&'a Self::Node, HashSet<&'a Self::Node>> = self.nodes().map(|u| {
292 let res = other.nodes().filter(|v| {
293 if self.type_same(u, *v) {
294 let sematic_clusters = delta.get_sematic_clusters(u, v);
295 for (cluster_u, cluster_v) in sematic_clusters {
296 let d_match_set = d_match.d_match(cluster_u, cluster_v);
297 if !d_match_set.contains(&(u.id(), v.id())) {
298 return false;
299 }
300 }
301 return true;
302 }
303 false
304 }).collect();
305 (u, res)
306 }).collect();
307
308 info!("END Initial, sim: is ");
309 for (u, v_set) in &simulation {
310 info!("\tsim({}) = {:?}", u.id(), v_set.iter().map(|v| v.id()).collect::<Vec<_>>());
311 }
312
313 let mut simulation_by_id: HashSet<(usize, usize)> = simulation.iter().flat_map(|(u, v_set)| {
314 v_set.iter().map(move |v| (u.id(), v.id()))
315 }).collect();
316
317 let mut changed = true;
318 while changed {
319 changed = false;
320 for u in self.nodes() {
321 let mut need_delete = Vec::new();
322 for v in simulation.get(u).unwrap() {
323 info!("Checking {} -> {}", u.id(), v.id());
324 let mut _delete = false;
325
326 let sematic_clusters = delta.get_sematic_clusters(u, v);
327 for (cluster_u, cluster_v) in sematic_clusters {
328 let d_relation = d_match.d_match(cluster_u, cluster_v);
329 if !d_relation.is_subset(&simulation_by_id) {
331 info!("Keeping {} -> {}", u.id(), v.id());
332 _delete = true;
333 break;
334 }
335 }
336
337 if _delete {
338 info!("Deleting {} -> {}", u.id(), v.id());
339 need_delete.push(v.clone());
340 }
341 }
342
343 for v in need_delete {
344 simulation.get_mut(u).unwrap().remove(v);
345 simulation_by_id.remove(&(u.id(), v.id()));
346 changed = true;
347 }
348 }
349 }
350
351 return simulation;
352 }
353}