@@ -2,48 +2,88 @@ package io.ksmt.solver.z3
22
33import com.microsoft.z3.Context
44import com.microsoft.z3.Solver
5+ import com.microsoft.z3.Z3Exception
56import com.microsoft.z3.decRefUnsafe
7+ import com.microsoft.z3.decRefUnsafeAll
68import com.microsoft.z3.incRefUnsafe
79import io.ksmt.KContext
810import io.ksmt.decl.KDecl
911import io.ksmt.expr.KExpr
1012import io.ksmt.expr.KUninterpretedSortValue
13+ import io.ksmt.solver.KSolverException
1114import io.ksmt.solver.util.KExprLongInternalizerBase.Companion.NOT_INTERNALIZED
1215import io.ksmt.sort.KSort
1316import io.ksmt.sort.KUninterpretedSort
1417import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap
1518import it.unimi.dsi.fastutil.longs.LongOpenHashSet
16- import it.unimi.dsi.fastutil.longs.LongSet
1719import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap
1820
1921@Suppress(" TooManyFunctions" )
20- class KZ3Context (
22+ class KZ3Context internal constructor (
2123 ksmtCtx : KContext ,
22- private val ctx : Context
24+ private val ctx : Context ,
25+ forkingSolverManager : KZ3ForkingSolverManager ? ,
2326) : AutoCloseable {
24- constructor (ksmtCtx: KContext ) : this (ksmtCtx, Context ())
27+ constructor (ksmtCtx: KContext , ctx: Context ) : this (ksmtCtx, ctx, null )
28+ constructor (ksmtCtx: KContext ) : this (ksmtCtx, Context (), null )
2529
2630 private var isClosed = false
27-
28- private val expressions = Object2LongOpenHashMap <KExpr <* >>().apply {
29- defaultReturnValue(NOT_INTERNALIZED )
30- }
31-
32- private val sorts = Object2LongOpenHashMap <KSort >().apply {
33- defaultReturnValue(NOT_INTERNALIZED )
34- }
35-
36- private val decls = Object2LongOpenHashMap <KDecl <* >>().apply {
37- defaultReturnValue(NOT_INTERNALIZED )
31+ private val isForking = forkingSolverManager != null
32+
33+ // common for parent and child structures
34+ private val expressions: Object2LongOpenHashMap <KExpr <* >>
35+ private val sorts: Object2LongOpenHashMap <KSort >
36+ private val decls: Object2LongOpenHashMap <KDecl <* >>
37+
38+ private val z3Expressions: Long2ObjectOpenHashMap <KExpr <* >>
39+ private val z3Sorts: Long2ObjectOpenHashMap <KSort >
40+ private val z3Decls: Long2ObjectOpenHashMap <KDecl <* >>
41+ private val tmpNativeObjects: LongOpenHashSet
42+ private val converterNativeObjects: LongOpenHashSet
43+
44+ private val uninterpretedSortValueInterpreter: HashMap <KUninterpretedSort , Long >
45+ private val uninterpretedSortValueDecls: Long2ObjectOpenHashMap <KUninterpretedSortValue >
46+ private val uninterpretedSortValueInterpreters: LongOpenHashSet
47+
48+
49+ val uninterpretedValuesTracker: ExpressionUninterpretedValuesTracker
50+
51+ init {
52+ if (forkingSolverManager != null ) {
53+ with (forkingSolverManager) {
54+ expressions = findExpressionsCache()
55+ sorts = findSortsCache()
56+ decls = findDeclsCache()
57+
58+ z3Expressions = findExpressionsReversedCache()
59+ z3Sorts = findSortsReversedCache()
60+ z3Decls = findDeclsReversedCache()
61+ tmpNativeObjects = findTmpNativeObjectsCache()
62+ converterNativeObjects = findConverterNativeObjectsCache()
63+ uninterpretedSortValueInterpreter = findUninterpretedSortValueInterpreter()
64+ uninterpretedSortValueDecls = findUninterpretedSortValueDecls()
65+ uninterpretedSortValueInterpreters = findUninterpretedSortValueInterpreters()
66+ }
67+ uninterpretedValuesTracker = ExpressionUninterpretedValuesTracker (ksmtCtx, this , forkingSolverManager)
68+ } else {
69+ expressions = Object2LongOpenHashMap <KExpr <* >>().apply { defaultReturnValue(NOT_INTERNALIZED ) }
70+ sorts = Object2LongOpenHashMap <KSort >().apply { defaultReturnValue(NOT_INTERNALIZED ) }
71+ decls = Object2LongOpenHashMap <KDecl <* >>().apply { defaultReturnValue(NOT_INTERNALIZED ) }
72+
73+ z3Expressions = Long2ObjectOpenHashMap <KExpr <* >>()
74+ z3Sorts = Long2ObjectOpenHashMap <KSort >()
75+ z3Decls = Long2ObjectOpenHashMap <KDecl <* >>()
76+ tmpNativeObjects = LongOpenHashSet ()
77+ converterNativeObjects = LongOpenHashSet ()
78+
79+ uninterpretedSortValueInterpreter = hashMapOf()
80+ uninterpretedSortValueDecls = Long2ObjectOpenHashMap ()
81+ uninterpretedSortValueInterpreters = LongOpenHashSet ()
82+
83+ uninterpretedValuesTracker = ExpressionUninterpretedValuesTracker (ksmtCtx, this )
84+ }
3885 }
3986
40- private val z3Expressions = Long2ObjectOpenHashMap <KExpr <* >>()
41- private val z3Sorts = Long2ObjectOpenHashMap <KSort >()
42- private val z3Decls = Long2ObjectOpenHashMap <KDecl <* >>()
43- private val tmpNativeObjects = LongOpenHashSet ()
44- private val converterNativeObjects = LongOpenHashSet ()
45-
46- val uninterpretedValuesTracker = ExpressionUninterpretedValuesTracker (ksmtCtx, this )
4787
4888 @JvmField
4989 val nCtx: Long = ctx.nCtx()
@@ -54,17 +94,24 @@ class KZ3Context(
5494 val isActive: Boolean
5595 get() = ! isClosed
5696
97+ internal fun fork (ksmtCtx : KContext , manager : KZ3ForkingSolverManager ): KZ3Context {
98+ require(isForking) { " Can't fork non-forking context" }
99+ return KZ3Context (ksmtCtx, ctx, manager).also {
100+ it.uninterpretedValuesTracker.fork(uninterpretedValuesTracker)
101+ }
102+ }
103+
104+ internal fun findInternalizedExprWithoutAnalysis (expr : KExpr <* >): Long {
105+ val result = expressions.getLong(expr)
106+ return if (result == NOT_INTERNALIZED ) NOT_INTERNALIZED else result
107+ }
108+
57109 /* *
58110 * Find internalized expr.
59111 * Returns [NOT_INTERNALIZED] if expression was not found.
60112 * */
61- fun findInternalizedExpr (expr : KExpr <* >): Long {
62- val result = expressions.getLong(expr)
63- if (result == NOT_INTERNALIZED ) return NOT_INTERNALIZED
64-
65- uninterpretedValuesTracker.expressionUse(expr)
66-
67- return result
113+ fun findInternalizedExpr (expr : KExpr <* >): Long = findInternalizedExprWithoutAnalysis(expr).also {
114+ if (it != NOT_INTERNALIZED ) uninterpretedValuesTracker.expressionUse(expr)
68115 }
69116
70117 fun saveInternalizedExpr (expr : KExpr <* >, internalized : Long ) {
@@ -148,11 +195,6 @@ class KZ3Context(
148195 return ast
149196 }
150197
151- private val uninterpretedSortValueInterpreter = hashMapOf<KUninterpretedSort , Long >()
152-
153- private val uninterpretedSortValueDecls = Long2ObjectOpenHashMap <KUninterpretedSortValue >()
154- private val uninterpretedSortValueInterpreters = LongOpenHashSet ()
155-
156198 fun saveUninterpretedSortValueDecl (decl : Long , value : KUninterpretedSortValue ): Long {
157199 if (uninterpretedSortValueDecls.putIfAbsent(decl, value) == null ) {
158200 incRefUnsafe(nCtx, decl)
@@ -264,37 +306,38 @@ class KZ3Context(
264306 if (isClosed) return
265307 isClosed = true
266308
309+ if (isForking) return
310+
267311 uninterpretedSortValueInterpreter.clear()
268312
269- uninterpretedSortValueDecls.keys.decRefAll( )
313+ uninterpretedSortValueDecls.keys.decRefUnsafeAll(nCtx )
270314 uninterpretedSortValueDecls.clear()
271315
272- uninterpretedSortValueInterpreters.decRefAll( )
316+ uninterpretedSortValueInterpreters.decRefUnsafeAll(nCtx )
273317 uninterpretedSortValueInterpreters.clear()
274318
275- converterNativeObjects.decRefAll( )
319+ converterNativeObjects.decRefUnsafeAll(nCtx )
276320 converterNativeObjects.clear()
277321
278- z3Expressions.keys.decRefAll( )
322+ z3Expressions.keys.decRefUnsafeAll(nCtx )
279323 expressions.clear()
280324 z3Expressions.clear()
281325
282- tmpNativeObjects.decRefAll( )
326+ tmpNativeObjects.decRefUnsafeAll(nCtx )
283327 tmpNativeObjects.clear()
284328
285- z3Decls.keys.decRefAll( )
329+ z3Decls.keys.decRefUnsafeAll(nCtx )
286330 decls.clear()
287331 z3Decls.clear()
288332
289- z3Sorts.keys.decRefAll( )
333+ z3Sorts.keys.decRefUnsafeAll(nCtx )
290334 sorts.clear()
291335 z3Sorts.clear()
292336
293- ctx.close()
294- }
295-
296- private fun LongSet.decRefAll () =
297- longIterator().forEachRemaining {
298- decRefUnsafe(nCtx, it)
337+ try {
338+ ctx.close()
339+ } catch (e: Z3Exception ) {
340+ throw KSolverException (e)
299341 }
342+ }
300343}
0 commit comments