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

Module:

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

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

#ifndef CPROVER_QDIMACS_CNF_H
#define CPROVER_QDIMACS_CNF_H

#include "dimacs_cnf.h"

#include <iostream>

class qdimacs_cnft:public dimacs_cnft
{
public:
  qdimacs_cnft() { }
  virtual ~qdimacs_cnft() { }
 
  virtual void write_qdimacs_cnf(std::ostream &out);

  // dummy functions
  
  virtual const std::string solver_text()
  {
    return "QDIMACS CNF";
  }
  
  class quantifiert
  {
  public:
    typedef enum { NONE, EXISTENTIAL, UNIVERSAL } typet;
    typet type;
    unsigned var_no;
    
    quantifiert():type(NONE), var_no(0)
    {
    }

    quantifiert(typet _type, literalt _l):type(_type), var_no(_l.var_no())
    {
    }
    
    friend bool operator==(const quantifiert &a, const quantifiert &b)
    {
      return a.type==b.type && a.var_no==b.var_no;
    }
    
    size_t hash() const
    {
      return var_no^(type<<24);
    }
  };
  
  // quantifiers
  typedef std::list<quantifiert> quantifierst;
  quantifierst quantifiers;

  void add_quantifier(const quantifiert &quantifier)
  {
    quantifiers.push_back(quantifier);
  }
  
  void add_quantifier(const quantifiert::typet type, const literalt l)
  {
    quantifiers.push_back(quantifiert(type, l));
  }
  
  friend bool operator==(const qdimacs_cnft &a, const qdimacs_cnft &b);
  
  size_t hash() const
  {
    size_t result=0;

    for(quantifierst::const_iterator it=quantifiers.begin();
        it!=quantifiers.end();
        it++)
      result=(result<<1)^it->hash()-result;
    
    return result^cnf_clause_listt::hash();
  }
  
protected:
  void write_prefix(std::ostream &out) const;
};

#endif
