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
23pub trait Delta<'a> {
24 type Node;
25 type Edge: Hyperedge;
26 fn get_sematic_clusters(&self, u: &'a Self::Node, v: &'a Self::Node) -> &'a Vec<(SematicCluster<'a, Self::Edge>, SematicCluster<'a, Self::Edge>)>;
27}
28
29pub trait DMatch<'a> {
30 type Edge: Hyperedge;
31 fn new() -> Self;
32 fn d_match_mut(&mut self, e: &SematicCluster<'a, Self::Edge>, e_prime: &SematicCluster<'a, Self::Edge>) -> &HashSet<(usize, usize)>;
33 fn d_match(&self, e: &SematicCluster<'a, Self::Edge>, e_prime: &SematicCluster<'a, Self::Edge>) -> &HashSet<(usize, usize)>;
34}
35
36pub trait LPredicate<'a>: Hypergraph<'a> {
37 fn l_predicate_node(&'a self, u: &'a Self::Node, v: &'a Self::Node) -> bool;
38 fn l_predicate_edge(&'a self, e: &'a Self::Edge, e_prime: &'a Self::Edge) -> bool;
39 fn l_predicate_set(&'a self, x: &HashSet<&'a Self::Node>, y: &HashSet<&'a Self::Node>) -> bool;
40}
41
42pub trait HyperSimulation<'a>: Hypergraph<'a> {
43
44 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>>;
45 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>>;
46 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>>;
47 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>>;
48 fn get_hyper_simulation_naive(&'a self, other: &'a Self, delta: &impl Delta<'a, Node = Self::Node, Edge = Self::Edge>, d_match: &mut impl DMatch<'a, Edge = Self::Edge>) -> HashMap<&'a Self::Node, HashSet<&'a Self::Node>>;
49}
50
51impl<'a, H> HyperSimulation<'a> for H
70where H: Hypergraph<'a> + Typed<'a> + LPredicate<'a> + ContainedHyperedge<'a> {
71 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>> {
72 todo!()
73 }
74
75 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>> {
76 todo!()
77 }
78
79 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>> {
80
81 init_global_logger_once("hyper-simulation.log");
93
94 info!("Start Naive Hyper Simulation");
95
96 let self_contained_hyperedge = self.get_hyperedges_list();
97 let other_contained_hyperedge = other.get_hyperedges_list();
98
99 let mut simulation: HashMap<&Self::Node, HashSet<&Self::Node>> = self.nodes().map(|u| {
100 let res = other.nodes().filter(|v| {
101 if self.type_same(u, *v) {
102 let mut l_match_intersection: Option<HashSet<usize>> = None;
105 for e in self.contained_hyperedges(&self_contained_hyperedge, u) {
106 let mut l_match_union: HashSet<usize> = HashSet::new();
107 for e_prime in other.contained_hyperedges(&other_contained_hyperedge, v) {
108 if self.l_predicate_edge(e, e_prime) {
109 let id_set = l_match.l_match_with_node_mut(e, e_prime, u.id());
111 l_match_union = l_match_union.union(&id_set).copied().collect();
112 }
113 }
114 l_match_intersection = match l_match_intersection {
115 Some(ref acc) => Some(acc.intersection(&l_match_union).copied().collect()),
116 None => Some(l_match_union),
117 };
118 }
119 if let Some(l_match_intersection) = l_match_intersection {
120 if l_match_intersection.contains(&v.id()){
121 return true;
122 }
123 }
124 }
125 false
126 }).collect();
127 (u, res)
128 }).collect();
129
130 info!("END Initial, sim: is ");
131 for (u, v_set) in &simulation {
132 info!("\tsim({}) = {:?}", u.id(), v_set.iter().map(|v| v.id()).collect::<Vec<_>>());
133 }
134
135
136 let mut changed = true;
137 while changed {
138 changed = false;
139 for u in self.nodes() {
140 let mut need_delete = Vec::new();
141 for v in simulation.get(u).unwrap() {
142 info!("Checking {} -> {}", u.id(), v.id());
143 let mut _delete = true;
144 for e in self.contained_hyperedges(&self_contained_hyperedge, u) {
145 if !_delete {
146 break;
147 }
148 for e_prime in other.contained_hyperedges(&other_contained_hyperedge, v) {
149 if self.l_predicate_edge(e, e_prime) {
150 if l_match.dom(e, e_prime).all(|u_prime| {
151 l_match.l_match_with_node(e, e_prime, u_prime.clone()).iter().map(|id| {other.get_node_by_id(*id)}).any(|v_prime| {
152 if let Some(v_prime) = v_prime {
153 return simulation.get(u).unwrap().contains(v_prime);
154 } else {
155 return false;
156 }
157 })
158 }) {
159 info!("Keeping {} -> {}", u.id(), v.id());
160 _delete = false;
161 break;
162 }
163 }
164 }
165 }
166 if _delete {
167 info!("Deleting {} -> {}", u.id(), v.id());
168 need_delete.push(v.clone());
169 }
170 }
171 for v in need_delete {
172 simulation.get_mut(u).unwrap().remove(v);
173 changed = true;
174 }
175 }
176 }
177
178 simulation
179 }
180
181 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>> {
182 init_global_logger_once("hyper-simulation.log");
183
184 info!("Start Naive Hyper Simulation");
185
186 let mut l_predicate_edges: HashMap<(usize, usize), Vec<(&Self::Edge, &Self::Edge)>> = HashMap::new();
190 for e in self.hyperedges() {
191 for e_prime in other.hyperedges() {
192 if self.l_predicate_edge(e, e_prime) {
193 for u in e.id_set() {
194 for v in e_prime.id_set() {
195 l_predicate_edges.entry((u, v)).or_default().push((e, e_prime));
196 }
197 }
198 }
199 }
200 }
201
202 let mut simulation: HashMap<&'a Self::Node, HashSet<&'a Self::Node>> = self.nodes().map(|u| {
203 let res = other.nodes().filter(|v| {
204 if self.type_same(u, *v) {
205 if let Some(edge_pairs) = l_predicate_edges.get(&(u.id(), v.id())) {
206 for (e, e_prime) in edge_pairs {
207 let id_set = l_match.l_match_with_node(e, e_prime, u.id());
208 if !id_set.contains(&v.id()) {
209 return false;
210 }
211 }
212 return true;
213 } else {
214 return true;
215 }
216 }
217 false
218 }).collect();
219 (u, res)
220 }).collect();
221
222 info!("END Initial, sim: is ");
223 for (u, v_set) in &simulation {
224 info!("\tsim({}) = {:?}", u.id(), v_set.iter().map(|v| v.id()).collect::<Vec<_>>());
225 }
226
227
228 let mut changed = true;
229 while changed {
230 changed = false;
231 for u in self.nodes() {
232 let mut need_delete = Vec::new();
233 for v in simulation.get(u).unwrap() {
234 info!("Checking {} -> {}", u.id(), v.id());
235 let mut _delete = false;
236
237 if let Some(edge_pairs) = l_predicate_edges.get(&(u.id(), v.id())) {
238 for (e, e_prime) in edge_pairs {
239 if l_match.dom(e, e_prime).all(|u_prime| {
240 l_match.l_match_with_node(e, e_prime, u_prime.clone()).iter().map(|id| {other.get_node_by_id(*id)}).any(|v_prime| {
241 if let Some(v_prime) = v_prime {
242 return simulation.get(u).unwrap().contains(v_prime);
243 } else {
244 return false;
245 }
246 })
247 }) {
248 info!("Keeping {} -> {}", u.id(), v.id());
249 _delete = true;
250 break;
251 }
252 }
253 }
254
255 if _delete {
256 info!("Deleting {} -> {}", u.id(), v.id());
257 need_delete.push(v.clone());
258 }
259 }
260
261 for v in need_delete {
262 simulation.get_mut(u).unwrap().remove(v);
263 changed = true;
264 }
265 }
266 }
267
268 simulation
269
270 }
271
272 fn get_hyper_simulation_naive(&'a self, other: &'a Self, delta: &impl Delta<'a, Node = Self::Node, Edge = Self::Edge>, d_match: &mut impl DMatch<'a, Edge = Self::Edge>) -> HashMap<&'a Self::Node, HashSet<&'a Self::Node>> {
273 init_global_logger_once("hyper-simulation.log");
274
275 let mut simulation: HashMap<&'a Self::Node, HashSet<&'a Self::Node>> = self.nodes().map(|u| {
276 let res = other.nodes().filter(|v| {
277 if self.type_same(u, *v) {
278 let sematic_clusters = delta.get_sematic_clusters(u, v);
279 for (cluster_u, cluster_v) in sematic_clusters {
280 let d_match_set = d_match.d_match_mut(cluster_u, cluster_v);
281 if !d_match_set.contains(&(u.id(), v.id())) {
282 return false;
283 }
284 }
285 return true;
286 }
287 false
288 }).collect();
289 (u, res)
290 }).collect();
291
292 info!("END Initial, sim: is ");
293 for (u, v_set) in &simulation {
294 info!("\tsim({}) = {:?}", u.id(), v_set.iter().map(|v| v.id()).collect::<Vec<_>>());
295 }
296
297 let mut simulation_by_id: HashSet<(usize, usize)> = simulation.iter().flat_map(|(u, v_set)| {
298 v_set.iter().map(move |v| (u.id(), v.id()))
299 }).collect();
300
301 let mut changed = true;
302 while changed {
303 changed = false;
304 for u in self.nodes() {
305 let mut need_delete = Vec::new();
306 for v in simulation.get(u).unwrap() {
307 info!("Checking {} -> {}", u.id(), v.id());
308 let mut _delete = false;
309
310 let sematic_clusters = delta.get_sematic_clusters(u, v);
311 for (cluster_u, cluster_v) in sematic_clusters {
312 let d_relation = d_match.d_match(cluster_u, cluster_v);
313 if !d_relation.is_subset(&simulation_by_id) {
315 info!("Keeping {} -> {}", u.id(), v.id());
316 _delete = true;
317 break;
318 }
319 }
320
321 if _delete {
322 info!("Deleting {} -> {}", u.id(), v.id());
323 need_delete.push(v.clone());
324 }
325 }
326
327 for v in need_delete {
328 simulation.get_mut(u).unwrap().remove(v);
329 simulation_by_id.remove(&(u.id(), v.id()));
330 changed = true;
331 }
332 }
333 }
334
335 return simulation;
336 }
337}