Skip to content

Commit 7e1b9dd

Browse files
committed
ebmc: normalize properties
This introduces a pass during which the given property is 'normalized', using heuristic rewrites, with the goal to reduce the burden of a large number of redundant case-splits in each backend.
1 parent f77b914 commit 7e1b9dd

12 files changed

+71
-29
lines changed

src/ebmc/bdd_engine.cpp

+11-9
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ int bdd_enginet::operator()()
165165
cmdline, transition_system, message.get_message_handler());
166166

167167
for(const propertyt &p : properties.properties)
168-
get_atomic_propositions(p.expr);
168+
get_atomic_propositions(p.normalized_expr);
169169

170170
message.status() << "Building BDD for netlist" << messaget::eom;
171171

@@ -376,7 +376,7 @@ void bdd_enginet::compute_counterexample(
376376

377377
::unwind(netlist, bmc_map, message, solver);
378378
::unwind_property(
379-
property.expr,
379+
property.normalized_expr,
380380
property.timeframe_literals,
381381
message.get_message_handler(),
382382
solver,
@@ -450,17 +450,18 @@ void bdd_enginet::check_property(propertyt &property)
450450
!has_temporal_operator(to_F_expr(to_G_expr(expr).op()).op());
451451
};
452452

453-
if(is_AGp(property.expr))
453+
if(is_AGp(property.normalized_expr))
454454
{
455455
AGp(property);
456456
}
457457
else if(
458-
is_AG_AFp(property.expr) || is_always_eventually(property.expr) ||
459-
is_GFp(property.expr))
458+
is_AG_AFp(property.normalized_expr) ||
459+
is_always_eventually(property.normalized_expr) ||
460+
is_GFp(property.normalized_expr))
460461
{
461462
AGAFp(property);
462463
}
463-
else if(!has_temporal_operator(property.expr))
464+
else if(!has_temporal_operator(property.normalized_expr))
464465
{
465466
just_p(property);
466467
}
@@ -482,7 +483,7 @@ Function: bdd_enginet::AGp
482483

483484
void bdd_enginet::AGp(propertyt &property)
484485
{
485-
const exprt &sub_expr = to_unary_expr(property.expr).op();
486+
const exprt &sub_expr = to_unary_expr(property.normalized_expr).op();
486487
BDD p = property2BDD(sub_expr);
487488

488489
// Start with !p, and go backwards until saturation or we hit an
@@ -563,7 +564,8 @@ Function: bdd_enginet::AGAFp
563564

564565
void bdd_enginet::AGAFp(propertyt &property)
565566
{
566-
const exprt &sub_expr = to_unary_expr(to_unary_expr(property.expr).op()).op();
567+
const exprt &sub_expr =
568+
to_unary_expr(to_unary_expr(property.normalized_expr).op()).op();
567569
BDD p = property2BDD(sub_expr);
568570

569571
// Start with p, and go backwards until saturation.
@@ -648,7 +650,7 @@ void bdd_enginet::just_p(propertyt &property)
648650
{
649651
// We check whether the BDD for the negation of the property
650652
// contains an initial state.
651-
exprt negation = negate_property(property.expr);
653+
exprt negation = negate_property(property.normalized_expr);
652654
BDD states = property2BDD(negation);
653655

654656
// do we have an initial state?

src/ebmc/bmc.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ void bmc(
4747
continue;
4848

4949
// Is it supported by the BMC engine?
50-
if(!bmc_supports_property(property.expr))
50+
if(!bmc_supports_property(property.normalized_expr))
5151
{
5252
property.failure("property not supported by BMC engine");
5353
continue;
5454
}
5555

5656
::property(
57-
property.expr,
57+
property.normalized_expr,
5858
property.timeframe_handles,
5959
message_handler,
6060
solver,

src/ebmc/ebmc_base.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ int ebmc_baset::do_bit_level_bmc(cnft &solver, bool convert_only)
200200
continue;
201201

202202
::unwind_property(
203-
property.expr,
203+
property.normalized_expr,
204204
property.timeframe_literals,
205205
message.get_message_handler(),
206206
solver,

src/ebmc/ebmc_properties.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Author: Daniel Kroening, [email protected]
1111
#include <langapi/language.h>
1212
#include <langapi/language_util.h>
1313
#include <langapi/mode.h>
14+
#include <temporal-logic/normalize_property.h>
1415
#include <verilog/sva_expr.h>
1516

1617
#include "ebmc_error.h"
@@ -70,7 +71,9 @@ ebmc_propertiest ebmc_propertiest::from_transition_system(
7071
else
7172
properties.properties.back().name = symbol.pretty_name;
7273

73-
properties.properties.back().expr = symbol.value;
74+
properties.properties.back().original_expr = symbol.value;
75+
properties.properties.back().normalized_expr =
76+
normalize_property(symbol.value);
7477
properties.properties.back().location = symbol.location;
7578
properties.properties.back().expr_string = value_as_string;
7679
properties.properties.back().mode = symbol.mode;
@@ -156,7 +159,8 @@ ebmc_propertiest ebmc_propertiest::from_command_line(
156159
ebmc_propertiest properties;
157160
properties.properties.push_back(propertyt());
158161
auto &p = properties.properties.back();
159-
p.expr = expr;
162+
p.original_expr = expr;
163+
p.normalized_expr = normalize_property(expr);
160164
p.expr_string = expr_as_string;
161165
p.mode = transition_system.main_symbol->mode;
162166
p.location.make_nil();

src/ebmc/ebmc_properties.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ class ebmc_propertiest
2929
source_locationt location;
3030
std::string expr_string;
3131
irep_idt mode;
32-
exprt expr;
32+
exprt original_expr;
33+
exprt normalized_expr;
3334
bvt timeframe_literals; // bit level
3435
exprt::operandst timeframe_handles; // word level
3536
std::string description;
@@ -143,7 +144,7 @@ class ebmc_propertiest
143144

144145
bool requires_lasso_constraints() const
145146
{
146-
return ::requires_lasso_constraints(expr);
147+
return ::requires_lasso_constraints(normalized_expr);
147148
}
148149
};
149150

src/ebmc/k_induction.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class k_inductiont
7171

7272
static bool supported(const ebmc_propertiest::propertyt &p)
7373
{
74-
auto &expr = p.expr;
74+
auto &expr = p.normalized_expr;
7575
if(expr.id() == ID_sva_always || expr.id() == ID_AG || expr.id() == ID_G)
7676
{
7777
// Must be AG p or equivalent.
@@ -264,7 +264,7 @@ void k_inductiont::induction_step()
264264
ns,
265265
false);
266266

267-
const exprt property(p_it.expr);
267+
const exprt property(p_it.normalized_expr);
268268
const exprt &p = to_unary_expr(property).op();
269269

270270
// assumption: time frames 0,...,k-1

src/ebmc/liveness_to_safety.cpp

+8-5
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,11 @@ void liveness_to_safetyt::operator()()
248248
{
249249
// We want GFp.
250250
if(
251-
property.expr.id() == ID_sva_always &&
252-
(to_sva_always_expr(property.expr).op().id() == ID_sva_eventually ||
253-
to_sva_always_expr(property.expr).op().id() == ID_sva_s_eventually))
251+
property.normalized_expr.id() == ID_sva_always &&
252+
(to_sva_always_expr(property.normalized_expr).op().id() ==
253+
ID_sva_eventually ||
254+
to_sva_always_expr(property.normalized_expr).op().id() ==
255+
ID_sva_s_eventually))
254256
{
255257
translate_GFp(property);
256258
}
@@ -265,7 +267,7 @@ void liveness_to_safetyt::operator()()
265267

266268
void liveness_to_safetyt::translate_GFp(propertyt &property)
267269
{
268-
auto &p = to_unary_expr(to_unary_expr(property.expr).op()).op();
270+
auto &p = to_unary_expr(to_unary_expr(property.normalized_expr).op()).op();
269271

270272
// create the 'live' symbol, one for each liveness property
271273
{
@@ -299,7 +301,8 @@ void liveness_to_safetyt::translate_GFp(propertyt &property)
299301
conjunction({transition_system.trans_expr.trans(), std::move(live_trans)});
300302

301303
// replace the liveness property
302-
property.expr = safety_replacement(property.name, property.expr);
304+
property.normalized_expr =
305+
safety_replacement(property.name, property.normalized_expr);
303306
}
304307

305308
void liveness_to_safety(

src/ebmc/neural_liveness.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -162,13 +162,14 @@ void neural_livenesst::validate_properties()
162162
{
163163
// ignore
164164
}
165-
else if(property.expr.id() == ID_AF)
165+
else if(property.normalized_expr.id() == ID_AF)
166166
{
167167
// ok
168168
}
169169
else if(
170-
property.expr.id() == ID_sva_always &&
171-
to_sva_always_expr(property.expr).op().id() == ID_sva_s_eventually)
170+
property.normalized_expr.id() == ID_sva_always &&
171+
to_sva_always_expr(property.normalized_expr).op().id() ==
172+
ID_sva_s_eventually)
172173
{
173174
// ok
174175
}
@@ -188,7 +189,7 @@ void neural_livenesst::set_live_signal(
188189
auto main_symbol_writeable = transition_system.symbol_table.get_writeable(
189190
transition_system.main_symbol->name);
190191
main_symbol_writeable->value = original_trans_expr; // copy
191-
::set_live_signal(transition_system, property.expr);
192+
::set_live_signal(transition_system, property.normalized_expr);
192193
}
193194

194195
std::function<void(trans_tracet)>
@@ -301,7 +302,7 @@ tvt neural_livenesst::verify(
301302

302303
auto result = is_ranking_function(
303304
transition_system,
304-
property.expr,
305+
property.normalized_expr,
305306
candidate,
306307
solver_factory,
307308
message.get_message_handler());

src/ebmc/ranking_function.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ int do_ranking_function(
109109

110110
auto result = is_ranking_function(
111111
transition_system,
112-
property.expr,
112+
property.normalized_expr,
113113
ranking_function,
114114
solver_factory,
115115
message_handler);

src/temporal-logic/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
SRC = negate_property.cpp \
2+
normalize_property.cpp \
23
temporal_logic.cpp \
34
#empty line
45

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*******************************************************************\
2+
3+
Module: Property Normalization
4+
5+
Author: Daniel Kroening, [email protected]
6+
7+
\*******************************************************************/
8+
9+
#include "normalize_property.h"
10+
11+
exprt normalize_property(exprt expr)
12+
{
13+
return expr;
14+
}
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*******************************************************************\
2+
3+
Module: Property Normalization
4+
5+
Author: Daniel Kroening, [email protected]
6+
7+
\*******************************************************************/
8+
9+
#ifndef CPROVER_TEMPORAL_LOGIC_NORMALIZE_PROPERTY_H
10+
#define CPROVER_TEMPORAL_LOGIC_NORMALIZE_PROPERTY_H
11+
12+
#include <util/expr.h>
13+
14+
exprt normalize_property(exprt);
15+
16+
#endif

0 commit comments

Comments
 (0)