5
5
6
6
from pyk .kast .inner import KApply , KVariable , build_cons
7
7
from pyk .kast .prelude .collections import list_of
8
- from pyk .kast .prelude .kint import leInt
8
+ from pyk .kast .prelude .kint import eqInt , leInt
9
9
from pyk .kast .prelude .ml import mlEqualsTrue
10
10
from pyk .kast .prelude .utils import token
11
11
@@ -133,7 +133,7 @@ def run(self, local_types: list[dict]) -> tuple[list[KInner], list[KInner]]:
133
133
return (self .locals + self .pointees , self .constraints )
134
134
135
135
def _add_local (self , ty : Ty , mutable : bool ) -> None :
136
- value , constraints = self ._symbolic_value (ty , mutable )
136
+ value , constraints , _ = self ._symbolic_value (ty , mutable )
137
137
138
138
self .locals .append (_typed_value (value , ty , mutable ))
139
139
self .constraints += constraints
@@ -143,16 +143,20 @@ def _fresh_var(self, prefix: str) -> KVariable:
143
143
self .counter += 1
144
144
return KVariable (name )
145
145
146
- def _symbolic_value (self , ty : Ty , mutable : bool ) -> tuple [KInner , Iterable [KInner ]]:
146
+ def _symbolic_value (self , ty : Ty , mutable : bool ) -> tuple [KInner , Iterable [KInner ], KInner | None ]:
147
+ # returns: symbolic value of given type, related constraints, related pointer metadata
147
148
match self .smir_info .types .get (ty ):
148
149
case Int (info ):
149
- return int_var (self ._fresh_var ('ARG_INT' ), info .value , True )
150
+ val , constraints = int_var (self ._fresh_var ('ARG_INT' ), info .value , True )
151
+ return val , constraints , None
150
152
151
153
case Uint (info ):
152
- return int_var (self ._fresh_var ('ARG_UINT' ), info .value , False )
154
+ val , constraints = int_var (self ._fresh_var ('ARG_UINT' ), info .value , False )
155
+ return val , constraints , None
153
156
154
157
case Bool ():
155
- return bool_var (self ._fresh_var ('ARG_BOOL' ))
158
+ val , constraints = bool_var (self ._fresh_var ('ARG_BOOL' ))
159
+ return val , constraints , None
156
160
157
161
case EnumT (_, _, discriminants ):
158
162
variant_var = self ._fresh_var ('ARG_VARIDX' )
@@ -163,51 +167,62 @@ def _symbolic_value(self, ty: Ty, mutable: bool) -> tuple[KInner, Iterable[KInne
163
167
mlEqualsTrue (leInt (variant_var , token (max_variant ))),
164
168
]
165
169
args = self ._fresh_var ('ENUM_ARGS' )
166
- return KApply ('Value::Aggregate' , (KApply ('variantIdx' , (variant_var ,)), args )), idx_range
170
+ return KApply ('Value::Aggregate' , (KApply ('variantIdx' , (variant_var ,)), args )), idx_range , None
167
171
168
172
case StructT (_, _, fields ):
169
173
field_vars : list [KInner ] = []
170
174
field_constraints : list [KInner ] = []
171
175
for _ty in fields :
172
- new_var , new_constraints = self ._symbolic_value (_ty , mutable )
176
+ new_var , new_constraints , _ = self ._symbolic_value (_ty , mutable )
173
177
field_vars .append (new_var )
174
178
field_constraints += new_constraints
175
179
return (
176
180
KApply ('Value::Aggregate' , (KApply ('variantIdx' , (token (0 ),)), list_of (field_vars ))),
177
181
field_constraints ,
182
+ None ,
178
183
)
179
184
180
185
case UnionT ():
181
186
args = self ._fresh_var ('ARG_UNION' )
182
- return KApply ('Value::Aggregate' , (KApply ('variantIdx' , (token (0 ),)), args )), []
187
+ return KApply ('Value::Aggregate' , (KApply ('variantIdx' , (token (0 ),)), args )), [], None
183
188
184
189
case ArrayT (_, None ):
185
190
elems = self ._fresh_var ('ARG_ARRAY' )
186
- return KApply ('Value::Range' , (elems ,)), []
191
+ len = self ._fresh_var ('ARG_ARRAY_LEN' )
192
+ return (
193
+ KApply ('Value::Range' , (elems ,)),
194
+ [mlEqualsTrue (eqInt (KApply ('sizeList' , (elems ,)), len ))],
195
+ KApply ('dynamicSize' , (len ,)),
196
+ )
187
197
188
198
case ArrayT (element_type , size ) if size is not None :
189
199
elem_vars : list [KInner ] = []
190
200
elem_constraints : list [KInner ] = []
191
201
for _ in range (size ):
192
- new_var , new_constraints = self ._symbolic_value (element_type , mutable )
202
+ new_var , new_constraints , _ = self ._symbolic_value (element_type , mutable )
193
203
elem_vars .append (new_var )
194
204
elem_constraints += new_constraints
195
- return KApply ('Value::Range' , (list_of (elem_vars ),)), elem_constraints
205
+ return (
206
+ KApply ('Value::Range' , (list_of (elem_vars ),)),
207
+ elem_constraints ,
208
+ KApply ('staticSize' , (token (size ),)),
209
+ )
196
210
197
211
case TupleT (components ):
198
212
elem_vars = []
199
213
elem_constraints = []
200
214
for _ty in components :
201
- new_var , new_constraints = self ._symbolic_value (_ty , mutable )
215
+ new_var , new_constraints , _ = self ._symbolic_value (_ty , mutable )
202
216
elem_vars .append (new_var )
203
217
elem_constraints += new_constraints
204
218
return (
205
219
KApply ('Value::Aggregate' , (KApply ('variantIdx' , (token (0 ),)), list_of (elem_vars ))),
206
220
elem_constraints ,
221
+ None ,
207
222
)
208
223
209
224
case RefT (pointee_ty ):
210
- pointee_var , pointee_constraints = self ._symbolic_value (pointee_ty , mutable )
225
+ pointee_var , pointee_constraints , metadata = self ._symbolic_value (pointee_ty , mutable )
211
226
ref = self .ref_offset
212
227
self .ref_offset += 1
213
228
self .pointees .append (_typed_value (pointee_var , pointee_ty , mutable ))
@@ -218,12 +233,14 @@ def _symbolic_value(self, ty: Ty, mutable: bool) -> tuple[KInner, Iterable[KInne
218
233
token (0 ),
219
234
KApply ('place' , (KApply ('local' , (token (ref ),)), KApply ('ProjectionElems::empty' , ()))),
220
235
KApply ('Mutability::Mut' , ()) if mutable else KApply ('Mutability::Not' , ()),
236
+ metadata if metadata is not None else KApply ('noMetadata' , ()),
221
237
),
222
238
),
223
239
pointee_constraints ,
240
+ None ,
224
241
)
225
242
case PtrT (pointee_ty ):
226
- pointee_var , pointee_constraints = self ._symbolic_value (pointee_ty , mutable )
243
+ pointee_var , pointee_constraints , metadata = self ._symbolic_value (pointee_ty , mutable )
227
244
ref = self .ref_offset
228
245
self .ref_offset += 1
229
246
self .pointees .append (_typed_value (pointee_var , pointee_ty , mutable ))
@@ -234,12 +251,14 @@ def _symbolic_value(self, ty: Ty, mutable: bool) -> tuple[KInner, Iterable[KInne
234
251
token (0 ),
235
252
KApply ('place' , (KApply ('local' , (token (ref ),)), KApply ('ProjectionElems::empty' , ()))),
236
253
KApply ('Mutability::Mut' , ()) if mutable else KApply ('Mutability::Not' , ()),
254
+ KApply ('PtrEmulation' , (metadata if metadata is not None else KApply ('noMetadata' , ()),)),
237
255
),
238
256
),
239
257
pointee_constraints ,
258
+ None ,
240
259
)
241
260
case other :
242
261
_LOGGER .warning (f'Missing type information ({ other } ) for type { ty } ' )
243
262
# missing type information, but can assert that this is a value
244
263
var = self ._fresh_var ('ARG' )
245
- return var , [mlEqualsTrue (KApply ('isValue' , (var ,)))]
264
+ return var , [mlEqualsTrue (KApply ('isValue' , (var ,)))], None
0 commit comments