You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
45 lines
1.9 KiB
45 lines
1.9 KiB
import { $, Term, _, _l, cnst, g, id, n, pipe, _r as ref } from './core';
|
|
import { EQ, GT, LT } from './ord';
|
|
import { False, True, iif } from './bool';
|
|
|
|
n('num');
|
|
|
|
export const Zero = g('Zero', _l(z => _l(_n => z)));
|
|
|
|
export const Succ = g('Succ', _l(p => _l(_z => _l(n => n._(p)))));
|
|
|
|
export const ifz = g('ifz', _l(n => _l(t => _l(f => n._(t)._(cnst._(f))))));
|
|
|
|
export const succ = g('succ', Succ);
|
|
|
|
export const pred = g('pred', _l(n => n._(Zero)._(id)));
|
|
|
|
export const cmp = g('cmp', _l(l => _l(r => l._(r._(EQ)._(cnst._(LT)))._(pipe._(r._(GT))._(ref('num', 'cmp'))))));
|
|
|
|
export const lt = g('lt', _l(l => _l(r => r._(False)._(l._(cnst._(True))._(ref('num', 'lt'))))));
|
|
|
|
export const le = g('le', _l(l => _l(r => l._(True)._(r._(cnst._(False))._(ref('num', 'ge'))))));
|
|
|
|
export const eq = g('eq', _l(l => _l(r => l._(r._(True)._(cnst._(False)))._(r._(cnst._(False))._(ref('num', 'eq'))))));
|
|
|
|
export const ge = g('ge', _l(l => _l(r => r._(True)._(l._(cnst._(False))._(ref('num', 'ge'))))));
|
|
|
|
export const gt = g('gt', _l(l => _l(r => l._(False)._(r._(cnst._(True))._(lt)))));
|
|
|
|
export const even = g('even', _l(n => n._(True)._(ref('num', 'odd'))));
|
|
|
|
export const odd = g('odd', _l(n => n._(False)._(ref('num', 'even'))));
|
|
|
|
export const sum = g('sum', _l(l => _l(r => r._(l)._(ref('num', 'sum')._(Succ._(l))))));
|
|
|
|
export const sub = g('sub', _l(l => _l(r => r._(l)._(l._(cnst._(Zero))._(ref('num', 'sub'))))));
|
|
|
|
export const mul = g('mul', _l(l => _l(r => l._(Zero)._(_l(pl => sum._(r)._(ref('num', 'mul')._(pl)._(r)))))));
|
|
|
|
export const div = g('div', _l(l => _l(r => iif._(lt._(l)._(r))._(Zero)._(succ._(ref('num', 'div')._(sub._(l)._(r))._(r))))));
|
|
|
|
export const mod = g('mod', _l(l => _l(r => iif._(lt._(l)._(r))._(l)._(ref('num', 'mod')._(sub._(l)._(r))._(r)))));
|
|
|
|
export const fromNumber: (n: number) => Term = n => !n ? Zero : Succ._(_(() => fromNumber(n - 1)));
|
|
|
|
export const toNumber: (n: Term) => number = n => $(n._(_(0))._(_l(p => _(({ p }) => _(1 + toNumber(p))))));
|
|
|