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)
*/