graph_simulation/utils/
predicate.rs1
2use std::{collections::{HashMap, HashSet}, hash::Hash};
3use rand_pcg::Pcg64;
4use lazy_static::lazy_static;
5use crate::utils::validation::Node;
6use serde::{Serialize, Deserialize};
7use fxhash::FxHashMap;
8use rand::{prelude::*, rng};
9use std::sync::RwLock;
10lazy_static!{
11 static ref l_save: RwLock<LSave> = RwLock::new(LSave::from_file());
12}
13
14#[derive(Serialize, Deserialize, PartialEq, Eq)]
15struct Hyperedge((HashSet<Node>, HashSet<Node>));
16
17impl Hash for Hyperedge {
18 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
19 for node in &self.0 .0 {
20 node.hash(state);
21 }
22 for node in &self.0 .1 {
23 node.hash(state);
24 }
25 }
26}
27
28#[derive(Serialize, Deserialize)]
29struct LSave {
30 l_predicate_node: FxHashMap<(Node, Node), bool>,
31 l_predicate_node_set: FxHashMap<Hyperedge, bool>,
32 l_match: FxHashMap<Hyperedge, HashMap<Node, Node>>,
33}
34
35impl LSave {
36 pub fn from_file() -> Self {
37 let file = std::fs::File::open("lsave_backup.json").expect("Unable to open file");
38 let reader = std::io::BufReader::new(file);
39 serde_json::from_reader(reader).expect("Unable to parse JSON")
40 }
41
42 fn l_predicate_node(&mut self, x: &Node, y: &Node, p: f64) -> bool {
43 if let Some(&result) = self.l_predicate_node.get(&(x.clone(), y.clone())) {
44 return result;
45 }
46 let mut rng = rng();
47 let result = rng.random_bool(p);
48 self.l_predicate_node.insert((x.clone(), y.clone()), result);
49 result
50 }
51
52 fn l_predicate_node_set(&mut self, x: &HashSet<Node>, y: &HashSet<Node>, p: f64) -> bool {
53 let hyperedge = Hyperedge((x.clone(), y.clone()));
54 if let Some(&result) = self.l_predicate_node_set.get(&hyperedge) {
55 return result;
56 }
57 let mut rng = rng();
58 let result = rng.random_bool(p);
59 self.l_predicate_node_set.insert(hyperedge, result);
60 result
61 }
62
63 fn l_match(&mut self, x: &HashSet<Node>, y: &HashSet<Node>, p: f64) -> HashMap<Node, Node> {
64 let hyperedge = Hyperedge((x.clone(), y.clone()));
65 if let Some(result) = self.l_match.get(&hyperedge) {
66 return result.clone();
67 }
68 let mut rng = rng();
69 let mut used = HashSet::new();
70 let mut result = HashMap::new();
71 for node_x in x {
72 let mut min = 1.0;
73 let mut min_node = None;
74 for node_y in y {
75 if !used.contains(node_y) {
76 let value = node_x.clone() ^ node_y.clone();
77 if value < min {
78 min = value;
79 min_node = Some(node_y);
80 }
81 }
82 if let Some(node_y) = min_node {
83 used.insert(node_y.clone());
84 result.insert(node_x.clone(), node_y.clone());
85 }
86 }
87 }
88 let mut final_result = HashMap::new();
89 for (key, value) in result {
90 if rng.random_bool(p) {
91 final_result.insert(key, value);
92 }
93 }
94 self.l_match.insert(hyperedge, final_result.clone());
95 final_result
96 }
97}
98
99impl Drop for LSave {
100 fn drop(&mut self) {
101 let file = std::fs::File::create("lsave_backup.json").expect("Unable to create file");
102 let writer = std::io::BufWriter::new(file);
103 serde_json::to_writer(writer, self).expect("Unable to write JSON");
104 }
105}
106
107pub fn l_predicate_node(x: &Node, y: &Node, p: f64) -> bool {
108 l_save.write().unwrap().l_predicate_node(x, y, p)
109}
110
111pub fn l_predicate_node_set(x: &HashSet<Node>, y: &HashSet<Node>, p: f64) -> bool {
112 l_save.write().unwrap().l_predicate_node_set(x, y, p)
113}
114
115pub fn l_match(x: &HashSet<Node>, y: &HashSet<Node>, p: f64) -> HashMap<Node, Node> {
116 l_save.write().unwrap().l_match(x, y, p)
117}