Skip to content

Commit 7d330f4

Browse files
Merge pull request #3683 from AayushSabharwal/as/rm-isequal-hash
refactor: remove old `==` and `hash` implementation for `System`
2 parents 368d2f7 + 90c7c66 commit 7d330f4

File tree

8 files changed

+28
-166
lines changed

8 files changed

+28
-166
lines changed

src/systems/system.jl

Lines changed: 0 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -784,97 +784,6 @@ function ignored_connections_equal(sys1::System, sys2::System)
784784
return _eq_unordered(ic1[1], ic2[1]) && _eq_unordered(ic1[2], ic2[2])
785785
end
786786

787-
function Base.:(==)(sys1::System, sys2::System)
788-
sys1 === sys2 && return true
789-
iv1 = get_iv(sys1)
790-
iv2 = get_iv(sys2)
791-
isequal(iv1, iv2) &&
792-
isequal(nameof(sys1), nameof(sys2)) &&
793-
_eq_unordered(get_eqs(sys1), get_eqs(sys2)) &&
794-
noise_equations_equal(sys1, sys2) &&
795-
_eq_unordered(get_jumps(sys1), get_jumps(sys2)) &&
796-
_eq_unordered(get_constraints(sys1), get_constraints(sys2)) &&
797-
_eq_unordered(get_costs(sys1), get_costs(sys2)) &&
798-
isequal(get_consolidate(sys1), get_consolidate(sys2)) &&
799-
_eq_unordered(get_unknowns(sys1), get_unknowns(sys2)) &&
800-
_eq_unordered(get_ps(sys1), get_ps(sys2)) &&
801-
_eq_unordered(get_brownians(sys1), get_brownians(sys2)) &&
802-
_eq_unordered(get_observed(sys1), get_observed(sys2)) &&
803-
_eq_unordered(get_parameter_dependencies(sys1), get_parameter_dependencies(sys2)) &&
804-
isequal(get_description(sys1), get_description(sys2)) &&
805-
isequal(get_defaults(sys1), get_defaults(sys2)) &&
806-
isequal(get_guesses(sys1), get_guesses(sys2)) &&
807-
_eq_unordered(get_initialization_eqs(sys1), get_initialization_eqs(sys2)) &&
808-
_eq_unordered(get_continuous_events(sys1), get_continuous_events(sys2)) &&
809-
_eq_unordered(get_discrete_events(sys1), get_discrete_events(sys2)) &&
810-
isequal(get_connector_type(sys1), get_connector_type(sys2)) &&
811-
isequal(get_assertions(sys1), get_assertions(sys2)) &&
812-
isequal(get_metadata(sys1), get_metadata(sys2)) &&
813-
isequal(get_gui_metadata(sys1), get_gui_metadata(sys2)) &&
814-
get_is_dde(sys1) == get_is_dde(sys2) &&
815-
_eq_unordered(get_tstops(sys1), get_tstops(sys2)) &&
816-
# not comparing tearing states because checking if they're equal up to ordering
817-
# is difficult
818-
getfield(sys1, :namespacing) == getfield(sys2, :namespacing) &&
819-
getfield(sys1, :complete) == getfield(sys2, :complete) &&
820-
ignored_connections_equal(sys1, sys2) &&
821-
get_parent(sys1) == get_parent(sys2) &&
822-
get_isscheduled(sys1) == get_isscheduled(sys2) &&
823-
all(s1 == s2 for (s1, s2) in zip(get_systems(sys1), get_systems(sys2)))
824-
end
825-
826-
function Base.hash(sys::System, h::UInt)
827-
h = hash(nameof(sys), h)
828-
h = hash(get_iv(sys), h)
829-
# be considerate of things compared using `_eq_unordered` in `==`
830-
eqs = get_eqs(sys)
831-
eq_sortperm = sortperm(eqs; by = string)
832-
h = hash(@view(eqs[eq_sortperm]), h)
833-
neqs = get_noise_eqs(sys)
834-
if neqs === nothing
835-
h = hash(nothing, h)
836-
elseif neqs isa Vector
837-
h = hash(@view(neqs[eq_sortperm]), h)
838-
else
839-
h = hash(@view(neqs[eq_sortperm, :]), h)
840-
end
841-
h = hash(Set(get_jumps(sys)), h)
842-
h = hash(Set(get_constraints(sys)), h)
843-
h = hash(Set(get_costs(sys)), h)
844-
h = hash(get_consolidate(sys), h)
845-
h = hash(Set(get_unknowns(sys)), h)
846-
h = hash(Set(get_ps(sys)), h)
847-
h = hash(Set(get_brownians(sys)), h)
848-
h = hash(Set(get_observed(sys)), h)
849-
h = hash(Set(get_parameter_dependencies(sys)), h)
850-
h = hash(get_description(sys), h)
851-
h = hash(get_defaults(sys), h)
852-
h = hash(get_guesses(sys), h)
853-
h = hash(Set(get_initialization_eqs(sys)), h)
854-
h = hash(Set(get_continuous_events(sys)), h)
855-
h = hash(Set(get_discrete_events(sys)), h)
856-
h = hash(get_connector_type(sys), h)
857-
h = hash(get_assertions(sys), h)
858-
h = hash(get_metadata(sys), h)
859-
h = hash(get_gui_metadata(sys), h)
860-
h = hash(get_is_dde(sys), h)
861-
h = hash(Set(get_tstops(sys)), h)
862-
h = hash(Set(getfield(sys, :namespacing)), h)
863-
h = hash(Set(getfield(sys, :complete)), h)
864-
ics = get_ignored_connections(sys)
865-
if ics === nothing
866-
h = hash(ics, h)
867-
else
868-
h = hash(Set(ics[1]), hash(Set(ics[2]), h), h)
869-
end
870-
h = hash(get_parent(sys), h)
871-
h = hash(get_isscheduled(sys), h)
872-
for s in get_systems(sys)
873-
h = hash(s, h)
874-
end
875-
return h
876-
end
877-
878787
"""
879788
$(TYPEDSIGNATURES)
880789

test/accessor_functions.jl

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -151,17 +151,11 @@ let
151151
# Checks `continuous_events_toplevel` and `discrete_events_toplevel` (straightforward
152152
# as I stored the same single event in all systems). Don't check for non-toplevel cases as
153153
# technically not needed for these tests and name spacing the events is a mess.
154-
bot_cev = ModelingToolkit.SymbolicContinuousCallback(
155-
cevs[1], alg_eqs = [O ~ (d + p_bot) * X_bot + Y])
156-
mid_dev = ModelingToolkit.SymbolicDiscreteCallback(
157-
devs[1], alg_eqs = [O ~ (d + p_mid1) * X_mid1 + Y])
158154
@test all_sets_equal(
159-
continuous_events_toplevel.([sys_bot, sys_bot_comp, sys_bot_ss])...,
160-
[bot_cev])
155+
continuous_events_toplevel.([sys_bot, sys_bot_comp, sys_bot_ss])...)
161156
@test all_sets_equal(
162157
discrete_events_toplevel.(
163-
[sys_mid1, sys_mid1_comp, sys_mid1_ss])...,
164-
[mid_dev])
158+
[sys_mid1, sys_mid1_comp, sys_mid1_ss])...)
165159
@test all(sym_issubset(
166160
continuous_events_toplevel(sys), get_continuous_events(sys))
167161
for sys in [sys_bot, sys_mid2, sys_mid1, sys_top])

test/analysis_points.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ using Symbolics: NAMESPACE_SEPARATOR
2222
sys_normal = System(eqs, t, systems = [P, C], name = :hej)
2323
sys_normal2 = @test_nowarn expand_connections(sys_normal)
2424

25-
@test isequal(sys_ap2, sys_normal2)
25+
@test issetequal(equations(sys_ap2), equations(sys_normal2))
2626
end
2727

2828
@testset "Inverse causality throws a warning" begin

test/nonlinearsystem.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ eqs = [0 ~ σ * (y - x) * h,
2626
0 ~ x *- z) - y,
2727
0 ~ x * y - β * z]
2828
@named ns = System(eqs, [x, y, z], [σ, ρ, β, h], defaults = Dict(x => 2))
29-
@test eval(toexpr(ns)) == ns
29+
ns2 = eval(toexpr(ns))
30+
@test issetequal(equations(ns), equations(ns2))
31+
@test issetequal(unknowns(ns), unknowns(ns2))
32+
@test issetequal(parameters(ns), parameters(ns2))
3033
test_nlsys_inference("standard", ns, (x, y, z), (σ, ρ, β, h))
3134
@test begin
3235
f = generate_rhs(ns, expression = Val{false})[2]

test/odesystem.jl

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ ssort(eqs) = sort(eqs, by = string)
3535
@named des[1:3] = System(eqs, t)
3636
@test length(unique(x -> ModelingToolkit.get_tag(x), des)) == 1
3737

38-
@test eval(toexpr(de)) == de
39-
@test hash(deepcopy(de)) == hash(de)
38+
de2 = eval(toexpr(de))
39+
@test issetequal(equations(de2), eqs)
40+
@test issetequal(unknowns(de2), unknowns(de))
41+
@test issetequal(parameters(de2), parameters(de))
4042

4143
function test_diffeq_inference(name, sys, iv, dvs, ps)
4244
@testset "System construction: $name" begin
@@ -710,7 +712,9 @@ let
710712
s1′ = sys1(; name = :s1)
711713
@named s2 = sys2()
712714
@unpack s1 = s2
713-
@test isequal(s1, s1′)
715+
@test isequal(unknowns(s1), unknowns(s1′))
716+
@test isequal(parameters(s1), parameters(s1′))
717+
@test isequal(equations(s1), equations(s1′))
714718

715719
defs = Dict(s1.dx => 0.0, D(s1.x) => s1.x, s1.x => 0.0)
716720
@test isequal(ModelingToolkit.defaults(s2), defs)
@@ -1427,33 +1431,6 @@ end
14271431
@test_nowarn @named osys = System(eqs, t)
14281432
end
14291433

1430-
# Test `isequal`
1431-
@testset "`isequal`" begin
1432-
@variables X(t)
1433-
@parameters p d(t)
1434-
eq = D(X) ~ p - d * X
1435-
1436-
osys1 = complete(System([eq], t; name = :osys))
1437-
osys2 = complete(System([eq], t; name = :osys))
1438-
@test osys1 == osys2 # true
1439-
1440-
continuous_events = [[X ~ 1.0] => [X ~ Pre(X) + 5.0]]
1441-
discrete_events = [SymbolicDiscreteCallback(
1442-
5.0 => [d ~ d / 2.0], discrete_parameters = [d])]
1443-
1444-
osys1 = complete(System([eq], t; name = :osys, continuous_events))
1445-
osys2 = complete(System([eq], t; name = :osys))
1446-
@test osys1 !== osys2
1447-
1448-
osys1 = complete(System([eq], t; name = :osys, discrete_events))
1449-
osys2 = complete(System([eq], t; name = :osys))
1450-
@test osys1 !== osys2
1451-
1452-
osys1 = complete(System([eq], t; name = :osys, continuous_events))
1453-
osys2 = complete(System([eq], t; name = :osys, discrete_events))
1454-
@test osys1 !== osys2
1455-
end
1456-
14571434
@testset "Constraint system construction" begin
14581435
@variables x(..) y(..) z(..)
14591436
@parameters a b c d e

test/sdesystem.jl

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -612,9 +612,8 @@ diffusion_eqs = [s*x 0
612612

613613
sys2 = SDESystem(drift_eqs, diffusion_eqs, tt, sts, ps, name = :sys1)
614614
sys2 = complete(sys2)
615-
@set! sys1.parent = nothing
616-
@set! sys2.parent = nothing
617-
@test sys1 == sys2
615+
616+
@test issetequal(ModelingToolkit.get_noise_eqs(sys1), ModelingToolkit.get_noise_eqs(sys2))
618617

619618
prob = SDEProblem(sys1, [sts .=> [1.0, 0.0, 0.0]; ps .=> [10.0, 26.0]],
620619
(0.0, 100.0))
@@ -927,31 +926,6 @@ end
927926
end
928927
end
929928

930-
@testset "SDESystem Equality with events" begin
931-
@variables X(t)
932-
@parameters p d
933-
@brownian a
934-
seq = D(X) ~ p - d * X + a
935-
@mtkcompile ssys1 = System([seq], t; name = :ssys)
936-
@mtkcompile ssys2 = System([seq], t; name = :ssys)
937-
@test ssys1 == ssys2 # true
938-
939-
continuous_events = [[X ~ 1.0] => [X ~ Pre(X) + 5.0]]
940-
discrete_events = [5.0 => [d ~ Pre(d) / 2.0]]
941-
942-
@mtkcompile ssys1 = System([seq], t; name = :ssys, continuous_events)
943-
@mtkcompile ssys2 = System([seq], t; name = :ssys)
944-
@test ssys1 !== ssys2
945-
946-
@mtkcompile ssys1 = System([seq], t; name = :ssys, discrete_events)
947-
@mtkcompile ssys2 = System([seq], t; name = :ssys)
948-
@test ssys1 !== ssys2
949-
950-
@mtkcompile ssys1 = System([seq], t; name = :ssys, continuous_events)
951-
@mtkcompile ssys2 = System([seq], t; name = :ssys, discrete_events)
952-
@test ssys1 !== ssys2
953-
end
954-
955929
@testset "Error when constructing SDEProblem without `mtkcompile`" begin
956930
@parameters σ ρ β
957931
@variables x(tt) y(tt) z(tt)

test/serialization.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ write(io, expand_connections(rc_model))
2727
str = String(take!(io))
2828

2929
sys = include_string(@__MODULE__, str)
30-
@test sys == expand_connections(rc_model) # this actually kind of works, but the variables would have different identities.
30+
rc2 = expand_connections(rc_model)
31+
@test issetequal(equations(sys), equations(rc2))
32+
@test issetequal(unknowns(sys), unknowns(rc2))
33+
@test issetequal(parameters(sys), parameters(rc2))
3134

3235
# check answer
3336
ss = mtkcompile(rc_model)

test/symbolic_events.jl

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,9 @@ end
310310
[D(x) ~ v
311311
D(v) ~ -9.8], t, continuous_events = root_eqs => affect)
312312

313-
@test only(continuous_events(ball)) ==
314-
SymbolicContinuousCallback(Equation[x ~ 0], Equation[v ~ -Pre(v)])
313+
cev = only(continuous_events(ball))
314+
@test isequal(only(equations(cev)), x ~ 0)
315+
@test isequal(only(observed(cev.affect.system)), v ~ -Pre(v))
315316
ball = mtkcompile(ball)
316317

317318
@test length(ModelingToolkit.continuous_events(ball)) == 1
@@ -343,10 +344,11 @@ end
343344

344345
cb = get_callback(prob)
345346
@test cb isa ModelingToolkit.DiffEqCallbacks.VectorContinuousCallback
346-
@test getfield(ball, :continuous_events)[1] ==
347-
SymbolicContinuousCallback(Equation[x ~ 0], Equation[vx ~ -Pre(vx)])
348-
@test getfield(ball, :continuous_events)[2] ==
349-
SymbolicContinuousCallback(Equation[y ~ -1.5, y ~ 1.5], Equation[vy ~ -Pre(vy)])
347+
_cevs = getfield(ball, :continuous_events)
348+
@test isequal(only(equations(_cevs[1])), x ~ 0)
349+
@test isequal(only(observed(_cevs[1].affect.system)), vx ~ -Pre(vx))
350+
@test issetequal(equations(_cevs[2]), [y ~ -1.5, y ~ 1.5])
351+
@test isequal(only(observed(_cevs[2].affect.system)), vy ~ -Pre(vy))
350352
cond = cb.condition
351353
out = [0.0, 0.0, 0.0]
352354
p0 = 0.0

0 commit comments

Comments
 (0)