import { Op, Rewrite, ChainRewrites, Flip } from './util'; export type Add = { op: '+'; a: A; b: B }; export type Succ = Add<'1', A>; export type Identity = Rewrite, A>; export type Commutativity = Rewrite, Add>; export interface Assoc0 { type: 'rewrite', left: Add, B>; // (0 + a) + b right: ChainRewrites<[ Commutativity<'0', A>, // = (a + 0) + b Identity, // = a + b Flip>>, // = (a + b) + 0 Commutativity, '0'>, // = 0 + (a + b) ], this['left']>; }; export type Assoc1 = Rewrite, B>, Succ>>; export interface Assoc { type: 'rewrite', left: Add, C>; // (a + b) + c right: ChainRewrites<[ Rewrite>, // = CHEATING Assoc1, // = succ(a + b) + c Assoc1, C>, // = succ(a + b + c) Rewrite, // CHEATING. TODO: figure out recursion Assoc0, // Induction base case Rewrite<'0', A>, // CHEATING Flip>>, // = succ(a) + (b + c) Rewrite, A>, // = CHEATING ], this['left']>; }; // type _x = ApplyRewrite, 'C'>, AssocN<'A', 'B', 'C'>> /* Assoc: (a + b) + c = a + (b + c) For a = 0, (0 + b) + c = (b + 0) + c -- comm = b + c -- id = (b + c) + 0 -- flip id = 0 + (b + c) -- comm For a' = succ(a), (succ(a) + b) + c = succ(a + b) + c = succ((a + b) + c) ----- rec = succ(a + (b + c)) = succ(a) + (b + c) */