export type Op = string | { op: string; a: Op; b: Op }; export type Rewrite = { type: 'rewrite'; left: left; right: right; }; export type RewriteKind = Rewrite; export type Flip = Rewrite; export type ApplyRewrite = O extends R['left'] ? R['right'] : O extends string ? O : O extends { a: Op, b: Op, op: string } ? ( ApplyRewrite extends O['a'] ? Omit & { b: ApplyRewrite } : Omit & { a: ApplyRewrite } ) : never; export type Add = { op: '+'; a: a; b: b }; export type Identity = Rewrite, A>; export type Commutativity = Rewrite, Add>; // type _x = ApplyRewrite, Identity<'0'>>; // type Assoc = /* Assoc: (a + b) + c = a + (b + c) For a = 0, (0 + b) + c = b + c = 0 + (b + c) For a = succ(), */