@@ -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
305305hashvec (xs, z) = foldr (hash, xs, init= z)
306+ hashvec2 (xs, z) = foldr (hash2, xs, init= z)
306307const SYM_SALT = 0x4de7d7c66d41da43 % UInt
307308const ADD_SALT = 0xaddaddaddaddadda % UInt
308309const SUB_SALT = 0xaaaaaaaaaaaaaaaa % UInt
@@ -350,9 +351,33 @@ includes the metadata and symtype in the hash calculation. This can be beneficia
350351consing, allowing for more effective deduplication of symbolically equivalent expressions
351352with different metadata or symtypes.
352353"""
354+ hash2 (s, salt:: UInt ) = hash (s, salt)
353355hash2 (s:: BasicSymbolic ) = hash2 (s, zero (UInt))
354356function 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))
356381end
357382
358383# ##
0 commit comments