implemented the cases; sometimes we need 5 operators, dont ask me why

This commit is contained in:
Zander Thannhauser 2025-06-06 10:05:54 -05:00
parent 5d04064f6d
commit dd13983e84

133
main.py
View file

@ -24,7 +24,8 @@ def parse_args(argv):
You can refer to them using their names or their symbols.
''')
parser.add_argument('-E', '--experimental-operators', help='''
parser.add_argument('-E', '--experimental-operators', action='store_true', \
help='''
For two boolean variables, there are four possible inputs into a
binary operator. For each of those four an operator could return true
or false. That would mean in theory there could exist up to 16
@ -90,6 +91,11 @@ def determine_available_operators(args):
extended = ("!|", "!&", "!=", "==", "|!", "&!");
experimental = (
"<00>",
"<01>",
"<10>",
"<11>",
"<0000>",
"<0001>",
"<0010>",
@ -199,40 +205,47 @@ def calculate_simplifications(args, available_operators):
unary_operators = {
'!': lambda x: ~x,
# these were found by running the simplifier with -o xor,and,or,not
# 10 - x
"<00>": lambda x: 0,
"<01>": lambda x: ~x,
"<10>": lambda x: x,
"<11>": lambda x: M,
}
binary_operators = {
'||': lambda x, y: (x | y) & M, # or
'&&': lambda x, y: (x & y) & M, # and
'||': lambda x, y: x | y, # or
'&&': lambda x, y: x & y, # and
'!|': lambda x, y: ~(x | y) & M, # nor
'!&': lambda x, y: ~(x & y) & M, # nand
'!|': lambda x, y: ~(x | y), # nor
'!&': lambda x, y: ~(x & y), # nand
'&!': lambda x, y: (~x & y) & M, # andn
'|!': lambda x, y: (~x | y) & M, # orn
'&!': lambda x, y: ~x & y, # andn
'|!': lambda x, y: ~x | y, # orn
'!=': lambda x, y: (x ^ y) & M, # xor
'==': lambda x, y: (~(x ^ y)) & M, # nxor
'!=': lambda x, y: x ^ y, # xor
'==': lambda x, y: ~(x ^ y), # nxor
# these were found by running the simplifier with -o xor,and,or,not
# 1100 - x
# 1010 - y
"<0000>": lambda x, y: 0, # 0
"<0001>": lambda x, y: 0, # ((x == 0) && (y == 0)) || 0
"<0010>": lambda x, y: 0, # ((x == 0) && (y == 1)) || 0
"<0011>": lambda x, y: 0, # ((x == 0) && (y == 1)) || ((x == 0) && (y == 0)) || 0
"<0100>": lambda x, y: 0, # ((x == 1) && (y == 0)) || 0
"<0101>": lambda x, y: 0, # ((x == 1) && (y == 0)) || ((x == 0) && (y == 0)) || 0
"<0110>": lambda x, y: 0, # ((x == 1) && (y == 0)) || ((x == 0) && (y == 1)) || 0
"<0111>": lambda x, y: 0, # ((x == 1) && (y == 0)) || ((x == 0) && (y == 1)) || ((x == 0) && (y == 0)) || 0
"<1000>": lambda x, y: 0, # ((x == 1) && (y == 1)) || 0
"<1001>": lambda x, y: 0, # ((x == 1) && (y == 1)) || ((x == 0) && (y == 0)) || 0
"<1010>": lambda x, y: 0, # ((x == 1) && (y == 1)) || ((x == 0) && (y == 1)) || 0
"<1011>": lambda x, y: 0, # ((x == 1) && (y == 1)) || ((x == 0) && (y == 1)) || ((x == 0) && (y == 0)) || 0
"<1100>": lambda x, y: 0, # ((x == 1) && (y == 1)) || ((x == 1) && (y == 0)) || 0
"<1101>": lambda x, y: 0, # ((x == 1) && (y == 1)) || ((x == 1) && (y == 0)) || ((x == 0) && (y == 0)) || 0
"<1110>": lambda x, y: 0, # ((x == 1) && (y == 1)) || ((x == 1) && (y == 0)) || ((x == 0) && (y == 1)) || 0
"<1111>": lambda x, y: M, # ((x == 1) && (y == 1)) || ((x == 1) && (y == 0)) || ((x == 0) && (y == 1)) || ((x == 0) && (y == 0)) || 0
# 0011 - x
# 0101 - y
"<0000>": lambda x, y: 0,
"<1000>": lambda x, y: ~(x | y),
"<0100>": lambda x, y: x ^ (x | y),
"<1100>": lambda x, y: ~x,
"<0010>": lambda x, y: x ^ (x & y),
"<1010>": lambda x, y: ~y,
"<0110>": lambda x, y: x ^ y,
"<1110>": lambda x, y: ~(x & y),
"<0001>": lambda x, y: x & y,
"<1001>": lambda x, y: x ^ ~y,
"<0101>": lambda x, y: y,
"<1101>": lambda x, y: ~x | y,
"<0011>": lambda x, y: x,
"<1011>": lambda x, y: x | ~y,
"<0111>": lambda x, y: x | y,
"<1111>": lambda x, y: M,
}
def print_status():
@ -394,32 +407,44 @@ def evaluate(expr):
return Z;
case ("!", subexp):
return ~evaluate(subexp) & M;
case (left, "||", right):
return evaluate(left) | evaluate(right);
case (left, "!|", right):
return ~(evaluate(left) | evaluate(right)) & M;
case (left, "|!", right):
return (~evaluate(left) | evaluate(right)) & M;
case (left, "&&", right):
return evaluate(left) & evaluate(right);
case (left, "!&", right):
return ~(evaluate(left) & evaluate(right)) & M;
case (left, "&!", right):
return (~evaluate(left) & evaluate(right)) & M;
case (left, "<", right):
return (~evaluate(left) & evaluate(right)) & M;
case (left, "<=", right):
return (~evaluate(left) | evaluate(right)) & M;
case (left, ">", right):
return (evaluate(left) & ~evaluate(right)) & M;
case (left, ">=", right):
return (evaluate(left) | ~evaluate(right)) & M;
case (left, "==", right):
return ~(evaluate(left) ^ evaluate(right)) & M;
case (left, "!=", right):
return evaluate(left) ^ evaluate(right);
case (first, "||", *rest):
result = evaluate(first);
for subexpr in rest[::2]:
subresult = evaluate(subexpr);
result = result | subresult;
return result;
# case (left, "!|", right):
# return ~(evaluate(left) | evaluate(right)) & M;
# case (left, "|!", right):
# return (~evaluate(left) | evaluate(right)) & M;
case (first, "&&", *rest):
result = evaluate(first);
for subexpr in rest[::2]:
subresult = evaluate(subexpr);
result = result & subresult;
return result;
# case (left, "!&", right):
# return ~(evaluate(left) & evaluate(right)) & M;
# case (left, "&!", right):
# return (~evaluate(left) & evaluate(right)) & M;
# case (left, "<", right):
# return (~evaluate(left) & evaluate(right)) & M;
# case (left, "<=", right):
# return (~evaluate(left) | evaluate(right)) & M;
# case (left, ">", right):
# return (evaluate(left) & ~evaluate(right)) & M;
# case (left, ">=", right):
# return (evaluate(left) | ~evaluate(right)) & M;
case (first, "==", *rest):
result = evaluate(first);
for subexpr in rest[::2]:
subresult = evaluate(subexpr);
result = ~(result ^ subresult) & M
return result;
# case (left, "!=", right):
# return evaluate(left) ^ evaluate(right);
case _:
print(exp);
print(expr);
assert(not "TODO");
def repl(args, cost, lookup):
@ -435,8 +460,8 @@ def repl(args, cost, lookup):
print();
# print(f'I can do anything in {max(cost.values())} operations.')
# print();
print(f'I can do anything in {max(cost.values())} operations.')
print();
parser = create_parser();