1use std::collections::{HashMap, HashSet, VecDeque};
2use log::{info, warn};
3use serde::{Serialize, Deserialize};
8use std::fs::File;
9use std::io::{BufReader, BufWriter};
10use std::error::Error;
11
12
13use graph_base::interfaces::{edge::{DirectedHyperedge, Hyperedge}, graph::SingleId, hypergraph::{ContainedDirectedHyperedge, ContainedHyperedge, DirectedHypergraph, Hypergraph}, typed::{Type, Typed}};
14
15use crate::{algorithm::simulation, utils::logger::init_global_logger_once};
16use crate::utils::logger::TraceLog;
17
18pub trait LMatch {
19 type Edge;
20 fn new() -> Self;
22 fn l_match_with_node_mut(&mut self, e: &Self::Edge, e_prime: &Self::Edge, u: usize) -> &HashSet<usize>;
23 fn l_match_with_node(&self, e: &Self::Edge, e_prime: &Self::Edge, u: usize) -> &HashSet<usize>;
24 fn dom(&self, e: &Self::Edge, e_prime: &Self::Edge) -> impl Iterator<Item = &usize>;
25}
26
27#[derive(Hash)]
28pub struct SematicCluster<'a, E: Hyperedge> {
29 id: usize,
30 hyperedges: Vec<&'a E>,
31}
32
33impl<'a, E: Hyperedge> SematicCluster<'a, E> {
34
35 pub fn new(id: usize, hyperedges: Vec<&'a E>) -> Self {
36 Self {
37 id,
38 hyperedges,
39 }
40 }
41
42 pub fn id(&self) -> usize {
43 self.id
44 }
45
46 pub fn hyperedges(&self) -> &Vec<&'a E> {
47 &self.hyperedges
48 }
49}
50
51pub trait Delta<'a> {
52 type Node;
53 type Edge: Hyperedge;
54 fn get_sematic_clusters(&'a self, u: &'a Self::Node, v: &'a Self::Node) -> &'a Vec<(SematicCluster<'a, Self::Edge>, SematicCluster<'a, Self::Edge>)>;
55}
56
57pub trait DMatch<'a> {
58 type Edge: Hyperedge;
59 fn d_match(&self, e: &SematicCluster<'a, Self::Edge>, e_prime: &SematicCluster<'a, Self::Edge>) -> &HashSet<(usize, usize)>;
61}
62
63pub trait LPredicate<'a>: Hypergraph<'a> {
64 fn l_predicate_node(&'a self, u: &'a Self::Node, v: &'a Self::Node) -> bool;
65 fn l_predicate_edge(&'a self, e: &'a Self::Edge, e_prime: &'a Self::Edge) -> bool;
66 fn l_predicate_set(&'a self, x: &HashSet<&'a Self::Node>, y: &HashSet<&'a Self::Node>) -> bool;
67}
68
69pub trait HyperSimulation<'a>: Hypergraph<'a> {
70 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>>;
71 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>>;
72 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>>;
73 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>>;
74 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>>;
75 fn get_hyper_simulation_effect(&'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>>;
76 fn get_hyper_simulation_strict(&'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>>;
77}
78impl<'a, H> HyperSimulation<'a> for H
97where H: Hypergraph<'a> + Typed<'a> + LPredicate<'a> + ContainedHyperedge<'a> {
98 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>> {
99 todo!()
100 }
101
102 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>> {
103 todo!()
104 }
105
106 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>> {
107
108 init_global_logger_once("hyper-simulation.log");
120
121 info!("Start Naive Hyper Simulation");
122
123 let self_contained_hyperedge = self.get_hyperedges_list();
124 let other_contained_hyperedge = other.get_hyperedges_list();
125
126 let mut simulation: HashMap<&Self::Node, HashSet<&Self::Node>> = self.nodes().map(|u| {
127 let res = other.nodes().filter(|v| {
128 if self.type_same(u, *v) {
129 let mut l_match_intersection: Option<HashSet<usize>> = None;
132 for e in self.contained_hyperedges(&self_contained_hyperedge, u) {
133 let mut l_match_union: HashSet<usize> = HashSet::new();
134 for e_prime in other.contained_hyperedges(&other_contained_hyperedge, v) {
135 if self.l_predicate_edge(e, e_prime) {
136 let id_set = l_match.l_match_with_node(e, e_prime, u.id());
138 l_match_union = l_match_union.union(&id_set).copied().collect();
139 }
140 }
141 l_match_intersection = match l_match_intersection {
142 Some(ref acc) => Some(acc.intersection(&l_match_union).copied().collect()),
143 None => Some(l_match_union),
144 };
145 }
146 if let Some(l_match_intersection) = l_match_intersection {
147 if l_match_intersection.contains(&v.id()){
148 return true;
149 }
150 }
151 }
152 false
153 }).collect();
154 (u, res)
155 }).collect();
156
157 info!("END Initial, sim: is ");
158 for (u, v_set) in &simulation {
159 info!("\tsim({}) = {:?}", u.id(), v_set.iter().map(|v| v.id()).collect::<Vec<_>>());
160 }
161
162
163 let mut changed = true;
164 while changed {
165 changed = false;
166 for u in self.nodes() {
167 let mut need_delete = Vec::new();
168 for v in simulation.get(u).unwrap() {
169 info!("Checking {} -> {}", u.id(), v.id());
170 let mut _delete = true;
171 for e in self.contained_hyperedges(&self_contained_hyperedge, u) {
172 if !_delete {
173 break;
174 }
175 for e_prime in other.contained_hyperedges(&other_contained_hyperedge, v) {
176 if self.l_predicate_edge(e, e_prime) {
177 if l_match.dom(e, e_prime).all(|u_prime| {
178 l_match.l_match_with_node(e, e_prime, u_prime.clone()).iter().map(|id| {other.get_node_by_id(*id)}).any(|v_prime| {
179 if let Some(v_prime) = v_prime {
180 return simulation.get(u).unwrap().contains(v_prime);
181 } else {
182 return false;
183 }
184 })
185 }) {
186 info!("Keeping {} -> {}", u.id(), v.id());
187 _delete = false;
188 break;
189 }
190 }
191 }
192 }
193 if _delete {
194 info!("Deleting {} -> {}", u.id(), v.id());
195 need_delete.push(v.clone());
196 }
197 }
198 for v in need_delete {
199 simulation.get_mut(u).unwrap().remove(v);
200 changed = true;
201 }
202 }
203 }
204
205 simulation
206 }
207
208 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>> {
209 init_global_logger_once("hyper-simulation.log");
210
211 info!("Start Naive Hyper Simulation");
212
213 let mut l_predicate_edges: HashMap<(usize, usize), Vec<(&Self::Edge, &Self::Edge)>> = HashMap::new();
217 for e in self.hyperedges() {
218 for e_prime in other.hyperedges() {
219 if self.l_predicate_edge(e, e_prime) {
220 for u in e.id_set() {
221 for v in e_prime.id_set() {
222 l_predicate_edges.entry((u, v)).or_default().push((e, e_prime));
223 }
224 }
225 }
226 }
227 }
228
229 let mut simulation: HashMap<&'a Self::Node, HashSet<&'a Self::Node>> = self.nodes().map(|u| {
230 let res = other.nodes().filter(|v| {
231 if self.type_same(u, *v) {
232 if let Some(edge_pairs) = l_predicate_edges.get(&(u.id(), v.id())) {
233 for (e, e_prime) in edge_pairs {
234 let id_set = l_match.l_match_with_node(e, e_prime, u.id());
235 if !id_set.contains(&v.id()) {
236 return false;
237 }
238 }
239 return true;
240 } else {
241 return true;
242 }
243 }
244 false
245 }).collect();
246 (u, res)
247 }).collect();
248
249 info!("END Initial, sim: is ");
250 for (u, v_set) in &simulation {
251 info!("\tsim({}) = {:?}", u.id(), v_set.iter().map(|v| v.id()).collect::<Vec<_>>());
252 }
253
254
255 let mut changed = true;
256 while changed {
257 changed = false;
258 for u in self.nodes() {
259 let mut need_delete = Vec::new();
260 for v in simulation.get(u).unwrap() {
261 info!("Checking {} -> {}", u.id(), v.id());
262 let mut _delete = false;
263
264 if let Some(edge_pairs) = l_predicate_edges.get(&(u.id(), v.id())) {
265 for (e, e_prime) in edge_pairs {
266 if l_match.dom(e, e_prime).all(|u_prime| {
267 l_match.l_match_with_node(e, e_prime, u_prime.clone()).iter().map(|id| {other.get_node_by_id(*id)}).any(|v_prime| {
268 if let Some(v_prime) = v_prime {
269 return simulation.get(u).unwrap().contains(v_prime);
270 } else {
271 return false;
272 }
273 })
274 }) {
275 info!("Keeping {} -> {}", u.id(), v.id());
276 _delete = true;
277 break;
278 }
279 }
280 }
281
282 if _delete {
283 info!("Deleting {} -> {}", u.id(), v.id());
284 need_delete.push(v.clone());
285 }
286 }
287
288 for v in need_delete {
289 simulation.get_mut(u).unwrap().remove(v);
290 changed = true;
291 }
292 }
293 }
294
295 simulation
296
297 }
298
299 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>> {
300 init_global_logger_once("logs/hyper-simulation.log");
301 let mut hs_trace = HyperSimulationTrace::new();
302 let mut simulation: HashMap<&'a Self::Node, HashSet<&'a Self::Node>> = self.nodes().map(|u| {
303 let res = other.nodes().filter(|v| {
304 if self.type_same(u, *v) {
305 let sematic_clusters = delta.get_sematic_clusters(u, v);
306 for (cluster_u, cluster_v) in sematic_clusters {
307 let d_match_set = d_match.d_match(cluster_u, cluster_v);
308 if !d_match_set.contains(&(u.id(), v.id())) {
309 hs_trace.add_base_event(cluster_u.id, d_match_set.clone());
311 return false;
312 }
313 }
314 return true;
315 }
316 false
317 }).collect();
318 (u, res)
319 }).collect();
320
321 info!("END Initial, raw-sim: is ");
322 for (u, v_set) in &simulation {
323 info!("\tsim({}) = {:?}", u.id(), v_set.iter().map(|v| v.id()).collect::<Vec<_>>());
324 }
325
326 let mut simulation_by_id: HashSet<(usize, usize)> = simulation.iter().flat_map(|(u, v_set)| {
327 v_set.iter().map(move |v| (u.id(), v.id()))
328 }).collect();
329
330 let mut changed = true;
331 while changed {
332 changed = false;
333 for u in self.nodes() {
334 let mut need_delete = Vec::new();
335 for v in simulation.get(u).unwrap() {
336 info!("Checking {} -> {}", u.id(), v.id());
337 let mut _delete = false;
338
339 let sematic_clusters = delta.get_sematic_clusters(u, v);
340 for (cluster_u, cluster_v) in sematic_clusters {
341 let d_relation = d_match.d_match(cluster_u, cluster_v);
342 if !d_relation.is_subset(&simulation_by_id) {
344 info!("Deleting {} -> {}", u.id(), v.id());
345 let uncoverd: HashSet<(usize, usize)> = d_relation.difference(&simulation_by_id).copied().collect();
347 hs_trace.add_derivation_event(cluster_u.id, uncoverd);
348 _delete = true;
349 break;
350 }
351 }
352
353 if _delete {
354 need_delete.push(v.clone());
355 }
356 }
357
358 for v in need_delete {
359 simulation.get_mut(u).unwrap().remove(v);
360 simulation_by_id.remove(&(u.id(), v.id()));
361 changed = true;
362 }
363 }
364 }
365
366 hs_trace.store_trace_file("logs/hyper_simulation.trace").unwrap();
367
368 return simulation;
369 }
370
371 fn get_hyper_simulation_strict(&'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>> {
372 init_global_logger_once("logs/hyper-simulation.log");
373 let mut hs_trace = HyperSimulationTrace::new();
374 let mut simulation: HashMap<&'a Self::Node, HashSet<&'a Self::Node>> = self.nodes().map(|u| {
375 let res = other.nodes().filter(|v| {
376 if self.type_same(u, *v) {
377 let sematic_clusters = delta.get_sematic_clusters(u, v);
378 if sematic_clusters.len() == 0 {
380 info!("Deleting {} -> {} because no sematic cluster", u.id(), v.id());
381 return false;
382 }
383 info!("Checking {} -> {}, sematic clusters size: {}", u.id(), v.id(), sematic_clusters.len());
384 for (cluster_u, cluster_v) in sematic_clusters {
385 let d_match_set = d_match.d_match(cluster_u, cluster_v);
386 if !d_match_set.contains(&(u.id(), v.id())) {
387 hs_trace.add_base_event(cluster_u.id, d_match_set.clone());
389 return false;
390 }
391 }
392 return true;
393 }
394 false
395 }).collect();
396 (u, res)
397 }).collect();
398
399 info!("END Initial, raw-sim: is ");
400 for (u, v_set) in &simulation {
401 info!("\tsim({}) = {:?}", u.id(), v_set.iter().map(|v| v.id()).collect::<Vec<_>>());
402 }
403
404 let mut simulation_by_id: HashSet<(usize, usize)> = simulation.iter().flat_map(|(u, v_set)| {
405 v_set.iter().map(move |v| (u.id(), v.id()))
406 }).collect();
407
408 let mut changed = true;
409 while changed {
410 changed = false;
411 for u in self.nodes() {
412 let mut need_delete = Vec::new();
413 for v in simulation.get(u).unwrap() {
414 info!("Checking {} -> {}", u.id(), v.id());
415 let mut _delete = false;
416
417 let sematic_clusters = delta.get_sematic_clusters(u, v);
418 for (cluster_u, cluster_v) in sematic_clusters {
419 let d_relation = d_match.d_match(cluster_u, cluster_v);
420 if !d_relation.is_subset(&simulation_by_id) {
422 info!("Deleting {} -> {}", u.id(), v.id());
423 let uncoverd: HashSet<(usize, usize)> = d_relation.difference(&simulation_by_id).copied().collect();
425 hs_trace.add_derivation_event(cluster_u.id, uncoverd);
426 _delete = true;
427 break;
428 }
429 }
430
431 if _delete {
432 need_delete.push(v.clone());
433 }
434 }
435
436 for v in need_delete {
437 simulation.get_mut(u).unwrap().remove(v);
438 simulation_by_id.remove(&(u.id(), v.id()));
439 changed = true;
440 }
441 }
442 }
443
444 hs_trace.store_trace_file("logs/hyper_simulation.trace").unwrap();
445
446 return simulation;
447 }
448
449 fn get_hyper_simulation_effect(
450 &'a self,
451 other: &'a Self,
452 delta: &'a impl Delta<'a, Node = Self::Node, Edge = Self::Edge>,
453 d_match: &impl DMatch<'a, Edge = Self::Edge>,
454 ) -> HashMap<&'a Self::Node, HashSet<&'a Self::Node>> {
455
456 init_global_logger_once("logs/hyper-simulation.log");
457
458 let mut id_to_u: HashMap<usize, &'a Self::Node> = HashMap::new();
460 let mut id_to_v: HashMap<usize, &'a Self::Node> = HashMap::new();
461
462 let mut hc_map: HashMap<(usize, usize), Vec<((usize, usize), HashSet<(usize, usize)>)>> = HashMap::new();
464
465 let mut pi: HashSet<(usize, usize)> = HashSet::new();
467
468 for u in self.nodes() {
474 id_to_u.insert(u.id(), u);
475 for v in other.nodes() {
476 id_to_v.insert(v.id(), v);
477
478 if self.type_same(u, v) {
479 let sematic_clusters = delta.get_sematic_clusters(u, v);
480 let mut valid = true;
481 let mut local_clusters = Vec::new();
482
483 for (cluster_u, cluster_v) in sematic_clusters {
484 let cu_id = cluster_u.id;
485 let cv_id = cluster_v.id;
486 let d_match_set = d_match.d_match(cluster_u, cluster_v);
487
488 if !d_match_set.contains(&(u.id(), v.id())) {
490 valid = false;
491 break; }
493 local_clusters.push(((cu_id, cv_id), d_match_set.clone()));
494 }
495
496 if valid {
497 pi.insert((u.id(), v.id()));
498 hc_map.insert((u.id(), v.id()), local_clusters);
499 }
500 }
501 }
502 }
503
504 let mut a_cluster_d_match: HashMap<(usize, usize), HashSet<(usize, usize)>> = HashMap::new();
506
507 let mut d_cluster: HashMap<(usize, usize), HashSet<(usize, usize)>> = HashMap::new();
510 let mut d_pair: HashMap<(usize, usize), HashSet<(usize, usize)>> = HashMap::new();
512
513 for (&(u_id, v_id), clusters) in &hc_map {
514 for ((cu_id, cv_id), d_match_set) in clusters {
515 let c_pair = (*cu_id, *cv_id);
516
517 d_cluster.entry(c_pair).or_default().insert((u_id, v_id));
519
520 if !a_cluster_d_match.contains_key(&c_pair) {
522 a_cluster_d_match.insert(c_pair, d_match_set.clone());
523
524 for &(up_id, vp_id) in d_match_set {
525 d_pair.entry((up_id, vp_id)).or_default().insert(c_pair);
526 }
527 }
528 }
529 }
530
531 info!("1. 初始化 Pi 并获取 HC 和 D-match");
532
533 let mut v_c: HashSet<(usize, usize)> = HashSet::new();
535 for (c_pair, d_match_set) in &a_cluster_d_match {
536 if d_match_set.is_subset(&pi) {
538 v_c.insert(*c_pair);
539 }
540 }
541
542 info!("2. 初始化 V_C (Valid Clusters)");
543
544 let mut q: VecDeque<(usize, usize)> = VecDeque::new();
546 let mut pi_retained = pi.clone();
547
548 for &(u_id, v_id) in &pi {
549 let mut all_in_vc = true;
550 if let Some(clusters) = hc_map.get(&(u_id, v_id)) {
551 for (c_pair, _) in clusters {
552 if !v_c.contains(c_pair) {
553 all_in_vc = false;
554 break;
555 }
556 }
557 }
558
559 if !all_in_vc {
560 q.push_back((u_id, v_id)); pi_retained.remove(&(u_id, v_id)); }
563 }
564 pi = pi_retained;
565
566 info!("3. 找出失效的 (u, v) 加入队列 Q");
567
568 while let Some((up_id, vp_id)) = q.pop_front() {
572 if let Some(dependent_clusters) = d_pair.get(&(up_id, vp_id)) {
574 for c_pair in dependent_clusters {
575 if v_c.contains(c_pair) {
577 v_c.remove(c_pair); if let Some(dependent_node_pairs) = d_cluster.get(c_pair) {
581 for node_pair in dependent_node_pairs {
582 if pi.contains(node_pair) {
583 pi.remove(node_pair);
584 q.push_back(*node_pair);
585 }
586 }
587 }
588 }
589 }
590 }
591 }
592
593 info!("结束了主调用");
594
595 let mut result: HashMap<&'a Self::Node, HashSet<&'a Self::Node>> =
600 self.nodes().map(|u| (u, HashSet::new())).collect();
601
602 for (u_id, v_id) in pi {
603 let u_node = id_to_u[&u_id];
605 let v_node = id_to_v[&v_id];
606 if let Some(set) = result.get_mut(u_node) {
607 set.insert(v_node);
608 }
609 }
610
611 result
612 }
613}
614
615#[derive(Serialize, Deserialize, Debug, PartialEq)]
616pub struct HyperSimulationTrace {
617 events: Vec<HSEvent>
618}
619
620impl HyperSimulationTrace {
621 fn new() -> Self {
622 HyperSimulationTrace {
623 events: Vec::new()
624 }
625 }
626
627 fn add_base_event(&mut self, sc_id: usize, d_match: HashSet<(usize, usize)>) {
628 let event = HSEvent::Base(sc_id, d_match);
629 self.events.push(event);
630 }
631 fn add_derivation_event(&mut self, sc_id: usize, uncoverd: HashSet<(usize, usize)>) {
632 let event = HSEvent::Derivation(sc_id, uncoverd);
633 self.events.push(event);
634 }
635}
636
637impl IntoIterator for HyperSimulationTrace {
638 type Item = HSEvent;
639 type IntoIter = std::vec::IntoIter<HSEvent>;
640
641 fn into_iter(self) -> Self::IntoIter {
642 self.events.into_iter()
643 }
644}
645
646impl<'a> IntoIterator for &'a HyperSimulationTrace {
647 type Item = &'a HSEvent;
648 type IntoIter = std::slice::Iter<'a, HSEvent>;
649
650 fn into_iter(self) -> Self::IntoIter {
651 self.events.iter()
652 }
653}
654
655impl TraceLog for HyperSimulationTrace {
656 fn store_trace_file(self, filename: &'static str) -> Result<(), Box<dyn Error>> {
657 let file = File::create(filename)?;
659 let mut writer = BufWriter::new(file);
660 bincode::serialize_into(&mut writer, &self)?;
661 Ok(())
662 }
663
664 fn get_trace(filename: &'static str) -> Result<Self, Box<dyn Error>> {
665 let file = File::open(filename)?;
666 let mut reader = BufReader::new(file);
667 let file_decoded: HyperSimulationTrace = bincode::deserialize_from(&mut reader)?;
668 Ok(file_decoded)
669 }
670}
671
672#[derive(Serialize, Deserialize, Debug, PartialEq)]
673pub enum HSEvent {
674 Base(usize, HashSet<(usize, usize)>), Derivation(usize, HashSet<(usize, usize)>) }