41 if(expr.
id()==ID_symbol ||
42 expr.
id()==ID_index ||
43 expr.
id()==ID_member ||
44 expr.
id()==ID_dereference)
69 for(goto_programt::instructionst::const_iterator
70 it=instructions.begin();
71 it!=instructions.end();
80 for(
const auto &step : path)
88 for(
const auto &step : loop)
97 modified.insert(t->assign_lhs());
101 std::map<exprt, polynomialt> polynomials,
117 std::vector<exprt> polynomials_hold;
122 for(std::map<exprt, polynomialt>::iterator it=polynomials.begin();
123 it!=polynomials.end();
126 const equal_exprt holds(it->first, it->second.to_expr());
129 polynomials_hold.push_back(holds);
142 for(
const auto &p : polynomials_hold)
146 std::cout <<
"Checking following program for inductiveness:\n";
156 std::cout <<
"Not inductive!\n";
165 catch(
const std::string &s)
167 std::cout <<
"Error in inductiveness SAT check: " << s <<
'\n';
170 catch (
const char *s)
172 std::cout <<
"Error in inductiveness SAT check: " << s <<
'\n';
179 std::map<exprt, polynomialt> &polynomials,
188 for(std::map<exprt, polynomialt>::iterator it=polynomials.begin();
189 it!=polynomials.end();
192 it->second.substitute(substitution);
203 std::set<symbol_exprt> vars;
204 for(
const exprt &expr : modified)
207 vars.erase(loop_counter_sym);
229 for(patht::reverse_iterator r_it=path.rbegin();
238 const exprt &lhs = t->assign_lhs();
239 const exprt &rhs = t->assign_rhs();
241 if(lhs.
id()==ID_symbol ||
242 lhs.
id()==ID_index ||
243 lhs.
id()==ID_dereference)
252 else if(t->is_assume() || t->is_assert())
261 if(!r_it->guard.is_true() && !r_it->guard.is_nil())
281 if(expr.
id()==ID_index ||
282 expr.
id()==ID_dereference)
284 expr_mapt::iterator it=abstractions.find(expr);
286 if(it==abstractions.end())
313 if(expr.
id() == ID_not &&
to_not_expr(expr).op().
id() == ID_nondet)
317 else if(expr.
id()==ID_equal ||
324 if(rel_expr.lhs().id() == ID_nondet || rel_expr.rhs().id() == ID_nondet)
332 std::map<exprt, polynomialt> polynomials,
367 std::vector<exprt> polynomials_hold;
369 for(std::map<exprt, polynomialt>::iterator it=polynomials.begin();
370 it!=polynomials.end();
374 exprt rhs=it->second.to_expr();
381 for(std::vector<exprt>::iterator it=polynomials_hold.begin();
382 it!=polynomials_hold.end();
394 for(std::map<exprt, polynomialt>::iterator p_it=polynomials.begin();
395 p_it!=polynomials.end();
398 program.
assign(p_it->first, p_it->second.to_expr());
401 program.
assume(condition);
406 for(std::map<exprt, polynomialt>::iterator p_it=polynomials.begin();
407 p_it!=polynomials.end();
410 program.
assign(p_it->first, p_it->second.to_expr());
421 std::cout <<
"Checking following program for monotonicity:\n";
430 std::cout <<
"Path is not monotone\n";
436 catch(
const std::string &s)
438 std::cout <<
"Error in monotonicity SAT check: " << s <<
'\n';
443 std::cout <<
"Error in monotonicity SAT check: " << s <<
'\n';
448 std::cout <<
"Path is monotone\n";
462 checker_options.
set_option(
"signed-overflow-check",
true);
463 checker_options.
set_option(
"unsigned-overflow-check",
true);
464 checker_options.
set_option(
"assert-to-assume",
true);
465 checker_options.
set_option(
"assumptions",
true);
471 std::cout <<
"Adding overflow checks at " << now <<
"...\n";
484 std::cout <<
"Done at " << now <<
".\n";
494 for(goto_programt::instructionst::reverse_iterator r_it=loop_body.rbegin();
495 r_it!=loop_body.rend();
498 if(r_it->is_assign())
501 exprt assignment_lhs = r_it->assign_lhs();
502 exprt assignment_rhs = r_it->assign_rhs();
504 if(assignment_lhs.
id() == ID_index)
507 assignments.push_back(std::make_pair(assignment_lhs, assignment_rhs));
511 arrays_written.insert(index_expr.
array());
517 for(expr_pairst::iterator a_it=assignments.begin();
518 a_it!=assignments.end();
521 replace_expr(assignment_lhs, assignment_rhs, a_it->first);
522 replace_expr(assignment_lhs, assignment_rhs, a_it->second);
533 std::map<exprt, polynomialt> &polynomials,
538 std::cout <<
"Doing arrays...\n";
547 std::cout <<
"Found " << array_assignments.size()
548 <<
" array assignments\n";
551 if(array_assignments.empty())
561 array_assignments, polynomials, poly_assignments, nondet_indices))
566 std::cout <<
"Couldn't model an array assignment :-(\n";
572 for(expr_sett::iterator it=arrays_written.begin();
573 it!=arrays_written.end();
583 for(polynomial_array_assignmentst::iterator it=poly_assignments.begin();
584 it!=poly_assignments.end();
615 for(expr_sett::iterator a_it=arrays_written.begin();
616 a_it!=arrays_written.end();
620 exprt old_array=substitution[array];
621 std::vector<polynomialt> indices;
622 bool nonlinear_index=
false;
624 for(polynomial_array_assignmentst::iterator it=poly_assignments.begin();
625 it!=poly_assignments.end();
632 indices.push_back(index);
640 nonlinear_index=
true;
662 pos_eliminator=neg_eliminator;
663 pos_eliminator.
mult(-1);
667 for(std::vector<polynomialt>::iterator it=indices.begin();
672 exprt max_idx, min_idx;
680 index.
add(pos_eliminator);
689 index.
add(neg_eliminator);
694 assert(!
"ITSALLGONEWRONG");
700 unchanged_operands.push_back(unchanged_by_this_one);
713 for(std::vector<polynomialt>::iterator it=indices.begin();
717 idx_touched_operands.push_back(
735 implies_exprt idx_not_touched_bound(l_bound, idx_not_touched);
737 idx_never_touched=
exprt(ID_forall);
752 implies_exprt idx_unchanged(idx_never_touched, value_unchanged);
760 program.
assume(array_unchanged);
768 std::map<exprt, polynomialt> &polynomials,
772 for(expr_pairst::iterator it=array_assignments.begin();
773 it!=array_assignments.end();
785 std::cout <<
"Couldn't convert index: "
792 std::cout <<
"Converted index to: "
797 if(it->second.id()==ID_nondet)
799 nondet_indices.push_back(poly_assignment.
index);
801 else if(!
expr2poly(it->second, polynomials, poly_assignment.
value))
805 std::cout <<
"Couldn't convert RHS: " <<
expr2c(it->second,
ns)
813 std::cout <<
"Converted RHS to: "
818 array_polynomials.push_back(poly_assignment);
827 std::map<exprt, polynomialt> &polynomials,
830 exprt subbed_expr=expr;
832 for(std::map<exprt, polynomialt>::iterator it=polynomials.begin();
833 it!=polynomials.end();
836 replace_expr(it->first, it->second.to_expr(), subbed_expr);
840 std::cout <<
"expr2poly(" <<
expr2c(subbed_expr,
ns) <<
")\n";
857 std::map<exprt, polynomialt> &polynomials,
868 std::unordered_set<index_exprt, irep_hash> array_writes;
872 for(std::map<exprt, polynomialt>::iterator it=polynomials.begin();
873 it!=polynomials.end();
876 const exprt &var=it->first;
891 for(expr_sett::iterator it=nonrecursive.begin();
892 it!=nonrecursive.end();
899 for(goto_programt::instructionst::iterator it=body.begin();
905 exprt lhs = it->assign_lhs();
906 exprt rhs = it->assign_rhs();
908 if(lhs.
id()==ID_dereference)
912 std::cout <<
"Bailing out on write-through-pointer\n";
917 if(lhs.
id()==ID_index)
921 array_writes.insert(lhs_index_expr);
923 if(arrays_written.find(lhs_index_expr.array()) != arrays_written.end())
928 std::cout <<
"Bailing out on array written to twice in loop: "
929 <<
expr2c(lhs_index_expr.array(),
ns) <<
'\n';
934 arrays_written.insert(lhs_index_expr.array());
945 for(expr_sett::iterator it=arrays_written.begin();
946 it!=arrays_written.end();
949 if(arrays_read.find(*it)!=arrays_read.end())
952 std::cout <<
"Bailing out on array read and written on same path\n";
958 for(expr_sett::iterator it=nonrecursive.begin();
959 it!=nonrecursive.end();
962 if(it->id()==ID_symbol)
964 exprt &val=state[*it];
968 std::cout <<
"Fitted nonrecursive: " <<
expr2c(*it,
ns) <<
"=" <<
974 for(
const auto &write : array_writes)
976 const auto &lhs = write;
977 const auto &rhs = state[write];
982 std::cout <<
"Failed to assign a nonrecursive array: " <<
998 std::cout <<
"Modelling array assignment " <<
expr2c(lhs,
ns) <<
"=" <<
1002 if(lhs.
id()==ID_dereference)
1006 std::cout <<
"Bailing out on write-through-pointer\n";
1024 const exprt &fresh_array =
1052 std::cout <<
"Trying to polynomialize " <<
expr2c(idx,
ns) <<
'\n';
1059 if(idx.
id()==ID_pointer_offset)
1072 std::cout <<
"Failed to polynomialize\n";
1086 std::cout <<
"Bailing out on nonlinear index: "
1094 exprt lower_bound=idx;
1095 exprt upper_bound=idx;
1116 std::cout <<
"Bailing out on write to constant array index: " <<
1121 else if(stride == 1 || stride == -1)
1159 exprt fresh_lhs=lhs;
1170 forall.
where() = implies;
1175 program.
assign(arr, fresh_array);
1184 if(e.
id() == ID_index)
1188 else if(e.
id() == ID_dereference)
1201 std::set<std::pair<expr_listt, exprt> > &coefficients,
1204 for(std::set<std::pair<expr_listt, exprt> >::iterator it=coefficients.begin();
1205 it!=coefficients.end();
1210 exprt coefficient=it->second;
1212 std::map<exprt, int> degrees;
1215 monomial.
coeff = numeric_cast_v<int>(mp);
1217 if(monomial.
coeff==0)
1222 for(
const auto &term : terms)
1224 if(degrees.find(term)!=degrees.end())
1234 for(std::map<exprt, int>::iterator it=degrees.begin();
1240 term.
exp=it->second;
1241 monomial.
terms.push_back(term);
1244 polynomial.
monomials.push_back(monomial);
1250 static int num_symbols=0;