@@ -26,6 +26,7 @@ const ENABLE_HASHCONSING = Ref(true)
2626@compactify show_methods= false begin
2727 @abstract mutable struct BasicSymbolic{T} <: Symbolic{T}
2828 metadata:: Metadata = NO_METADATA
29+ id:: RefValue{UInt64} = Ref {UInt64} (0 )
2930 end
3031 mutable struct Sym{T} <: BasicSymbolic{T}
3132 name:: Symbol = :OOF
@@ -107,11 +108,11 @@ function ConstructionBase.setproperties(obj::BasicSymbolic{T}, patch::NamedTuple
107108 # Call outer constructor because hash consing cannot be applied in inner constructor
108109 @compactified obj:: BasicSymbolic begin
109110 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 ) )
115116 _ => Unityper. rt_constructor (obj){T}(;nt_new... )
116117 end
117118end
255256
256257function Base. isequal (a:: BasicSymbolic{T} , b:: BasicSymbolic{S} ) where {T,S}
257258 a === b && return true
259+ a. id == b. id && a. id != 0 && return true
258260
259261 E = exprtype (a)
260262 E === exprtype (b) || return false
@@ -298,6 +300,7 @@ function.
298300"""
299301function isequal_with_metadata (a:: BasicSymbolic{T} , b:: BasicSymbolic{S} ):: Bool where {T, S}
300302 a === b && return true
303+ a. id == b. id && a. id != 0 && return true
301304
302305 E = exprtype (a)
303306 E === exprtype (b) || return false
513516# ## Constructors
514517# ##
515518
519+ mutable struct AtomicIDCounter
520+ @atomic x:: UInt64
521+ end
522+
523+ const ID_COUNTER = AtomicIDCounter (0 )
524+
516525"""
517526$(TYPEDSIGNATURES)
518527
@@ -542,21 +551,27 @@ function BasicSymbolic(s::BasicSymbolic)::BasicSymbolic
542551 h = hash2 (s)
543552 k = get! (cache, h, s)
544553 if isequal_with_metadata (k, s)
554+ if iszero (k. id[])
555+ k. id[] = @atomic ID_COUNTER. x += 1
556+ end
545557 return k
546558 else
559+ if iszero (s. id[])
560+ s. id[] = @atomic ID_COUNTER. x += 1
561+ end
547562 return s
548563 end
549564end
550565
551566function Sym {T} (name:: Symbol ; kw... ) where {T}
552- s = Sym {T} (; name, kw... )
567+ s = Sym {T} (; name, kw... , id = Ref {UInt} ( 0 ) )
553568 BasicSymbolic (s)
554569end
555570
556571function Term {T} (f, args; kw... ) where T
557572 args = SmallV {Any} (args)
558573
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 ) )
560575 BasicSymbolic (s)
561576end
562577
@@ -586,7 +601,7 @@ function Add(::Type{T}, coeff, dict; metadata=NO_METADATA, kw...) where T
586601 end
587602 end
588603
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 ) )
590605 BasicSymbolic (s)
591606end
592607
@@ -604,7 +619,7 @@ function Mul(T, a, b; metadata=NO_METADATA, kw...)
604619 else
605620 coeff = a
606621 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 ) )
608623 BasicSymbolic (s)
609624 end
610625end
@@ -672,7 +687,7 @@ function Div{T}(n, d, simplified=false; metadata=nothing, kwargs...) where {T}
672687 end
673688 end
674689
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 ) )
676691 BasicSymbolic (s)
677692end
678693
@@ -692,7 +707,7 @@ function Pow{T}(a, b; metadata=NO_METADATA, kwargs...) where {T}
692707 b = unwrap (b)
693708 _iszero (b) && return 1
694709 _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 ) )
696711 BasicSymbolic (s)
697712end
698713
0 commit comments