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}