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

Module: CNF Generation

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

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

#ifndef CPROVER_PROP_CNF_H
#define CPROVER_PROP_CNF_H

#include <list>

#include "propdec/prop.h"

class cnft:public virtual propt
{
public:
  cnft();
  virtual ~cnft();

  virtual literalt constant(bool value)
  { return value?l_const1:l_const0; }

  virtual void land(literalt a, literalt b, literalt o);
  virtual void lor(literalt a, literalt b, literalt o);
  virtual void lxor(literalt a, literalt b, literalt o);
  virtual void lnand(literalt a, literalt b, literalt o);
  virtual void lnor(literalt a, literalt b, literalt o);
  virtual void lequal(literalt a, literalt b, literalt o);
  virtual void limplies(literalt a, literalt b, literalt o);
  
  virtual void init_const();

  virtual literalt land(literalt a, literalt b);
  virtual literalt lor(literalt a, literalt b);
  virtual literalt land(const bvt &bv);
  virtual literalt lor(const bvt &bv);
  virtual literalt lxor(const bvt &bv);
  virtual literalt lnot(literalt a);
  virtual literalt lxor(literalt a, literalt b);
  virtual literalt lnand(literalt a, literalt b);
  virtual literalt lnor(literalt a, literalt b);
  virtual literalt lequal(literalt a, literalt b);
  virtual literalt limplies(literalt a, literalt b);
  virtual literalt lselect(literalt a, literalt b, literalt c); // a?b:c
  virtual literalt new_literal();
  virtual void l_set_to(literalt a, bool value);
  virtual unsigned no_literals() const { return _no_literals; }
  virtual void set_no_literals(unsigned no) { _no_literals=no; }
  virtual unsigned no_clauses() const=0;
  
protected:
  unsigned _no_literals;
  
  literalt l_const0, l_const1;
  
  void eliminate_duplicates(const bvt &bv, bvt &dest);
  bool process_clause(const bvt &bv, bvt &dest);
};

class cnf_solvert:public cnft
{
public:
  cnf_solvert():status(INIT), clause_counter(0)
  {
  }
  
  virtual unsigned no_clauses() const
  {
    return clause_counter;
  }

protected:
  typedef enum { INIT, SAT, UNSAT, ERROR } statust;
  statust status;
  unsigned clause_counter;
}; 

#endif
