Skip to content

Commit a6276c5

Browse files
committed
Handle unconditional loop during synthesis
1 parent 065a56b commit a6276c5

File tree

2 files changed

+21
-13
lines changed

2 files changed

+21
-13
lines changed

src/goto-synthesizer/enumerative_loop_contracts_synthesizer.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,13 @@ void enumerative_loop_contracts_synthesizert::init_candidates()
100100
// we only synthesize invariants and assigns for unannotated loops
101101
if(loop_end->condition().find(ID_C_spec_loop_invariant).is_nil())
102102
{
103-
// Store the loop guard.
104-
exprt guard =
105-
get_loop_head(
106-
loop_end->loop_number,
107-
goto_model.goto_functions.function_map[function_p.first])
108-
->condition();
109-
neg_guards[new_id] = guard;
103+
// Store the loop guard if exists.
104+
auto loop_head = get_loop_head(
105+
loop_end->loop_number,
106+
goto_model.goto_functions.function_map[function_p.first]);
107+
108+
if(loop_head->has_condition())
109+
neg_guards[new_id] = loop_head->condition();
110110

111111
// Initialize invariant clauses as `true`.
112112
in_invariant_clause_map[new_id] = true_exprt();

src/goto-synthesizer/synthesizer_utils.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,18 +144,26 @@ invariant_mapt combine_in_and_post_invariant_clauses(
144144
const invariant_mapt &neg_guards)
145145
{
146146
// Combine invariant
147-
// (in_inv || !guard) && (!guard -> pos_inv)
147+
// (in_inv || !guard) && (!guard -> pos_inv) for loops with loop guard
148+
// in_inv && pos_inv for loops without loop guard
148149
invariant_mapt result;
149150
for(const auto &in_clause : in_clauses)
150151
{
151152
const auto &id = in_clause.first;
152153
const auto &it_guard = neg_guards.find(id);
153154

154-
INVARIANT(it_guard != neg_guards.end(), "Some loop guard is missing.");
155-
156-
result[id] = and_exprt(
157-
or_exprt(it_guard->second, in_clause.second),
158-
implies_exprt(it_guard->second, post_clauses.at(id)));
155+
// Unconditional loop or failed to get loop guard.
156+
if(it_guard == neg_guards.end())
157+
{
158+
result[id] = and_exprt(in_clause.second, post_clauses.at(id));
159+
}
160+
// Loops with loop guard.
161+
else
162+
{
163+
result[id] = and_exprt(
164+
or_exprt(it_guard->second, in_clause.second),
165+
implies_exprt(it_guard->second, post_clauses.at(id)));
166+
}
159167
}
160168
return result;
161169
}

0 commit comments

Comments
 (0)