Skip to content

Optimization

The optimizer applies rules to simplify expressions and detect logical issues.

Basic Examples

from therismos import optimize, F, TRUE, FALSE, AllExpr, AnyExpr

age = F("age")

# Identity elimination
expr = AllExpr(age > 18, TRUE, age < 65)
result, _ = optimize(expr)
# result: AllExpr(age > 18, age < 65)

# Contradiction detection
expr = (age == 25) & (age != 25)
result, _ = optimize(expr)
# result: FALSE

# Tautology detection
expr = (age < 30) | (age >= 30)
result, _ = optimize(expr)
# result: TRUE

# NOT simplification (De Morgan's laws)
name = F("name")
expr = ~((age > 18) & (name == "Alice"))
result, _ = optimize(expr)
# result: (age <= 18) OR (name != "Alice")

Optimization Rules Reference

Atomic Expression Simplifications

Rule Before After
Empty IN to FALSE f IN () FALSE
Single-value IN to Eq f IN (v) f == v
Empty Between range f.between(a, b) where a >= b FALSE

NOT Expression Simplifications

Rule Before After
NOT of TRUE NOT(TRUE) FALSE
NOT of FALSE NOT(FALSE) TRUE
Double negation NOT(NOT(x)) x
NOT of equality NOT(f == v) f != v
NOT of inequality NOT(f != v) f == v
NOT of less-than NOT(f < v) f >= v
NOT of less-or-equal NOT(f <= v) f > v
NOT of greater-than NOT(f > v) f <= v
NOT of greater-or-equal NOT(f >= v) f < v
NOT of null check NOT(f.is_null()) f.is_not_null()
NOT of not-null check NOT(f.is_not_null()) f.is_null()
De Morgan's law (AND) NOT(a AND b) NOT(a) OR NOT(b)
De Morgan's law (OR) NOT(a OR b) NOT(a) AND NOT(b)

AND Expression Simplifications

Rule Before After
Empty AND AND() TRUE
Single operand AND(x) x
FALSE propagation AND(..., FALSE, ...) FALSE
TRUE elimination AND(..., TRUE, ...) AND(...)
Eq/Eq same value (f == v) AND (f == v) f == v
Eq/Eq different values (f == v1) AND (f == v2) FALSE
Eq/In intersection (member) (f == v) AND (f IN (v, ...)) f == v
Eq/In intersection (non-member) (f == v) AND (f IN (...)) FALSE
In/In intersection (empty) (f IN (v1, v2)) AND (f IN (v3, v4)) FALSE
In/In intersection (single) (f IN (v1, v2)) AND (f IN (v2, v3)) f == v2
In/In intersection (multiple) (f IN (v1, v2, v3)) AND (f IN (v2, v3, v4)) f IN (v2, v3)

OR Expression Simplifications

Rule Before After
Empty OR OR() FALSE
Single operand OR(x) x
TRUE propagation OR(..., TRUE, ...) TRUE
FALSE elimination OR(..., FALSE, ...) OR(...)
Eq/Eq union (f == v1) OR (f == v2) f IN (v1, v2)
Eq/In union (f == v) OR (f IN (v2, v3)) f IN (v, v2, v3)
In/In union (f IN (v1, v2)) OR (f IN (v3, v4)) f IN (v1, v2, v3, v4)

Contradiction Detection (AND)

Pattern Result
(f == v) AND (f != v) FALSE
f.is_null() AND f.is_not_null() FALSE
(f < a) AND (f > b) where b >= a FALSE
(f <= a) AND (f > a) FALSE
(f >= b) AND (f < b) FALSE
f.between(a, b) AND f.between(c, d) — non-overlapping FALSE
f.between(a, b) AND f.between(c, d) — overlapping f.between(max(a,c), min(b,d))
f.between(a, b) AND (f > c) where c >= b FALSE
f.between(a, b) AND (f < c) where c <= a FALSE

Between Range Union (OR)

Pattern Result
Overlapping ranges f.between(min(a,c), max(b,d))
Adjacent ranges f.between(a, d)

Tautology Detection (OR)

Pattern Result
(f == v) OR (f != v) TRUE
f.is_null() OR f.is_not_null() TRUE
(f < v) OR (f >= v) TRUE
(f <= v) OR (f > v) TRUE

Optimization Tracking

result, records = optimize(expr)
for record in records:
    print(f"Applied: {record.reason}")
    print(f"Before:  {record.before}")
    print(f"After:   {record.after}")

Accumulate records across multiple calls:

my_records = []
result1, _ = optimize(expr1, my_records)
result2, _ = optimize(expr2, my_records)
# my_records contains steps from both calls

See Advanced Optimization Example for a complex real-world scenario.