Advertisement
Guest User

Untitled

a guest
Dec 28th, 2014
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.31 KB | None | 0 0
  1. from inspect import getfullargspec
  2.  
  3. def validate(fun):
  4.   annotations = fun.__annotations__
  5.   def wrapped(*args, **kwargs):
  6.  
  7.     for arg, arg_name in zip(args, getfullargspec(fun).args):
  8.       if arg_name in annotations:
  9.         t = annotations[arg_name]
  10.         assert isinstance(arg, t)
  11.  
  12.     for k, v in annotations.items():
  13.       if k != "return" and k in kwargs:
  14.         assert isinstance(kwargs[k], v)
  15.  
  16.     out = fun(*args, **kwargs)
  17.     if "return" in annotations:
  18.       assert isinstance(out, annotations["return"])
  19.     return out
  20.  
  21.   return wrapped
  22.  
  23. class Term:
  24.   pass
  25.  
  26. class Symbol(Term):
  27.   @validate
  28.   def __init__(self, wrapped):
  29.     self.wrapped = wrapped
  30.  
  31.   def __repr__(self):
  32.     return repr(self.wrapped)
  33.  
  34.   def __eq__(self, other):
  35.     return self.wrapped == other.wrapped
  36.  
  37. class Abstr(Term):
  38.   @validate
  39.   def __init__(self, var : Symbol, body : Term):
  40.     self.var = var
  41.     self.body = body
  42.  
  43.   def to_tuple(self):
  44.     return ("lambda", self.var, self.body)
  45.  
  46.   def __repr__(self):
  47.     return repr(self.to_tuple())
  48.  
  49. class App(Term):
  50.   @validate
  51.   def __init__(self, t : Term, s : Term):
  52.     self.t = t
  53.     self.s = s
  54.  
  55.   def to_tuple(self):
  56.     return (self.t, self.s)
  57.  
  58.   def __repr__(self):
  59.     return repr(self.to_tuple())
  60.  
  61. @validate
  62. def substitute(body : Term, var_name : Symbol, arg : Term):
  63.   "capture avoiding substitution"
  64.   if isinstance(body, Symbol):
  65.     # change the symbol if the symbol is the same
  66.     return arg if body == var_name else body
  67.   elif isinstance(body, Abstr):
  68.     # variable has same name as replaced variable, block substitution.
  69.     if body.var == var_name:
  70.       return body
  71.     # otherwise, substitution recurses down
  72.     else:
  73.       return Abstr(body.var, substitute(body.body, var_name, arg))
  74.   elif isinstance(body, App):
  75.     # substitute into the function and the arguments
  76.     return App(
  77.       substitute(body.t, var_name, arg),
  78.       substitute(body.s, var_name, arg)
  79.     )
  80.  
  81. @validate
  82. def hit(x : Term):
  83.   "hit expression, perform beta reduction"
  84.   if isinstance(x, App):
  85.     fun = x.t
  86.     body = x.s
  87.     if isinstance(fun, Abstr):
  88.       return substitute(fun.body, fun.var, body)
  89.   return None
  90.  
  91. a = Symbol("a")
  92. x = Symbol("x")
  93. y = Symbol("y")
  94.  
  95. expr = Abstr(x, Abstr(y, App(x,y)))
  96. print(expr)
  97.  
  98. print( hit(App(expr,a)) )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement