Skip to content

Commit 3f53de6

Browse files
fix: [AI] deduplicate alias equations after substitution in find_perfect_aliases!
When a sticky (high state_priority) non-target variable is directly aliased to a zero-priority variable in the same group, the c1/c2 removal check correctly keeps the equation (c1 ≠ c2). After the substitution loop rewrites that zero-priority variable to the group target, the surviving equation becomes structurally identical to the direct alias between the sticky variable and the target — a redundant duplicate. Multiple such duplicates over-constrain the bipartite graph and cause Pantelides to fail on downstream acceleration variables. Fix: after the substitution loop, scan surviving candidate equations for pairs with the same (v_a, v_b) variable endpoints and remove all but the first. This is O(n) in the number of candidate alias equations. The equation-count tiebreaker in pick_alias_target is retained as a secondary heuristic to prefer targets that already have derivative chains in var_to_diff, reducing unnecessary var_derivative! calls. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 062dbb0 commit 3f53de6

1 file changed

Lines changed: 23 additions & 0 deletions

File tree

src/systems/alias_elimination.jl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,29 @@ function find_perfect_aliases!(
197197
end
198198
end
199199

200+
# After substitution, alias equations that connected a sticky non-target
201+
# variable to a zero-priority variable become structurally identical to the
202+
# direct alias between the sticky variable and the target (since the
203+
# zero-priority variable was redirected to the target in the graph). Remove
204+
# all but the first copy of each (v_a, v_b) variable pair.
205+
let seen = Set{Tuple{Int,Int}}()
206+
eqs_rm_set = Set(eqs_to_rm)
207+
removed_additional_eqs = false
208+
for (ieq, _, _) in candidate_eqs
209+
ieq in eqs_rm_set && continue
210+
snbors = 𝑠neighbors(graph, ieq)
211+
length(snbors) == 2 || continue
212+
pair = minmax(snbors[1], snbors[2])
213+
if pair in seen
214+
removed_additional_eqs = true
215+
push!(eqs_to_rm, ieq)
216+
else
217+
push!(seen, pair)
218+
end
219+
end
220+
removed_additional_eqs && sort!(eqs_to_rm)
221+
end
222+
200223
@set! sys.eqs = eqs
201224
state.sys = sys
202225

0 commit comments

Comments
 (0)