Skip to content

Commit 0c005a5

Browse files
authored
Merge pull request #616 from isaacsas/avoid_repeated_reactants
Disallow repeated reactants and making hashing order independent
2 parents 7088109 + 7b021a5 commit 0c005a5

File tree

3 files changed

+37
-5
lines changed

3 files changed

+37
-5
lines changed

src/networkapi.jl

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,11 +1302,15 @@ end
13021302

13031303
function hash(rx::Reaction, h::UInt)
13041304
h = Base.hash(rx.rate, h)
1305-
h = Base.hash(rx.substrates, h)
1306-
h = Base.hash(rx.products, h)
1307-
h = Base.hash(rx.prodstoich, h)
1308-
h = Base.hash(rx.substoich, h)
1309-
h = Base.hash(rx.netstoich, h)
1305+
for s in Iterators.flatten((rx.substrates, rx.products))
1306+
h ⊻= hash(s)
1307+
end
1308+
for s in Iterators.flatten((rx.substoich, rx.prodstoich))
1309+
h ⊻= hash(s)
1310+
end
1311+
for s in rx.netstoich
1312+
h ⊻= hash(s)
1313+
end
13101314
Base.hash(rx.only_use_rate, h)
13111315
end
13121316

src/reactionsystem.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ function Reaction(rate, subs, prods, substoich, prodstoich;
142142
else
143143
subs = value.(subs)
144144
end
145+
allunique(subs) ||
146+
throw(ArgumentError("Substrates can not be repeated in the list provided to `Reaction`, please modify the stoichiometry for any repeated substrates instead."))
145147
S = eltype(substoich)
146148

147149
if isnothing(prods)
@@ -152,6 +154,8 @@ function Reaction(rate, subs, prods, substoich, prodstoich;
152154
else
153155
prods = value.(prods)
154156
end
157+
allunique(prods) ||
158+
throw(ArgumentError("Products can not be repeated in the list provided to `Reaction`, please modify the stoichiometry for any repeated products instead."))
155159
T = eltype(prodstoich)
156160

157161
# try to get a common type for stoichiometry, using Any if have Syms

test/reactionsystem.jl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,3 +676,27 @@ let
676676
@test issetequal(parameters(osys), [k1, k2])
677677
@test length(equations(osys)) == 3
678678
end
679+
680+
# test errors for repeated substrates or products
681+
let
682+
@variables t
683+
@species A(t) B(t)
684+
@test_throws ArgumentError Reaction(1.0, [A, A, B], [B])
685+
@test_throws ArgumentError Reaction(1.0, [B], [A, A])
686+
@test_throws ArgumentError Reaction(1.0, [A, A], [B, B])
687+
end
688+
689+
# test order of species and products doesn't matter for equality or hashing
690+
let
691+
@variables t
692+
@species A(t) α(t)
693+
rx = Reaction(1.0, [α, A], [α, A], [2, 3], [4, 5])
694+
rx2 = Reaction(1.0, [A, α], [A, α], [3, 2], [5, 4])
695+
@test rx == rx2
696+
@test hash(rx) == hash(rx2)
697+
698+
rx = Reaction(1.0, [α, A], [α, A], [2, 3], [4, 5]; netstoich ==> 2, A => 2])
699+
rx2 = Reaction(1.0, [A, α], [A, α], [3, 2], [5, 4]; netstoich = [A => 2, α => 2])
700+
@test rx == rx2
701+
@test hash(rx) == hash(rx2)
702+
end

0 commit comments

Comments
 (0)