@@ -34,18 +34,21 @@ const ENABLE_HASHCONSING = Ref(true)
34
34
f:: Any = identity # base/num if Pow; issorted if Add/Dict
35
35
arguments:: Vector{Any} = EMPTY_ARGS
36
36
hash:: RefValue{UInt} = EMPTY_HASH
37
+ hash2:: RefValue{UInt} = EMPTY_HASH
37
38
end
38
39
mutable struct Mul{T} <: BasicSymbolic{T}
39
40
coeff:: Any = 0 # exp/den if Pow
40
41
dict:: EMPTY_DICT_T = EMPTY_DICT
41
42
hash:: RefValue{UInt} = EMPTY_HASH
43
+ hash2:: RefValue{UInt} = EMPTY_HASH
42
44
arguments:: Vector{Any} = EMPTY_ARGS
43
45
issorted:: RefValue{Bool} = NOT_SORTED
44
46
end
45
47
mutable struct Add{T} <: BasicSymbolic{T}
46
48
coeff:: Any = 0 # exp/den if Pow
47
49
dict:: EMPTY_DICT_T = EMPTY_DICT
48
50
hash:: RefValue{UInt} = EMPTY_HASH
51
+ hash2:: RefValue{UInt} = EMPTY_HASH
49
52
arguments:: Vector{Any} = EMPTY_ARGS
50
53
issorted:: RefValue{Bool} = NOT_SORTED
51
54
end
@@ -98,11 +101,11 @@ function ConstructionBase.setproperties(obj::BasicSymbolic{T}, patch::NamedTuple
98
101
# Call outer constructor because hash consing cannot be applied in inner constructor
99
102
@compactified obj:: BasicSymbolic begin
100
103
Sym => Sym {T} (nt_new. name; nt_new... )
101
- Term => Term {T} (nt_new. f, nt_new. arguments; nt_new... , hash = RefValue (UInt (0 )))
102
- Add => Add (T, nt_new. coeff, nt_new. dict; nt_new... , hash = RefValue (UInt (0 )))
103
- Mul => Mul (T, nt_new. coeff, nt_new. dict; nt_new... , hash = RefValue (UInt (0 )))
104
- Div => Div {T} (nt_new. num, nt_new. den, nt_new. simplified; nt_new... , hash = RefValue (UInt (0 )))
105
- Pow => Pow {T} (nt_new. base, nt_new. exp; nt_new... , hash = RefValue (UInt (0 )))
104
+ Term => Term {T} (nt_new. f, nt_new. arguments; nt_new... , hash = RefValue (UInt (0 )), hash2 = RefValue ( UInt ( 0 )) )
105
+ Add => Add (T, nt_new. coeff, nt_new. dict; nt_new... , hash = RefValue (UInt (0 )), hash2 = RefValue ( UInt ( 0 )) )
106
+ Mul => Mul (T, nt_new. coeff, nt_new. dict; nt_new... , hash = RefValue (UInt (0 )), hash2 = RefValue ( UInt ( 0 )) )
107
+ Div => Div {T} (nt_new. num, nt_new. den, nt_new. simplified; nt_new... , hash = RefValue (UInt (0 )), hash2 = RefValue ( UInt ( 0 )) )
108
+ Pow => Pow {T} (nt_new. base, nt_new. exp; nt_new... , hash = RefValue (UInt (0 )), hash2 = RefValue ( UInt ( 0 )) )
106
109
_ => Unityper. rt_constructor (obj){T}(;nt_new... )
107
110
end
108
111
end
@@ -461,6 +464,9 @@ function hash2(s::BasicSymbolic{T}, salt::UInt)::UInt where {T}
461
464
if E === SYM
462
465
h = hash (nameof (s), salt ⊻ SYM_SALT)
463
466
elseif E === ADD || E === MUL
467
+ if ! iszero (s. hash2[])
468
+ return s. hash2[]
469
+ end
464
470
hashoffset = isadd (s) ? ADD_SALT : SUB_SALT
465
471
hv = Base. hasha_seed
466
472
for (k, v) in s. dict
@@ -473,13 +479,20 @@ function hash2(s::BasicSymbolic{T}, salt::UInt)::UInt where {T}
473
479
elseif E === POW
474
480
h = hash2 (s. exp, hash2 (s. base, salt ⊻ POW_SALT))
475
481
elseif E === TERM
482
+ if ! iszero (s. hash2[])
483
+ return s. hash2[]
484
+ end
476
485
op = operation (s)
477
486
oph = op isa Function ? nameof (op) : op
478
487
h = hashvec2 (arguments (s), hash (oph, salt))
479
488
else
480
489
error_on_type ()
481
490
end
482
- hash (metadata (s), hash (T, h))
491
+ h = hash (metadata (s), hash (T, h))
492
+ if hasproperty (s, :hash2 )
493
+ s. hash2[] = h
494
+ end
495
+ return h
483
496
end
484
497
485
498
# ##
@@ -530,7 +543,7 @@ function Term{T}(f, args; kw...) where T
530
543
args = convert (Vector{Any}, args)
531
544
end
532
545
533
- s = Term {T} (;f= f, arguments= args, hash= Ref (UInt (0 )), kw... )
546
+ s = Term {T} (;f= f, arguments= args, hash= Ref (UInt (0 )), hash2 = Ref ( UInt ( 0 )), kw... )
534
547
BasicSymbolic (s)
535
548
end
536
549
@@ -551,7 +564,7 @@ function Add(::Type{T}, coeff, dict; metadata=NO_METADATA, kw...) where T
551
564
end
552
565
end
553
566
554
- s = Add {T} (; coeff, dict, hash= Ref (UInt (0 )), metadata, arguments= [], issorted= RefValue (false ), kw... )
567
+ s = Add {T} (; coeff, dict, hash= Ref (UInt (0 )), hash2 = Ref ( UInt ( 0 )), metadata, arguments= [], issorted= RefValue (false ), kw... )
555
568
BasicSymbolic (s)
556
569
end
557
570
@@ -567,7 +580,7 @@ function Mul(T, a, b; metadata=NO_METADATA, kw...)
567
580
else
568
581
coeff = a
569
582
dict = b
570
- s = Mul {T} (; coeff, dict, hash= Ref (UInt (0 )), metadata, arguments= [], issorted= RefValue (false ), kw... )
583
+ s = Mul {T} (; coeff, dict, hash= Ref (UInt (0 )), hash2 = Ref ( UInt ( 0 )), metadata, arguments= [], issorted= RefValue (false ), kw... )
571
584
BasicSymbolic (s)
572
585
end
573
586
end
0 commit comments