graph-simulation 0.1.29

A library for simulation algorithm
Documentation

use std::{collections::{HashMap, HashSet}, hash::Hash};
use rand_pcg::Pcg64;
use lazy_static::lazy_static;
use crate::utils::validation::Node;
use serde::{Serialize, Deserialize};
use fxhash::FxHashMap;
use rand::{prelude::*, rng};
use std::sync::RwLock;
lazy_static!{
    static ref l_save: RwLock<LSave> = RwLock::new(LSave::from_file());
}

#[derive(Serialize, Deserialize, PartialEq, Eq)]
struct Hyperedge((HashSet<Node>, HashSet<Node>));

impl Hash for Hyperedge {
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
        for node in &self.0 .0 {
            node.hash(state);
        }
        for node in &self.0 .1 {
            node.hash(state);
        }
    }
}

#[derive(Serialize, Deserialize)]
struct LSave {
    l_predicate_node: FxHashMap<(Node, Node), bool>,
    l_predicate_node_set: FxHashMap<Hyperedge, bool>,
    l_match: FxHashMap<Hyperedge, HashMap<Node, Node>>,
}

impl LSave {
    pub fn from_file() -> Self {
        let file = std::fs::File::open("lsave_backup.json").expect("Unable to open file");
        let reader = std::io::BufReader::new(file);
        serde_json::from_reader(reader).expect("Unable to parse JSON")
    }

    fn l_predicate_node(&mut self, x: &Node, y: &Node, p: f64) -> bool {
        if let Some(&result) = self.l_predicate_node.get(&(x.clone(), y.clone())) {
            return result;
        }
        let mut rng = rng();
        let result = rng.random_bool(p);
        self.l_predicate_node.insert((x.clone(), y.clone()), result);
        result
    }

    fn l_predicate_node_set(&mut self, x: &HashSet<Node>, y: &HashSet<Node>, p: f64) -> bool {
        let hyperedge = Hyperedge((x.clone(), y.clone()));
        if let Some(&result) = self.l_predicate_node_set.get(&hyperedge) {
            return result;
        }
        let mut rng = rng();
        let result = rng.random_bool(p);
        self.l_predicate_node_set.insert(hyperedge, result);
        result
    }

    fn l_match(&mut self, x: &HashSet<Node>, y: &HashSet<Node>, p: f64) -> HashMap<Node, Node> {
        let hyperedge = Hyperedge((x.clone(), y.clone()));
        if let Some(result) = self.l_match.get(&hyperedge) {
            return result.clone();
        }
        let mut rng = rng();
        let mut used = HashSet::new();
        let mut result = HashMap::new();
        for node_x in x {
            let mut min = 1.0;
            let mut min_node = None;
            for node_y in y {
                if !used.contains(node_y) {
                    let value = node_x.clone() ^ node_y.clone();
                    if value < min {
                        min = value;
                        min_node = Some(node_y);
                    }
                }
                if let Some(node_y) = min_node {
                    used.insert(node_y.clone());
                    result.insert(node_x.clone(), node_y.clone());
                }
            }
        }
        let mut final_result = HashMap::new();
        for (key, value) in result {
            if rng.random_bool(p) {
                final_result.insert(key, value);
            }
        }
        self.l_match.insert(hyperedge, final_result.clone());
        final_result
    }
}

impl Drop for LSave {
    fn drop(&mut self) {
        let file = std::fs::File::create("lsave_backup.json").expect("Unable to create file");
        let writer = std::io::BufWriter::new(file);
        serde_json::to_writer(writer, self).expect("Unable to write JSON");
    }
}

pub fn l_predicate_node(x: &Node, y: &Node, p: f64) -> bool {
    l_save.write().unwrap().l_predicate_node(x, y, p)
}

pub fn l_predicate_node_set(x: &HashSet<Node>, y: &HashSet<Node>, p: f64) -> bool {
    l_save.write().unwrap().l_predicate_node_set(x, y, p)
}

pub fn l_match(x: &HashSet<Node>, y: &HashSet<Node>, p: f64) -> HashMap<Node, Node> {
    l_save.write().unwrap().l_match(x, y, p)
}