CBMC
propagate.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Propagate
4 
5 Author: Daniel Kroening, dkr@amazon.com
6 
7 \*******************************************************************/
8 
11 
12 #include "propagate.h"
13 
14 #include <util/console.h>
15 #include <util/format_expr.h>
16 #include <util/simplify_expr.h>
17 
18 #include "simplify_state_expr.h"
19 #include "state.h"
20 
21 #include <iomanip>
22 #include <iostream>
23 
24 void propagate(
25  const std::vector<framet> &frames,
26  const workt &work,
27  const std::unordered_set<symbol_exprt, irep_hash> &address_taken,
28  bool verbose,
29  const namespacet &ns,
30  const std::function<void(const symbol_exprt &, exprt, const workt::patht &)>
31  &propagator)
32 {
33  auto &f = frames[work.frame.index];
34 
35  if(verbose)
36  {
37  std::cout << '\n';
38  std::cout << consolet::faint;
39  std::cout << ' ' << std::setw(2) << work.frame.index << ' ';
40  std::cout << consolet::reset << consolet::cyan << format(work.invariant);
41  std::cout << consolet::reset << '\n';
42  }
43 
44  for(const auto &implication : f.implications)
45  {
46  if(verbose)
47  {
48  std::cout << consolet::green;
49  std::cout << 'C' << consolet::faint << std::setw(2) << work.frame.index
50  << consolet::reset << ' ';
51  std::cout << consolet::green << format(implication.as_expr());
52  std::cout << consolet::reset << '\n';
53  }
54 
55  auto &next_state = implication.rhs.arguments().front();
56  auto lambda_expr = lambda_exprt({state_expr()}, work.invariant);
57  auto instance = lambda_expr.instantiate({next_state});
58  auto simplified1 = simplify_state_expr(instance, address_taken, ns);
59  auto simplified1a = simplify_state_expr(simplified1, address_taken, ns);
60  if(simplified1 != simplified1a)
61  {
62  std::cout << "SIMP0: " << format(instance) << "\n";
63  std::cout << "SIMP1: " << format(simplified1) << "\n";
64  std::cout << "SIMPa: " << format(simplified1a) << "\n";
65  abort();
66  }
67 
68  auto simplified2 = simplify_expr(simplified1, ns);
69 
70  if(implication.lhs.id() == ID_function_application)
71  {
72  // Sxx(ς) ⇒ Syy(ς[update])
73  auto &state = to_symbol_expr(
75  propagator(state, simplified2, work.path);
76  }
77  else if(
78  implication.lhs.id() == ID_and &&
79  to_and_expr(implication.lhs).op0().id() == ID_function_application)
80  {
81  // Sxx(ς) ∧ ς(COND) ⇒ Syy(ς)
82  auto &function_application =
84  auto &state = to_symbol_expr(function_application.function());
85  auto cond1 = to_and_expr(implication.lhs).op1();
86  auto cond2 = implies_exprt(cond1, simplified2);
87  auto simplified = simplify_expr(cond2, ns);
88  propagator(state, simplified, work.path);
89  }
90  }
91 }
std::unordered_set< symbol_exprt, irep_hash > address_taken(const std::vector< exprt > &src)
exprt instantiate(const exprt::operandst &) const
substitute free occurrences of the variables in where() by the given values
Definition: std_expr.cpp:225
static std::ostream & reset(std::ostream &)
Definition: console.cpp:176
static std::ostream & cyan(std::ostream &)
Definition: console.cpp:112
static std::ostream & green(std::ostream &)
Definition: console.cpp:120
static std::ostream & faint(std::ostream &)
Definition: console.cpp:160
Base class for all expressions.
Definition: expr.h:56
std::size_t index
Definition: solver_types.h:31
Boolean implication.
Definition: std_expr.h:2183
const irep_idt & id() const
Definition: irep.h:388
A (mathematical) lambda expression.
exprt & op1()
Definition: std_expr.h:938
exprt & op0()
Definition: std_expr.h:932
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:94
Expression to hold a symbol (variable)
Definition: std_expr.h:131
Console.
static format_containert< T > format(const T &o)
Definition: format.h:37
static exprt implication(exprt lhs, exprt rhs)
const function_application_exprt & to_function_application_expr(const exprt &expr)
Cast an exprt to a function_application_exprt.
void propagate(const std::vector< framet > &frames, const workt &work, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, bool verbose, const namespacet &ns, const std::function< void(const symbol_exprt &, exprt, const workt::patht &)> &propagator)
Definition: propagate.cpp:24
Propagate.
exprt simplify_state_expr(exprt, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, const namespacet &)
exprt simplify_expr(exprt src, const namespacet &ns)
Simplify State Expression.
static symbol_exprt state_expr()
Definition: state.h:28
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:272
const and_exprt & to_and_expr(const exprt &expr)
Cast an exprt to a and_exprt.
Definition: std_expr.h:2167
void abort(void)
Definition: stdlib.c:128
exprt invariant
Definition: solver_types.h:178
patht path
Definition: solver_types.h:180
std::vector< frame_reft > patht
Definition: solver_types.h:167
frame_reft frame
Definition: solver_types.h:177