Ejemplo n.º 1
0
 def test_remove(self):
     expr = boolean.parse("a*b*c")
     p1 = boolean.parse("b*d")
     p2 = boolean.parse("a*c")
     result = boolean.parse("b")
     self.assertTrue(expr.remove(p1) == expr)
     self.assertTrue(expr.remove(p2) == result)
Ejemplo n.º 2
0
    def test_or(self):
        expr = boolean.Symbol("A") + boolean.Symbol("B")
        plus = boolean.parse("A+B")
        l_or = boolean.parse("A∨B")

        self.assertEqual(expr, plus)
        self.assertEqual(expr, l_or)
Ejemplo n.º 3
0
 def test_simplify(self):
     a = boolean.Symbol("a")
     self.assertTrue(~a == ~a)
     self.assertFalse(a == boolean.parse("~~a", simplify=False))
     self.assertTrue(a == ~~a)
     self.assertTrue(~a == ~~~a)
     self.assertTrue(a == ~~~~a)
     self.assertTrue(~(a * a * a) == ~(a * a * a))
     self.assertFalse(a == boolean.parse("~ ~a", simplify=False))
Ejemplo n.º 4
0
    def test_not(self):
        expr = ~boolean.Symbol("A")
        prime = boolean.parse("A'")
        tilde = boolean.parse("~A")
        l_not = boolean.parse("¬A")
        p_not = boolean.parse("!A")

        self.assertEqual(expr, prime)
        self.assertEqual(expr, tilde)
        self.assertEqual(expr, l_not)
        self.assertEqual(expr, p_not)
Ejemplo n.º 5
0
 def test_class_order(self):
     order = ((boolean.TRUE, boolean.FALSE),
              (boolean.Symbol(), boolean.Symbol("x")),
              (boolean.parse("x*y"),),
              (boolean.parse("x+y"),),
              )
     for i, tests in enumerate(order):
         for case1 in tests:
             for j in range(i + 1, len(order)):
                 for case2 in order[j]:
                     self.assertTrue(case1 < case2)
                     self.assertTrue(case2 > case1)
Ejemplo n.º 6
0
    def test_and(self):
        expr = boolean.Symbol("A") * boolean.Symbol("B")
        star = boolean.parse("A*B")
        dot = boolean.parse("A∙B")
        decimal = boolean.parse("A.B")
        hat = boolean.parse("A^B")
        l_and = boolean.parse("A∧B")

        self.assertEqual(expr, star)
        self.assertEqual(expr, dot)
        self.assertEqual(expr, decimal)
        self.assertEqual(expr, hat)
        self.assertEqual(expr, l_and)
Ejemplo n.º 7
0
 def test_class_order(self):
     order = (
         (boolean.TRUE, boolean.FALSE),
         (boolean.Symbol(), boolean.Symbol("x")),
         (boolean.parse("x*y"), ),
         (boolean.parse("x+y"), ),
     )
     for i, tests in enumerate(order):
         for case1 in tests:
             for j in range(i + 1, len(order)):
                 for case2 in order[j]:
                     self.assertTrue(case1 < case2)
                     self.assertTrue(case2 > case1)
Ejemplo n.º 8
0
 def test_demorgan(self):
     a, b = boolean.symbols("a", "b")
     parse = lambda x: boolean.parse(x, simplify=False)
     self.assertTrue(parse("~(a*b)").demorgan() == ~a + ~b)
     self.assertTrue(parse("~(a+b+c)").demorgan()
                     == parse("~a*~b*~c"))
     self.assertTrue(parse("~(~a*b)").demorgan() == a + ~b)
Ejemplo n.º 9
0
 def test_cancel(self):
     a = boolean.Symbol("a")
     parse = lambda x: boolean.parse(x, simplify=False)
     self.assertTrue(~a == (~a).cancel())
     self.assertTrue(a == parse("~~a").cancel())
     self.assertTrue(~a == parse("~~~a").cancel())
     self.assertTrue(a == parse("~~~~a").cancel())
Ejemplo n.º 10
0
 def test_printing(self):
     a = boolean.Symbol("a")
     self.assertTrue(str(~a) == "~a")
     self.assertTrue(repr(~a) == "NOT(Symbol('a'))")
     expr = boolean.parse("~(a*a)", simplify=False)
     self.assertTrue(str(expr) == "~(a*a)")
     self.assertTrue(repr(expr) == "NOT(AND(Symbol('a'), Symbol('a')))")
Ejemplo n.º 11
0
 def test_cancel(self):
     a = boolean.Symbol("a")
     parse = lambda x: boolean.parse(x, eval=False)
     self.assertTrue(~a == (~a).cancel())
     self.assertTrue(a == parse("~~a").cancel())
     self.assertTrue(~a == parse("~~~a").cancel())
     self.assertTrue(a == parse("~~~~a").cancel())
Ejemplo n.º 12
0
    def __init__(self,
                 pos,
                 dual_expression,
                 hidden=False,
                 anonymous_symbols=True):
        if isinstance(dual_expression, str):
            dual_expression = boolean.parse(dual_expression)
        if not isinstance(dual_expression, boolean.Function):
            raise TypeError("Argument must be str or Function but it is {}"
                            .format(dual_expression.__class__))
        if len(dual_expression.symbols) != 2:
            raise ValueError("Argument must only contain two symbols but contains {}"
                             .format(len(dual_expression.symbols)))

        component = logic_circuit.Gate(dual_expression,
                                       anonymous_symbols=anonymous_symbols)
        super().__init__(pos, hidden, component)

        input_symbols = tuple(k for k, v in self.component.inputs.items())

        # Comments are the maths behind the ratio for where the inputs are
        # (30.939-(22.482+0.825/2))*self.h/30.939
        top_input_y = int(0.260012 * self.h)
        # (30.939-(7.633+0.825/2))*self.h/30.939
        botton_input_y = math.ceil(0.739956 * self.h)

        self.inputs[(SELECT_RADIUS, top_input_y)] = input_symbols[0]
        self.inputs[(SELECT_RADIUS, botton_input_y)] = input_symbols[1]
Ejemplo n.º 13
0
 def test_printing(self):
     a = boolean.Symbol("a")
     self.assertTrue(str(~a) == "a'")
     self.assertTrue(repr(~a) == "NOT(Symbol('a'))")
     expr = boolean.parse("~(a*a)", eval=False)
     self.assertTrue(str(expr) == "(a∙a)'")
     self.assertTrue(repr(expr) == "NOT(AND(Symbol('a'), Symbol('a')))")
Ejemplo n.º 14
0
 def test_subs(self):
     a, b, c = boolean.symbols("a", "b", "c")
     expr = a * b + c
     self.assertEqual(expr.subs({a: b}), b + c)
     self.assertEqual(expr.subs({a: a}), expr)
     self.assertEqual(expr.subs({a: b + c}), boolean.parse("(b+c)*b+c"))
     self.assertEqual(expr.subs({a * b: a}), a + c)
     self.assertEqual(expr.subs({c: boolean.TRUE}), boolean.TRUE)
Ejemplo n.º 15
0
 def test_subs(self):
     a, b, c = boolean.symbols("a", "b", "c")
     expr = a * b + c
     self.assertEqual(expr.subs({a: b}), b + c)
     self.assertEqual(expr.subs({a: a}), expr)
     self.assertEqual(expr.subs({a: b + c}), boolean.parse("(b+c)*b+c"))
     self.assertEqual(expr.subs({a * b: a}), a + c)
     self.assertEqual(expr.subs({c: boolean.TRUE}), boolean.TRUE)
Ejemplo n.º 16
0
 def expression(self, expression):
     if isinstance(expression, str):
         expression = boolean.parse(expression, False)
     if not isinstance(expression, boolean.Expression):
         raise TypeError(
             "Argument must be str or Expression but it is {}".format(
                 expression.__class__))
     return expression
Ejemplo n.º 17
0
 def test_eval(self):
     a = boolean.Symbol("a")
     self.assertTrue(~a == ~a)
     self.assertFalse(a == boolean.parse("~~a", eval=False))
     self.assertTrue(a == ~~a)
     self.assertTrue(~a, ~~~a)
     self.assertTrue(a, ~~~~a)
     self.assertTrue(~(a * a * a) == ~(a * a * a))
Ejemplo n.º 18
0
 def test_printing(self):
     parse = lambda x: boolean.parse(x, simplify=False)
     self.assertTrue(str(parse("a*a")) == "a*a")
     self.assertTrue(repr(parse("a*a")) == "AND(Symbol('a'), Symbol('a'))")
     self.assertTrue(str(parse("a+a")) == "a+a")
     self.assertTrue(repr(parse("a+a")) == "OR(Symbol('a'), Symbol('a'))")
     self.assertTrue(str(parse("(a+b)*c")) == "(a+b)*c")
     self.assertTrue(repr(parse("(a+b)*c")) ==
                     "AND(OR(Symbol('a'), Symbol('b')), Symbol('c'))")
Ejemplo n.º 19
0
 def test_creation(self):
     E = boolean.Expression
     expr_str = "(a+b+c)*d*(~e+(f*g))"
     expr = boolean.parse(expr_str)
     self.assertTrue(E(expr) is expr)
     self.assertTrue(E(expr_str) == expr)
     self.assertTrue(E(1) is boolean.TRUE)
     self.assertTrue(E(True) is boolean.TRUE)
     self.assertTrue(E(0) is boolean.FALSE)
     self.assertTrue(E(False) is boolean.FALSE)
Ejemplo n.º 20
0
 def test_literals(self):
     a = boolean.Symbol("a")
     l = ~a
     self.assertTrue(l.isliteral)
     self.assertTrue(l in l.literals)
     self.assertTrue(len(l.literals) == 1)
     l = boolean.parse("~(a*a)", simplify=False)
     self.assertFalse(l.isliteral)
     self.assertTrue(a in l.literals)
     self.assertTrue(len(l.literals) == 1)
Ejemplo n.º 21
0
 def test_creation(self):
     E = boolean.Expression
     expr_str = "(a+b+c)*d*(~e+(f*g))"
     expr = boolean.parse(expr_str)
     self.assertTrue(E(expr) is expr)
     self.assertTrue(E(expr_str) == expr)
     self.assertTrue(E(1) is boolean.TRUE)
     self.assertTrue(E(True) is boolean.TRUE)
     self.assertTrue(E(0) is boolean.FALSE)
     self.assertTrue(E(False) is boolean.FALSE)
Ejemplo n.º 22
0
 def table(self, table):
     if isinstance(table, str):
         table = boolean.parse(table, False)
     if isinstance(table, boolean.Expression):
         table = boolean.truth_table(table)
     else:
         raise TypeError("Argument must be Expression but it is {}".format(
             table.__class__))
     # Table should not be directly modified
     return tuple(table)
Ejemplo n.º 23
0
 def test_literals(self):
     a = boolean.Symbol("a")
     l = ~a
     self.assertTrue(l.isliteral)
     self.assertTrue(l in l.literals)
     self.assertTrue(len(l.literals) == 1)
     l = boolean.parse("~(a*a)", eval=False)
     self.assertFalse(l.isliteral)
     self.assertTrue(a in l.literals)
     self.assertTrue(len(l.literals) == 1)
Ejemplo n.º 24
0
    def test_flatten(self):
        p = lambda x: boolean.parse(x, simplify=False)

        t1 = p("a * (b*c)")
        t2 = p("a*b*c")
        self.assertFalse(t1 == t2)
        self.assertTrue(t1.flatten() == t2)

        t1 = p("a + ((b*c) + (a*c)) + b")
        t2 = p("a + (b*c) + (a*c) + b")
        self.assertFalse(t1 == t2)
        self.assertTrue(t1.flatten() == t2)
Ejemplo n.º 25
0
 def test_simplify(self):
     a = self.a
     b = self.b
     c = self.c
     _0 = boolean.FALSE
     _1 = boolean.TRUE
     # Idempotence
     self.assertTrue(a == a * a)
     # Idempotence + Associativity
     self.assertTrue(a + b == a + (a + b))
     # Annihilation
     self.assertTrue(_0 == (a * _0))
     self.assertTrue(_1 == (a + _1))
     # Identity
     self.assertTrue(a == (a * _1))
     self.assertTrue(a == (a + _0))
     # Complementation
     self.assertTrue(_0 == a * ~a)
     self.assertTrue(_1 == a + ~a)
     # Absorption
     self.assertTrue(a == a * (a + b))
     self.assertTrue(a == a + (a * b))
     self.assertTrue(b * a == (b * a) + (b * a * c))
     # Elimination
     self.assertTrue(a == (a * ~b) + (a * b))
     expr = boolean.parse("(~a*b*c) + (a*~b*c) + (a*b*~c) + (a*b*c)")
     result = boolean.parse("(a*b)+(b*c)+(a*c)")
     self.assertTrue(expr == result)
     expr = boolean.parse("(~a*b*~c*~d) + (a*~b*~c*~d) + (a*~b*c*~d) +"
                          "(a*~b*c*d) + (a*b*~c*~d) + (a*b*c*d)")
     result = boolean.parse("(~b*~d*a) + (~c*~d*b) + (a*c*d)")
     self.assertTrue(expr == result)
     expr = boolean.parse("(a*b*c*d) + (b*d)")
     result = boolean.parse("b*d")
     self.assertTrue(expr == result)
Ejemplo n.º 26
0
 def test_printing(self):
     parse = lambda x: boolean.parse(x, eval=False)
     a = self.a
     b = self.b
     c = self.c
     self.assertTrue(str(parse("a*a")) == "a∙a")
     self.assertTrue(repr(parse("a*a")) == "AND(Symbol('a'), Symbol('a'))")
     self.assertTrue(str(parse("a+a")) == "a+a")
     self.assertTrue(repr(parse("a+a")) == "OR(Symbol('a'), Symbol('a'))")
     self.assertTrue(str(parse("(a+b)*c")) == "(a+b)∙c")
     self.assertTrue(
         repr(parse("(a+b)*c")) ==
         "AND(OR(Symbol('a'), Symbol('b')), Symbol('c'))")
Ejemplo n.º 27
0
 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'
     expr = boolean.parse(expr_str, simplify=False)
     expected = boolean.OR(
         boolean.TRUE,
         boolean.FALSE,
         boolean.FALSE,
         boolean.FALSE,
         boolean.TRUE,
         boolean.TRUE,
         boolean.FALSE,
         boolean.FALSE,
         simplify=False
     )
     self.assertEqual(expected, expr)
Ejemplo n.º 28
0
    def test_flatten(self):
        p = lambda x: boolean.parse(x, eval=False)
        a = self.a
        b = self.b
        c = self.c

        t1 = p("a * (b*c)")
        t2 = p("a*b*c")
        self.assertFalse(t1 == t2)
        self.assertTrue(t1.flatten() == t2)

        t1 = p("a + ((b*c) + (a*c)) + b")
        t2 = p("a + (b*c) + (a*c) + b")
        self.assertFalse(t1 == t2)
        self.assertTrue(t1.flatten() == t2)
Ejemplo n.º 29
0
 def simplify_expression(self, obj):
     try:
         txt = self.inp.text
         db = root.drawingboard
         sim_exp = boolean.parse(txt)
         exp = Label(text=str(sim_exp),
                     pos=self.pos,
                     size=self.size,
                     font_size=75,
                     color=[0, 0, 0, 1])
         db.clear_widgets()
         db.add_widget(exp)
         self.error.text = ""
     except:
         error = "Invalid Expression"
         self.error.text = error
Ejemplo n.º 30
0
    def test_parse_can_use_iterable_from_alternative_tokenizer(self):

        class CustomSymbol(boolean.Symbol):
            pass

        def tokenizer(s):
            "Sample tokenizer using custom operators and symbols"
            ops = {
                'WHY_NOT': boolean.TOKEN_OR,
                'ALSO': boolean.TOKEN_AND,
                'NEITHER': boolean.TOKEN_NOT,
                '(': boolean.TOKEN_LPAR,
                ')': boolean.TOKEN_RPAR,
            }

            for row, line in enumerate(s.splitlines(False)):
                for col, tok in enumerate(line.split()):
                    if tok in ops:
                        yield ops[tok], tok, row, col
                    elif tok == 'Custom':
                        yield CustomSymbol(tok), tok, row, col
                    else:
                        yield boolean.Symbol(tok), tok, row, col

        expr_str = """( Custom WHY_NOT regular ) ALSO NEITHER  (
                      not_custom ALSO standard )
                    """

        tokenized = tokenizer(expr_str)
        expr = boolean.parse(tokenized, simplify=False)
        expected = boolean.AND(
            boolean.OR(
                CustomSymbol('Custom'),
                boolean.Symbol('regular'),
                simplify=False
            ),
            boolean.NOT(
                boolean.AND(
                    boolean.Symbol('not_custom'),
                    boolean.Symbol('standard'),
                    simplify=False
                ),
                simplify=False
            ),
            simplify=False
        )
        self.assertEqual(expected, expr)
Ejemplo n.º 31
0
    def test_simplify_complex_expression_failing(self):
        a = boolean.Symbol('a')
        b = boolean.Symbol('b')
        c = boolean.Symbol('c')
        d = boolean.Symbol('d')

        test_expression = ''.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())

        expected = eval(test_expression, None, dict(a=a, b=b, c=c, d=d))
        parsed = boolean.parse(test_expression, 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(str(parsed), str(expected))
Ejemplo n.º 32
0
    def __init__(self, expression=None, input_dict={}, anonymous_symbols=True):
        Component.__init__(self)
        self._output = None

        if isinstance(expression, str):
            expression = boolean.parse(expression)
        if not isinstance(expression, boolean.Expression):
            raise ValueError(
                "Argument must be of type str or Expression but is type {}".
                format(expression.__class__))

        if anonymous_symbols:
            new_input_dict = {}
            for symbol in (s for s in expression.symbols.copy()):
                # if s.obj != None):
                new_symbol = boolean.Symbol(None)
                expression = expression.subs({symbol: new_symbol})
                if input_dict.get(symbol) is not None:
                    new_input_dict[new_symbol] = input_dict[symbol]
                elif input_dict.get(str(symbol)) is not None:
                    new_input_dict[new_symbol] = input_dict[str(symbol)]
            input_dict = new_input_dict
        else:

            def symbol_if_string(e):
                if isinstance(e, str):
                    return boolean.Symbol(e)
                elif isinstance(e, boolean.Symbol):
                    return e
                else:
                    raise TypeError(
                        "Argument must be of type str of Symbol but is type {}"
                        .format(e.__class__))

            input_dict = {
                symbol_if_string(k): v
                for k, v in input_dict.items()
            }

        self._expression = expression
        # inputs maps symbols to components
        # This can make an output to itself
        self.inputs = {s: None for s in expression.symbols}
        self.inputs.update(input_dict)
Ejemplo n.º 33
0
    def test_parse_with_mixed_operators_multilines_and_custom_symbol(self):

        class MySymbol(boolean.Symbol):
            pass

        expr_str = """(a or ~ b +_c  ) and #some comment
                      d & ( ! e_
                      | (my * g OR 1 or 0) ) AND that """

        expr = boolean.parse(expr_str, simplify=False, symbol_class=MySymbol)

        expected = boolean.AND(
            boolean.OR(
                MySymbol('a'),
                boolean.NOT(boolean.Symbol('b')),
                MySymbol('_c'),
                simplify=False
            ),
            MySymbol('d'),
            boolean.OR(
                boolean.NOT(MySymbol('e_')),
                boolean.OR(
                    boolean.AND(
                        MySymbol('my'),
                        MySymbol('g'),
                        simplify=False
                    ),
                    boolean.TRUE,
                    boolean.FALSE,
                    simplify=False
                ),
                simplify=False
            ),
            MySymbol('that'),
            simplify=False
        )

        self.assertEqual(expected, expr)
Ejemplo n.º 34
0
 def test_eval(self):
     a = self.a
     b = self.b
     c = self.c
     _0 = boolean.FALSE
     _1 = boolean.TRUE
     # Idempotence
     self.assertTrue(a == a * a)
     # Idempotence + Associativity
     self.assertTrue(a + b == a + (a + b))
     # Annihilation
     self.assertTrue(_0 == (a * _0))
     self.assertTrue(_1 == (a + _1))
     # Identity
     self.assertTrue(a == (a * _1))
     self.assertTrue(a == (a + _0))
     # Complementation
     self.assertTrue(_0 == a * ~a)
     self.assertTrue(_1 == a + ~a)
     # Absorption
     self.assertTrue(a == a * (a + b))
     self.assertTrue(a == a + (a * b))
     self.assertTrue(b * a == (b * a) + (b * a * c))
     # Elimination
     self.assertTrue(a == (a * ~b) + (a * b))
     expr = boolean.parse("(~a*b*c) + (a*~b*c) + (a*b*~c) + (a*b*c)")
     result = boolean.parse("(a*b)+(b*c)+(a*c)")
     self.assertTrue(expr == result)
     expr = boolean.parse("(~a*b*~c*~d) + (a*~b*~c*~d) + (a*~b*c*~d) +"
                          "(a*~b*c*d) + (a*b*~c*~d) + (a*b*c*d)")
     result = boolean.parse("(~b*~d*a) + (~c*~d*b) + (a*c*d)")
     self.assertTrue(expr == result)
     expr = boolean.parse("(a*b*c*d) + (b*d)")
     result = boolean.parse("b*d")
     self.assertTrue(expr == result)
     expr = boolean.parse(
         "(~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)")
Ejemplo n.º 35
0
 def simplify(self, expr):
     sim_exp = boolean.parse(expr)
     exp = Simp(text=str(sim_exp), pos=self.pos, size=self.size)
     self.board.board_canvas.clear_widgets()
     self.board.board_canvas.add_widget(exp)
Ejemplo n.º 36
0
 def on_deselect(self, others, keys, events):
     super().on_deselect(others, keys, events)
     try:
         self.text = str(boolean.parse(self.text, False))
     except TypeError:
         pass
Ejemplo n.º 37
0
 def test_dual(self):
     self.assertTrue(boolean.AND.getdual() is boolean.OR)
     self.assertTrue(boolean.OR.getdual() is boolean.AND)
     self.assertTrue(boolean.parse("a+b").dual is boolean.AND)
     self.assertTrue(boolean.parse("a*b").dual is boolean.OR)
Ejemplo n.º 38
0
 def test_identity(self):
     self.assertTrue(boolean.parse("a+b").identity is boolean.FALSE)
     self.assertTrue(boolean.parse("a*b").identity is boolean.TRUE)
Ejemplo n.º 39
0
 def test_annihilator(self):
     a = boolean.Symbol("a")
     p = lambda x: boolean.parse(x, eval=False)
     self.assertTrue(p("a*a").annihilator is boolean.FALSE)
     self.assertTrue(p("a+a").annihilator is boolean.TRUE)
Ejemplo n.º 40
0
 def test_annihilator(self):
     p = lambda x: boolean.parse(x, simplify=False)
     self.assertTrue(p("a*a").annihilator is boolean.FALSE)
     self.assertTrue(p("a+a").annihilator is boolean.TRUE)
Ejemplo n.º 41
0
 def test_demorgan(self):
     a, b, c = boolean.symbols("a", "b", "c")
     parse = lambda x: boolean.parse(x, eval=False)
     self.assertTrue(parse("~(a*b)").demorgan() == ~a + ~b)
     self.assertTrue(parse("~(a+b+c)").demorgan() == parse("~a*~b*~c"))
     self.assertTrue(parse("~(~a*b)").demorgan() == a + ~b)
Ejemplo n.º 42
0
    def test_parse_with_advanced_tokenizer_example(self):

        class PlainVar(boolean.Symbol):
            "Plain boolean variable"

        class ColonDotVar(boolean.Symbol):
            "Colon and dot-separated string boolean variable"

        def advanced_tokenizer_example(expr):
            """
            Example custom tokenizer derived from the standard tokenizer with
            this extra feature: a colon- and dot-separated string is recognized
            and stored in a custom symbol. Also, in contrast with the standard
            tokenizer, only these boolean operators are recognized : & | ! and
            or not.

            For more advanced tokenization you could also consider forking the
            `tokenize` standard library module.
            """

            if not isinstance(expr, basestring):
                raise TypeError("expr must be string but it is %s." % type(expr))

            # mapping of lowercase token strings to a token object instance for
            # standard operators, parens and common true or false symbols
            TOKENS = {
                '&': boolean.TOKEN_AND,
                'and': boolean.TOKEN_AND,
                '|': boolean.TOKEN_OR,
                'or': boolean.TOKEN_OR,
                '!': boolean.TOKEN_NOT,
                'not': boolean.TOKEN_NOT,
                '(': boolean.TOKEN_LPAR,
                ')': boolean.TOKEN_RPAR,
                'true': boolean.TRUE,
                '1': boolean.TRUE,
                'false': boolean.FALSE,
                '0': boolean.FALSE,
                'none': boolean.FALSE,
            }

            ignored_token_types = (
                tokenize.NL, tokenize.NEWLINE, tokenize.COMMENT,
                tokenize.INDENT, tokenize.DEDENT,
                tokenize.ENDMARKER
            )

            # note: an unbalanced expression may raise a TokenError here.
            tokens = ((toktype, tok, row, col,) for toktype, tok, (row, col,), _, _
                      in tokenize.generate_tokens(StringIO(expr).readline)
                      if tok and tok.strip())

            COLON_DOT = (':', '.',)

            def build_symbol(current_dotted):
                if current_dotted:
                    if any(s in current_dotted for s in COLON_DOT):
                        sym = ColonDotVar(current_dotted)
                    else:
                        sym = PlainVar(current_dotted)
                    return sym

            # accumulator for dotted symbols that span several `tokenize` tokens
            dotted, srow, scol = '', None, None

            for toktype, tok, row, col in tokens:
                if toktype in ignored_token_types:
                    # we reached a break point and should yield the current dotted
                    symbol = build_symbol(dotted)
                    if symbol is not None:
                        yield symbol, dotted, srow, scol
                        dotted, srow, scol = '', None, None

                    continue

                std_token = TOKENS.get(tok.lower())
                if std_token is not None:
                    # we reached a break point and should yield the current dotted
                    symbol = build_symbol(dotted)
                    if symbol is not None:
                        yield symbol, dotted, srow, scol
                        dotted, srow, scol = '', 0, 0

                    yield std_token, tok, row, col

                    continue

                if toktype == tokenize.NAME or (toktype == tokenize.OP and tok in COLON_DOT):
                    if not dotted:
                        srow = row
                        scol = col
                    dotted += tok

                else:
                    raise TypeError('Unknown token: %(tok)r at line: %(row)r, column: %(col)r' % locals())

        test_expr = """
            (colon1:dot1.dot2 or colon2_name:col_on3:do_t1.do_t2.do_t3 )
            and
            ( plain_symbol & !Custom )
        """

        tokenized = advanced_tokenizer_example(test_expr)
        expr = boolean.parse(tokenized, simplify=False)
        expected = boolean.AND(
            boolean.OR(
                ColonDotVar('colon1:dot1.dot2'),
                ColonDotVar('colon2_name:col_on3:do_t1.do_t2.do_t3'),
                simplify=False
            ),
            boolean.AND(
                PlainVar('plain_symbol'),
                boolean.NOT(PlainVar('Custom')),
                simplify=False
            ),
            simplify=False
        )
        self.assertEqual(expected, expr)
Ejemplo n.º 43
0
 def test_isliteral(self):
     s = boolean.Symbol(1)
     self.assertTrue(boolean.NOT(s).isliteral)
     self.assertFalse(boolean.parse("~(a+b)").isliteral)
Ejemplo n.º 44
0
    def test_simplify_complex_expression(self):
        a = boolean.Symbol('a')
        b = boolean.Symbol('b')
        c = boolean.Symbol('c')
        d = boolean.Symbol('d')

        test_expression = ''.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())

        expected = (a * ~b * d) + (~a * b) + (~a * ~c) + (b * c * d)
        self.assertEqual(expected, boolean.parse(test_expression, simplify=True))

        expected = '(~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)'
        self.assertEqual(test_expression, str(boolean.parse(test_expression, simplify=False)))

        expected = '(a*~b*d)+(~a*b)+(~a*~c)+(b*c*d)'
        self.assertEqual(expected, str(boolean.parse(test_expression, simplify=True)))

        expected = boolean.OR(
            boolean.AND(
                boolean.NOT(boolean.Symbol('a')),
                boolean.NOT(boolean.Symbol('b')),
                boolean.NOT(boolean.Symbol('c')),
                boolean.NOT(boolean.Symbol('d'))
            ),
            boolean.AND(
                boolean.NOT(boolean.Symbol('a')),
                boolean.NOT(boolean.Symbol('b')),
                boolean.NOT(boolean.Symbol('c')),
                boolean.Symbol('d')
            ),
            boolean.AND(
                boolean.NOT(boolean.Symbol('a')),
                boolean.Symbol('b'),
                boolean.NOT(boolean.Symbol('c')),
                boolean.NOT(boolean.Symbol('d'))
            ),
            boolean.AND(
                boolean.NOT(boolean.Symbol('a')),
                boolean.Symbol('b'),
                boolean.Symbol('c'),
                boolean.Symbol('d')),
            boolean.AND(
                boolean.NOT(boolean.Symbol('a')),
                boolean.Symbol('b'),
                boolean.NOT(boolean.Symbol('c')),
                boolean.Symbol('d')
            ),
            boolean.AND(
                boolean.NOT(boolean.Symbol('a')),
                boolean.Symbol('b'),
                boolean.Symbol('c'),
                boolean.NOT(boolean.Symbol('d'))
            ),
            boolean.AND(
                boolean.Symbol('a'),
                boolean.NOT(boolean.Symbol('b')),
                boolean.NOT(boolean.Symbol('c')),
                boolean.Symbol('d')
            ),
            boolean.AND(
                boolean.NOT(boolean.Symbol('a')),
                boolean.Symbol('b'),
                boolean.Symbol('c'),
                boolean.Symbol('d')
            ),
            boolean.AND(
                boolean.Symbol('a'),
                boolean.NOT(boolean.Symbol('b')),
                boolean.Symbol('c'),
                boolean.Symbol('d')
            ),
            boolean.AND(
                boolean.Symbol('a'),
                boolean.Symbol('b'),
                boolean.Symbol('c'),
                boolean.Symbol('d')
            )
        )

        self.assertEqual(expected, boolean.parse(test_expression, simplify=True))
Ejemplo n.º 45
0
 def test_isliteral(self):
     s = boolean.Symbol(1)
     self.assertTrue(boolean.NOT(s).isliteral)
     self.assertFalse(boolean.parse("~(a+b)").isliteral)
Ejemplo n.º 46
0
 def test_identity(self):
     self.assertTrue(boolean.parse("a+b").identity is boolean.FALSE)
     self.assertTrue(boolean.parse("a*b").identity is boolean.TRUE)
Ejemplo n.º 47
0
def renderable_components(expression, pos=(0, 0), bulb=True):
    """
    Returns an list of renderable components when given an expression.
    """
    if isinstance(expression, str):
        expression = boolean.parse(expression, eval=False)
    if not isinstance(expression, boolean.Expression):
        raise TypeError(
            "Argument must be str or Expression but it is {}"
            .format(expression.__class__))

    r = [Bulb(pos)]
    symbol_dict = {}

    def recursive_components(e):
        # This function can be used if there is ever the want to attempt to make the
        # converted logic circuit look nicer by spacing the components
        def append(r_comp):
            r.append(r_comp)

        if isinstance(e, boolean.BaseElement):
            rc = Switch(pos)
        elif isinstance(e, boolean.Symbol):
            if e in symbol_dict.keys():
                return symbol_dict[e]
            else:
                rc = Switch(pos)
                symbol_dict[e] = rc
        elif isinstance(e, boolean.NOT):
            pre = recursive_components(e.args[0])
            w = Wire(pos, pos, pre.component)
            append(w)

            rc = Not(pos, w.component)
        elif isinstance(e, boolean.DualBase):
            if len(e.args) != 2:
                new_expr = e.__class__(e.args[0], e.args[1])
                for i in range(2, len(e.args)):
                    new_expr = e.__class__(new_expr, e.args[i], eval=False)
                e = new_expr
            pre0 = recursive_components(e.args[0])
            pre1 = recursive_components(e.args[1])
            w0 = Wire(pos, pos, pre0.component)
            w1 = Wire(pos, pos, pre1.component)
            append(w0)
            append(w1)

            if isinstance(e, boolean.AND):
                rc = And(pos)
            elif isinstance(e, boolean.OR):
                rc = Or(pos)
            c = rc.component
            c.inputs[c.empty_input_keys[0]] = w0.component
            c.inputs[c.empty_input_keys[0]] = w1.component
        append(rc)
        return rc

    recursive_components(expression)
    if bulb:
        w = Wire(pos, pos, r[-1].component)
        r[0].component.input = w.component
        r.append(w)
    else:
        r.pop(0)
    return r
Ejemplo n.º 48
0
 def test_dual(self):
     self.assertTrue(boolean.AND.getdual() is boolean.OR)
     self.assertTrue(boolean.OR.getdual() is boolean.AND)
     self.assertTrue(boolean.parse("a+b").dual is boolean.AND)
     self.assertTrue(boolean.parse("a*b").dual is boolean.OR)
Ejemplo n.º 49
0
def circuit_board(expression, bulb=True, eval=False):
    """
    Takes an expression and converts it into a circuit board.
    """
    if isinstance(expression, str):
        expression = boolean.parse(expression, eval=eval)
    if not isinstance(expression, boolean.Expression):
        raise TypeError(
            "Argument must be str or Expression but it is {}".format(
                expression.__class__))

    # A list would work equally as well
    b = CircuitBoard()
    # A symbol can exist multiple times in an expression
    symbol_dict = {}

    def recursive_gate(e):
        """
        Recursively adds components to the circuit board.
        """
        if isinstance(e, boolean.BaseElement):
            # TODO: Either make the the same or create a constant component.
            s = Switch()
            b.append(s)
            return s
        elif isinstance(e, boolean.Symbol):
            if e in symbol_dict.keys():
                return symbol_dict[e]
            else:
                s = Switch()
                symbol_dict[e] = s
                b.append(s)
                return s
        elif isinstance(e, boolean.Function):
            # All gates are of type Gate instead of And, Or and Not
            if e.order == (1, 1):
                pre = recursive_gate(e.args[0])
                w = Wire(pre)
                b.append(w)

                s = boolean.Symbol(None)
                g = Gate(e.subs({e.args[0]: s}), {s: w})
                b.append(g)
                return g
            else:
                input_dict = {}
                expr = e
                for arg in e.args:
                    pre = recursive_gate(arg)
                    w = Wire(pre)
                    b.append(w)

                    s = boolean.Symbol(None)
                    expr = expr.subs({arg: s})
                    input_dict[s] = w
                g = Gate(expr, input_dict)
                b.append(g)
                return g

    recursive_gate(expression)
    if bulb:
        # Due to the nature of recursive_gate, the last component is last in the list
        w = Wire(b[-1])
        o = Bulb(w)
        b.append(w)
        b.append(o)
    return b
Ejemplo n.º 50
0
def renderable_components(expression):
    """
    Returns an list of renderable components when given an expression.
    """
    if isinstance(expression, str):
        expression = boolean.parse(expression, eval=False)
    if not isinstance(expression, boolean.Expression):
        raise TypeError(
            "Argument must be str or Expression but it is {}"
            .format(expression.__class__))

    def get_max_depth(e, max_depth, depth):
        if isinstance(e, boolean.Symbol):
            if max_depth < depth:
                max_depth += 1
            return max_depth
        elif isinstance(e, boolean.NOT):
            if max_depth < depth:
                max_depth += 1
            max_d = get_max_depth(e.args[0], max_depth, depth+1)
        elif isinstance(e, boolean.DualBase):
            if len(e.args) != 2:
                new_expr = e.__class__(e.args[0], e.args[1])
                for i in range(2, len(e.args)):
                    new_expr = e.__class__(new_expr, e.args[i], eval=False)
                e = new_expr
            if max_depth < depth:
                max_depth += 1
            max_d0 = get_max_depth(e.args[0], max_depth, depth+1)
            max_d1 = get_max_depth(e.args[1], max_depth, depth+1)
            if max_d1 > max_d0:
                max_d = max_d1
            else:
                max_d = max_d0
        return max_d

    max_depth = get_max_depth(expression, 0, 0)
    width = (50 * (2 ** max_depth))/2
    no_component = [0]
    symbols = {}
    no_symbols = [0]

    def recursive_components(e, depth, width):
        # This function can be used if there is ever the want to attempt to make the
        # converted logic circuit look nicer by spacing the components

        if isinstance(e, boolean.Symbol):
            if e in symbols.keys():
                pos = symbols[e]
                rc = Symbol(str(e), pos=pos)
            else:
                x = 20
                y = width
                pos = (x + (no_symbols[0] * 10), 35 + y)
                rc = Symbol(str(e), pos=pos)
                symbols[e] = pos
                no_symbols[0] += 1
        elif isinstance(e, boolean.NOT):
            x = 35 + (120 * (max_depth - depth))
            y = width
            pre = recursive_components(e.args[0], depth+1, width)
            pos = (x, 35 + y)
            no = str(no_component[0])
            no_component[0] += 1
            g = NotGate("N"+no, pos=pos)
            start = pre.get_output()
            stop = g.get_input()
            output = g.get_output()
            w = Wire(e.args[0], start, stop)
            temp = Temp(output=output)
            temp.add_widget(pre)
            temp.add_widget(w)
            temp.add_widget(g)
            rc = temp
        elif isinstance(e, boolean.DualBase):
            if len(e.args) != 2:
                new_expr = e.__class__(e.args[0], e.args[1])
                for i in range(2, len(e.args)):
                    new_expr = e.__class__(new_expr, e.args[i], eval=False)
                e = new_expr

            x = 35 + (120 * (max_depth - depth))
            y = width
            w = ((50 * (2 ** (max_depth - depth)))/2)

            pre0 = recursive_components(e.args[0], depth + 1, width + w/2)
            pre1 = recursive_components(e.args[1], depth + 1, width - w/2)

            pos = (x, 35 + y)
            no = str(no_component[0])
            no_component[0] += 1

            if isinstance(e, boolean.AND):
                g = AndGate("A"+no, pos=pos)
            elif isinstance(e, boolean.OR):
                g = OrGate("O"+no, pos=pos)
            start0 = pre0.get_output()
            stop0 = g.get_input1()
            start1 = pre1.get_output()
            stop1 = g.get_input2()
            output = g.get_output()
            w0 = Wire(e.args[0], start0, stop0)
            w1 = Wire(e.args[1], start1, stop1)
            temp = Temp(output=output)
            temp.add_widget(pre0)
            temp.add_widget(pre1)
            temp.add_widget(w0)
            temp.add_widget(w1)
            temp.add_widget(g)
            rc = temp
        return rc

    rc = recursive_components(expression, 0, width)
    pos = (35 + (120 * (max_depth + 1)), width + 35)
    g = Output(str(expression), pos=pos)
    start = rc.get_output()
    stop = g.get_input()
    w0 = Wire("", start, stop)
    temp = Temp(height=2*width, width=max_depth*120+35)
    temp.add_widget(g)
    temp.add_widget(rc)
    temp.add_widget(w0)
    # temp.size = (max_depth * 125, width)
    return temp