1#![no_std]
3extern crate alloc;
4use alloc::boxed::Box;
5use alloc::collections::{BTreeMap, BTreeSet};
6use alloc::string::String;
7use alloc::format;
8use alloc::vec::Vec;
9use alloc::vec;
10use core::{convert::Infallible, fmt::Display, hash::Hash, marker::PhantomData, ops::Index};
11
12use chumsky::{prelude::*, text::keyword, Error};
13use either::Either::{self, Left, Right};
14use lambda_calculus::Term::{self, Abs, App, Var};
15use num_bigint::{BigUint, ToBigUint};
16use num_traits::{One, Zero};
17use serde::{Deserialize, Serialize};
18pub struct Ref<'a, V: Binder, M> {
137 pub current: &'a mut GTerm<V, M>,
138}
139impl<'a, V: Binder, M> Ref<'a, V, M> {
140 pub fn app(&mut self, x: GTerm<V, M>) {
141 let mut b = Box::new((x, GTerm::Undef));
142 let c = unsafe { core::mem::transmute::<_, &'a mut (GTerm<V, M>, GTerm<V, M>)>(&mut *b) };
143
144 *self.current = GTerm::App(b);
145 self.current = &mut c.1;
146 }
147 pub fn abs(&mut self, x: V) {
148 let mut b = Box::new((x, GTerm::Undef));
149 let c = unsafe { core::mem::transmute::<_, &'a mut (V, GTerm<V, M>)>(&mut *b) };
150
151 *self.current = GTerm::Abs(b);
152 self.current = &mut c.1;
153 }
154 pub fn wrap(&mut self, v: V, x: GTerm<V, M>)
155 where
156 V: Clone,
157 {
158 self.app(app(x, var(v.clone().get_var())));
159 self.abs(v.clone());
160 }
161}
162
163pub trait Binder {
164 type Var: Binder<Var = Self::Var>;
165 type Wrap<X: Binder>: Binder<Var = X::Var>;
166 fn get_var(self) -> Self::Var;
167 fn get_var_ref(&self) -> &Self::Var;
168 fn get_var_mut(&mut self) -> &mut Self::Var;
169 fn inside<X: Binder<Var = X>>(self, f: &mut impl FnMut(Self::Var) -> X) -> Self::Wrap<X>;
170}
171pub trait Backend<V: Binder + Clone + Eq, M: Eq + Clone>
172where
173 V::Var: Eq + Ord + Clone,
174{
175 type Output;
176 fn undef(&mut self) -> Self::Output;
177 fn var(&mut self, v: V::Var) -> Self::Output;
178 fn selfreference(&mut self, v: Self::Output) -> Self::Output;
179 fn abs(&mut self, b: V, o: Self::Output) -> Self::Output;
180 fn app(&mut self, a: Self::Output, b: Self::Output) -> Self::Output;
181 fn mix(&mut self, x: M) -> Self::Output;
182 fn compile(&mut self, a: GTerm<V, M>) -> Self::Output {
183 if let Some(b) = a.is_sapp() {
184 let c = self.compile(b);
185 return self.selfreference(c);
186 }
187 match a {
188 GTerm::Undef => self.undef(),
189 GTerm::Var(v) => self.var(v),
190 GTerm::Abs(b) => {
191 let (a, b) = *b;
192 let b = self.compile(b);
193 return self.abs(a, b);
194 }
195 GTerm::App(b) => {
196 let (a, b) = *b;
197 let a = self.compile(a);
198 let b = self.compile(b);
199 return self.app(a, b);
200 }
201 GTerm::Mix(m) => self.mix(m),
202 }
203 }
204}
205pub struct Lam {}
206impl<V: Binder + Clone + Eq, M: Clone + Eq> Backend<V, M> for Lam
207where
208 V::Var: Eq + Ord + Clone,
209{
210 type Output = GTerm<V, M>;
211 fn undef(&mut self) -> Self::Output {
212 GTerm::Undef
213 }
214
215 fn var(&mut self, v: V::Var) -> Self::Output {
216 crate::var(v)
217 }
218
219 fn selfreference(&mut self, v: Self::Output) -> Self::Output {
220 crate::app(v.clone(), v.clone())
221 }
222
223 fn abs(&mut self, b: V, o: Self::Output) -> Self::Output {
224 crate::abs(b, o)
225 }
226
227 fn app(&mut self, a: Self::Output, b: Self::Output) -> Self::Output {
228 crate::app(a, b)
229 }
230 fn mix(&mut self, x: M) -> Self::Output {
231 return GTerm::Mix(x);
232 }
233}
234pub trait Incr {
235 fn incr(&mut self);
236}
237impl Incr for usize {
238 fn incr(&mut self) {
239 *self += 1;
240 }
241}
242impl Incr for String {
243 fn incr(&mut self) {
244 *self = format!("%${self}")
245 }
246}
247#[derive(Eq, Ord, Clone, PartialEq, PartialOrd, Hash, Serialize, Deserialize)]
248#[repr(transparent)]
249#[serde(transparent)]
250pub struct Id(pub String);
251impl Incr for Id {
252 fn incr(&mut self) {
253 self.0.incr();
254 }
255}
256impl From<usize> for Id {
257 fn from(value: usize) -> Self {
258 return Id(format!("%{value}"));
259 }
260}
261impl From<String> for Id {
262 fn from(value: String) -> Self {
263 return Id(value);
264 }
265}
266impl Display for Id {
267 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
268 write!(f, "{}", self.0)
269 }
270}
271macro_rules! simple_binder {
273 ($x:ty) => {
274 impl $crate::Binder for $x {
275 type Var = $x;
276 type Wrap<X: $crate::Binder> = X;
277 fn get_var(self) -> Self::Var {
278 return self;
279 }
280 fn get_var_ref(&self) -> &Self::Var {
281 return self;
282 }
283 fn get_var_mut(&mut self) -> &mut Self::Var {
284 return self;
285 }
286 fn inside<X: $crate::Binder<Var = X>>(
287 self,
288 f: &mut impl FnMut(Self::Var) -> X,
289 ) -> Self::Wrap<X> {
290 return f(self);
291 }
292 }
293 };
295}
296simple_binder!(usize);
297simple_binder!(String);
298simple_binder!(Id);
299
300#[derive(Eq, Ord, Clone, PartialEq, PartialOrd, Hash, Debug, Serialize, Deserialize)]
301pub enum GTerm<V: Binder, M> {
302 Undef,
303 Var(V::Var),
304 Abs(Box<(V, GTerm<V, M>)>),
305 App(Box<(GTerm<V, M>, GTerm<V, M>)>),
306 Mix(M),
307}
308
309pub fn parser<'a, Y: 'a + 'static, X: 'a + 'static + Binder, E: Error<char> + 'a + 'static>(
310 x: impl Parser<char, X, Error = E> + 'a + 'static + Clone,
311 v: impl Parser<char, X::Var, Error = E> + 'a + 'static + Clone,
312 y: impl Parser<char, Y, Error = E> + 'a + 'static + Clone,
313 splice: impl Parser<char, GTerm<X, Y>, Error = E> + 'a + 'static + Clone,
314) -> impl Parser<char, GTerm<X, Y>, Error = E> + 'a + 'static + Clone
315where
316 <X as Binder>::Var: 'a + 'static,
317 GTerm<X, Y>: 'a + 'static,
318{
319 return recursive(|go| {
320 let var = v
321 .clone()
322 .map(|v| GTerm::Var(v))
323 .then_ignore(text::whitespace());
324 let fun = just('\\')
325 .then(x.then_ignore(just('.')).separated_by(text::whitespace()))
326 .then(go.clone())
327 .map(|((_, k), v)| {
328 k.into_iter()
329 .rev()
330 .fold(v, |a, b| GTerm::Abs(Box::new((b, a))))
331 });
332 let b = choice((
333 var.clone(),
334 fun.clone(),
335 go.clone().delimited_by(just('('), just(')')),
336 y.map(|x| GTerm::Mix(x)),
337 ));
338 choice((b
339 .clone()
340 .then_ignore(text::whitespace())
341 .repeated()
342 .at_least(1)
343 .map(|x| x.into_iter().reduce(|acc, e| app(acc, e)).unwrap()),))
344 });
345}
346pub fn void<I: Clone + Hash + Eq, O>() -> impl Parser<I, O, Error = Simple<I>> + Clone {
392 return end().try_map(|a, b| Err(Simple::custom(b, "")));
393}
394pub fn str_parser() -> impl Parser<char, GTerm<String, Infallible>, Error = Simple<char>> + Clone {
395 return parser(
396 chumsky::text::ident(),
397 chumsky::text::ident(),
398 void(),
399 void(),
400 );
401}
402
403#[derive(Eq, Ord, Clone, PartialEq, PartialOrd, Hash)]
404#[repr(transparent)]
405pub struct Scope<T: Binder>(pub BTreeMap<T::Var, T>);
406
407impl<V: Binder, M> GTerm<V, M> {
408 pub fn to_args<'a>(&'a self, args: &mut Vec<&'a GTerm<V, M>>) -> &'a GTerm<V, M> {
409 let GTerm::App(k) = self else {
410 return self;
411 };
412 let (a, b) = k.as_ref();
413 let a = a.to_args(args);
414 args.push(b);
415 return a;
416 }
417 pub fn map_vars<X: Binder<Var = X>>(
418 self,
419 f: &mut impl FnMut(V::Var) -> X,
420 ) -> GTerm<V::Wrap<X>, M> {
421 match self {
422 GTerm::Undef => GTerm::Undef,
423 GTerm::Var(v) => GTerm::Var(f(v)),
424 GTerm::Abs(k) => {
425 let (k, w) = *k;
426 let k = k.inside(f);
427 let w = w.map_vars(f);
428 return abs(k, w);
429 }
430 GTerm::App(a) => {
431 let (a, b) = *a;
432 return app(a.map_vars(f), b.map_vars(f));
433 }
434 GTerm::Mix(m) => GTerm::Mix(m),
435 }
436 }
437 pub fn map_all<X: Binder>(
438 self,
439 f: &mut impl FnMut(V::Var) -> X::Var,
440 g: &mut impl FnMut(V) -> X,
441 ) -> GTerm<X, M> {
442 match self {
443 GTerm::Undef => GTerm::Undef,
444 GTerm::Var(v) => GTerm::Var(f(v)),
445 GTerm::Abs(k) => {
446 let (k, w) = *k;
447 let k = g(k);
448 let w = w.map_all(f, g);
449 return abs(k, w);
450 }
451 GTerm::App(a) => {
452 let (a, b) = *a;
453 return app(a.map_all(f, g), b.map_all(f, g));
454 }
455 GTerm::Mix(m) => GTerm::Mix(m),
456 }
457 }
458 pub fn map_mix<N>(self, f: &mut impl FnMut(M) -> N) -> GTerm<V, N> {
459 return self.lower_mix(&mut |a| GTerm::Mix(f(a)));
460 }
461 pub fn lower_mix<N>(self, f: &mut impl FnMut(M) -> GTerm<V, N>) -> GTerm<V, N> {
462 match self {
463 GTerm::Undef => GTerm::Undef,
464 GTerm::Var(v) => GTerm::Var(v),
465 GTerm::Abs(k) => {
466 let (k, w) = *k;
467 return abs(k, w.lower_mix(f));
468 }
469 GTerm::App(a) => {
470 let (a, b) = *a;
471 return app(a.lower_mix(f), b.lower_mix(f));
472 }
473 GTerm::Mix(m) => f(m),
474 }
475 }
476 pub fn subst(self, f: &mut impl FnMut(&V::Var) -> Option<GTerm<V, M>>) -> GTerm<V, M> {
477 match self {
478 GTerm::Undef => GTerm::Undef,
479 GTerm::Var(v) => match f(&v) {
480 Some(a) => a,
481 None => GTerm::Var(v),
482 },
483 GTerm::Abs(k) => {
484 let (k, w) = *k;
485 match f(k.get_var_ref()) {
486 Some(_) => abs(k, w),
487 None => abs(k, w.subst(f)),
488 }
489 }
490 GTerm::App(b) => {
491 let (a, b) = *b;
492 return app(a.subst(f), b.subst(f));
493 }
494 GTerm::Mix(m) => GTerm::Mix(m),
495 }
496 }
497}
498impl<V: Binder, M> GTerm<V, M>
499where
500 V::Var: Eq,
501{
502 pub fn subst_var_fun(self, v: &V::Var, f: &mut impl FnMut() -> GTerm<V, M>) -> GTerm<V, M> {
503 return self.subst(&mut |x| if x == v { Some(f()) } else { None });
504 }
505}
506impl<V: Binder + Clone, M: Clone> GTerm<V, M>
507where
508 V::Var: Eq + Clone,
509{
510 pub fn subst_var(self, v: &V::Var, f: GTerm<V, M>) -> GTerm<V, M> {
511 return self.subst_var_fun(v, &mut || f.clone());
512 }
513 pub fn apply(&mut self, o: GTerm<V, M>) {
514 if let GTerm::Abs(a) = self {
515 let (ref mut k, ref mut w) = **a;
516 *self = w.clone().subst_var(k.get_var_mut(), o);
517 return;
518 }
519 *self = app(self.clone(), o);
520 }
521}
522#[derive(Eq, Ord, Clone, PartialEq, PartialOrd, Hash)]
523pub struct Scott<V: Binder, M> {
524 pub cases: Vec<V::Var>,
525 pub current_case: usize,
526 pub with: Vec<GTerm<V, M>>,
527}
528#[derive(Eq, Ord, Clone, PartialEq, PartialOrd, Hash)]
529pub struct Let<V: Binder<Var: Ord>, M> {
530 pub vars: BTreeMap<V::Var, GTerm<V, M>>,
531 pub body: GTerm<V, M>,
532}
533impl<V: Binder + Clone, M: Clone> Scott<V, M>
534where
535 V::Var: Eq + Ord + Clone,
536{
537 pub fn apply(mut self, mut other: GTerm<V, M>) -> Either<GTerm<V, M>, Scott<V, M>> {
538 if self.current_case == 0 {
539 for x in self.with.into_iter() {
540 other.apply(x);
541 }
542 return Left(other);
543 }
544 self.current_case -= 1;
545 self.cases.pop();
546 return Right(self);
547 }
548 pub fn render(mut self) -> GTerm<V, M>
549 where
550 V: Binder<Var = V>,
551 {
552 let mut r = var(self.cases[self.current_case].clone());
553 for w in self.with.into_iter() {
554 r = app(r, w);
555 }
556 for c in self.cases.into_iter().rev() {
557 r = abs(c, r);
558 }
559 return r;
560 }
561}
562impl<V: Binder + Clone + Eq, M: Clone + Eq> GTerm<V, M>
563where
564 V::Var: Eq + Ord + Clone,
565{
566 pub fn is_sapp(&self) -> Option<GTerm<V, M>> {
567 if let GTerm::App(a) = self {
568 let (ref a, ref b) = **a;
569 if a.clone() == b.clone() {
570 return Some(a.clone());
571 }
572 }
573 None
574 }
575}
576impl<V: Binder + Clone, M: Clone> GTerm<V, M>
577where
578 V::Var: Eq + Ord + Clone,
579{
580 pub fn frees_internal(&self, o: &mut BTreeSet<V::Var>) {
581 match self {
582 GTerm::Undef => {}
583 GTerm::Var(s) => {
584 o.insert(s.clone());
585 }
586 GTerm::Abs(a) => {
587 let (ref k, ref w) = **a;
588 let mut r = w.frees();
589 r.remove(k.get_var_ref());
590 o.append(&mut r);
591 }
592 GTerm::App(a) => {
593 let (ref a, ref b) = **a;
594 a.frees_internal(o);
595 b.frees_internal(o);
596 }
597 GTerm::Mix(m) => {}
598 }
599 }
600 pub fn frees(&self) -> BTreeSet<V::Var> {
601 let mut r = BTreeSet::new();
602 self.frees_internal(&mut r);
603 return r;
604 }
605 pub fn r#let(self) -> Let<V, M> {
606 let mut l = Let {
607 body: self,
608 vars: BTreeMap::new(),
609 };
610 loop {
611 let GTerm::App(a) = l.body.clone() else {
612 return l;
613 };
614 let GTerm::Abs(b) = a.0 else {
615 return l;
616 };
617 l.vars.insert(b.0.get_var(), a.1);
618 l.body = b.1;
619 }
620 }
621 pub fn scott(&self) -> Option<Scott<V, M>> {
622 let mut this = self;
623 let mut v = vec![];
624 while let GTerm::Abs(k) = this {
625 let (ref k, ref w) = **k;
626 v.push(k.clone().get_var());
627 this = w;
628 }
629 let mut args = vec![];
630 loop {
631 if let GTerm::App(b) = this {
632 let (ref a, ref b) = **b;
633 for f in b.frees() {
652 if !v.contains(&f) {
653 return None;
654 }
655 }
656 args.push(b.clone());
657 this = a;
658 } else {
659 break;
660 }
661 }
662 if let GTerm::Var(r) = this {
663 match v.iter().enumerate().find(|a| a.1 == r.get_var_ref()) {
664 Some((a, b)) => {
665 return Some(Scott {
666 cases: v,
667 current_case: a,
668 with: args.into_iter().rev().collect(),
669 })
670 }
671 None => return None,
672 }
673 }
674 return None;
675 }
676}
677
678pub fn var<V: Binder, M>(a: V::Var) -> GTerm<V, M> {
679 return GTerm::Var(a);
680}
681
682pub fn abs<V: Binder, M>(a: V, b: GTerm<V, M>) -> GTerm<V, M> {
683 return GTerm::Abs(Box::new((a, b)));
684}
685
686pub fn app<V: Binder, M>(a: GTerm<V, M>, b: GTerm<V, M>) -> GTerm<V, M> {
687 return GTerm::App(Box::new((a, b)));
688}
689
690pub fn debrijun_internal<X: From<usize> + Binder, Y>(x: Term, depth: usize) -> GTerm<X, Y>
691where
692 <X as Binder>::Var: From<usize>,
693{
694 match x {
695 Var(0) => GTerm::Undef,
696 Var(v) => GTerm::Var((depth - v).into()),
697 Abs(a) => GTerm::Abs(Box::new((depth.into(), debrijun_internal(*a, depth + 1)))),
698 App(b) => {
699 let (a, b) = *b;
700 let a = debrijun_internal(a, depth);
701 let b = debrijun_internal(b, depth);
702 return GTerm::App(Box::new((a, b)));
703 }
704 }
705}
706pub fn debrijun<X: From<usize> + Binder, Y>(x: Term) -> GTerm<X, Y>
707where
708 <X as Binder>::Var: From<usize>,
709{
710 return debrijun_internal(x, 1);
711}
712pub fn brujin_internal<X: Binder>(
713 t: GTerm<X, Infallible>,
714 m: &BTreeMap<<X as Binder>::Var, usize>,
715) -> Term
716where
717 <X as Binder>::Var: Eq + Ord + Clone,
718{
719 match t {
720 GTerm::Undef => Var(0),
721 GTerm::Var(a) => Var(m[&a]),
722 GTerm::Abs(a) => {
723 let (k, w) = *a;
724 let mut n = BTreeMap::new();
725 for (a, b) in m.iter() {
726 n.insert(a.clone(), *b + 1);
727 }
728 n.insert(k.get_var(), 1);
729 return Abs(Box::new(brujin_internal(w, &n)));
730 }
731 GTerm::App(b) => {
732 let (a, b) = *b;
733 let a = brujin_internal(a, m);
734 let b = brujin_internal(b, m);
735 return App(Box::new((a, b)));
736 }
737 GTerm::Mix(x) => match x {},
738 }
739}
740pub fn brujin<X: Binder>(t: GTerm<X, Infallible>) -> Term
741where
742 <X as Binder>::Var: Eq + Ord + Clone,
743{
744 return brujin_internal(t, &BTreeMap::new());
745}
746pub fn brujin_map_f_internal<X: Binder, Y: Binder, M>(
747 t: GTerm<X, Infallible>,
748 m: &BTreeMap<<X as Binder>::Var, usize>,
749 depth: usize,
750 into: &mut impl FnMut(usize) -> Y,
751) -> GTerm<Y, M>
752where
753 <X as Binder>::Var: Eq + Ord + Clone,
754{
755 match t {
756 GTerm::Undef => GTerm::Undef,
757 GTerm::Var(a) => GTerm::Var(into(depth - m[&a]).get_var()),
758 GTerm::Abs(a) => {
759 let (k, w) = *a;
760 let mut n = BTreeMap::new();
761 for (a, b) in m.iter() {
762 n.insert(a.clone(), *b + 1);
763 }
764 n.insert(k.get_var(), 1);
765 return abs(into(depth), brujin_map_f_internal(w, &n, depth + 1, into));
766 }
767 GTerm::App(b) => {
768 let (a, b) = *b;
769 let a = brujin_map_f_internal(a, m, depth, into);
770 let b = brujin_map_f_internal(b, m, depth, into);
771 return app(a, b);
772 }
773 GTerm::Mix(x) => match x {},
774 }
775}
776pub fn brujin_map<X: Binder, Y: Binder + From<usize>, M>(t: GTerm<X, Infallible>) -> GTerm<Y, M>
777where
778 <X as Binder>::Var: Eq + Ord + Clone,
779 <Y as Binder>::Var: From<usize>,
780{
781 return brujin_map_f_internal(t, &BTreeMap::new(), 1, &mut |a| a.into());
782}
783pub fn brujin_map_f<X: Binder, Y: Binder, M>(
784 t: GTerm<X, Infallible>,
785 into: &mut impl FnMut(usize) -> Y,
786) -> GTerm<Y, M>
787where
788 <X as Binder>::Var: Eq + Ord + Clone,
789{
790 return brujin_map_f_internal(t, &BTreeMap::new(), 1, into);
791}
792
793#[cfg(test)]
794mod tests {
795 use chumsky::Stream;
796
797 use super::*;
798 #[test]
799 fn rtrip() {
800 let a = lambda_calculus::parse(
801 "\\a.\\b.\\c.c a b (\\d.d c b a)",
802 lambda_calculus::term::Notation::Classic,
803 )
804 .unwrap();
805 assert_eq!(
806 brujin::<usize>(brujin_map(debrijun::<usize, Infallible>(a.clone()))),
807 a
808 );
809 }
810 #[test]
811 fn parse() {
812 let s = "\\a.\\b.\\c.c a b (\\d.d c b a)";
813 let a = lambda_calculus::parse(s, lambda_calculus::term::Notation::Classic).unwrap();
814 let b = str_parser().map(|x| brujin(x)).parse(Stream::from(s));
815 assert_eq!(b.unwrap(), a);
816 }
817 #[test]
818 fn r#let() {
819 let s = "let a = \\b.a in \\c.c a";
820 let b = str_parser().parse(s);
821 assert!(b.is_ok());
822 }
823 #[test]
824 fn scott_simple() {
825 let a = debrijun::<usize, Infallible>(
826 lambda_calculus::parse("\\a.a", lambda_calculus::term::Notation::Classic).unwrap(),
827 );
828 let a = a.scott().unwrap();
837 assert_eq!(a.current_case, 0);
839 assert_eq!(a.with, vec![]);
840 }
841 #[test]
842 fn scott_field() {
843 let ab = debrijun::<usize, Infallible>(
844 lambda_calculus::parse(
845 "\\c.\\a.a (\\b.b)",
846 lambda_calculus::term::Notation::Classic,
847 )
848 .unwrap(),
849 );
850 let b = debrijun::<usize, Infallible>(
851 lambda_calculus::parse("\\a.a", lambda_calculus::term::Notation::Classic).unwrap(),
852 );
853 let a = ab.scott().unwrap();
862 assert_eq!(brujin(a.clone().render()), brujin(ab.clone()));
863 assert_eq!(a.current_case, 1);
865 assert_eq!(a.with.len(), 1);
866 assert_eq!(brujin(b), brujin(a.with[0].clone()))
867 }
868 #[test]
869 fn scott_bool() {
870 let ab = debrijun::<usize, Infallible>(
871 lambda_calculus::parse("\\b.\\a.a", lambda_calculus::term::Notation::Classic).unwrap(),
872 );
873 let a = ab.scott().unwrap();
882 assert_eq!(brujin(a.clone().render()), brujin(ab.clone()));
883 assert_eq!(a.current_case, 1);
885 assert_eq!(a.with, vec![]);
886 }
887}