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

#ifndef TermH
#define TermH

class Term {
  friend class PLA;
  private:
	int dim;            // dimension. -1 means that it is not computed yet. Just internally.
    string IM;           // the term. '0', '1' and '-' are valid values
    string OM;          // the term output. '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:
	int tmp;				// for different local purposes. Its value must not be modified by the kernel. It is not initialized

    Term(void);
    Term( unsigned int iv, unsigned int ov );
    ~Term(void);

		// setters and getters
    void SetIM( const unsigned int pos, const char val );      // sets one value in the IM
    void SetOM( const unsigned int pos, const char val );      // sets one value in the OM
    void SetIM( const string val );      // sets IM
    void SetOM( const string val );      // sets OM
    char GetIM( const unsigned int pos ) const { return IM[pos]; };
    char GetOM( const unsigned int pos ) const { return OM[pos]; };
    string GetIM(void) const { return IM; };
    string GetOM(void) const { return OM; };
    unsigned int GetIMSize(void) const { return IM.size(); };
    unsigned int GetOMSize(void) const { return OM.size(); };
    unsigned int GetDim(void);
    unsigned int GetOC(void) const;
	void SetUnwanted(void) { unwanted = true; };
	bool IsUnwanted(void) const { return unwanted; };
	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]; };
		
 //   void DiscardDim();            //will it be needed?
    bool Intersects( const string& s ) const;				// does it intersect a term given by a string? 
    int IntersectSize( const string& 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;					// 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
    bool Contains_noOM_Check( const Term& t ) const;		// does it contain t? Outputs are ignored
	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.
	Term Intersection( const Term& t ) const;				// returns an intersection of two terms. Outputs are ignored. The intersection must exist
    void Merge( const Term& t );							// Merge the terms by output matrices 
	bool EqualIM( const Term& t ) const;					// returns true, if IMs are equal

		// 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
