@@ -32,20 +32,24 @@ import io.ksmt.sort.KSortVisitor
3232import io.ksmt.sort.KUninterpretedSort
3333import java.util.TreeMap
3434
35- class KCvc5Context private constructor(
35+ class KCvc5Context internal constructor(
3636 private val solver : Solver ,
37+ /* *
38+ * Used as context for expressions lifetime separation.
39+ * Exprs which stored in [KCvc5Context], created with [mkExprSolver]
40+ */
3741 val mkExprSolver : Solver ,
3842 private val ctx : KContext ,
39- parent : KCvc5Context ? ,
40- val isForking : Boolean
43+ forkingSolverManager : KCvc5ForkingSolverManager ? = null
4144) : AutoCloseable {
42- constructor (solver: Solver , mkExprSolver: Solver , ctx: KContext , isForking : Boolean = false )
43- : this (solver, mkExprSolver, ctx, null , isForking )
45+ constructor (solver: Solver , mkExprSolver: Solver , ctx: KContext )
46+ : this (solver, mkExprSolver, ctx, null )
4447
45- constructor (solver: Solver , ctx: KContext , isForking : Boolean = false )
46- : this (solver, solver, ctx, null , isForking )
48+ constructor (solver: Solver , ctx: KContext )
49+ : this (solver, solver, ctx, null )
4750
4851 private var isClosed = false
52+ val isForking = forkingSolverManager != null
4953
5054 private val uninterpretedSortCollector = KUninterpretedSortCollector (this )
5155 private var exprCurrentLevelCacheRestorer = KCurrentScopeExprCacheRestorer (uninterpretedSortCollector, ctx)
@@ -72,14 +76,11 @@ class KCvc5Context private constructor(
7276 * that is in global cache, but whose sorts / decls have been erased after pop()
7377 * (and put this expr to the cache of current accumulated scope)
7478 */
75- private val currentAccumulatedScopeExpressions: HashMap <KExpr <* >, Term >
79+ private val currentAccumulatedScopeExpressions = HashMap <KExpr <* >, Term > ()
7680 private val expressions: HashMap <KExpr <* >, Term >
7781
7882 /* *
7983 * We can't use HashMap with Term and Sort (hashcode is not implemented)
80- *
81- * Avoid to close cache explicitly due to its sharing between forking hierarchy.
82- * It will be garbage collected on last solver close in forking hierarchy
8384 */
8485 private val cvc5Expressions: TreeMap <Term , KExpr <* >>
8586 private val sorts: HashMap <KSort , Sort >
@@ -102,28 +103,26 @@ class KCvc5Context private constructor(
102103
103104 init {
104105 if (isForking) {
105- uninterpretedSorts = (parent?.uninterpretedSorts as ? ScopedLinkedFrame )?.fork()
106- ? : ScopedLinkedFrame (::HashSet , ::HashSet )
107- declarations = (parent?.declarations as ? ScopedLinkedFrame )?.fork()
108- ? : ScopedLinkedFrame (::HashSet , ::HashSet )
106+ uninterpretedSorts = ScopedLinkedFrame (::HashSet , ::HashSet )
107+ declarations = ScopedLinkedFrame (::HashSet , ::HashSet )
109108 } else {
110109 uninterpretedSorts = ScopedArrayFrame (::HashSet )
111110 declarations = ScopedArrayFrame (::HashSet )
112111 }
113112
114- if (parent != null ) {
115- currentAccumulatedScopeExpressions = parent.currentAccumulatedScopeExpressions.toMap(HashMap ())
116- expressions = parent.expressions
117- cvc5Expressions = parent.cvc5Expressions
118- sorts = parent.sorts
119- cvc5Sorts = parent.cvc5Sorts
120- decls = parent.decls
121- cvc5Decls = parent.cvc5Decls
122- uninterpretedSortValueDescriptors = parent.uninterpretedSortValueDescriptors
123- uninterpretedSortValueInterpreter = parent.uninterpretedSortValueInterpreter
124- uninterpretedSortValues = parent.uninterpretedSortValues
113+ if (forkingSolverManager != null ) {
114+ with (forkingSolverManager) {
115+ expressions = findExpressionsCache()
116+ cvc5Expressions = findExpressionsReversedCache()
117+ sorts = findSortsCache()
118+ cvc5Sorts = findSortsReversedCache()
119+ decls = findDeclsCache()
120+ cvc5Decls = findDeclsReversedCache()
121+ uninterpretedSortValueDescriptors = findUninterpretedSortsValueDescriptors()
122+ uninterpretedSortValueInterpreter = findUninterpretedSortsValueInterpretersCache()
123+ uninterpretedSortValues = findUninterpretedSortValues()
124+ }
125125 } else {
126- currentAccumulatedScopeExpressions = HashMap ()
127126 expressions = HashMap ()
128127 cvc5Expressions = TreeMap ()
129128 sorts = HashMap ()
@@ -155,12 +154,18 @@ class KCvc5Context private constructor(
155154 val isActive: Boolean
156155 get() = ! isClosed
157156
158- fun fork (solver : Solver , mkExprSolver : Solver ): KCvc5Context =
159- KCvc5Context (solver, mkExprSolver, ctx, this , true ).also { forkCtx ->
157+ fun fork (solver : Solver , forkingSolverManager : KCvc5ForkingSolverManager ): KCvc5Context {
158+ require(isForking) { " Can't fork non-forking context" }
159+ return KCvc5Context (solver, mkExprSolver, ctx, forkingSolverManager).also { forkCtx ->
160+ forkCtx.currentAccumulatedScopeExpressions + = currentAccumulatedScopeExpressions
161+ (forkCtx.uninterpretedSorts as ScopedLinkedFrame ).fork(uninterpretedSorts as ScopedLinkedFrame )
162+ (forkCtx.declarations as ScopedLinkedFrame ).fork(declarations as ScopedLinkedFrame )
163+
160164 repeat(assertedConstraintLevels.size) {
161165 forkCtx.pushAssertionLevel()
162166 }
163167 }
168+ }
164169
165170 fun push () {
166171 declarations.push()
@@ -262,7 +267,7 @@ class KCvc5Context private constructor(
262267 *
263268 * todo: precise uninterpreted sort values tracking
264269 * */
265- private data class UninterpretedSortValueDescriptor (
270+ internal data class UninterpretedSortValueDescriptor (
266271 val value : KUninterpretedSortValue ,
267272 val nativeUniqueValueDescriptor : Term ,
268273 val nativeValueTerm : Term
@@ -414,6 +419,18 @@ class KCvc5Context private constructor(
414419 isClosed = true
415420
416421 currentAccumulatedScopeExpressions.clear()
422+
423+ if (! isForking) {
424+ expressions.clear()
425+ cvc5Expressions.clear()
426+ sorts.clear()
427+ cvc5Sorts.clear()
428+ decls.clear()
429+ cvc5Decls.clear()
430+ uninterpretedSortValueDescriptors.clear()
431+ uninterpretedSortValueInterpreter.clear()
432+ uninterpretedSortValues.clear()
433+ }
417434 }
418435
419436 class KUninterpretedSortCollector (private val cvc5Ctx : KCvc5Context ) : KSortVisitor<Unit> {
0 commit comments