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

Module:

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

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

#ifndef CPROVER_PROP_H
#define CPROVER_PROP_H

// decision procedure wrapper for boolean propositional logics

#include <vector>

#include <message.h>
#include <threeval.h>

#include "literal.h"

class propt:public virtual messaget
{
public:
  propt() { }
  virtual ~propt() { }
 
  // constants
  virtual literalt constant(bool value)=0;

  // boolean operators
  virtual literalt land(literalt a, literalt b)=0;
  virtual literalt lor(literalt a, literalt b)=0;
  virtual literalt land(const bvt &bv)=0;
  virtual literalt lor(const bvt &bv)=0;
  virtual literalt lnot(literalt a)=0;
  virtual literalt lxor(literalt a, literalt b)=0;
  virtual literalt lxor(const bvt &bv)=0;
  virtual literalt lnand(literalt a, literalt b)=0;
  virtual literalt lnor(literalt a, literalt b)=0;
  virtual literalt lequal(literalt a, literalt b)=0;
  virtual literalt limplies(literalt a, literalt b)=0;
  virtual literalt lselect(literalt a, literalt b, literalt c)=0; // a?b:c
  
  virtual bool has_set_to() { return true; }

  literalt neg(literalt a) { return lnot(a); }
  literalt pos(literalt a) { return a; }

  // constraints
  virtual void lcnf(const bvt &bv)=0;
  virtual void l_set_to(literalt a, bool value)=0;

  void l_set_to_true(literalt a)
  { l_set_to(a, true); }
  void l_set_to_false(literalt a)
  { l_set_to(a, false); }
   
  virtual void set_equal(literalt a, literalt b);

  // literals
  virtual literalt new_literal()=0;
  virtual unsigned no_literals() const=0;
  
  // solving
  virtual const std::string solver_text()=0;
  typedef enum { P_SATISFIABLE, P_UNSATISFIABLE, P_ERROR } resultt;
  virtual resultt prop_solve()=0;  
  
  // satisfying assignment
  virtual tvt l_get(literalt a) const=0;
  virtual void set_assignment(literalt a, bool value);
  virtual void copy_assignment_from(const propt &prop);

  // cores
  virtual bool is_in_core(literalt l) const;  
};

#endif
