//---------------------------------------------------------------------------

#ifndef CubeH
#define CubeH

class Cube {
  friend class PLA;
  friend class SoPLA;
  protected:
	int dim;            // dimension. -1 means that it is not computed yet. Just internally.
    string IM;           // the term. '0', '1' and '-' are valid values
    unsigned int index;  // index of the term
	bool unwanted;		// this one is to be deleted by Purge();
	vector<bitvector> SO_CoverVector;	// vector of source function terms, which are covered by it, for each output separately
	bitvector CoverVector;	// vector of source function terms, which are covered by it

	void SetIndex( const unsigned int val ) { index = val; };
	unsigned int GetIndex(void) const { return index; };		// !Needs not be recomputed! Do use PLA.GetIndex() instead

  public:

    Cube(void);
    Cube( unsigned int iv );
    ~Cube(void);

	int tmp;

	void clear(void);				// clears all data
	void init( unsigned int iv );	// assigns all dc values
		// setters and getters
    
	void ClearIM(void);
	void SetIM( const unsigned int pos, const char val );      // sets one value in the IM
    void SetIM( const string val );      // sets IM
    char GetIM( const unsigned int pos ) const { return IM[pos]; };
    string GetIM(void) const { return IM; };
    unsigned int GetIMSize(void) const { return IM.size(); };
    unsigned int GetDim(void);
	void SetUnwanted(void) { unwanted = true; };
	bool IsUnwanted(void) const { return unwanted; };
	unsigned int GetInputs(void) const { return IM.size(); };		// returns # of term variables

	void SetCoverVector( const bitvector _CoverVector ) { CoverVector = _CoverVector; };
	bitvector *GetCoverVector(void) { return &CoverVector; };
	void SetSO_CoverVector( const vector<bitvector> _SO_CoverVector ) { SO_CoverVector = _SO_CoverVector; };
	bitvector *GetSO_CoverVector( const unsigned int ov ) { return &SO_CoverVector[ov]; };
	vector<bitvector> *GetSO_CoverVector() { return &SO_CoverVector; };

    bool Intersects( const string &s ) const;				// does it intersect a term given by a string? 
	bool Intersects( const Cube &t ) const {return Intersects(t.IM);};				// does it intersect a term? 
    bool Contains( const string &s ) const;		// does it contain s?
	bool Contains( const Cube &t ) const { return Contains(t.GetIM()); };		// does it contain t?
	bool EqualIM( const string &s ) const { return this->IM == s;};	// returns true, if IMs are equal
	Cube Intersection( const string &s ) const;				// returns an intersection of two terms. Outputs are ignored. The intersection must exist
	int IntersectSize( const string& s ) const;
};

typedef list<Cube> CubeList;

//---------------------------------------------------------------------------
#endif
