added ternary support. explodes time complexity, but I think it could really help the max expression-tree size
This commit is contained in:
parent
2499db7c7d
commit
98bf135199
1 changed files with 58 additions and 2 deletions
60
main.py
60
main.py
|
|
@ -67,6 +67,7 @@ symbol_to_name = {
|
||||||
"==": "nxor",
|
"==": "nxor",
|
||||||
"|!": "orn",
|
"|!": "orn",
|
||||||
"&!": "andn",
|
"&!": "andn",
|
||||||
|
"?:": "ternary",
|
||||||
};
|
};
|
||||||
|
|
||||||
def determine_available_operators(args):
|
def determine_available_operators(args):
|
||||||
|
|
@ -201,6 +202,8 @@ def calculate_simplifications(args, available_operators):
|
||||||
return extract_variables(inner);
|
return extract_variables(inner);
|
||||||
case (_, left, right):
|
case (_, left, right):
|
||||||
return extract_variables(left) + extract_variables(right);
|
return extract_variables(left) + extract_variables(right);
|
||||||
|
case (_, cond, true, false):
|
||||||
|
return extract_variables(cond) + extract_variables(true) + extract_variables(false);
|
||||||
case _:
|
case _:
|
||||||
print(exp);
|
print(exp);
|
||||||
assert(not "TODO");
|
assert(not "TODO");
|
||||||
|
|
@ -225,6 +228,10 @@ def calculate_simplifications(args, available_operators):
|
||||||
'==': lambda x, y: ~(x ^ y), # nxor
|
'==': lambda x, y: ~(x ^ y), # nxor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ternary_operators = {
|
||||||
|
'?:': lambda x, y, z: (x & y) | (~x & z), # ternary
|
||||||
|
};
|
||||||
|
|
||||||
def print_status():
|
def print_status():
|
||||||
numerator = 65536 - todo_count[0];
|
numerator = 65536 - todo_count[0];
|
||||||
denominator = 65536
|
denominator = 65536
|
||||||
|
|
@ -307,6 +314,29 @@ def calculate_simplifications(args, available_operators):
|
||||||
|
|
||||||
consider(binary_truthtable, binary_expression, binary_cost);
|
consider(binary_truthtable, binary_expression, binary_cost);
|
||||||
|
|
||||||
|
# consider ternary operators:
|
||||||
|
for name, function in sorted(ternary_operators.items()):
|
||||||
|
if name in available_operators:
|
||||||
|
s = sorted(lookup.items());
|
||||||
|
for a_truthtable, a_expression in s:
|
||||||
|
for b_truthtable, b_expression in s:
|
||||||
|
# x ? y : z
|
||||||
|
ternary_truthtable = function(
|
||||||
|
my_truthtable, a_truthtable, b_truthtable) & M;
|
||||||
|
ternary_expression = (name,
|
||||||
|
my_expression, a_expression, b_expression);
|
||||||
|
ternary_cost = 1 + my_cost + \
|
||||||
|
costs[a_truthtable] + costs[b_truthtable];
|
||||||
|
|
||||||
|
consider(ternary_truthtable, ternary_expression, \
|
||||||
|
ternary_cost);
|
||||||
|
|
||||||
|
# y ? x : z
|
||||||
|
# assert(not "TODO");
|
||||||
|
|
||||||
|
# z ? y : z
|
||||||
|
# assert(not "TODO");
|
||||||
|
|
||||||
return costs, lookup
|
return costs, lookup
|
||||||
|
|
||||||
pathname = "simplifications.bin"
|
pathname = "simplifications.bin"
|
||||||
|
|
@ -393,7 +423,7 @@ def parse(text):
|
||||||
self.tokendata = self.text[self.position];
|
self.tokendata = self.text[self.position];
|
||||||
self.position += 1;
|
self.position += 1;
|
||||||
|
|
||||||
case "(" | ")":
|
case "(" | ")" | "?" | ":":
|
||||||
self.tokenkind = self.text[self.position];
|
self.tokenkind = self.text[self.position];
|
||||||
self.position += 1;
|
self.position += 1;
|
||||||
|
|
||||||
|
|
@ -551,8 +581,30 @@ def parse(text):
|
||||||
|
|
||||||
return left;
|
return left;
|
||||||
|
|
||||||
|
def parse_ternary(tokenizer):
|
||||||
|
exp = parse_ors(tokenizer);
|
||||||
|
|
||||||
|
if tokenizer.tokenkind in ("?", ):
|
||||||
|
cond = exp;
|
||||||
|
|
||||||
|
tokenizer.next();
|
||||||
|
|
||||||
|
true = parse_ors(tokenizer);
|
||||||
|
|
||||||
|
if tokenizer.tokenkind != ":":
|
||||||
|
raise BaseException("expecting ':' in ternary expression, "
|
||||||
|
"found: '{tokenizer.tokenkind}'!");
|
||||||
|
|
||||||
|
tokenizer.next();
|
||||||
|
|
||||||
|
false = parse_ternary(tokenizer);
|
||||||
|
|
||||||
|
return ("?:", cond, true, false);
|
||||||
|
else:
|
||||||
|
return exp;
|
||||||
|
|
||||||
def parse_root(tokenizer):
|
def parse_root(tokenizer):
|
||||||
return parse_ors(tokenizer);
|
return parse_ternary(tokenizer);
|
||||||
|
|
||||||
tokenizer = Tokenizer(text);
|
tokenizer = Tokenizer(text);
|
||||||
|
|
||||||
|
|
@ -608,6 +660,10 @@ def evaluate(expr):
|
||||||
case ("!&", left, right):
|
case ("!&", left, right):
|
||||||
return ~(evaluate(left) & evaluate(right)) & M;
|
return ~(evaluate(left) & evaluate(right)) & M;
|
||||||
|
|
||||||
|
case ("?:", cond, left, right):
|
||||||
|
cond = evaluate(cond);
|
||||||
|
return (cond & evaluate(left)) | (~cond & evaluate(right));
|
||||||
|
|
||||||
case _:
|
case _:
|
||||||
print(f'expr = {expr}');
|
print(f'expr = {expr}');
|
||||||
assert(not "TODO");
|
assert(not "TODO");
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue