Skip to content

Commit f2d7791

Browse files
committed
Make hash2 recursively incorporate metadata and symtype
1 parent e9e5b25 commit f2d7791

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

src/types.jl

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ Base.nameof(s::BasicSymbolic) = issym(s) ? s.name : error("None Sym BasicSymboli
303303

304304
## This is much faster than hash of an array of Any
305305
hashvec(xs, z) = foldr(hash, xs, init=z)
306+
hashvec2(xs, z) = foldr(hash2, xs, init=z)
306307
const SYM_SALT = 0x4de7d7c66d41da43 % UInt
307308
const ADD_SALT = 0xaddaddaddaddadda % UInt
308309
const SUB_SALT = 0xaaaaaaaaaaaaaaaa % UInt
@@ -350,9 +351,33 @@ includes the metadata and symtype in the hash calculation. This can be beneficia
350351
consing, allowing for more effective deduplication of symbolically equivalent expressions
351352
with different metadata or symtypes.
352353
"""
354+
hash2(s, salt::UInt) = hash(s, salt)
353355
hash2(s::BasicSymbolic) = hash2(s, zero(UInt))
354356
function hash2(s::BasicSymbolic{T}, salt::UInt)::UInt where {T}
355-
hash(metadata(s), hash(T, hash(s, salt)))
357+
E = exprtype(s)
358+
h::UInt = 0
359+
if E === SYM
360+
h = hash(nameof(s), salt SYM_SALT)
361+
elseif E === ADD || E === MUL
362+
hashoffset = isadd(s) ? ADD_SALT : SUB_SALT
363+
hv = Base.hasha_seed
364+
for (k, v) in s.dict
365+
hv ⊻= hash2(k, hash(v))
366+
end
367+
h = hash(hv, salt)
368+
h = hash(hashoffset, hash(s.coeff, h))
369+
elseif E === DIV
370+
h = hash2(s.num, hash2(s.den, salt DIV_SALT))
371+
elseif E === POW
372+
h = hash2(s.exp, hash2(s.base, salt POW_SALT))
373+
elseif E === TERM
374+
op = operation(s)
375+
oph = op isa Function ? nameof(op) : op
376+
h = hashvec2(arguments(s), hash(oph, salt))
377+
else
378+
error_on_type()
379+
end
380+
hash(metadata(s), hash(T, h))
356381
end
357382

358383
###

0 commit comments

Comments
 (0)