import logging as log

class BooleanOperator(object):
    def __init__(self, precedence_in, bool_func_in, *args):
        self.precedence = precedence_in
        self.bool_func = bool_func_in
        self.equivalent_symbols = list(args)

    def result(self, a, b):
        return self.bool_func(a, b)

def bool_not(a, b):
    # this should never be called;
    # not is implemented as xor w/ 1
    log.fatal("Boolean not function was explicitly called.\n"
              "This should not happen; not is implemented as xor with 1.\n"
              "Cannot continue program execution.\n")
    raise RuntimeError

def bool_and(a, b):
    return int(a and b)

def bool_nand(a, b):
    return int(not (a and b))

def bool_xor(a, b):
    return int(a != b)

def bool_xnor(a, b):
    return int(a == b)

def bool_or(a, b):
    return int(a or b)

def bool_nor(a, b):
    return int(not (a or b))

# Define schema information

precedence = {
    "ZERO" : 0,
    "LOW" : 1,
    "MEDIUM" : 2,
    "HIGH" : 3
}

SYM_NOT = "~"
SYM_XOR = "+"
SYM_XNOR = "@"
SYM_AND = "&"
SYM_NAND = "$"
SYM_OR = "|"
SYM_NOR = "%"

# TODO: possibly allow users to make their own precedence maps in the future
schema = {
    SYM_NOT : BooleanOperator(precedence["HIGH"], bool_not, "not", "NOT", "~", "!"),
    SYM_XOR : BooleanOperator(precedence["MEDIUM"], bool_xor, "xor", "XOR"),
    SYM_XNOR : BooleanOperator(precedence["MEDIUM"], bool_xnor, "xnor", "XNOR", "nxor", "NXOR"),
    SYM_AND : BooleanOperator(precedence["LOW"], bool_and, "and", "AND", "&", "&&", "/\\"),
    SYM_NAND : BooleanOperator(precedence["LOW"], bool_nand, "nand", "NAND"),
    SYM_OR : BooleanOperator(precedence["ZERO"], bool_or, "or", "OR", "|", "||", "\\/"),
    SYM_NOR : BooleanOperator(precedence["ZERO"], bool_nor, "nor", "NOR")
}

schema_search_ordered_list = [SYM_XNOR, SYM_XOR, SYM_NOR, SYM_NAND, SYM_AND, SYM_OR, SYM_NOT]
@@ -16,16 +16,289 @@
 as log%0A%0A
+__all__ = %5B%22BooleanOperator%22,%0A           %22schema%22,%0A           %22schema_search_ordered_list%22,%0A           %22precedence%22,%0A           %22SYM_NOT%22,%0A           %22SYM_NAND%22,%0A           %22SYM_AND%22,%0A           %22SYM_OR%22,%0A           %22SYM_NOR%22,%0A           %22SYM_XNOR%22,%0A           %22SYM_XOR%22%5D%0A%0A
 class Bo
@@ -573,99 +573,410 @@
 b)%0A%0A
-def bool_not(a, b):%0A    # this should never be called;%0A    # not is implemented as xor w/ 1
+# functions called in Boolean expression evaluation;%0A# a and b should always be passed as ints to these functions%0Att_and = lambda a, b: int(a and b)%0Att_nand = lambda a, b: int(not tt_and(a, b))%0Att_or = lambda a, b: int(a or b)%0Att_nor = lambda a, b: int(not tt_or(a, b))%0Att_xor = lambda a, b: int((not a and b) or (a and not b))%0Att_xnor = lambda a, b: int(not tt_xor(a, b))%0A%0Adef tt_not_uncallable(a, b):
 %0A   
@@ -1029,24 +1029,26 @@
 y called.%5Cn%22
+ %5C
 %0A           
@@ -1111,16 +1111,18 @@
 th 1.%5Cn%22
+ %5C
 %0A       
@@ -1196,287 +1196,8 @@
 or%0A%0A
-def bool_and(a, b):%0A    return int(a and b)%0A%0Adef bool_nand(a, b):%0A    return int(not (a and b))%0A%0Adef bool_xor(a, b):%0A    return int(a != b)%0A%0Adef bool_xnor(a, b):%0A    return int(a == b)%0A%0Adef bool_or(a, b):%0A    return int(a or b)%0A%0Adef bool_nor(a, b):%0A    return int(not (a or b))%0A%0A
 # De
@@ -1545,16 +1545,25 @@
 %22%5D, 
-bool_not
+tt_not_uncallable
 , %22n
@@ -1637,20 +1637,18 @@
 DIUM%22%5D, 
-bool
+tt
 _xor, %22x
@@ -1713,20 +1713,18 @@
 DIUM%22%5D, 
-bool
+tt
 _xnor, %22
@@ -1804,20 +1804,18 @@
 %22LOW%22%5D, 
-bool
+tt
 _and, %22a
@@ -1895,20 +1895,18 @@
 %22LOW%22%5D, 
-bool
+tt
 _nand, %22
@@ -1970,20 +1970,18 @@
 ZERO%22%5D, 
-bool
+tt
 _or, %22or
@@ -2058,20 +2058,18 @@
 ZERO%22%5D, 
-bool
+tt
 _nor, %22n

Refactor boolean function definitions in schema_provider.