Commit 563a463
Fix MustNotOverwrite when setting slices/indices of slices (#1325)
Closes #1321.
Claude did most of this, I tweaked the tests a fair bit from what it
wrote though.
If anyone is interested, this is the prompt I fed Claude
<details>
# Issue
In VarNamedTuple you can set different indices of the same *slice* of
the same array (i.e. x[1:2][1] and x[1:2][2]):
```julia
julia> using DynamicPPL
julia> vnt = VarNamedTuple()
VarNamedTuple()
julia> x = zeros(2)
2-element Vector{Float64}:
0.0
0.0
julia> vnt = DynamicPPL.templated_setindex!!(vnt, 1.0, @varname(x[1:2][1]), x)
VarNamedTuple
└─ x => PartialArray size=(2,) data::Vector{Float64}
└─ (1,) => 1.0
julia> vnt = DynamicPPL.templated_setindex!!(vnt, 2.0, @varname(x[1:2][2]), x)
VarNamedTuple
└─ x => PartialArray size=(2,) data::Vector{Float64}
├─ (1,) => 1.0
└─ (2,) => 2.0
```
This required some careful thought to make sure that the second set
didn't overwrite the first one.
See e.g. lines 217 to 234 of src/varnamedtuple/getset.jl.
However, I forgot to handle this for the case where we check for
MustNotOverwrite:
```julia
julia> using AbstractPPL: @opticof
julia> using DynamicPPL.VarNamedTuples: _setindex_optic!!, SkipTemplate, MustNotOverwrite
julia> vnt = VarNamedTuple()
VarNamedTuple()
julia> vnt = _setindex_optic!!(vnt, 1.0, @opticof(_.x[1:2][1]), SkipTemplate{1}(x), MustNotOverwrite(@varname(x[1:2][1])))
VarNamedTuple
└─ x => PartialArray size=(2,) data::Vector{Float64}
└─ (1,) => 1.0
julia> vnt = _setindex_optic!!(vnt, 2.0, @opticof(_.x[1:2][2]), SkipTemplate{1}(x), MustNotOverwrite(@varname(x[1:2][2])))
ERROR: MustNotOverwriteError: Attempted to set a value for x[1:2][2], but a value already existed. This indicates that a value is being set twice (e.g. if the same variable occurs in a model twice).
Stacktrace:
[1] _setindex_optic!!(pa::DynamicPPL.VarNamedTuples.PartialArray{…}, value::Float64, optic::AbstractPPL.Index{…}, template::Vector{…}, permissions::MustNotOverwrite{…})
@ DynamicPPL.VarNamedTuples ~/ppl/dppl/src/varnamedtuple/getset.jl:173
[2] _setindex_optic!!(vnt::VarNamedTuple{…}, value::Float64, optic::AbstractPPL.Property{…}, template::SkipTemplate{…}, permissions::MustNotOverwrite{…})
@ DynamicPPL.VarNamedTuples ~/ppl/dppl/src/varnamedtuple/getset.jl:276
[3] top-level scope
@ REPL[20]:1
Some type information was truncated. Use `show(err)` to see complete types.
```
Two requests:
(1) could you help me fix that?
And after we've done that (but don't launch into this first; just do the
fix first)
(2) could you reason about whether there's a better way to handle the
ordinary case (the first code block)? Right now we do a merge, but I
think it might be possible for us to create a separate method for
setting a (slice of a) PartialArray into a PartialArray, where we make
sure to only copy the indices where the mask is set to true.
</details>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>1 parent 297e2e0 commit 563a463
File tree
5 files changed
+85
-2
lines changed- src/varnamedtuple
- test
5 files changed
+85
-2
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
1 | 5 | | |
2 | 6 | | |
3 | 7 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
168 | 168 | | |
169 | 169 | | |
170 | 170 | | |
171 | | - | |
| 171 | + | |
172 | 172 | | |
173 | 173 | | |
174 | 174 | | |
| |||
248 | 248 | | |
249 | 249 | | |
250 | 250 | | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
251 | 261 | | |
252 | 262 | | |
253 | 263 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
39 | 67 | | |
40 | 68 | | |
41 | 69 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1101 | 1101 | | |
1102 | 1102 | | |
1103 | 1103 | | |
| 1104 | + | |
| 1105 | + | |
1104 | 1106 | | |
1105 | 1107 | | |
1106 | 1108 | | |
| |||
1174 | 1176 | | |
1175 | 1177 | | |
1176 | 1178 | | |
| 1179 | + | |
| 1180 | + | |
| 1181 | + | |
| 1182 | + | |
| 1183 | + | |
| 1184 | + | |
| 1185 | + | |
| 1186 | + | |
| 1187 | + | |
| 1188 | + | |
| 1189 | + | |
| 1190 | + | |
| 1191 | + | |
| 1192 | + | |
| 1193 | + | |
| 1194 | + | |
| 1195 | + | |
| 1196 | + | |
| 1197 | + | |
| 1198 | + | |
| 1199 | + | |
| 1200 | + | |
| 1201 | + | |
| 1202 | + | |
| 1203 | + | |
| 1204 | + | |
| 1205 | + | |
| 1206 | + | |
| 1207 | + | |
| 1208 | + | |
| 1209 | + | |
| 1210 | + | |
| 1211 | + | |
| 1212 | + | |
| 1213 | + | |
| 1214 | + | |
| 1215 | + | |
| 1216 | + | |
| 1217 | + | |
1177 | 1218 | | |
1178 | 1219 | | |
1179 | 1220 | | |
| |||
0 commit comments