def test_parse_with_mixed_operators_multilines_and_custom_symbol(self): class MySymbol(Symbol): pass expr_str = '''(a or ~ b +_c ) and d & ( ! e_ | (my * g OR 1 or 0) ) AND that ''' algebra = BooleanAlgebra(Symbol_class=MySymbol) expr = algebra.parse(expr_str) expected = algebra.AND( algebra.OR( algebra.Symbol('a'), algebra.NOT(algebra.Symbol('b')), algebra.Symbol('_c'), ), algebra.Symbol('d'), algebra.OR( algebra.NOT(algebra.Symbol('e_')), algebra.OR( algebra.AND( algebra.Symbol('my'), algebra.Symbol('g'), ), algebra.TRUE, algebra.FALSE, ), ), algebra.Symbol('that'), ) self.assertEqual(expected.pretty(), expr.pretty()) self.assertEqual(expected, expr)
def test_parse(self): algebra = BooleanAlgebra() a, b, c = algebra.Symbol('a'), algebra.Symbol('b'), algebra.Symbol('c') self.assertEqual(algebra.parse('0'), algebra.FALSE) self.assertEqual(algebra.parse('(0)'), algebra.FALSE) self.assertEqual(algebra.parse('1') , algebra.TRUE) self.assertEqual(algebra.parse('(1)'), algebra.TRUE) self.assertEqual(algebra.parse('a'), a) self.assertEqual(algebra.parse('(a)'), a) self.assertEqual(algebra.parse('(a)'), a) self.assertEqual(algebra.parse('~a'), algebra.parse('~(a)')) self.assertEqual(algebra.parse('~(a)'), algebra.parse('(~a)')) self.assertEqual(algebra.parse('~a'), ~a) self.assertEqual(algebra.parse('(~a)'), ~a) self.assertEqual(algebra.parse('~~a', simplify=True), (~~a).simplify()) self.assertEqual(algebra.parse('a&b'), a & b) self.assertEqual(algebra.parse('~a&b'), ~a & b) self.assertEqual(algebra.parse('a&~b'), a & ~b) self.assertEqual(algebra.parse('a&b&c'), algebra.parse('a&b&c')) self.assertEqual(algebra.parse('a&b&c'), algebra.AND(a, b, c)) self.assertEqual(algebra.parse('~a&~b&~c'), algebra.parse('~a&~b&~c')) self.assertEqual(algebra.parse('~a&~b&~c'), algebra.AND(~a, ~b, ~c)) self.assertEqual(algebra.parse('a|b'), a | b) self.assertEqual(algebra.parse('~a|b'), ~a | b) self.assertEqual(algebra.parse('a|~b'), a | ~b) self.assertEqual(algebra.parse('a|b|c'), algebra.parse('a|b|c')) self.assertEqual(algebra.parse('a|b|c'), algebra.OR(a, b, c)) self.assertEqual(algebra.parse('~a|~b|~c'), algebra.OR(~a, ~b, ~c)) self.assertEqual(algebra.parse('(a|b)'), a | b) self.assertEqual(algebra.parse('a&(a|b)', simplify=True), (a & (a | b)).simplify()) self.assertEqual(algebra.parse('a&(a|~b)', simplify=True), (a & (a | ~b)).simplify()) self.assertEqual(algebra.parse('(a&b)|(b&((c|a)&(b|(c&a))))', simplify=True), ((a & b) | (b & ((c | a) & (b | (c & a))))).simplify()) self.assertEqual(algebra.parse('(a&b)|(b&((c|a)&(b|(c&a))))', simplify=True), algebra.parse('a&b | b&(c|a)&(b|c&a)', simplify=True))
def test_dual(self): algebra = BooleanAlgebra() self.assertEqual(algebra.AND(algebra.Symbol('a'), algebra.Symbol('b')).dual, algebra.OR) self.assertEqual(algebra.OR(algebra.Symbol('a'), algebra.Symbol('b')).dual, algebra.AND) self.assertEqual(algebra.parse('a|b').dual, algebra.AND) self.assertEqual(algebra.parse('a&b').dual, algebra.OR)
def test_distributive(self): algebra = BooleanAlgebra() a = algebra.Symbol('a') b = algebra.Symbol('b') c = algebra.Symbol('c') d = algebra.Symbol('d') e = algebra.Symbol('e') self.assertEqual((a & (b | c)).distributive(), (a & b) | (a & c)) t1 = algebra.AND(a, (b | c), (d | e)) t2 = algebra.OR(algebra.AND(a, b, d), algebra.AND(a, b, e), algebra.AND(a, c, d), algebra.AND(a, c, e)) self.assertEqual(t1.distributive(), t2)
def test_parse_recognizes_trueish_and_falsish_symbol_tokens(self): expr_str = 'True or False or None or 0 or 1 or TRue or FalSE or NONe' algebra = BooleanAlgebra() expr = algebra.parse(expr_str) expected = algebra.OR( algebra.TRUE, algebra.FALSE, algebra.FALSE, algebra.FALSE, algebra.TRUE, algebra.TRUE, algebra.FALSE, algebra.FALSE, ) self.assertEqual(expected, expr)
def test_simplify_complex_expression_parsed_then_simplified(self): # FIXME: THIS SHOULD NOT FAIL algebra = BooleanAlgebra() a = algebra.Symbol('a') b = algebra.Symbol('b') c = algebra.Symbol('c') d = algebra.Symbol('d') parse = algebra.parse test_expression_str = ''.join(''' (~a&~b&~c&~d) | (~a&~b&~c&d) | (~a&b&~c&~d) | (~a&b&c&d) | (~a&b&~c&d) | (~a&b&c&~d) | (a&~b&~c&d) | (~a&b&c&d) | (a&~b&c&d) | (a&b&c&d) '''.split()) test_expression = ((~a & ~b & ~c & ~d) | (~a & ~b & ~c & d) | (~a & b & ~c & ~d) | (~a & b & c & d) | (~a & b & ~c & d) | (~a & b & c & ~d) | (a & ~b & ~c & d) | (~a & b & c & d) | (a & ~b & c & d) | (a & b & c & d)) parsed = parse(test_expression_str) self.assertEqual(test_expression_str, str(parsed)) expected = (a & ~b & d) | (~a & b) | (~a & ~c) | (b & c & d) self.assertEqual(expected.pretty(), test_expression.simplify().pretty()) parsed = parse(test_expression_str, simplify=True) # FIXME: THIS SHOULD NOT FAIL # we have a different simplify behavior for expressions built from python expressions # vs. expression built from an object tree vs. expression built from a parse self.assertEqual(expected.simplify().pretty(), parsed.simplify().pretty()) expected_str = '(a&~b&d)|(~a&b)|(~a&~c)|(b&c&d)' self.assertEqual(expected_str, str(parsed)) parsed2 = parse(test_expression_str) self.assertEqual(expected.pretty(), parsed2.simplify().pretty()) self.assertEqual(expected_str, str(parsed2.simplify())) expected = algebra.OR( algebra.AND(algebra.NOT(algebra.Symbol('a')), algebra.NOT(algebra.Symbol('b')), algebra.NOT(algebra.Symbol('c')), algebra.NOT(algebra.Symbol('d'))), algebra.AND(algebra.NOT(algebra.Symbol('a')), algebra.NOT(algebra.Symbol('b')), algebra.NOT(algebra.Symbol('c')), algebra.Symbol('d')), algebra.AND(algebra.NOT(algebra.Symbol('a')), algebra.Symbol('b'), algebra.NOT(algebra.Symbol('c')), algebra.NOT(algebra.Symbol('d'))), algebra.AND(algebra.NOT(algebra.Symbol('a')), algebra.Symbol('b'), algebra.Symbol('c'), algebra.Symbol('d')), algebra.AND(algebra.NOT(algebra.Symbol('a')), algebra.Symbol('b'), algebra.NOT(algebra.Symbol('c')), algebra.Symbol('d')), algebra.AND(algebra.NOT(algebra.Symbol('a')), algebra.Symbol('b'), algebra.Symbol('c'), algebra.NOT(algebra.Symbol('d'))), algebra.AND(algebra.Symbol('a'), algebra.NOT(algebra.Symbol('b')), algebra.NOT(algebra.Symbol('c')), algebra.Symbol('d')), algebra.AND(algebra.NOT(algebra.Symbol('a')), algebra.Symbol('b'), algebra.Symbol('c'), algebra.Symbol('d')), algebra.AND(algebra.Symbol('a'), algebra.NOT(algebra.Symbol('b')), algebra.Symbol('c'), algebra.Symbol('d')), algebra.AND(algebra.Symbol('a'), algebra.Symbol('b'), algebra.Symbol('c'), algebra.Symbol('d'))) result = parse(test_expression_str) result = result.simplify() self.assertEqual(expected, result)