From efc0358c1e2b52308d3df68aa713cef5dc6e6bfe Mon Sep 17 00:00:00 2001 From: Akshay Nair Date: Fri, 15 Dec 2023 22:36:03 +0530 Subject: refactor: moves stuff around --- src/utils/nat.ts | 10 +++++++ src/utils/theorem.ts | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 src/utils/nat.ts create mode 100644 src/utils/theorem.ts (limited to 'src/utils') diff --git a/src/utils/nat.ts b/src/utils/nat.ts new file mode 100644 index 0000000..af8f3da --- /dev/null +++ b/src/utils/nat.ts @@ -0,0 +1,10 @@ +import { Op } from './theorem'; + +export type Add = { op: '+'; a: A; b: B }; +export type Multiply = { op: '*'; a: A; b: B }; +export type Succ = { op: 'succ', a: A }; + +export type _0 = '0' +export type _1 = Succ<_0> +export type _2 = Succ<_1> +export type _3 = Succ<_2> diff --git a/src/utils/theorem.ts b/src/utils/theorem.ts new file mode 100644 index 0000000..a4dd2e9 --- /dev/null +++ b/src/utils/theorem.ts @@ -0,0 +1,75 @@ +type DyadicOp = { op: string; a: Op; b: Op } +type MonadicOp = { op: string; a: Op } +export type Op = string | MonadicOp | DyadicOp; + +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 string } ? `${O['op']}(${a})` + : O extends { op: string, a: infer a extends DyadicOp } ? `${O['op']}(${OpToStr})` + : never; + +type RwType = 'rewrite' | 'imperative'; + +export interface RewriteBase { + type: RwType; + left: Op; + right: Op; + assume?: Record; +} + +export interface Rewrite extends RewriteBase { + type: Typ; + left: left; + right: right; +}; + +export type Sym = Rewrite; +export type Subst = Rewrite + +export type ApplyRewrite = + R['type'] extends 'imperative' ? (R & { left: O })['right'] + : O extends R['left'] ? R['right'] + : O extends string ? O + : O extends DyadicOp ? ( + ApplyRewrite extends O['a'] + ? (ApplyRewrite extends O['b'] ? O + : Omit & { b: ApplyRewrite }) + : Omit & { a: ApplyRewrite } + ) + : O extends MonadicOp ? ( + ApplyRewrite extends O['a'] ? O : Omit & { a: ApplyRewrite } + ) + : never; + +export type ChainRewrites = + Rws extends [] ? O + : Rws extends [infer R extends RewriteBase, ...infer Rs extends RewriteBase[]] + ? ChainRewrites> + : never; + +export type VerifyEquation = + Eq['right'] extends 'true' ? true : false & Eq['right']; + +export type Evaluate = ApplyRewrite; + +export type assert = T; +export type assertFalse = T; +export type Eq = ([a] extends [b] ? ([b] extends [a] ? true : false & { lhs: a; rhs: b }) : false & { lhs: a; rhs: b }); + +export type Equation = { op: '=', a: A, b: B }; + +export interface Refl extends RewriteBase { + type: 'imperative'; + left: Op; + right: this['left'] extends { op: '=', a: infer a, b: infer b } + ? (Eq extends true ? 'true' : this['left']) + : this['left']; +}; + +// Like Refl, but you have to specify the sides of the equation and this one works recursively +export type ReflR = Rewrite, 'true'>; -- cgit v1.3.1