From 27a0bda83fd38ce066773266805769f33073bfaf Mon Sep 17 00:00:00 2001 From: portnov Date: Sun, 1 Jun 2008 14:55:05 +0000 Subject: [PATCH] Almost full rewrite of alpha-conversion and beta-reduction. New implementation is in data2.py, which is used instead of data.py. Eta-reduction is not implemented yet. --- data.py | 182 ++++++++++++++++++++++++++++++++++++++++----------------- data.pyc | Bin 16384 -> 21267 bytes lambdalex.pyc | Bin 1801 -> 1809 bytes parsetab.pyc | Bin 4096 -> 4086 bytes pylambda.py | 8 +- 5 files changed, 133 insertions(+), 57 deletions(-) diff --git a/data.py b/data.py index 41859d5..34477df 100644 --- a/data.py +++ b/data.py @@ -8,6 +8,64 @@ vars = dict() varnames = "xyztspqfgabcdehijklmnoruvwABCDEFGHIJKLMNOPQRSTUVWXYZ" DBFILE = os.path.expanduser("~/.config/pylambda.vars") +DEBUG = 1 + +if DEBUG: + def debug(s): + print s +else: + def debug(s): + pass + +def multy_lambda(arglist,expr): + "Return Lambda(arglist[0],Lambda(arglist[1],...Lambda(arglist[n],expr))..)." + if len(arglist) == 1: + return Lambda(Var(arglist[0]),expr) + else: + return Lambda(Var(arglist[0]),multy_lambda(arglist[1:],expr)) + +def first_var(num,excl_list=[]): + n = num + while varnames[n] in excl_list: + n = n+1 + return varnames[n] + +def nextvar(old): + if old.count("'") < 3: + n = old + "'" + else: + o = old[0] + i = (varnames.index(o)+1)%len(varnames) + n = varnames[i] + return n + +def FV(obj): + return obj.FV() + +def V(obj): + return obj.V() + +def Clos(obj): + fv = FV(obj) + l = obj + for v in fv: + l = Lambda(v,l) + return l + +def CV(obj): + return V(obj).difference(FV(obj)) + +def alpha(obj,app): + vs = V(obj) + fv = FV(app) + vs = vs.union(fv) + if type(obj) == Lambda: + for v in CV(obj): + nv = first_var(0,vs) + debug(">> Changing %s for %s in %s" % (v,nv,obj)) + obj = obj.subst(v.show(), Var(nv)) + vs.add(nv) + return obj def lambda_pow(var,expr,const): "Returns right part of (\var.expr^{n})" @@ -28,6 +86,16 @@ class Expr(object): self.a1 = a1 self.a2 = a2 + def __repr__(self): + return "" % (self.a1,self.op,self.a2) + + def FV(self): + "Set of free variables in this expression." + return self.a1.FV().union(self.a2.FV()) + + def V(self): + return self.a1.V().union(self.a2.V()) + def show(self): "String representation of an object." if self.op == "@": @@ -47,14 +115,14 @@ class Expr(object): return self.a1.freeof(name) and self.a2.freeof(name) def alpha(self,badlist,vlist=[]): -# print ">> [%d]Expr.Renaming off %s" % (self.number,badlist) + debug(">> [%d]Expr.Renaming off %s" % (self.number,badlist)) a = self.a1.alpha(badlist,vlist) b = self.a2.alpha(badlist,vlist) return Expr(self.op,a,b) def apply(self,expr,excl_list=[]): "Try apply self (as a function) to given Expr." -# print ">> [%d]Expr.Apply: <%s> to <%s>" % (self.number,self.show(),expr.show()) + debug(">> [%d]Expr.Apply: <%s> to <%s>" % (self.number,self.show(),expr.show())) t = self.eval(excl_list) if isinstance(t,Lambda): return t.apply(expr.alpha(excl_list),excl_list) @@ -63,7 +131,7 @@ class Expr(object): def eval_vars(self,excl_list=[]): "Evaluate expression and substitute variables values where possible." -# print ">> [%d]Expr.Eval_vars: <%s> excl_list = %s" % (self.number,self.show(),excl_list) + debug(">> [%d]Expr.Eval_vars: <%s> excl_list = %s" % (self.number,self.show(),excl_list)) tmp = self.eval(excl_list) if isinstance(tmp,Lambda) or isinstance(tmp,Var) or isinstance(tmp,Const) or isinstance(tmp,Null): return tmp @@ -91,7 +159,7 @@ class Expr(object): print "Cannot function-style exponent for constant." return Null() else: - print "Should not reach: unknown operation." + debug("Should not reach: unknown operation.") if self.op == "!": t = self.a1.eval_vars(excl_list) if isinstance(self.a2,Const) and isinstance(t,Lambda): @@ -115,13 +183,13 @@ class Expr(object): def eval(self,excl_list=[]): "Evaluate Expr." -# print ">> [%d]Expr.Eval: <%s> excl_list = %s" % (self.number,self.show(), excl_list) + debug(">> [%d]Expr.Eval: <%s> excl_list = %s" % (self.number,self.show(), excl_list)) lt = self.a1.eval(excl_list) if self.op == "@": if isinstance(lt,Lambda): # if isinstance(self.a2,Var) and isinstance(lt,Lambda): lt = lt.alpha([self.a2.show()]) -# print ">> [%d]Expr.Eval: LT = <%s>" % (self.number,lt.show()) + debug(">> [%d]Expr.Eval: LT = <%s>" % (self.number,lt.show())) l = lt.lambda_vars() e = lt.apply(self.a2.alpha(excl_list,l),excl_list) return e @@ -149,6 +217,9 @@ class Assignment(Expr): self.expr = expr vars[var.show()] = expr + def __repr__(self): + return "" % (self.var,self.expr) + def show(self): return "%s = %s" % (self.var.show(),self.expr.show()) @@ -176,7 +247,7 @@ class Comma(Expr): return Comma(e,self.assign) def eval_vars(self,excl_list=[]): -# print ">> Eval_vars: <%s> excl_list = %s" % (self.show(),excl_list) + debug(">> Eval_vars: <%s> excl_list = %s" % (self.show(),excl_list)) t = self.expr.eval_vars(excl_list) return t.subst(self.assign.var.show(),self.assign.expr).eval_vars(excl_list) @@ -192,33 +263,11 @@ class Null(Expr): def lambda_vars(self): return [] def eval_vars(self,excl_list=[]): -# print ">> Eval_vars: <%s> excl_list = %s" % (self.show(),excl_list) + debug(">> Eval_vars: <%s> excl_list = %s" % (self.show(),excl_list)) return self def eval(self,excl_list=[]): return self -def multy_lambda(arglist,expr): - "Return Lambda(arglist[0],Lambda(arglist[1],...Lambda(arglist[n],expr))..)." - if len(arglist) == 1: - return Lambda(Var(arglist[0]),expr) - else: - return Lambda(Var(arglist[0]),multy_lambda(arglist[1:],expr)) - -def first_var(num,excl_list=[]): - n = num - while varnames[n] in excl_list: - n = n+1 - return varnames[n] - -def nextvar(old): - if old.count("'") < 3: - n = old + "'" - else: - o = old[0] - i = (varnames.index(o)+1)%len(varnames) - n = varnames[i] - return n - class Lambda(Expr): "Lambda-expression." @@ -232,6 +281,15 @@ class Lambda(Expr): self.var = var self.expr = expr + def __repr__(self): + return "" % (self.var,self.expr) + + def FV(self): + return self.expr.FV().difference(set([self.var])) + + def V(self): + return self.expr.V().union(set([self.var])) + def show(self): return "(λ%s.%s)" % (self.var.show(), self.expr.show()) @@ -244,7 +302,7 @@ class Lambda(Expr): return self.expr.freeof(name) def alpha(self, badlist, vlist = []): -# print ">> [%d]Lambda.Renaming <%s> off %s." % (self.number,self.show(),badlist) + debug(">> [%d]Lambda.Renaming <%s> off %s." % (self.number,self.show(),badlist)) o = self.var.show() s = nextvar(o) while s in badlist: @@ -252,49 +310,49 @@ class Lambda(Expr): b = copy(vlist) if o in badlist: v = Var(s) -# print ">> [%d]Lambda.Rename: renamed <%s> to <%s>." % (self.number,o,s) + debug(">> [%d]Lambda.Rename: renamed <%s> to <%s>." % (self.number,o,s)) b.append(o) e = self.expr.alpha(badlist,b) r = Lambda(v,e,False) else: -# print ">> [%d]Lambda.Rename: will not rename var: my var is <%s>" % (self.number, o) + debug(">> [%d]Lambda.Rename: will not rename var: my var is <%s>" % (self.number, o)) e = self.expr.alpha(badlist,b) # e = self.expr r = Lambda(self.var,e,False) -# print ">> [%d]Lambda.Rename result = <%s>" % (self.number,r.show()) + debug(">> [%d]Lambda.Rename result = <%s>" % (self.number,r.show())) return r def subst(self,old,new): - if self.var.show() != old: + if self.var.show() != old and not new in FV(self): return Lambda(self.var,self.expr.subst(old,new)) else: - return self + return Lambda(new,self.expr.subst(old,new)) def apply(self,expr,excl_list=[]): -# print ">> [%d]Lambda.Apply Excl_list = %s." % (self.number,excl_list) + debug(">> [%d]Lambda.Apply Excl_list = %s." % (self.number,excl_list)) l = self.lambda_vars() -# print ">> [%d]Lambda.Apply Lambda_vars = %s" % (self.number,l) + debug(">> [%d]Lambda.Apply Lambda_vars = %s" % (self.number,l)) q = expr.alpha(l) e = self.expr.subst(self.var.show(),q) -# print ">> [%d]Lambda.Apply <%s> to <%s> result: <%s>" % (self.number,self.show(),q.show(),e.show()) + debug(">> [%d]Lambda.Apply <%s> to <%s> result: <%s>" % (self.number,self.show(),q.show(),e.show())) return e def eval_vars(self,excl_list=[]): -# print ">> Lambda.Eval_vars: <%s> excl_list = %s" % (self.show(),excl_list) + debug(">> Lambda.Eval_vars: <%s> excl_list = %s" % (self.show(),excl_list)) l = copy(excl_list) l.append(self.var.show()) e = self.expr.eval_vars(l).alpha(l) return Lambda(self.var,e) def eval(self,excl_list=[]): -# print ">> [%d]Lambda.Eval: <%s> excl_list = %s" % (self.number,self.show(),excl_list) + debug(">> [%d]Lambda.Eval: <%s> excl_list = %s" % (self.number,self.show(),excl_list)) if self.var.show() in excl_list: t = self.alpha(excl_list) else: t = copy(self) l = copy(excl_list) l.append(t.var.show()) -# print " > > [ % d]Lambda.Eval: L = % s" % (self.number, l) + debug(" > > [ % d]Lambda.Eval: L = % s" % (self.number, l)) # Perform η-reduction try: if t.expr.op == "@" and isinstance(t.expr.a2,Var) and not isinstance(t.expr.a2,Const): @@ -335,6 +393,15 @@ class Var(Expr): def __init__(self,name): self.name = name + def __repr__(self): + return "" % self.name + + def FV(self): + return set([self]) + + def V(self): + return set([self]) + def show(self): return self.name @@ -352,43 +419,43 @@ class Var(Expr): def alpha(self,badlist,vlist=[]): # return self -# print ">> [%s]Var.Renaming off %s, %s" % (self.name,badlist,vlist) + debug(">> [%s]Var.Renaming off %s, %s" % (self.name,badlist,vlist)) if self.name in vlist and not self.name in vars: o = nextvar(self.name) while o in vlist+badlist: o = nextvar(o) v = Var(o) -# print ">> [%s]Var.Rename: Lists: %s, %s. Renaming to <%s>" % (self.name,badlist,vlist,o) + debug(">> [%s]Var.Rename: Lists: %s, %s. Renaming to <%s>" % (self.name,badlist,vlist,o)) return v else: return self def apply(self,expr,excl_list=[]): -# print ">> Var.Apply called." + debug(">> Var.Apply called.") return Expr('@',copy(self),expr) def eval_vars(self,excl_list=[]): -# print ">> [%s]Var.Eval_vars: excl_list = %s" % (self.show(),excl_list) + debug(">> [%s]Var.Eval_vars: excl_list = %s" % (self.show(),excl_list)) if self.name in excl_list: return Var(self.name) else: e = self.eval(excl_list).alpha(excl_list) -# print ">> Eval_vars: Var <%s> evaluated to <%s>." % (self.name,e.show()) + debug(">> Eval_vars: Var <%s> evaluated to <%s>." % (self.name,e.show())) return e def eval(self,excl_list=[]): -# print ">> [%s]Var.Eval: excl_list = %s" % (self.show(),excl_list) + debug(">> [%s]Var.Eval: excl_list = %s" % (self.show(),excl_list)) if (self.name in vars) and not (self.name in excl_list): e = vars[self.name].alpha(excl_list) -# print ">> [%s]Var.Eval: read <%s> from hash" % (self.show(),e.show()) + debug(">> [%s]Var.Eval: read <%s> from hash" % (self.show(),e.show())) if isinstance(e,Lambda): if e.var.show() in excl_list: -# print ">> [%s]Var.Eval: this is Lambda, creating new Lambda with new var." % self.show() + debug(">> [%s]Var.Eval: this is Lambda, creating new Lambda with new var." % self.show()) e = Lambda(e.var,e.expr.alpha(excl_list),True,excl_list) -# print ">> -------" + debug(">> -------") else: e = copy(self) -# print ">> Var.Eval: Var <%s> evaluated to <%s>." % (self.name,e.show()) + debug(">> Var.Eval: Var <%s> evaluated to <%s>." % (self.name,e.show())) return e class Const(Var): @@ -396,6 +463,15 @@ class Const(Var): def __init__(self,num): self.num = num + def __repr__(self): + return "" % self.num + + def FV(self): + return set() + + def V(self): + return set() + def show(self): return str(self.num) @@ -409,7 +485,7 @@ class Const(Var): return copy(self) def eval_vars(self,excl_list=[]): -# print ">> Eval_vars: <%s> excl_list = %s" % (self.show(),excl_list) + debug(">> Eval_vars: <%s> excl_list = %s" % (self.show(),excl_list)) return copy(self) def apply(self,expr,excl_list=[]): diff --git a/data.pyc b/data.pyc index ccd78c2e9ef7e2555f08191ff341132a73a9a51b..48cdfc633b6b22c36e6301be300fdf3ee3fa9a7d 100644 GIT binary patch literal 21267 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 a^^sa_`aOINdtmzf^pkLQhxBi(R{vk~7)B!i diff --git a/lambdalex.pyc b/lambdalex.pyc index fe3150418d1a0af27d18c2980142c181bb42b134..e10913ba5f6768e8c3af538b65eb758fada3f391 100644 GIT binary patch delta 555 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 diff --git a/pylambda.py b/pylambda.py index f01adeb..941f1c1 100755 --- a/pylambda.py +++ b/pylambda.py @@ -7,7 +7,7 @@ from ply import yacc from lambdalex import tokens # from data import Assignment,Comma,Expr,Lambda,Var,Const,multy_lambda,typeof,load,save,show_vars -from data import * +from data2 import * precedence = ( ('left','EQ'), @@ -32,7 +32,7 @@ def p_generic_assign(t): def p_assignment(t): 'assignment : VAR EQ expr' - if not t[3].freeof(t[1]): + if Var(t[1]) in FV(t[3]): print "Warning: recursive assignment." t[0]= Assignment(Var(t[1]),t[3]) @@ -160,8 +160,8 @@ if __name__ == "__main__": break if s == "" : continue try: - value = yacc.parse(s).eval().eval_vars() - print ": %s :: %s" % (value.show(), typeof(value)) + value = yacc.parse(s).eval().eval() + print ": %s :: %s" % (value, typeof(value)) set_old_value(value) except TypeError,e: print e -- 1.7.2.3