Skip to content

Commit e82ae8b

Browse files
committed
word-level BMC: add missing SVA expressions
1 parent d559b64 commit e82ae8b

File tree

7 files changed

+66
-6
lines changed

7 files changed

+66
-6
lines changed

src/ebmc/k_induction.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ Author: Daniel Kroening, [email protected]
1111
#include <util/string2int.h>
1212

1313
#include <temporal-logic/temporal_logic.h>
14-
#include <trans-word-level/instantiate_word_level.h>
14+
#include <trans-word-level/obligations.h>
15+
#include <trans-word-level/property.h>
1516
#include <trans-word-level/trans_trace_word_level.h>
1617
#include <trans-word-level/unwind.h>
1718

@@ -261,7 +262,8 @@ void k_inductiont::induction_step()
261262
const exprt &p = to_unary_expr(property.normalized_expr).op();
262263
for(std::size_t c = 0; c < no_timeframes; c++)
263264
{
264-
exprt tmp = instantiate(p, c, no_timeframes);
265+
exprt tmp =
266+
property_obligations(p, c, no_timeframes).conjunction().second;
265267
solver.set_to_true(tmp);
266268
}
267269
}
@@ -272,13 +274,16 @@ void k_inductiont::induction_step()
272274
// assumption: time frames 0,...,k-1
273275
for(std::size_t c = 0; c < no_timeframes - 1; c++)
274276
{
275-
exprt tmp = instantiate(p, c, no_timeframes - 1);
277+
exprt tmp =
278+
property_obligations(p, c, no_timeframes - 1).conjunction().second;
276279
solver.set_to_true(tmp);
277280
}
278281

279282
// property: time frame k
280283
{
281-
exprt tmp = instantiate(p, no_timeframes - 1, no_timeframes);
284+
exprt tmp = property_obligations(p, no_timeframes - 1, no_timeframes)
285+
.conjunction()
286+
.second;
282287
solver.set_to_false(tmp);
283288
}
284289

src/temporal-logic/nnf.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@ std::optional<exprt> negate_property_node(const exprt &expr)
136136
auto not_b = not_exprt{followed_by.property()};
137137
return sva_non_overlapped_implication_exprt{followed_by.lhs(), not_b};
138138
}
139+
else if(expr.id() == ID_sva_not)
140+
{
141+
return to_sva_not_expr(expr).op();
142+
}
139143
else
140144
return {};
141145
}

src/temporal-logic/normalize_property.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ exprt normalize_property(exprt expr)
182182
expr = trivial_sva(expr);
183183

184184
// now do recursion
185-
expr = normalize_property_rec(expr);
185+
// expr = normalize_property_rec(expr);
186186

187187
return expr;
188188
}

src/temporal-logic/temporal_logic.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,16 @@ bool is_SVA_sequence(const exprt &expr)
7272
return id == ID_sva_and || id == ID_sva_or ||
7373
id == ID_sva_overlapped_implication ||
7474
id == ID_sva_non_overlapped_implication || id == ID_sva_cycle_delay ||
75+
id == ID_sva_cycle_delay_plus || id == ID_sva_cycle_delay_star ||
7576
id == ID_sva_sequence_concatenation ||
7677
id == ID_sva_sequence_intersect || id == ID_sva_sequence_first_match ||
7778
id == ID_sva_sequence_throughout || id == ID_sva_sequence_within ||
7879
id == ID_sva_sequence_goto_repetition ||
7980
id == ID_sva_sequence_consecutive_repetition ||
8081
id == ID_sva_sequence_non_consecutive_repetition ||
8182
id == ID_sva_sequence_repetition_star ||
82-
id == ID_sva_sequence_repetition_plus;
83+
id == ID_sva_sequence_repetition_plus || id == ID_sva_strong ||
84+
id == ID_sva_weak;
8385
}
8486

8587
bool is_SVA_operator(const exprt &expr)

src/trans-word-level/property.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,20 @@ static obligationst property_obligations_rec(
399399
return obligationst{no_timeframes - 1, true_exprt()}; // works on NNF only
400400
}
401401
}
402+
else if(property_expr.id() == ID_sva_indexed_nexttime)
403+
{
404+
auto &nexttime = to_sva_indexed_nexttime_expr(property_expr);
405+
auto always = sva_ranged_always_exprt{
406+
nexttime.index(), nexttime.index(), nexttime.op()};
407+
return property_obligations_rec(always, current, no_timeframes);
408+
}
409+
else if(property_expr.id() == ID_sva_indexed_s_nexttime)
410+
{
411+
auto &nexttime = to_sva_indexed_s_nexttime_expr(property_expr);
412+
auto s_always = sva_ranged_always_exprt{
413+
nexttime.index(), nexttime.index(), nexttime.op()};
414+
return property_obligations_rec(s_always, current, no_timeframes);
415+
}
402416
else if(property_expr.id() == ID_sva_s_until || property_expr.id() == ID_U)
403417
{
404418
auto &p = to_binary_expr(property_expr).lhs();

src/trans-word-level/sequence.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,26 @@ std::vector<std::pair<mp_integer, exprt>> instantiate_sequence(
176176

177177
return result;
178178
}
179+
else if(expr.id() == ID_sva_strong || expr.id() == ID_sva_weak)
180+
{
181+
// not distinguished
182+
auto &op = to_unary_expr(expr).op();
183+
return instantiate_sequence(op, t, no_timeframes);
184+
}
185+
else if(expr.id() == ID_sva_cycle_delay_plus)
186+
{
187+
auto new_expr = sva_s_eventually_exprt{
188+
sva_s_nexttime_exprt{to_sva_cycle_delay_plus_expr(expr).op()}};
189+
auto obligations = property_obligations(new_expr, t, no_timeframes);
190+
return {obligations.conjunction()};
191+
}
192+
else if(expr.id() == ID_sva_cycle_delay_star)
193+
{
194+
auto new_expr =
195+
sva_s_eventually_exprt{to_sva_cycle_delay_star_expr(expr).op()};
196+
auto obligations = property_obligations(new_expr, t, no_timeframes);
197+
return {obligations.conjunction()};
198+
}
179199
else
180200
{
181201
// not a sequence, evaluate as state predicate

src/verilog/sva_expr.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,11 @@ class sva_not_exprt : public unary_predicate_exprt
657657
: unary_predicate_exprt(ID_sva_not, std::move(op))
658658
{
659659
}
660+
661+
not_exprt lower() const
662+
{
663+
return not_exprt{op()};
664+
}
660665
};
661666

662667
static inline const sva_not_exprt &to_sva_not_expr(const exprt &expr)
@@ -731,6 +736,11 @@ class sva_iff_exprt : public binary_predicate_exprt
731736
: binary_predicate_exprt(std::move(op0), ID_sva_iff, std::move(op1))
732737
{
733738
}
739+
740+
equal_exprt lower() const
741+
{
742+
return equal_exprt{lhs(), rhs()};
743+
}
734744
};
735745

736746
static inline const sva_iff_exprt &to_sva_iff_expr(const exprt &expr)
@@ -754,6 +764,11 @@ class sva_implies_exprt : public binary_predicate_exprt
754764
: binary_predicate_exprt(std::move(op0), ID_sva_implies, std::move(op1))
755765
{
756766
}
767+
768+
implies_exprt lower() const
769+
{
770+
return implies_exprt{lhs(), rhs()};
771+
}
757772
};
758773

759774
static inline const sva_implies_exprt &to_sva_implies_expr(const exprt &expr)

0 commit comments

Comments
 (0)