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}