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",
|
||||
"|!": "orn",
|
||||
"&!": "andn",
|
||||
"?:": "ternary",
|
||||
};
|
||||
|
||||
def determine_available_operators(args):
|
||||
|
|
@ -201,6 +202,8 @@ def calculate_simplifications(args, available_operators):
|
|||
return extract_variables(inner);
|
||||
case (_, left, right):
|
||||
return extract_variables(left) + extract_variables(right);
|
||||
case (_, cond, true, false):
|
||||
return extract_variables(cond) + extract_variables(true) + extract_variables(false);
|
||||
case _:
|
||||
print(exp);
|
||||
assert(not "TODO");
|
||||
|
|
@ -225,6 +228,10 @@ def calculate_simplifications(args, available_operators):
|
|||
'==': lambda x, y: ~(x ^ y), # nxor
|
||||
}
|
||||
|
||||
ternary_operators = {
|
||||
'?:': lambda x, y, z: (x & y) | (~x & z), # ternary
|
||||
};
|
||||
|
||||
def print_status():
|
||||
numerator = 65536 - todo_count[0];
|
||||
denominator = 65536
|
||||
|
|
@ -307,6 +314,29 @@ def calculate_simplifications(args, available_operators):
|
|||
|
||||
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
|
||||
|
||||
pathname = "simplifications.bin"
|
||||
|
|
@ -393,7 +423,7 @@ def parse(text):
|
|||
self.tokendata = self.text[self.position];
|
||||
self.position += 1;
|
||||
|
||||
case "(" | ")":
|
||||
case "(" | ")" | "?" | ":":
|
||||
self.tokenkind = self.text[self.position];
|
||||
self.position += 1;
|
||||
|
||||
|
|
@ -551,8 +581,30 @@ def parse(text):
|
|||
|
||||
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):
|
||||
return parse_ors(tokenizer);
|
||||
return parse_ternary(tokenizer);
|
||||
|
||||
tokenizer = Tokenizer(text);
|
||||
|
||||
|
|
@ -608,6 +660,10 @@ def evaluate(expr):
|
|||
case ("!&", left, right):
|
||||
return ~(evaluate(left) & evaluate(right)) & M;
|
||||
|
||||
case ("?:", cond, left, right):
|
||||
cond = evaluate(cond);
|
||||
return (cond & evaluate(left)) | (~cond & evaluate(right));
|
||||
|
||||
case _:
|
||||
print(f'expr = {expr}');
|
||||
assert(not "TODO");
|
||||
|
|
|
|||
Loading…
Reference in a new issue