From 28e27ffaf105f765b64a763962158b8216fbea6c Mon Sep 17 00:00:00 2001 From: "Bowen S. Zhu" Date: Tue, 5 Nov 2024 11:00:56 -0500 Subject: [PATCH] Add `isequal2` function for checking metadata comparison --- src/types.jl | 20 ++++++++++++++++++++ test/basics.jl | 9 ++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/types.jl b/src/types.jl index 2aca744b..64cd9667 100644 --- a/src/types.jl +++ b/src/types.jl @@ -267,6 +267,26 @@ function _isequal(a, b, E) end end +""" +$(TYPEDSIGNATURES) + +Checks for equality between two `BasicSymbolic` objects, considering both their +values and metadata. + +The default `Base.isequal` function for `BasicSymbolic` only compares their expressions +and ignores metadata. This can lead to hash collisions when metadata is relevant +for distinguishing expressions, particularly in hashing contexts. This function +provides a stricter equality check that includes metadata comparison, preventing +such collisions. + +Modifying `Base.isequal` directly breaks numerous tests in `SymbolicUtils.jl` and +downstream packages like `ModelingToolkit.jl`, hence the need for this separate +function. +""" +function isequal2(a::BasicSymbolic, b::BasicSymbolic)::Bool + isequal(a, b) && isequal(metadata(a), metadata(b)) +end + Base.one( s::Symbolic) = one( symtype(s)) Base.zero(s::Symbolic) = zero(symtype(s)) diff --git a/test/basics.jl b/test/basics.jl index 1402f9ac..93dfbd42 100644 --- a/test/basics.jl +++ b/test/basics.jl @@ -1,4 +1,4 @@ -using SymbolicUtils: Symbolic, Sym, FnType, Term, Add, Mul, Pow, symtype, operation, arguments, issym, isterm, BasicSymbolic, term +using SymbolicUtils: Symbolic, Sym, FnType, Term, Add, Mul, Pow, symtype, operation, arguments, issym, isterm, BasicSymbolic, term, isequal2 using SymbolicUtils using IfElse: ifelse using Setfield @@ -336,6 +336,13 @@ end @test !isequal(a, missing) @test !isequal(missing, b) + + a1 = setmetadata(a, Ctx1, "meta_1") + a2 = setmetadata(a, Ctx1, "meta_1") + a3 = setmetadata(a, Ctx2, "meta_2") + @test !isequal2(a, a1) + @test isequal2(a1, a2) + @test !isequal2(a1, a3) end @testset "subtyping" begin