class Exp:
label = None
value = None
e1, e2 = None, None
def __init__(self):
pass
def __str__(self):
rInt = lambda x: "Int {0!s}".format(x)
r = lambda label: lambda x, y: "{0!s} ({1!s}) ({2!s})".format(label, x, y)
return foldE(rInt, r("Add"), r("Min"), r("Mul"), self)
# if self.label == "EInt":
# return "EInt {0!s}".format(self.value)
# else:
# return "{0!s} ({1!s}) ({2!s})".format(self.label, self.e1, self.e2)
def __eq__(self, other):
pair = (self.label, other.label)
if pair == ("EInt", "EInt"):
return self.value == other.value
else:
return self.label == other.label and self.e1 == other.e1 and self.e2 == other.e2
def eval(self):
rInt = lambda x: x
rAdd = lambda x, y: x + y
rMin = lambda x, y: x - y
rMul = lambda x, y: x * y
return foldE(rInt, rAdd, rMin, rMul, self)
def depth(self):
rInt = lambda x: 1
r = lambda x, y: 1 + max (x, y)
return foldE(rInt, r, r, r, self)
def foldE(rInt, rAdd, rMin, rMul, exp):
if exp.label == "EInt":
return rInt(exp.value)
elif exp.label == "EAdd":
r1 = foldE(rInt, rAdd, rMin, rMul, exp.e1)
r2 = foldE(rInt, rAdd, rMin, rMul, exp.e2)
return rAdd(r1, r2)
elif exp.label == "EMin":
r1 = foldE(rInt, rAdd, rMin, rMul, exp.e1)
r2 = foldE(rInt, rAdd, rMin, rMul, exp.e2)
return rMin(r1, r2)
elif exp.label == "EMul":
r1 = foldE(rInt, rAdd, rMin, rMul, exp.e1)
r2 = foldE(rInt, rAdd, rMin, rMul, exp.e2)
return rMul(r1, r2)
else:
pass
def EInt(v):
ret = Exp()
ret.label = "EInt"
ret.value = v
return ret
def EAdd(e1, e2):
ret = Exp()
ret.label = "EAdd"
ret.e1 = e1
ret.e2 = e2
return ret
def EMin(e1, e2):
ret = Exp()
ret.label = "EMin"
ret.e1 = e1
ret.e2 = e2
return ret
def EMul(e1, e2):
ret = Exp()
ret.label = "EMul"
ret.e1 = e1
ret.e2 = e2
return ret
testvalue = EMin (EAdd(EInt(1), EInt(2)), (EMul (EInt(3), EAdd(EInt(4), EInt(5)))))
print(testvalue)
print(testvalue.eval())
# print(testvalue.depth())