/*******************************************************************\

Module: Bounded Model Checking for ANSI-C + HDL

Author: Daniel Kroening, kroening@cs.cmu.edu

\*******************************************************************/

#ifndef CPROVER_CBMC_BMC_H
#define CPROVER_CBMC_BMC_H

#include <list>
#include <map>

#include <hash_cont.h>
#include <options.h>

#include <propdec/prop.h>
#include <propsolve/cnf.h>
#include <propsolve/satcheck.h>
#include <propsolve/cnf_clause_list.h>
#include <propdec/prop_conv.h>
#include <langapi/language_ui.h>
#include <goto-symex/symex_target_equation.h>

#include "symex_bmc.h"

class bmc_baset:public messaget
{
public:
  bmc_baset(
    const contextt &_context,
    symex_bmct &_symex,
    symex_target_equationt &_equation,
    message_handlert &_message_handler):
    messaget(_message_handler),
    context(_context),
    symex(_symex),
    equation(_equation),
    ui(ui_message_handlert::PLAIN)
  {
  }
 
  optionst options;
  
  virtual bool run(const goto_functionst &goto_functions);
  virtual ~bmc_baset() { }

  // additional stuff   
  expr_listt bmc_constraints;  
  
  friend class cbmc_satt;
  friend class hw_cbmc_satt;
  friend class counterexample_beautification_greedyt;
  friend class counterexample_beautification_pbst;
  
  void set_ui(language_uit::uit _ui) { ui=_ui; }
  
protected:
  const contextt &context;
  symex_bmct &symex;
  symex_target_equationt &equation;
 
  // counterexample
  virtual void counterexample_beautification(
    cnf_clause_listt &cnf,
    class bv_cbmct &bv_cbmc);

  // use gui format
  language_uit::uit ui;
  
  virtual bool decide();
  virtual bool run_decision_procedure(prop_convt &prop_conv);
  virtual bool cvc();
  virtual bool cvc_conv(std::ostream &out);
  virtual bool smt();
  virtual bool smt_conv(std::ostream &out);
  virtual bool write_dimacs();
  virtual bool write_dimacs(std::ostream &out);
  
  // unwinding
  virtual void setup_unwind();

  virtual void do_unwind_module(
    decision_proceduret &decision_procedure);

  virtual void do_cbmc(prop_convt &solver);
  virtual void show_vcc();
  virtual void show_vcc(std::ostream &out);
  virtual void show_program();
  virtual void report_success();
  virtual void report_failure();

  virtual void error_trace(
    const prop_convt &prop_conv);
};

class bmct:public bmc_baset
{
public:
  bmct(
    const contextt &_context,
    message_handlert &_message_handler):
    bmc_baset(_context, _symex, _equation, _message_handler),
    ns(_context, new_context),
    _equation(ns),
    _symex(ns, new_context, _equation)
  {
  }
 
protected:
  contextt new_context;
  namespacet ns;
  symex_target_equationt _equation;
  symex_bmct _symex;
};

#endif
