@@ -8,6 +8,8 @@ import io.ksmt.expr.KArrayStoreBase
88import io.ksmt.expr.KExpr
99import io.ksmt.expr.KFunctionAsArray
1010import io.ksmt.expr.KUninterpretedSortValue
11+ import io.ksmt.expr.transformer.KExprVisitResult
12+ import io.ksmt.expr.transformer.KNonRecursiveVisitor
1113import io.ksmt.solver.KModel
1214import io.ksmt.solver.model.KFuncInterp
1315import io.ksmt.solver.model.KFuncInterpEntryVarsFree
@@ -29,7 +31,7 @@ import io.ksmt.symfpu.operations.pack
2931import io.ksmt.utils.asExpr
3032import io.ksmt.utils.uncheckedCast
3133
32- class SymFpuModel (private val kModel : KModel , val ctx : KContext , val transformer : FpToBvTransformer ) : KModel {
34+ class KSymFpuModel (private val kModel : KModel , val ctx : KContext , val transformer : FpToBvTransformer ) : KModel {
3335 override val declarations: Set <KDecl <* >>
3436 get() = kModel.declarations.mapTo(hashSetOf()) { transformer.findFpDeclByMappedDecl(it) ? : it }
3537
@@ -38,6 +40,7 @@ class SymFpuModel(private val kModel: KModel, val ctx: KContext, val transformer
3840
3941 private val evaluatorWithModelCompletion by lazy { KModelEvaluator (ctx, this , isComplete = true ) }
4042 private val evaluatorWithoutModelCompletion by lazy { KModelEvaluator (ctx, this , isComplete = false ) }
43+ private val functionAsArrayVisitor = FunctionAsArrayVisitor ()
4144 private val interpretations: MutableMap <KDecl <* >, KFuncInterp <* >> = hashMapOf()
4245
4346 override fun uninterpretedSortUniverse (sort : KUninterpretedSort ): Set <KUninterpretedSortValue >? =
@@ -55,7 +58,9 @@ class SymFpuModel(private val kModel: KModel, val ctx: KContext, val transformer
5558 return interpretations.getOrPut(decl) {
5659 val mappedDecl = transformer.findMappedDeclForFpDecl(decl)
5760 if (mappedDecl == null ) {
58- return @getOrPut kModel.interpretation<T >(decl) ? : return null
61+ val interpretation = kModel.interpretation<T >(decl)
62+ interpretation?.let { functionAsArrayVisitor.visitInterpretation(it) }
63+ return @getOrPut interpretation ? : return null
5964 }
6065
6166 val interpretation = kModel.interpretation(mappedDecl) ? : return null
@@ -257,4 +262,30 @@ class SymFpuModel(private val kModel: KModel, val ctx: KContext, val transformer
257262
258263 return KModelImpl (ctx, interpretations.toMap(), uninterpretedSortsUniverses)
259264 }
265+
266+ override fun toString (): String = detach().toString()
267+ override fun hashCode (): Int = detach().hashCode()
268+ override fun equals (other : Any? ): Boolean {
269+ if (this == = other) return true
270+ if (other !is KModel ) return false
271+ return detach() == other
272+ }
273+
274+ private inner class FunctionAsArrayVisitor : KNonRecursiveVisitor <Unit >(ctx) {
275+ override fun <T : KSort > defaultValue (expr : KExpr <T >) = Unit
276+ override fun mergeResults (left : Unit , right : Unit ) = Unit
277+
278+ override fun <A : KArraySortBase <R >, R : KSort > visit (expr : KFunctionAsArray <A , R >): KExprVisitResult <Unit > {
279+ interpretation(expr.function)
280+ return saveVisitResult(expr, Unit )
281+ }
282+
283+ fun <T : KSort > visitInterpretation (interpretation : KFuncInterp <T >) {
284+ // Non-array expression cannot contain function-as-array
285+ if (interpretation.sort !is KArraySortBase <* >) return
286+
287+ interpretation.default?.let { applyVisitor(it) }
288+ interpretation.entries.forEach { applyVisitor(it.value) }
289+ }
290+ }
260291}
0 commit comments