| import inspect
|
|
|
| from rpython.rlib.objectmodel import import_from_mixin
|
|
|
| class InvalidCammy(Exception):
|
| def __init__(self, message): self.message = message
|
|
|
| class Cammy(object):
|
| # holes
|
| def hole(self, i):
|
| raise InvalidCammy("Holes not permitted in semantic domain " +
|
| self.__class__.__name__)
|
| def substitute(self, args): pass
|
| # category
|
| def id(self): pass
|
| def comp(self, arrs): pass
|
| # terminal object
|
| def ignore(self): pass
|
| # products
|
| def project(self, k, n): pass
|
| def tuple(self, arrs): pass
|
| # sums
|
| def inject(self, k, n): pass
|
| def case(self, arrs): pass
|
| # internal homs
|
| def curry(self, arr): pass
|
| def uncurry(self, arr): pass
|
| # natural numbers object
|
| def nat(self, k): pass
|
| def succ(self): pass
|
| def pr(self, f, g): pass
|
| # ordinal objects
|
| def ord(self, k, n): pass
|
| # free monoids
|
| def nil(self): pass
|
| def cons(self): pass
|
| def fold(self, f, g): pass
|
| # free binary trees
|
| def tnil(self): pass
|
| def tcons(self): pass
|
| def tfold(self, f, g): pass
|
| # boolean object
|
| def t(self): pass
|
| def f(self): pass
|
| def either(self): pass
|
| def conj(self): pass
|
| def disj(self): pass
|
| def not_(self): pass
|
| # floating-point object
|
| def f0(self): pass
|
| def f1(self): pass
|
| def pi(self): pass
|
| def f_sign(self): pass
|
| def f_lt(self): pass
|
| def f_negate(self): pass
|
| def f_recip(self): pass
|
| def f_add(self): pass
|
| def f_mul(self): pass
|
| def f_floor(self): pass
|
| def f_sqrt(self): pass
|
| def f_sin(self): pass
|
| def f_cos(self): pass
|
| def f_atan2(self): pass
|
| def f_exp(self): pass
|
| def f_log1p(self): pass
|
|
|
| # jets
|
| def dup(self): return self.tuple([self.id()] * 2)
|
| def zero(self): return self.nat(0)
|
| def fst(self): return self.project(0, 2)
|
| def snd(self): return self.project(1, 2)
|
| def swap(self): return self.tuple([self.snd(), self.fst()])
|
| def left(self): return self.inject(0, 2)
|
| def right(self): return self.inject(1, 2)
|
| def app(self): return self.uncurry(self.id())
|
| def n_double(self):
|
| return self.pr(self.zero(), self.comp([self.succ()] * 2))
|
| def n_add(self):
|
| return self.uncurry(self.pr(self.curry(self.snd()),
|
| self.curry(self.comp([self.app(),
|
| self.succ()]))))
|
| def n_pred_maybe(self):
|
| return self.pr(self.right(), self.comp([self.case([self.succ(),
|
| self.zero()]),
|
| self.left()]))
|
| def n_mul(self):
|
| return self.uncurry(self.pr(self.curry(self.comp([self.ignore(),
|
| self.zero()])),
|
| self.curry(self.comp([self.tuple([self.app(),
|
| self.snd()]),
|
| self.n_add()]))))
|
|
|
|
|
| def PairOf(d1, d2):
|
| class PairDomain(object):
|
| import_from_mixin(Cammy)
|
| def __init__(self, d1, d2):
|
| self.d1 = d1
|
| self.d2 = d2
|
|
|
| def hole(self, i): return self.d1.hole(i), self.d2.hole(i)
|
| def substitute(self, args):
|
| return (self.d1.substitute([arg[0] for arg in args]),
|
| self.d2.substitute([arg[1] for arg in args]))
|
| def comp(self, arrs):
|
| return (self.d1.comp([arr[0] for arr in arrs]),
|
| self.d2.comp([arr[1] for arr in arrs]))
|
| def project(self, k, n):
|
| return self.d1.project(k, n), self.d2.project(k, n)
|
| def tuple(self, arrs):
|
| return (self.d1.tuple([arr[0] for arr in arrs]),
|
| self.d2.tuple([arr[1] for arr in arrs]))
|
| def inject(self, k, n):
|
| return self.d1.inject(k, n), self.d2.inject(k, n)
|
| def case(self, arrs):
|
| return (self.d1.case([arr[0] for arr in arrs]),
|
| self.d2.case([arr[1] for arr in arrs]))
|
| def curry(self, arr):
|
| return self.d1.curry(arr[0]), self.d2.curry(arr[1])
|
| def uncurry(self, arr):
|
| return self.d1.uncurry(arr[0]), self.d2.uncurry(arr[1])
|
| def nat(self, k): return self.d1.nat(k), self.d2.nat(k)
|
| def pr(self, f, g):
|
| return self.d1.pr(f[0], g[0]), self.d2.pr(f[1], g[1])
|
| def ord(self, k, n): return self.d1.ord(k, n), self.d2.ord(k, n)
|
| def fold(self, f, g):
|
| return self.d1.fold(f[0], g[0]), self.d2.fold(f[1], g[1])
|
| def tfold(self, f, g):
|
| return self.d1.tfold(f[0], g[0]), self.d2.tfold(f[1], g[1])
|
|
|
| for verb, meth in inspect.getmembers(Cammy, inspect.ismethod):
|
| if verb.startswith("__"): continue
|
| argspec = inspect.getargspec(meth)
|
| if len(argspec[0]) != 1: continue
|
| exec """def {verb}(self): return self.d1.{verb}(), self.d2.{verb}()""".format(verb=verb)
|
| return PairDomain(d1, d2)
|