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