@@ -26,6 +26,7 @@ const ENABLE_HASHCONSING = Ref(true)
26
26
@compactify show_methods= false begin
27
27
@abstract mutable struct BasicSymbolic{T} <: Symbolic{T}
28
28
metadata:: Metadata = NO_METADATA
29
+ id:: RefValue{UInt64} = Ref {UInt64} (0 )
29
30
end
30
31
mutable struct Sym{T} <: BasicSymbolic{T}
31
32
name:: Symbol = :OOF
@@ -107,11 +108,11 @@ function ConstructionBase.setproperties(obj::BasicSymbolic{T}, patch::NamedTuple
107
108
# Call outer constructor because hash consing cannot be applied in inner constructor
108
109
@compactified obj:: BasicSymbolic begin
109
110
Sym => Sym {T} (nt_new. name; nt_new... )
110
- Term => Term {T} (nt_new. f, nt_new. arguments; nt_new... , hash = RefValue (UInt (0 )), hash2 = RefValue (UInt (0 )))
111
- Add => Add (T, nt_new. coeff, nt_new. dict; nt_new... , hash = RefValue (UInt (0 )), hash2 = RefValue (UInt (0 )))
112
- Mul => Mul (T, nt_new. coeff, nt_new. dict; nt_new... , hash = RefValue (UInt (0 )), hash2 = RefValue (UInt (0 )))
113
- Div => Div {T} (nt_new. num, nt_new. den, nt_new. simplified; nt_new... , hash = RefValue (UInt (0 )), hash2 = RefValue (UInt (0 )))
114
- Pow => Pow {T} (nt_new. base, nt_new. exp; nt_new... , hash = RefValue (UInt (0 )), hash2 = RefValue (UInt (0 )))
111
+ Term => Term {T} (nt_new. f, nt_new. arguments; nt_new... , hash = RefValue (UInt (0 )), hash2 = RefValue (UInt (0 )), id = Ref {UInt64} ( 0 ) )
112
+ Add => Add (T, nt_new. coeff, nt_new. dict; nt_new... , hash = RefValue (UInt (0 )), hash2 = RefValue (UInt (0 )), id = Ref {UInt64} ( 0 ) )
113
+ Mul => Mul (T, nt_new. coeff, nt_new. dict; nt_new... , hash = RefValue (UInt (0 )), hash2 = RefValue (UInt (0 )), id = Ref {UInt64} ( 0 ) )
114
+ Div => Div {T} (nt_new. num, nt_new. den, nt_new. simplified; nt_new... , hash = RefValue (UInt (0 )), hash2 = RefValue (UInt (0 )), id = Ref {UInt64} ( 0 ) )
115
+ Pow => Pow {T} (nt_new. base, nt_new. exp; nt_new... , hash = RefValue (UInt (0 )), hash2 = RefValue (UInt (0 )), id = Ref {UInt64} ( 0 ) )
115
116
_ => Unityper. rt_constructor (obj){T}(;nt_new... )
116
117
end
117
118
end
255
256
256
257
function Base. isequal (a:: BasicSymbolic{T} , b:: BasicSymbolic{S} ) where {T,S}
257
258
a === b && return true
259
+ a. id == b. id && a. id != 0 && return true
258
260
259
261
E = exprtype (a)
260
262
E === exprtype (b) || return false
@@ -298,6 +300,7 @@ function.
298
300
"""
299
301
function isequal_with_metadata (a:: BasicSymbolic{T} , b:: BasicSymbolic{S} ):: Bool where {T, S}
300
302
a === b && return true
303
+ a. id == b. id && a. id != 0 && return true
301
304
302
305
E = exprtype (a)
303
306
E === exprtype (b) || return false
513
516
# ## Constructors
514
517
# ##
515
518
519
+ mutable struct AtomicIDCounter
520
+ @atomic x:: UInt64
521
+ end
522
+
523
+ const ID_COUNTER = AtomicIDCounter (0 )
524
+
516
525
"""
517
526
$(TYPEDSIGNATURES)
518
527
@@ -542,21 +551,27 @@ function BasicSymbolic(s::BasicSymbolic)::BasicSymbolic
542
551
h = hash2 (s)
543
552
k = get! (cache, h, s)
544
553
if isequal_with_metadata (k, s)
554
+ if iszero (k. id[])
555
+ k. id[] = @atomic ID_COUNTER. x += 1
556
+ end
545
557
return k
546
558
else
559
+ if iszero (s. id[])
560
+ s. id[] = @atomic ID_COUNTER. x += 1
561
+ end
547
562
return s
548
563
end
549
564
end
550
565
551
566
function Sym {T} (name:: Symbol ; kw... ) where {T}
552
- s = Sym {T} (; name, kw... )
567
+ s = Sym {T} (; name, kw... , id = Ref {UInt} ( 0 ) )
553
568
BasicSymbolic (s)
554
569
end
555
570
556
571
function Term {T} (f, args; kw... ) where T
557
572
args = SmallV {Any} (args)
558
573
559
- s = Term {T} (;f= f, arguments= args, hash= Ref (UInt (0 )), hash2= Ref (UInt (0 )), kw... )
574
+ s = Term {T} (;f= f, arguments= args, hash= Ref (UInt (0 )), hash2= Ref (UInt (0 )), kw... , id = Ref {UInt64} ( 0 ) )
560
575
BasicSymbolic (s)
561
576
end
562
577
@@ -586,7 +601,7 @@ function Add(::Type{T}, coeff, dict; metadata=NO_METADATA, kw...) where T
586
601
end
587
602
end
588
603
589
- s = Add {T} (; coeff, dict, hash= Ref (UInt (0 )), hash2= Ref (UInt (0 )), metadata, arguments= SmallV {Any} (), kw... )
604
+ s = Add {T} (; coeff, dict, hash= Ref (UInt (0 )), hash2= Ref (UInt (0 )), metadata, arguments= SmallV {Any} (), kw... , id = Ref {UInt64} ( 0 ) )
590
605
BasicSymbolic (s)
591
606
end
592
607
@@ -604,7 +619,7 @@ function Mul(T, a, b; metadata=NO_METADATA, kw...)
604
619
else
605
620
coeff = a
606
621
dict = b
607
- s = Mul {T} (; coeff, dict, hash= Ref (UInt (0 )), hash2= Ref (UInt (0 )), metadata, arguments= SmallV {Any} (), kw... )
622
+ s = Mul {T} (; coeff, dict, hash= Ref (UInt (0 )), hash2= Ref (UInt (0 )), metadata, arguments= SmallV {Any} (), kw... , id = Ref {UInt64} ( 0 ) )
608
623
BasicSymbolic (s)
609
624
end
610
625
end
@@ -672,7 +687,7 @@ function Div{T}(n, d, simplified=false; metadata=nothing, kwargs...) where {T}
672
687
end
673
688
end
674
689
675
- s = Div {T} (; num= n, den= d, simplified, arguments= SmallV {Any} (), metadata)
690
+ s = Div {T} (; num= n, den= d, simplified, arguments= SmallV {Any} (), metadata, id = Ref {UInt64} ( 0 ) )
676
691
BasicSymbolic (s)
677
692
end
678
693
@@ -692,7 +707,7 @@ function Pow{T}(a, b; metadata=NO_METADATA, kwargs...) where {T}
692
707
b = unwrap (b)
693
708
_iszero (b) && return 1
694
709
_isone (b) && return a
695
- s = Pow {T} (; base= a, exp= b, arguments= SmallV {Any} (), metadata)
710
+ s = Pow {T} (; base= a, exp= b, arguments= SmallV {Any} (), metadata, id = Ref {UInt64} ( 0 ) )
696
711
BasicSymbolic (s)
697
712
end
698
713
0 commit comments