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

#ifndef TermH
#define TermH

class Term:public Cube {
  friend class PLA;
  private:
    string OM;          // the term output. '0', '1', '-' and '~' are valid values
	//pair<bitvector, bitvector> OM_data;
	bitvector OM_data;
	bool valid;
  public:
	inline void invalidate() { valid = false; }
	inline bool invalid() { return valid == false; }
    Term(void);
    Term( unsigned int iv, unsigned int ov );
    //~Term(void);

	void clear(void);				// clears all data
	void init( const unsigned int iv, const unsigned int ov );	// assigns all DC values to the term

		// setters and getters
	void setOM_0( const unsigned int pos );		// sets one OM bit to 0
	void setOM_1( const unsigned int pos );		// sets one OM bit to 1
	void setOM_dc( const unsigned int pos );		// sets one OM bit to dc (-)
	void setOM_undef( const unsigned int pos );		// sets one OM bit to undef (~)
	bool isOM_0( const unsigned int pos ) const;	// is the OM bit 0?
	bool isOM_1( const unsigned int pos ) const;	// is the OM bit 1?
	bool isOM_dc( const unsigned int pos ) const;	// is the OM bit dc (-)?
	bool isOM_undef( const unsigned int pos ) const;	// is the OM bit undef (~)?
	unsigned int OM_size(void) const { return OM_data.size(); };
	void assignOM(Literal val);
	void assignOM( unsigned int size, Literal val );

	// Deprecated
    void setOM( const unsigned int pos, const char val );      // sets one value in the OM
    void setOM( const string val );      // sets OM
    char getOM( const unsigned int pos ) const { return OM[pos]; };
    string getOM(void) const { return OM; };
    unsigned int getOMSize(void) const { return OM.size(); };
    unsigned int getOC(void) const;
	unsigned int outputs(void) const { return OM.size(); };	// returns the number of outputs
		
 //   void DiscardDim();            //will it be needed?
    bool intersects( const Term& t ) const;					// do they intersect? Both inputs and outputs must intersect.
    int intersectSize( const Term& t ) const;					// do they intersect? Both inputs and outputs must intersect. The number of DC x non-DCs or -1 is returned
    bool intersects( const Term& t, const unsigned int _ov ) const;  // do they intersect in an output _ov?
    bool contains( const Term& t ) const;					// does it contain t? Both inputs and outputs must match
	unsigned int Relation( const Term& t ) const;			// computes more complex relations (equality, containment, intersection)
	unsigned int Relation2( const Term& t ) const;			// computes more complex relations (equality, containment, intersection). Terminates when there is no IM intersection.
    void Merge( const Term& t );							// Merge the terms by output matrices. The terms are considered to have equal IM! Only for f(d) type!

		// for debug purposes
	unsigned short origin;		// bit 0 - produced by CD-S, bit 1 - produced by FC-Min, bit 2 - produced by IE, bit 3 - produced by IR
};


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