Skip to content

Commit ad07cd5

Browse files
committed
Reject ambiguous prefix-based variable lookups
1 parent 5c11730 commit ad07cd5

2 files changed

Lines changed: 16 additions & 24 deletions

File tree

src/core/parameter_estimation.jl

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,9 +1257,7 @@ function lookup_value(var, var_search, soln_index::Int,
12571257
# Candidate template names, in order:
12581258
# 1. The FULL model-style name + "_<deriv_count>". A parameter named
12591259
# k_1 must map to the jet variable k_1_0 — treating its trailing
1260-
# _1 as a derivative order collided distinct parameters onto one
1261-
# template variable (k_1 AND k_2 both resolved to k_2_0 via the
1262-
# base-name startswith fallback below; review P0#4).
1260+
# _1 as a derivative order can collide distinct parameters.
12631261
# 2. If the name already carries a _n suffix, the name verbatim
12641262
# (covers callers that pass jet-style names like y1_2 directly).
12651263
has_suffix = occursin(r"_[0-9]+$", name_str)
@@ -1281,27 +1279,6 @@ function lookup_value(var, var_search, soln_index::Int,
12811279
end
12821280
isnothing(index) || break
12831281
end
1284-
1285-
# Extra base-name fallback: prefer `_0`, then any `_n`
1286-
if isnothing(index)
1287-
base_name = has_suffix ? replace(name_str, r"_[0-9]+$" => "") : name_str
1288-
preferred = base_name * "_0"
1289-
idx0 = findfirst(i -> string(final_varlist[i]) == preferred, eachindex(final_varlist))
1290-
if isnothing(idx0)
1291-
idx0 = findfirst(i -> string(trimmed_varlist[i]) == preferred, eachindex(trimmed_varlist))
1292-
end
1293-
if !isnothing(idx0)
1294-
index = idx0
1295-
else
1296-
idx_any = findfirst(i -> startswith(string(final_varlist[i]), base_name * "_"), eachindex(final_varlist))
1297-
if isnothing(idx_any)
1298-
idx_any = findfirst(i -> startswith(string(trimmed_varlist[i]), base_name * "_"), eachindex(trimmed_varlist))
1299-
end
1300-
if !isnothing(idx_any)
1301-
index = idx_any
1302-
end
1303-
end
1304-
end
13051282
catch e
13061283
_rethrow_if_interrupt(e)
13071284
@debug "Variable index fallback lookup failed" exception = e

test/result_processing_helpers.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,21 @@ end
249249
# Unresolvable search throws — no silent fabrication of a value.
250250
unresolvable = only(ModelingToolkit.@variables nonexistent_q)
251251
@test_throws Exception lv(unresolvable)
252+
253+
# A missing exact jet must never borrow a similarly prefixed variable.
254+
# The removed fallback stripped k_1 to k, then returned the first k_*;
255+
# in this case it silently returned k_10_0's value for k_1.
256+
prefix_neighbor = only(ModelingToolkit.@variables k_10_0)
257+
@test_throws Exception ODEParameterEstimation.lookup_value(
258+
params[1],
259+
params[1],
260+
1,
261+
Dict{Any, Any}(),
262+
Dict{Any, Any}(),
263+
Any[prefix_neighbor],
264+
Any[],
265+
[[99.0]],
266+
)
252267
end
253268

254269
@testset "template_var_map drives SI-workflow lookups (Phase B)" begin

0 commit comments

Comments
 (0)