Skip to content

Commit a05f1e4

Browse files
committed
Add struct decoding to encoding class
1 parent e697f0b commit a05f1e4

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

src/solvers/smt2_incremental/encoding/struct_encoding.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <util/make_unique.h>
88
#include <util/namespace.h>
99
#include <util/range.h>
10+
#include <util/simplify_expr.h>
1011

1112
#include <solvers/flattening/boolbv_width.h>
1213

@@ -177,3 +178,31 @@ exprt struct_encodingt::encode(exprt expr) const
177178
}
178179
return expr;
179180
}
181+
182+
exprt struct_encodingt::decode(
183+
const exprt &encoded,
184+
const struct_tag_typet &original_type) const
185+
{
186+
// The algorithm below works by extracting each of the separate fields from
187+
// the combined encoded value using a `member_exprt` which is itself encoded
188+
// into a `bit_extract_exprt`. These separated fields can then be combined
189+
// using a `struct_exprt`. This is expected to duplicate the input encoded
190+
// expression for each of the fields. However for the case where the input
191+
// encoded expression is a `constant_exprt`, expression simplification will be
192+
// able simplify away the duplicated portions of the constant and the bit
193+
// extraction expressions. This yields a clean struct expression where each
194+
// field is a separate constant containing the data solely relevant to that
195+
// field.
196+
INVARIANT(
197+
can_cast_type<bv_typet>(encoded.type()),
198+
"Structs are expected to be encoded into bit vectors.");
199+
const struct_typet definition = ns.get().follow_tag(original_type);
200+
exprt::operandst encoded_fields;
201+
for(const auto &component : definition.components())
202+
{
203+
encoded_fields.push_back(typecast_exprt::conditional_cast(
204+
encode(member_exprt{typecast_exprt{encoded, original_type}, component}),
205+
component.type()));
206+
}
207+
return simplify_expr(struct_exprt{encoded_fields, original_type}, ns);
208+
}

src/solvers/smt2_incremental/encoding/struct_encoding.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
class namespacet;
1212
class boolbv_widtht;
1313
class member_exprt;
14+
class struct_tag_typet;
1415

1516
/// Encodes struct types/values into non-struct expressions/types.
1617
class struct_encodingt final
@@ -22,6 +23,10 @@ class struct_encodingt final
2223

2324
typet encode(typet type) const;
2425
exprt encode(exprt expr) const;
26+
/// Reconstructs a struct expression of the \p original_type using the data
27+
/// from the bit vector \p encoded expression.
28+
exprt
29+
decode(const exprt &encoded, const struct_tag_typet &original_type) const;
2530

2631
private:
2732
std::unique_ptr<boolbv_widtht> boolbv_width;

0 commit comments

Comments
 (0)