@@ -22,13 +22,14 @@ typealias UInstantiator<RegionId, Key, Sort> = (key: Key, UMemoryRegion<RegionId
2222 * @property defaultValue describes the initial values for the region. If [defaultValue] equals `null` then this region
2323 * is filled with symbolics.
2424 */
25- data class UMemoryRegion <RegionId : URegionId <Key >, Key , Sort : USort >(
25+ data class UMemoryRegion <out RegionId : URegionId <Key , Sort >, Key , Sort : USort >(
2626 val regionId : RegionId ,
27- val sort : Sort ,
2827 val updates : UMemoryUpdates <Key , Sort >,
29- private val defaultValue : UExpr <Sort >? , // If defaultValue = null then this region is filled with symbolics
3028 private val instantiator : UInstantiator <RegionId , Key , Sort >,
3129) {
30+ val sort: Sort get() = regionId.sort
31+ private val defaultValue = regionId.defaultValue
32+
3233 private fun read (key : Key , updates : UMemoryUpdates <Key , Sort >): UExpr <Sort > {
3334 val lastUpdatedElement = updates.lastUpdatedElementOrNull()
3435
@@ -159,26 +160,28 @@ data class UMemoryRegion<RegionId : URegionId<Key>, Key, Sort : USort>(
159160 composer : UComposer <Field , Type >,
160161 instantiator : UInstantiator <RegionId , Key , Sort > = this.instantiator,
161162 ): UMemoryRegion <RegionId , Key , Sort > {
162- // Map the updates and the default value
163+ // Map the updates and the regionId
164+ @Suppress(" UNCHECKED_CAST" )
165+ val mappedRegionId = regionId.map(composer) as RegionId
163166 val mappedUpdates = updates.map(regionId.keyMapper(composer), composer)
164- val mappedDefaultValue = defaultValue?.let { composer.compose(it) }
165167
166168 // Note that we cannot use optimization with unchanged mappedUpdates and mappedDefaultValues here
167169 // since in a new region we might have an updated instantiator.
168170 // Therefore, we have to check their reference equality as well.
169- if (mappedUpdates == = updates && mappedDefaultValue == = defaultValue && instantiator == = this .instantiator) {
171+ if (mappedUpdates == = updates && mappedRegionId == = regionId && instantiator == = this .instantiator) {
170172 return this
171173 }
172174
173- return UMemoryRegion (regionId, sort, mappedUpdates, mappedDefaultValue, instantiator)
175+ // Otherwise, construct a new region with mapped values and a new instantiator.
176+ return UMemoryRegion (mappedRegionId, mappedUpdates, instantiator)
174177 }
175178
176179 @Suppress(" UNCHECKED_CAST" )
177180 fun <Field , Type > applyTo (heap : USymbolicHeap <Field , Type >) {
178181 // Apply each update on the copy
179182 updates.forEach {
180183 when (it) {
181- is UPinpointUpdateNode <Key , Sort > -> regionId.write(it.key, sort, heap , it.value, it.guard)
184+ is UPinpointUpdateNode <Key , Sort > -> regionId.write(heap, it.key, it.value, it.guard)
182185 is URangedUpdateNode <* , * , * , Key , Sort > -> {
183186 it.region.applyTo(heap)
184187
@@ -198,7 +201,7 @@ data class UMemoryRegion<RegionId : URegionId<Key>, Key, Sort : USort>(
198201 * with values from memory region [fromRegion] read from range
199202 * of addresses [[keyConverter].convert([fromKey]) : [keyConverter].convert([toKey])]
200203 */
201- fun <ArrayType , OtherRegionId : UArrayId <ArrayType , SrcKey >, SrcKey > copyRange (
204+ fun <ArrayType , OtherRegionId : UArrayId <ArrayType , SrcKey , Sort >, SrcKey > copyRange (
202205 fromRegion : UMemoryRegion <OtherRegionId , SrcKey , Sort >,
203206 fromKey : Key , toKey : Key ,
204207 keyConverter : UMemoryKeyConverter <SrcKey , Key >,
@@ -243,7 +246,7 @@ class GuardBuilder(nonMatchingUpdates: UBoolExpr) {
243246typealias USymbolicArrayIndex = Pair <UHeapRef , USizeExpr >
244247
245248fun heapRefEq (ref1 : UHeapRef , ref2 : UHeapRef ): UBoolExpr =
246- ref1.uctx.mkHeapRefEq(ref1, ref2) // TODO: use simplified equality!
249+ ref1.uctx.mkHeapRefEq(ref1, ref2)
247250
248251@Suppress(" UNUSED_PARAMETER" )
249252fun heapRefCmpSymbolic (ref1 : UHeapRef , ref2 : UHeapRef ): UBoolExpr =
@@ -254,17 +257,16 @@ fun heapRefCmpConcrete(ref1: UHeapRef, ref2: UHeapRef): Boolean =
254257 error(" Heap references should not be compared!" )
255258
256259fun indexEq (idx1 : USizeExpr , idx2 : USizeExpr ): UBoolExpr =
257- idx1.ctx.mkEq(idx1, idx2) // TODO: use simplified equality!
260+ idx1.ctx.mkEq(idx1, idx2)
258261
259262fun indexLeSymbolic (idx1 : USizeExpr , idx2 : USizeExpr ): UBoolExpr =
260- idx1.ctx.mkBvSignedLessOrEqualExpr(idx1, idx2) // TODO: use simplified comparison!
263+ idx1.ctx.mkBvSignedLessOrEqualExpr(idx1, idx2)
261264
262265fun indexLeConcrete (idx1 : USizeExpr , idx2 : USizeExpr ): Boolean =
263266 // TODO: to optimize things up, we could pass path constraints here and lookup the numeric bounds for idx1 and idx2
264267 idx1 == idx2 || (idx1 is UConcreteSize && idx2 is UConcreteSize && idx1.numberValue <= idx2.numberValue)
265268
266269fun refIndexEq (idx1 : USymbolicArrayIndex , idx2 : USymbolicArrayIndex ): UBoolExpr = with (idx1.first.ctx) {
267- // TODO: use simplified operations!
268270 return @with (idx1.first eq idx2.first) and indexEq(idx1.second, idx2.second)
269271}
270272
@@ -301,9 +303,9 @@ fun refIndexRangeRegion(
301303 idx2 : USymbolicArrayIndex ,
302304): UArrayIndexRegion = indexRangeRegion(idx1.second, idx2.second)
303305
304- typealias UInputFieldRegion <Field , Sort > = UMemoryRegion <UInputFieldRegionId <Field >, UHeapRef , Sort >
305- typealias UAllocatedArrayRegion <ArrayType , Sort > = UMemoryRegion <UAllocatedArrayId <ArrayType >, USizeExpr , Sort >
306- typealias UInputArrayRegion <ArrayType , Sort > = UMemoryRegion <UInputArrayId <ArrayType >, USymbolicArrayIndex , Sort >
306+ typealias UInputFieldRegion <Field , Sort > = UMemoryRegion <UInputFieldRegionId <Field , Sort >, UHeapRef , Sort >
307+ typealias UAllocatedArrayRegion <ArrayType , Sort > = UMemoryRegion <UAllocatedArrayId <ArrayType , Sort >, USizeExpr , Sort >
308+ typealias UInputArrayRegion <ArrayType , Sort > = UMemoryRegion <UInputArrayId <ArrayType , Sort >, USymbolicArrayIndex , Sort >
307309typealias UInputArrayLengthRegion <ArrayType > = UMemoryRegion <UInputArrayLengthId <ArrayType >, UHeapRef , USizeSort >
308310
309311typealias KeyMapper <Key > = (Key ) -> Key
@@ -325,51 +327,47 @@ val <ArrayType> UInputArrayLengthRegion<ArrayType>.inputLengthArrayType
325327fun <Field , Sort : USort > emptyInputFieldRegion (
326328 field : Field ,
327329 sort : Sort ,
328- instantiator : UInstantiator <UInputFieldRegionId <Field >, UHeapRef , Sort >,
330+ instantiator : UInstantiator <UInputFieldRegionId <Field , Sort >, UHeapRef , Sort >,
329331): UInputFieldRegion <Field , Sort > = UMemoryRegion (
330- UInputFieldRegionId (field),
331- sort,
332+ UInputFieldRegionId (field, sort),
332333 UEmptyUpdates (::heapRefEq, ::heapRefCmpConcrete, ::heapRefCmpSymbolic),
333- defaultValue = null ,
334334 instantiator
335335)
336336
337337fun <ArrayType , Sort : USort > emptyAllocatedArrayRegion (
338338 arrayType : ArrayType ,
339339 address : UConcreteHeapAddress ,
340340 sort : Sort ,
341- instantiator : UInstantiator <UAllocatedArrayId <ArrayType >, USizeExpr , Sort >,
341+ instantiator : UInstantiator <UAllocatedArrayId <ArrayType , Sort >, USizeExpr , Sort >,
342342): UAllocatedArrayRegion <ArrayType , Sort > {
343343 val updates = UTreeUpdates <USizeExpr , UArrayIndexRegion , Sort >(
344344 updates = emptyRegionTree(),
345345 ::indexRegion, ::indexRangeRegion, ::indexEq, ::indexLeConcrete, ::indexLeSymbolic
346346 )
347- val regionId = UAllocatedArrayId (arrayType, address)
348- return UMemoryRegion (regionId, sort, updates, sort.defaultValue() , instantiator)
347+ val regionId = UAllocatedArrayId (arrayType, address, sort )
348+ return UMemoryRegion (regionId, updates, instantiator)
349349}
350350
351351fun <ArrayType , Sort : USort > emptyInputArrayRegion (
352352 arrayType : ArrayType ,
353353 sort : Sort ,
354- instantiator : UInstantiator <UInputArrayId <ArrayType >, USymbolicArrayIndex , Sort >,
354+ instantiator : UInstantiator <UInputArrayId <ArrayType , Sort >, USymbolicArrayIndex , Sort >,
355355): UInputArrayRegion <ArrayType , Sort > {
356356 val updates = UTreeUpdates <USymbolicArrayIndex , UArrayIndexRegion , Sort >(
357357 updates = emptyRegionTree(),
358358 ::refIndexRegion, ::refIndexRangeRegion, ::refIndexEq, ::refIndexCmpConcrete, ::refIndexCmpSymbolic
359359 )
360- return UMemoryRegion (UInputArrayId (arrayType) , sort, updates, defaultValue = null , instantiator)
360+ return UMemoryRegion (UInputArrayId (arrayType, sort) , updates, instantiator)
361361}
362362
363363fun <ArrayType > emptyArrayLengthRegion (
364364 arrayType : ArrayType ,
365- ctx : UContext ,
365+ sizeSort : USizeSort ,
366366 instantiator : UInstantiator <UInputArrayLengthId <ArrayType >, UHeapRef , USizeSort >,
367367): UInputArrayLengthRegion <ArrayType > =
368368 UMemoryRegion (
369- UInputArrayLengthId (arrayType),
370- ctx.sizeSort,
369+ UInputArrayLengthId (arrayType, sizeSort),
371370 UEmptyUpdates (::heapRefEq, ::heapRefCmpConcrete, ::heapRefCmpSymbolic),
372- defaultValue = null ,
373371 instantiator
374372 )
375373
0 commit comments