def test_is_number(self): """Test is_number.""" self.assertTrue(utils.is_number(0)) self.assertTrue(utils.is_number(1)) self.assertTrue(utils.is_number(1.5)) self.assertTrue(utils.is_number(5j)) self.assertTrue(utils.is_number(2 + 5j)) self.assertTrue(utils.is_number(999999999999999L)) # See utils.is_number source if wondering about NaNs. self.assertTrue(utils.is_number(float('NaN'))) self.assertFalse(utils.is_number('a')) self.assertFalse(utils.is_number({}))
def expr2(s): """Create an Expr representing a logic expression by parsing the input string. Symbols and numbers are automatically converted to Exprs. In addition you can use alternative spellings of these operators: 'x ==> y' parses as (x >> y) # Implication 'x <== y' parses as (x << y) # Reverse implication 'x <=> y' parses as (x % y) # Logical equivalence 'x =/= y' parses as (x ^ y) # Logical disequality (xor) But BE CAREFUL; precedence of implication is wrong. expr('P & Q ==> R & S') is ((P & (Q >> R)) & S); so you must use expr('(P & Q) ==> (R & S)'). >>> expr('P <=> Q(1)') (P <=> Q(1)) >>> expr('P & Q | ~R(x, F(x))') ((P & Q) | ~R(x, F(x))) """ if isinstance(s, Expr): return s if utils.is_number(s): return Expr(s) if isinstance(s, Description): return Expr(s) ## Replace the alternative spellings of operators with canonical spellings s = s.replace('==>', '>>').replace('<==', '<<') s = s.replace('<=>', '%').replace('=/=', '^') ## Replace a symbol or number, such as 'P' with 'Expr('P')' s = re.sub(r'([a-zA-Z0-9_\-$.?]+)', r"Expr('\1')", s) ## Now eval the string. (A security hole; do not use with an adversary.) # print 'EVALLING: %s' % (s,) return eval(s, {'Expr': Expr})
def __init__(self, op, *args): """Op is a string or number; args are Exprs (or are coerced to Exprs).""" assert (isinstance(op, str) or isinstance(op, Description) or (utils.is_number(op) and not args)) if isinstance(op, Description): self.op = op else: self.op = utils.num_or_str(op) self.args = map(expr, args) # Coerce args to Exprs