Skip to content

Commit fc4308d

Browse files
author
Enrico Steffinlongo
committed
Lower enum_tags to its enum underlying type.
In order to support expressions with type `c_enum_tag_typet` in the incremental SMT2 solver, a new `lower_enum` has been added. Such function lowers the type of each expression node in the AST with type `c_enum_tag_type` to the underlying type of the `c_enum_typet` that the tag points to.
1 parent 7630989 commit fc4308d

File tree

4 files changed

+73
-2
lines changed

4 files changed

+73
-2
lines changed

src/solvers/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ SRC = $(BOOLEFORCE_SRC) \
211211
smt2_incremental/smt_to_smt2_string.cpp \
212212
smt2_incremental/smt2_incremental_decision_procedure.cpp \
213213
smt2_incremental/encoding/struct_encoding.cpp \
214+
smt2_incremental/encoding/enum_encoding.cpp \
214215
smt2_incremental/theories/smt_array_theory.cpp \
215216
smt2_incremental/theories/smt_bit_vector_theory.cpp \
216217
smt2_incremental/theories/smt_core_theory.cpp \
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Author: Diffblue Ltd.
2+
3+
#include "enum_encoding.h"
4+
5+
#include <util/c_types.h>
6+
#include <util/expr_cast.h>
7+
#include <util/namespace.h>
8+
9+
#include <queue>
10+
11+
// Internal function to lower inner types of compound types (at the moment only
12+
// arrays)
13+
static typet encode(typet type, const namespacet &ns)
14+
{
15+
std::queue<typet *> work_queue;
16+
work_queue.push(&type);
17+
while(!work_queue.empty())
18+
{
19+
typet &current = *work_queue.front();
20+
work_queue.pop();
21+
if(const auto c_enum_tag = type_try_dynamic_cast<c_enum_tag_typet>(current))
22+
{
23+
// Replace the type of the c_enum_tag with the underlying type of the enum
24+
// it points to
25+
current = ns.follow_tag(*c_enum_tag).underlying_type();
26+
}
27+
if(const auto array = type_try_dynamic_cast<array_typet>(current))
28+
{
29+
// Add the type of the array's elements to the queue to be explored
30+
work_queue.push(&array->element_type());
31+
}
32+
}
33+
return type;
34+
}
35+
36+
// Worklist algorithm to lower enum types of expr and its sub-expressions.
37+
exprt lower_enum(exprt expr, const namespacet &ns)
38+
{
39+
std::queue<exprt *> work_queue;
40+
work_queue.push(&expr);
41+
while(!work_queue.empty())
42+
{
43+
exprt &current = *work_queue.front();
44+
work_queue.pop();
45+
46+
// Replace the type of the expression node with the encoded one
47+
current.type() = encode(current.type(), ns);
48+
49+
for(auto &operand : current.operands())
50+
work_queue.push(&operand);
51+
}
52+
return expr;
53+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Author: Diffblue Ltd.
2+
3+
#ifndef CPROVER_SOLVERS_SMT2_INCREMENTAL_ENCODING_ENUM_ENCODING_H
4+
#define CPROVER_SOLVERS_SMT2_INCREMENTAL_ENCODING_ENUM_ENCODING_H
5+
6+
#include <util/expr.h>
7+
8+
/// Function to lower `expr` and its sub-expressions containing enum types.
9+
/// Specifically it replaces the node `c_enum_tag_typet` type with the
10+
/// underlying type of the enum the tag points to.
11+
/// @param expr the expression to lower.
12+
/// @param ns the namespace where to lookup `c_enum_tag_type`s.
13+
/// @return the lowered expression.
14+
exprt lower_enum(exprt expr, const namespacet &ns);
15+
16+
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_ENCODING_ENUM_ENCODING_H

src/solvers/smt2_incremental/smt2_incremental_decision_procedure.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <solvers/smt2_incremental/ast/smt_terms.h>
1717
#include <solvers/smt2_incremental/construct_value_expr_from_smt.h>
1818
#include <solvers/smt2_incremental/convert_expr_to_smt.h>
19+
#include <solvers/smt2_incremental/encoding/enum_encoding.h>
1920
#include <solvers/smt2_incremental/smt_solver_process.h>
2021
#include <solvers/smt2_incremental/theories/smt_array_theory.h>
2122
#include <solvers/smt2_incremental/theories/smt_core_theory.h>
@@ -590,8 +591,8 @@ void smt2_incremental_decision_proceduret::define_object_properties()
590591

591592
exprt smt2_incremental_decision_proceduret::lower(exprt expression)
592593
{
593-
const exprt lowered =
594-
struct_encoding.encode(lower_byte_operators(expression, ns));
594+
const exprt lowered = struct_encoding.encode(
595+
lower_enum(lower_byte_operators(expression, ns), ns));
595596
log.conditional_output(log.debug(), [&](messaget::mstreamt &debug) {
596597
if(lowered != expression)
597598
debug << "lowered to -\n " << lowered.pretty(2, 0) << messaget::eom;

0 commit comments

Comments
 (0)