From 4a0fb237cac8796e45d7b217db0d808452454820 Mon Sep 17 00:00:00 2001 From: Akshay Nair Date: Sat, 16 Dec 2023 17:31:12 +0530 Subject: feat: lambda calculus --- src/equation.ts | 9 ++-- src/lambda-calculus.ts | 114 +++++++++++++++++++++++++++++++++++++++++++++++++ src/utils/theorem.ts | 7 +-- 3 files changed, 122 insertions(+), 8 deletions(-) create mode 100644 src/lambda-calculus.ts (limited to 'src') diff --git a/src/equation.ts b/src/equation.ts index 0ec25d6..cc668b1 100644 --- a/src/equation.ts +++ b/src/equation.ts @@ -1,4 +1,4 @@ -import { Op, Rewrite, ChainRewrites, Sym, Equation, VerifyEquation, assert, ApplyRewrite, Evaluate, OpToStr } from './utils/theorem'; +import { Op, Rewrite, ChainRewrites, Sym, Equation, VerifyEquation, assert, ApplyRewrite, Evaluate, OpToStr, SubstEq } from './utils/theorem'; export namespace equation { type F = { op: 'F', a: X }; @@ -9,7 +9,6 @@ export namespace equation { export type Congruence = Rewrite, Equation, F>>; - export type SubstituteEq> = Rewrite export interface SubstituteEq_Proof { type: 'rewrite', known: { @@ -18,7 +17,7 @@ export namespace equation { left: Equation, F>; // f(a) = f(b) right: ChainRewrites<[ Sym>, // a = b - SubstituteEq, // b = b + SubstEq, // b = b Reflexivity, ], this['left']>; }; @@ -36,8 +35,8 @@ export namespace equation { }, left: Equation, Equation>; // (a = b) = (b = c) right: ChainRewrites<[ - SubstituteEq, // (b = b) = (b = c) - SubstituteEq>>, // (b = b) = (c = b) + SubstEq, // (b = b) = (b = c) + SubstEq>>, // (b = b) = (c = b) Reflexivity, // true = (b = b) Reflexivity, // true = true Reflexivity<'true'>, diff --git a/src/lambda-calculus.ts b/src/lambda-calculus.ts new file mode 100644 index 0000000..bbd2d1e --- /dev/null +++ b/src/lambda-calculus.ts @@ -0,0 +1,114 @@ +import { Op, Rewrite, ChainRewrites, Sym, Equation, Refl, VerifyEquation, assert, Subst, ApplyRewrite, Evaluate, OpToStr, SubstEq } from './utils/theorem'; + +export type Abs = { op: '->', a: x, b: o }; // \x. o +export type Ap = { op: '$', a: F, b: x }; // F(x) +export type Comp = { op: '.', a: F, b: G }; // F . G +export type Id = Abs // \x. x +export type Const = Abs> // \x. \y. x +export type Inv = { op: 'inv', a: F } + +export namespace composition { + export type Abstraction = Rewrite, v>, y>; + + export type Composition = Rewrite, x>, Ap>>; + + // Identity + export type Identity = Rewrite, x>; + export namespace proof { + export interface Identity_Proof { + type: 'rewrite'; + left: Equation, x>, x>; // id(x) = x + right: ChainRewrites<[ + Abstraction, // x = x + Refl, + ], this['left']>; + } + + export interface Identity_Composition_Proof { + type: 'rewrite'; + left: Equation, x>, Ap>; // (f . id)(x) = f(x) + right: ChainRewrites<[ + Composition, // f(id(x)) = f(x) + Identity, // f(x) = f(x) + Refl, + ], this['left']>; + } + + export type identity = [ + assert>>, + assert>>, + ] + } + + // Associativity + export type Associativity = Rewrite< + Comp, H>, + Comp> + > + export namespace proof { + export interface Assoc_Proof { + type: 'rewrite'; + left: Equation, H>, x>, Ap>, x>>; // ((f . g) . h)(x) = (f . (g . h))(x) + right: ChainRewrites<[ + Composition, H, x>, // (f . g)(h(x)) = (f . (g . h))(x) + Composition>, // f(g(h(x))) = (f . (g . h))(x) + Composition, x>, // f(g(h(x))) = f((g . h)(x)) + Composition, // f(g(h(x))) = f(g(h(x))) + Refl, + ], this['left']>; + } + export type associativity = [ + assert>>, + ] + } + + // Identity + export type Transitivity = Rewrite, Abs>, Abs>; + export namespace proof { + export interface Transitivity_Proof { + type: 'rewrite'; + left: Equation, Abs>, x>, Ap, x>>; // ((\y -> z) . (\x -> y))(x) = (\x -> z)(x) + right: ChainRewrites<[ + Composition, Abs, x>, // (\y -> z) $ (\x -> y)(x) = (\x -> z)(x) + Abstraction, // (\y -> z) $ y = (\x -> z)(x) + Abstraction, // z = (\x -> z)(x) + Abstraction, // z = z + Refl, + ], this['left']>; + } + export type transitivity = [ + // OpToStr>>, + assert>>, + ] + } + + // Inverse functions + export type Inverse = Rewrite>, Abs>; + export namespace proof { + export interface Composition_Inverse_Proof { + type: 'rewrite', + known: { + 'f': Equation>, + 'g': Equation>, + }, + left: Equation>, Comp, Inv>>, // inv(f . g) = inv(g) . inv(f) + right: ChainRewrites<[ + SubstEq, + SubstEq, // inv((\y -> z) . g) = inv(g) . inv(\y -> z) + SubstEq, + SubstEq, // inv((\y -> z) . (\x -> y)) = inv(\x -> y) . inv(\y -> z) + Inverse<'x', 'y'>, + Inverse<'y', 'z'>, // inv((\x -> y) . (\y -> z)) = (\z -> y) . (\y -> x) + Transitivity<'x', 'y', 'z'>, // inv(\x -> z) = (\z -> y) . (\y -> x) + Transitivity<'z', 'y', 'x'>, // inv(\x -> z) = \z -> x + Inverse<'x', 'z'>, // \z -> x = \z -> x + Refl + ], this['left']>, + } + export type inverse = [ + // OpToStr>>, + assert>>, + ] + } +} + diff --git a/src/utils/theorem.ts b/src/utils/theorem.ts index a4dd2e9..be19b94 100644 --- a/src/utils/theorem.ts +++ b/src/utils/theorem.ts @@ -6,9 +6,9 @@ export type OpToStr = O extends string ? O : O extends { op: string, a: infer a extends string, b: infer b extends string } ? `(${a} ${O['op']} ${b})` - : O extends { op: string, a: infer a extends DyadicOp, b: infer b extends string } ? `(${OpToStr} ${O['op']} ${b})` - : O extends { op: string, a: infer a extends string, b: infer b extends DyadicOp } ? `(${a} ${O['op']} ${OpToStr})` - : O extends { op: string, a: infer a extends DyadicOp, b: infer b extends DyadicOp } ? `(${OpToStr} ${O['op']} ${OpToStr})` + : O extends { op: string, a: infer a extends DyadicOp | MonadicOp, b: infer b extends string } ? `(${OpToStr} ${O['op']} ${b})` + : O extends { op: string, a: infer a extends string, b: infer b extends DyadicOp | MonadicOp } ? `(${a} ${O['op']} ${OpToStr})` + : O extends { op: string, a: infer a extends DyadicOp | MonadicOp, b: infer b extends DyadicOp | MonadicOp } ? `(${OpToStr} ${O['op']} ${OpToStr})` : O extends { op: string, a: infer a extends string } ? `${O['op']}(${a})` : O extends { op: string, a: infer a extends DyadicOp } ? `${O['op']}(${OpToStr})` : never; @@ -30,6 +30,7 @@ export interface Rewrite = Rewrite; export type Subst = Rewrite +export type SubstEq> = Rewrite export type ApplyRewrite = R['type'] extends 'imperative' ? (R & { left: O })['right'] -- cgit v1.3.1