@@ -3,13 +3,12 @@ package io.ksmt.solver.yices
33import com.sri.yices.Terms
44import com.sri.yices.Types
55import com.sri.yices.Yices
6- import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
7- import it.unimi.dsi.fastutil.ints.IntOpenHashSet
8- import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap
6+ import io.ksmt.KContext
97import io.ksmt.decl.KDecl
108import io.ksmt.expr.KConst
119import io.ksmt.expr.KExpr
1210import io.ksmt.expr.KInterpretedValue
11+ import io.ksmt.expr.KUninterpretedSortValue
1312import io.ksmt.solver.KSolverUnsupportedFeatureException
1413import io.ksmt.solver.util.KExprIntInternalizerBase.Companion.NOT_INTERNALIZED
1514import io.ksmt.solver.yices.TermUtils.addTerm
@@ -19,37 +18,45 @@ import io.ksmt.solver.yices.TermUtils.funApplicationTerm
1918import io.ksmt.solver.yices.TermUtils.mulTerm
2019import io.ksmt.solver.yices.TermUtils.orTerm
2120import io.ksmt.sort.KSort
22- import io.ksmt.utils.NativeLibraryLoader
21+ import io.ksmt.sort.KUninterpretedSort
22+ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
23+ import it.unimi.dsi.fastutil.ints.IntOpenHashSet
24+ import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap
2325import java.math.BigInteger
2426import java.util.concurrent.atomic.AtomicInteger
2527
26- open class KYicesContext : AutoCloseable {
27- private var isClosed = false
28+ open class KYicesContext ( ctx : KContext ) : AutoCloseable {
29+ protected var isClosed = false
2830
29- private val expressions = mkTermCache<KExpr <* >>()
30- private val yicesExpressions = mkTermReverseCache<KExpr <* >>()
31+ protected open val expressions = mkTermCache<KExpr <* >>()
32+ protected open val yicesExpressions = mkTermReverseCache<KExpr <* >>()
3133
32- private val sorts = mkSortCache<KSort >()
33- private val yicesSorts = mkSortReverseCache<KSort >()
34+ protected open val sorts = mkSortCache<KSort >()
35+ protected open val yicesSorts = mkSortReverseCache<KSort >()
3436
35- private val decls = mkTermCache<KDecl <* >>()
36- private val yicesDecls = mkTermReverseCache<KDecl <* >>()
37+ protected open val decls = mkTermCache<KDecl <* >>()
38+ protected open val yicesDecls = mkTermReverseCache<KDecl <* >>()
3739
38- private val vars = mkTermCache<KDecl <* >>()
39- private val yicesVars = mkTermReverseCache<KDecl <* >>()
40+ protected open val vars = mkTermCache<KDecl <* >>()
41+ protected open val yicesVars = mkTermReverseCache<KDecl <* >>()
4042
41- private val yicesTypes = mkSortSet()
42- private val yicesTerms = mkTermSet()
43+ protected open val yicesTypes = mkSortSet()
44+ protected open val yicesTerms = mkTermSet()
4345
4446 val isActive: Boolean
4547 get() = ! isClosed
4648
47- fun findInternalizedExpr (expr : KExpr <* >): YicesTerm = expressions.getInt(expr)
49+ fun findInternalizedExpr (expr : KExpr <* >): YicesTerm = expressions.getInt(expr).also {
50+ if (it != NOT_INTERNALIZED )
51+ uninterpretedSortValuesTracker.expressionUse(expr)
52+ }
53+
4854 fun saveInternalizedExpr (expr : KExpr <* >, internalized : YicesTerm ) {
4955 if (expressions.putIfAbsent(expr, internalized) == NOT_INTERNALIZED ) {
5056 if (expr is KInterpretedValue <* > || expr is KConst <* >) {
5157 yicesExpressions.put(internalized, expr)
5258 }
59+ uninterpretedSortValuesTracker.expressionSave(expr)
5360 }
5461 }
5562
@@ -175,9 +182,9 @@ open class KYicesContext : AutoCloseable {
175182 fun functionType (domain : YicesSortArray , range : YicesSort ) = mkType { Types .functionType(domain, range) }
176183 fun newUninterpretedType (name : String ) = mkType { Types .newUninterpretedType(name) }
177184
178- val zero = mkTerm { Terms .intConst(0L ) }
179- val one = mkTerm { Terms .intConst(1L ) }
180- val minusOne = mkTerm { Terms .intConst(- 1L ) }
185+ val zero by lazy { mkTerm { Terms .intConst(0L ) } }
186+ val one by lazy { mkTerm { Terms .intConst(1L ) } }
187+ val minusOne by lazy { mkTerm { Terms .intConst(- 1L ) } }
181188
182189 private inline fun mkTerm (mk : () -> YicesTerm ): YicesTerm = withGcGuard {
183190 val term = mk()
@@ -294,7 +301,32 @@ open class KYicesContext : AutoCloseable {
294301
295302 fun uninterpretedSortConst (sort : YicesSort , idx : Int ) = mkTerm { Terms .mkConst(sort, idx) }
296303
297- private var maxValueIndex = 0
304+ protected open var maxValueIndex = 0
305+
306+ /* *
307+ * Collects uninterpreted sort values usage for [KYicesModel.uninterpretedSortUniverse]
308+ */
309+ protected open val uninterpretedSortValuesTracker = UninterpretedValuesTracker (
310+ ctx,
311+ ScopedArrayFrame (::HashSet ),
312+ ScopedArrayFrame (::HashMap ),
313+ Object2IntOpenHashMap <KExpr <* >>()
314+ )
315+
316+ fun pushAssertionLevel () {
317+ uninterpretedSortValuesTracker.push()
318+ }
319+
320+ fun popAssertionLevel (n : UInt ) {
321+ uninterpretedSortValuesTracker.pop(n)
322+ }
323+
324+ fun registerUninterpretedSortValue (value : KUninterpretedSortValue ) {
325+ uninterpretedSortValuesTracker.addToCurrentLevel(value)
326+ }
327+
328+ fun uninterpretedSortValues (sort : KUninterpretedSort ) =
329+ uninterpretedSortValuesTracker.getUninterpretedSortValues(sort)
298330
299331 /* *
300332 * Yices can produce different values with the same index.
@@ -339,20 +371,6 @@ open class KYicesContext : AutoCloseable {
339371 }
340372
341373 companion object {
342- init {
343- if (! Yices .isReady()) {
344- NativeLibraryLoader .load { os ->
345- when (os) {
346- NativeLibraryLoader .OS .LINUX -> listOf (" libyices" , " libyices2java" )
347- NativeLibraryLoader .OS .WINDOWS -> listOf (" libyices" , " libyices2java" )
348- NativeLibraryLoader .OS .MACOS -> listOf (" libyices" , " libyices2java" )
349- }
350- }
351- Yices .init ()
352- Yices .setReadyFlag(true )
353- }
354- }
355-
356374 private const val UNINTERPRETED_SORT_VALUE_SHIFT = 1 shl 30
357375 private const val UNINTERPRETED_SORT_MAX_ALLOWED_VALUE = UNINTERPRETED_SORT_VALUE_SHIFT / 2
358376 private const val UNINTERPRETED_SORT_MIN_ALLOWED_VALUE = - UNINTERPRETED_SORT_MAX_ALLOWED_VALUE
@@ -420,7 +438,8 @@ open class KYicesContext : AutoCloseable {
420438 }
421439 }
422440
423- private fun performGc () {
441+ @JvmStatic
442+ protected fun performGc () {
424443 // spin wait until [gcGuard] == [FREE]
425444 while (true ) {
426445 if (gcGuard.compareAndSet(FREE , ON_GC )) {
0 commit comments