gorf_lcobj/
lib.rs

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