Skip to content

Save expr == var in csemap to catch silly user mistakes#972

Open
IgnaceBleukx wants to merge 4 commits into
masterfrom
expr_eq_var_in_csemap
Open

Save expr == var in csemap to catch silly user mistakes#972
IgnaceBleukx wants to merge 4 commits into
masterfrom
expr_eq_var_in_csemap

Conversation

@IgnaceBleukx

Copy link
Copy Markdown
Collaborator

As discussed offline, it would be useful to catch silly mistakes by the user, where an aux var is introduced for some expression, but then the expression is used later on as a nested expression somewhere.

To fix this, this PR saves the csemap[expr] = var whenever we encounter a top-level == constraint.

@IgnaceBleukx IgnaceBleukx requested a review from tias May 8, 2026 11:40
# save expr == var to the csemap, so we don't make a new variable for expr later
if csemap is not None and exprname == '==': # cheap checks first
if isinstance(lexpr, Expression) and isinstance(rexpr, Expression) and \
lexpr.is_bool() == rexpr.is_bool() and __is_flat_var(rexpr): # types must match

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isinstance(rexpr, Expression) and __is_flat_var(rexpr) sounds like isinstance(rexpr, IntVarImpl)?

and what if its var == expr? or is that already normalized out before this line?

if csemap is not None and exprname == '==': # cheap checks first
if isinstance(lexpr, Expression) and isinstance(rexpr, Expression) and \
lexpr.is_bool() == rexpr.is_bool() and __is_flat_var(rexpr): # types must match
csemap[lexpr] = rexpr # save lexpr == rexpr to the csemap

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if lexpr is already in? we would overwrite it?
if its in, we could post rexpr == csemap[lexpr] and store csemap[rexpr] == csemap[lexpr]?


def __setitem__(self, attr, val):
raise ValueError("__setitem__ is not supported for flat_map, use get_or_make_var instead")
def __setitem__(self, attr: Expression, val: _IntVarImpl) -> None:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree we need it for the code below, but maybe add a doc "Use get_or_make_var() instead, which will create a fresh variable for you as needed. Only use this function if you must register an existing attr == val.

@IgnaceBleukx

Copy link
Copy Markdown
Collaborator Author

Already implemented for booleans via #1010; too be revisited in another PR if we want to do this for int expressions too.
The main use-case was reifications anyway as they should be catched to improve the linearize_reified_varvals transform.

@tias

tias commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

I did not realize these were 2 separate commits; it makes sense to do it for integers too yes; lets keep it open for a little longer to remind ourselves?

@tias tias reopened this Jun 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants