graph_simulation/utils/
predicate.rs

1
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}