Skip to content

Commit 6648620

Browse files
authored
Merge pull request #5478 from natasha-jeppu/array_theory
CBMC additional profiling info: Count and report all array constraints added during postprocessing
2 parents 9e97874 + 04341a8 commit 6648620

File tree

12 files changed

+167
-10
lines changed

12 files changed

+167
-10
lines changed
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include <stdlib.h>
2+
int main()
3+
{
4+
size_t array_size;
5+
int a[array_size];
6+
7+
unsigned int index;
8+
a[index] = 1;
9+
10+
assert(a[index] == 1);
11+
return 0;
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
--show-array-constraints
4+
^EXIT=1$
5+
^SIGNAL=0$
6+
--
7+
--
8+
To test output for --show-array-constraints option that displays the count and list of all array constraints added during post processing in json format.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
KNOWNBUG
2+
main.c
3+
--show-array-constraints --json-ui
4+
activate-multi-line-match
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
\{\n\s*"arrayConstraints": \{\n\s*"arrayEquality": \[.*\],\n\s*"arrayWith": \[.*\]\n\s*\},\n\s*"numOfConstraints": 4\n\s*\}
8+
--
9+
--
10+
To test output for --show-array-constraints option that displays the count and list of all array constraints added during post processing in json format.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
--show-array-constraints --xml-ui
4+
^EXIT=1$
5+
^SIGNAL=0$
6+
--
7+
--
8+
To test output for --show-array-constraints option that displays the count and list of all array constraints added during post processing in json format.

src/cbmc/cbmc_parse_options.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ void cbmc_parse_optionst::set_default_options(optionst &options)
123123
options.set_option("simplify-if", true);
124124
options.set_option("show-goto-symex-steps", false);
125125
options.set_option("show-points-to-sets", false);
126+
options.set_option("show-array-constraints", false);
126127

127128
// Other default
128129
options.set_option("arrays-uf", "auto");
@@ -348,6 +349,9 @@ void cbmc_parse_optionst::get_command_line_options(optionst &options)
348349
if(cmdline.isset("dimacs"))
349350
options.set_option("dimacs", true);
350351

352+
if(cmdline.isset("show-array-constraints"))
353+
options.set_option("show-array-constraints", true);
354+
351355
if(cmdline.isset("refine-arrays"))
352356
{
353357
options.set_option("refine", true);
@@ -577,6 +581,17 @@ int cbmc_parse_optionst::doit()
577581
}
578582
}
579583

584+
if(cmdline.isset("show-array-constraints"))
585+
{
586+
if(!cmdline.isset("json-ui") || cmdline.isset("xml-ui"))
587+
{
588+
log.error() << "--show-array-constraints supports only"
589+
" json output. Use --json-ui."
590+
<< messaget::eom;
591+
return CPROVER_EXIT_USAGE_ERROR;
592+
}
593+
}
594+
580595
register_languages();
581596

582597
// configure gcc, if required
@@ -1155,6 +1170,9 @@ void cbmc_parse_optionst::help()
11551170
HELP_TIMESTAMP
11561171
" --write-solver-stats-to json-file\n"
11571172
" collect the solver query complexity\n"
1173+
" --show-array-constraints show array theory constraints added\n"
1174+
" during post processing.\n"
1175+
" Requires --json-ui.\n"
11581176
"\n";
11591177
// clang-format on
11601178
}

src/cbmc/cbmc_parse_options.h

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class optionst;
4747
"(debug-level):(no-propagation)(no-simplify-if)" \
4848
"(document-subgoals)(outfile):(test-preprocessor)" \
4949
"(write-solver-stats-to):" \
50+
"(show-array-constraints)" \
5051
"D:I:(c89)(c99)(c11)(cpp98)(cpp03)(cpp11)" \
5152
"(object-bits):" \
5253
OPT_GOTO_CHECK \

src/goto-checker/solver_factory.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,10 @@ std::unique_ptr<solver_factoryt::solvert> solver_factoryt::get_default()
219219
solver->set_prop(make_satcheck_prop<satcheckt>(message_handler, options));
220220
}
221221

222-
auto bv_pointers =
223-
util_make_unique<bv_pointerst>(ns, solver->prop(), message_handler);
222+
bool get_array_constraints =
223+
options.get_bool_option("show-array-constraints");
224+
auto bv_pointers = util_make_unique<bv_pointerst>(
225+
ns, solver->prop(), message_handler, get_array_constraints);
224226

225227
if(options.get_option("arrays-uf") == "never")
226228
bv_pointers->unbounded_array = bv_pointerst::unbounded_arrayt::U_NONE;

src/solvers/flattening/arrays.cpp

+73-2
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@ Author: Daniel Kroening, [email protected]
1010

1111
#include <util/arith_tools.h>
1212
#include <util/format_expr.h>
13+
#include <util/json_irep.h>
14+
#include <util/message.h>
1315
#include <util/namespace.h>
1416
#include <util/replace_expr.h>
1517
#include <util/std_expr.h>
1618
#include <util/std_types.h>
19+
#include <util/ui_message.h>
1720

1821
#include <solvers/prop/prop.h>
1922

@@ -26,11 +29,17 @@ Author: Daniel Kroening, [email protected]
2629
arrayst::arrayst(
2730
const namespacet &_ns,
2831
propt &_prop,
29-
message_handlert &message_handler)
30-
: equalityt(_prop, message_handler), ns(_ns)
32+
message_handlert &_message_handler,
33+
bool _get_array_constraints)
34+
: equalityt(_prop, _message_handler),
35+
ns(_ns),
36+
log(_message_handler),
37+
message_handler(_message_handler)
3138
{
3239
lazy_arrays = false; // will be set to true when --refine is used
3340
incremental_cache = false; // for incremental solving
41+
// get_array_constraints is true when --show-array-constraints is used
42+
get_array_constraints = _get_array_constraints;
3443
}
3544

3645
void arrayst::record_array_index(const index_exprt &index)
@@ -365,6 +374,7 @@ void arrayst::add_array_Ackermann_constraints()
365374
lazy_constraintt lazy(lazy_typet::ARRAY_ACKERMANN,
366375
implies_exprt(literal_exprt(indices_equal_lit), values_equal));
367376
add_array_constraint(lazy, true); // added lazily
377+
array_constraint_count[constraint_typet::ARRAY_ACKERMANN]++;
368378

369379
#if 0 // old code for adding, not significantly faster
370380
prop.lcnf(!indices_equal_lit, convert(values_equal));
@@ -451,6 +461,7 @@ void arrayst::add_array_constraints_equality(
451461
// equality constraints are not added lazily
452462
// convert must be done to guarantee correct update of the index_set
453463
prop.lcnf(!array_equality.l, convert(equality_expr));
464+
array_constraint_count[constraint_typet::ARRAY_EQUALITY]++;
454465
}
455466
}
456467

@@ -511,6 +522,7 @@ void arrayst::add_array_constraints(
511522
lazy_constraintt lazy(lazy_typet::ARRAY_TYPECAST,
512523
equal_exprt(index_expr1, index_expr2));
513524
add_array_constraint(lazy, false); // added immediately
525+
array_constraint_count[constraint_typet::ARRAY_TYPECAST]++;
514526
}
515527
}
516528
else if(expr.id()==ID_index)
@@ -549,6 +561,7 @@ void arrayst::add_array_constraints_with(
549561
lazy_constraintt lazy(
550562
lazy_typet::ARRAY_WITH, equal_exprt(index_expr, value));
551563
add_array_constraint(lazy, false); // added immediately
564+
array_constraint_count[constraint_typet::ARRAY_WITH]++;
552565

553566
updated_indices.insert(index);
554567
}
@@ -582,7 +595,9 @@ void arrayst::add_array_constraints_with(
582595
// add constraint
583596
lazy_constraintt lazy(lazy_typet::ARRAY_WITH, or_exprt(equality_expr,
584597
literal_exprt(guard_lit)));
598+
585599
add_array_constraint(lazy, false); // added immediately
600+
array_constraint_count[constraint_typet::ARRAY_WITH]++;
586601

587602
#if 0 // old code for adding, not significantly faster
588603
{
@@ -678,6 +693,7 @@ void arrayst::add_array_constraints_array_of(
678693
lazy_constraintt lazy(
679694
lazy_typet::ARRAY_OF, equal_exprt(index_expr, expr.what()));
680695
add_array_constraint(lazy, false); // added immediately
696+
array_constraint_count[constraint_typet::ARRAY_OF]++;
681697
}
682698
}
683699

@@ -713,6 +729,7 @@ void arrayst::add_array_constraints_array_constant(
713729
lazy_constraintt lazy{lazy_typet::ARRAY_CONSTANT,
714730
equal_exprt{index_expr, v}};
715731
add_array_constraint(lazy, false); // added immediately
732+
array_constraint_count[constraint_typet::ARRAY_CONSTANT]++;
716733
}
717734
else
718735
{
@@ -755,6 +772,7 @@ void arrayst::add_array_constraints_array_constant(
755772
implies_exprt{index_constraint,
756773
equal_exprt{index_expr, operands[range.first]}}};
757774
add_array_constraint(lazy, true); // added lazily
775+
array_constraint_count[constraint_typet::ARRAY_CONSTANT]++;
758776
}
759777
}
760778
}
@@ -778,7 +796,9 @@ void arrayst::add_array_constraints_comprehension(
778796
lazy_constraintt lazy(
779797
lazy_typet::ARRAY_COMPREHENSION,
780798
equal_exprt(index_expr, comprehension_body));
799+
781800
add_array_constraint(lazy, false); // added immediately
801+
array_constraint_count[constraint_typet::ARRAY_COMPREHENSION]++;
782802
}
783803
}
784804

@@ -806,6 +826,7 @@ void arrayst::add_array_constraints_if(
806826
or_exprt(literal_exprt(!cond_lit),
807827
equal_exprt(index_expr1, index_expr2)));
808828
add_array_constraint(lazy, false); // added immediately
829+
array_constraint_count[constraint_typet::ARRAY_IF]++;
809830

810831
#if 0 // old code for adding, not significantly faster
811832
prop.lcnf(!cond_lit, convert(equal_exprt(index_expr1, index_expr2)));
@@ -825,9 +846,59 @@ void arrayst::add_array_constraints_if(
825846
or_exprt(literal_exprt(cond_lit),
826847
equal_exprt(index_expr1, index_expr2)));
827848
add_array_constraint(lazy, false); // added immediately
849+
array_constraint_count[constraint_typet::ARRAY_IF]++;
828850

829851
#if 0 // old code for adding, not significantly faster
830852
prop.lcnf(cond_lit, convert(equal_exprt(index_expr1, index_expr2)));
831853
#endif
832854
}
833855
}
856+
857+
std::string arrayst::enum_to_string(constraint_typet type)
858+
{
859+
switch(type)
860+
{
861+
case constraint_typet::ARRAY_ACKERMANN:
862+
return "arrayAckermann";
863+
case constraint_typet::ARRAY_WITH:
864+
return "arrayWith";
865+
case constraint_typet::ARRAY_IF:
866+
return "arrayIf";
867+
case constraint_typet::ARRAY_OF:
868+
return "arrayOf";
869+
case constraint_typet::ARRAY_TYPECAST:
870+
return "arrayTypecast";
871+
case constraint_typet::ARRAY_CONSTANT:
872+
return "arrayConstant";
873+
case constraint_typet::ARRAY_COMPREHENSION:
874+
return "arrayComprehension";
875+
case constraint_typet::ARRAY_EQUALITY:
876+
return "arrayEquality";
877+
default:
878+
UNREACHABLE;
879+
}
880+
}
881+
882+
void arrayst::display_array_constraint_count()
883+
{
884+
json_objectt json_result;
885+
json_objectt &json_array_theory =
886+
json_result["arrayConstraints"].make_object();
887+
888+
size_t num_constraints = 0;
889+
890+
array_constraint_countt::iterator it = array_constraint_count.begin();
891+
while(it != array_constraint_count.end())
892+
{
893+
std::string contraint_type_string = enum_to_string(it->first);
894+
json_array_theory[contraint_type_string] =
895+
json_numbert(std::to_string(it->second));
896+
897+
num_constraints += it->second;
898+
it++;
899+
}
900+
901+
json_result["numOfConstraints"] =
902+
json_numbert(std::to_string(num_constraints));
903+
log.status() << ",\n" << json_result;
904+
}

src/solvers/flattening/arrays.h

+24-1
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,15 @@ class arrayst:public equalityt
3333
arrayst(
3434
const namespacet &_ns,
3535
propt &_prop,
36-
message_handlert &message_handler);
36+
message_handlert &message_handler,
37+
bool get_array_constraints = false);
3738

3839
void post_process() override
3940
{
4041
post_process_arrays();
4142
SUB::post_process();
43+
if(get_array_constraints)
44+
display_array_constraint_count();
4245
}
4346

4447
// NOLINTNEXTLINE(readability/identifiers)
@@ -49,6 +52,8 @@ class arrayst:public equalityt
4952

5053
protected:
5154
const namespacet &ns;
55+
messaget log;
56+
message_handlert &message_handler;
5257

5358
virtual void post_process_arrays()
5459
{
@@ -103,10 +108,28 @@ class arrayst:public equalityt
103108

104109
bool lazy_arrays;
105110
bool incremental_cache;
111+
bool get_array_constraints;
106112
std::list<lazy_constraintt> lazy_array_constraints;
107113
void add_array_constraint(const lazy_constraintt &lazy, bool refine = true);
108114
std::map<exprt, bool> expr_map;
109115

116+
enum class constraint_typet
117+
{
118+
ARRAY_ACKERMANN,
119+
ARRAY_WITH,
120+
ARRAY_IF,
121+
ARRAY_OF,
122+
ARRAY_TYPECAST,
123+
ARRAY_CONSTANT,
124+
ARRAY_COMPREHENSION,
125+
ARRAY_EQUALITY
126+
};
127+
128+
typedef std::map<constraint_typet, size_t> array_constraint_countt;
129+
array_constraint_countt array_constraint_count;
130+
void display_array_constraint_count();
131+
std::string enum_to_string(constraint_typet);
132+
110133
// adds all the constraints eagerly
111134
void add_array_constraints();
112135
void add_array_Ackermann_constraints();

src/solvers/flattening/boolbv.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ class boolbvt:public arrayst
3737
boolbvt(
3838
const namespacet &_ns,
3939
propt &_prop,
40-
message_handlert &message_handler)
41-
: arrayst(_ns, _prop, message_handler),
40+
message_handlert &message_handler,
41+
bool get_array_constraints = false)
42+
: arrayst(_ns, _prop, message_handler, get_array_constraints),
4243
unbounded_array(unbounded_arrayt::U_NONE),
4344
boolbv_width(_ns),
4445
bv_utils(_prop),

src/solvers/flattening/bv_pointers.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,10 @@ literalt bv_pointerst::convert_rest(const exprt &expr)
8282
bv_pointerst::bv_pointerst(
8383
const namespacet &_ns,
8484
propt &_prop,
85-
message_handlert &message_handler)
86-
: boolbvt(_ns, _prop, message_handler), pointer_logic(_ns)
85+
message_handlert &message_handler,
86+
bool get_array_constraints)
87+
: boolbvt(_ns, _prop, message_handler, get_array_constraints),
88+
pointer_logic(_ns)
8789
{
8890
object_bits=config.bv_encoding.object_bits;
8991
std::size_t pointer_width = boolbv_width(pointer_type(empty_typet()));

src/solvers/flattening/bv_pointers.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ class bv_pointerst:public boolbvt
2020
bv_pointerst(
2121
const namespacet &_ns,
2222
propt &_prop,
23-
message_handlert &message_handler);
23+
message_handlert &message_handler,
24+
bool get_array_constraints = false);
2425

2526
void post_process() override;
2627

0 commit comments

Comments
 (0)