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