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

Module:

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

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

#ifndef CPROVER_PROPDEC_LITERAL_H
#define CPROVER_PROPDEC_LITERAL_H

#include <vector>

class literalt
{
public:
  class literalt negation() const
  {
    literalt result(*this);
    result.invert();
    return result;
  }
  
  class literalt cond_negation(bool cond) const
  {
    literalt result(*this);
    result.cond_invert(cond);
    return result;
  }
  
  friend inline bool operator ==(const literalt a, const literalt b)
  {
    return a.l==b.l;
  }

  friend inline bool operator !=(const literalt a, const literalt b)
  {
    return a.l!=b.l;
  }

  // for sets  
  friend inline bool operator <(const literalt a, const literalt b)
  {
    return a.l<b.l;
  }
  
  inline unsigned var_no() const
  {
    return l>>1;
  }
  
  inline bool sign() const
  {
    return l&1;
  }
  
  inline void set(unsigned _l)
  {
    l=_l;
  }
  
  inline void set(unsigned v, bool sign)
  {
    l=(v<<1)|sign;
  }
  
  inline unsigned get() const
  {
    return l;
  }
  
  inline void invert()
  {
    l^=1;
  }
  
  inline void cond_invert(bool a)
  {
    l^=a;
  }
  
  int dimacs() const
  {
    int result=var_no();

    if(sign())
      result=-result;

    return result;
  }
  
  void from_dimacs(int d)
  {
    bool sign=d<0;
    if(sign) d=-d;
    set(d, sign);
  }
  
  void clear()
  {
    l=0;
  }
  
  void swap(literalt &x)
  {
    std::swap(x.l, l);
  }

protected:
  unsigned l;
};

typedef std::vector<literalt> bvt;

#endif
