gorf_lcobj/
lib.rs

1use std::{
2    collections::{BTreeMap, BTreeSet},
3    fmt::Display,
4};
5
6use gorf_core::{Binder, GTerm};
7use serde::{Deserialize, Serialize};
8pub mod make;
9#[derive(Serialize, Deserialize)]
10pub struct Symbol<V: Binder, M> {
11    pub deps: Vec<V>,
12    #[serde(bound(
13        deserialize = "GTerm<V,M>: Deserialize<'de>",
14        serialize = "GTerm<V,M>: Serialize"
15    ))]
16    pub r#impl: GTerm<V, M>,
17}
18
19impl<V: Binder<Var: Clone> + Clone, M: Clone> Clone for Symbol<V, M> {
20    fn clone(&self) -> Self {
21        Self {
22            deps: self.deps.clone(),
23            r#impl: self.r#impl.clone(),
24        }
25    }
26}
27
28impl<V: Binder, M> Symbol<V, M> {
29    pub fn emit(self) -> GTerm<V, M> {
30        return self
31            .deps
32            .into_iter()
33            .fold(self.r#impl, |s, d| GTerm::Abs(Box::new((d, s))));
34    }
35}
36#[derive(Serialize, Deserialize)]
37pub struct Obj<V: Binder + Ord, M> {
38    #[serde(bound(
39        deserialize = "Symbol<V,M>: Deserialize<'de>, V: Deserialize<'de>",
40        serialize = "Symbol<V,M>: Serialize, V: Serialize"
41    ))]
42    pub syms: BTreeMap<V, Symbol<V, M>>,
43}
44impl<V: Binder<Var: Clone> + Clone + Ord, M: Clone> Clone for Obj<V, M> {
45    fn clone(&self) -> Self {
46        Self {
47            syms: self.syms.clone(),
48        }
49    }
50}
51impl<V: Binder<Var: Clone> + From<String> + Display + Ord + Clone, M: Clone> Obj<V, M> {
52    pub fn sees(&self, v: &V, w: &V) -> bool {
53        if v == w {
54            return true;
55        }
56        match self.syms.get(v) {
57            None => false,
58            Some(s) => s.deps.iter().any(|d| self.sees(d, w)),
59        }
60    }
61    pub fn rbake(&self, v: &V, stack: &BTreeSet<V>) -> GTerm<V, M> {
62        if stack.contains(v) {
63            let v = gorf_core::var(V::get_var(format!("@{v}").into()));
64            return gorf_core::app(v.clone(), v);
65        }
66        let mut stack = stack.clone();
67        stack.insert(v.clone());
68        let s = self.syms.get(v).unwrap();
69        let mut b = GTerm::Var(v.get_var_ref().clone());
70        for d in s.deps.iter() {
71            b = gorf_core::app(b, self.rbake(d, &stack))
72        }
73
74        return gorf_core::app(
75            gorf_core::abs(
76                v.clone(),
77                gorf_core::app(
78                    gorf_core::var(v.get_var_ref().clone()),
79                    gorf_core::var(v.get_var_ref().clone()),
80                ),
81            ),
82            gorf_core::abs(format!("@{v}").into(), b),
83        );
84    }
85    pub fn link(&self, root: &V) -> GTerm<V, M> {
86        let mut x = self.rbake(root, &BTreeSet::new());
87        for (k, v) in self.syms.clone().into_iter() {
88            x = gorf_core::app(gorf_core::abs(k, x), v.emit());
89        }
90        return x;
91    }
92}