|
@@ -50,8 +50,9 @@ OP_HINT = 20
|
|
|
OP_REWRITE_ALL = 21
|
|
OP_REWRITE_ALL = 21
|
|
|
OP_REWRITE = 22
|
|
OP_REWRITE = 22
|
|
|
|
|
|
|
|
-# Special identifierd
|
|
|
|
|
|
|
+# Special identifiers
|
|
|
PI = 'pi'
|
|
PI = 'pi'
|
|
|
|
|
+E = 'e'
|
|
|
|
|
|
|
|
|
|
|
|
|
TYPE_MAP = {
|
|
TYPE_MAP = {
|
|
@@ -178,7 +179,7 @@ class ExpressionBase(object):
|
|
|
and (identifier == None or self.value == identifier)
|
|
and (identifier == None or self.value == identifier)
|
|
|
|
|
|
|
|
def is_variable(self):
|
|
def is_variable(self):
|
|
|
- return self.type == TYPE_IDENTIFIER and self.value != PI
|
|
|
|
|
|
|
+ return self.type == TYPE_IDENTIFIER and self.value not in (PI, E)
|
|
|
|
|
|
|
|
def is_int(self):
|
|
def is_int(self):
|
|
|
return self.type == TYPE_INTEGER
|
|
return self.type == TYPE_INTEGER
|
|
@@ -217,6 +218,20 @@ class ExpressionBase(object):
|
|
|
"""Negate the node n times."""
|
|
"""Negate the node n times."""
|
|
|
return negate(self, self.negated + n)
|
|
return negate(self, self.negated + n)
|
|
|
|
|
|
|
|
|
|
+ def contains(self, node, include_self=True):
|
|
|
|
|
+ """
|
|
|
|
|
+ Check if a node equal to the specified one exists within this node.
|
|
|
|
|
+ """
|
|
|
|
|
+ if include_self and self == node:
|
|
|
|
|
+ return True
|
|
|
|
|
+
|
|
|
|
|
+ if not self.is_leaf:
|
|
|
|
|
+ for child in self:
|
|
|
|
|
+ if child.contains(node, include_self=True):
|
|
|
|
|
+ return True
|
|
|
|
|
+
|
|
|
|
|
+ return False
|
|
|
|
|
+
|
|
|
|
|
|
|
|
class ExpressionNode(Node, ExpressionBase):
|
|
class ExpressionNode(Node, ExpressionBase):
|
|
|
def __init__(self, *args, **kwargs):
|
|
def __init__(self, *args, **kwargs):
|