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

#ifndef SoPLAH
#define SoPLAH

class SoPLA {
  private:
	string name;			// name of the output
	unsigned int inps;		// number of inputs
	list<Cube> data;
    bool indexed;        // are indexes valid?
	bool type;			// true = f, false = r

	bool DFF;		// true if DFF.

	vector<CubeList::iterator> indexterm;		// vector of terms, if SoPLA is indexed

	string gatename;		// type of the gate, if known. Like "and", "or", ...

	vector<string> inames;          // names of input variables. Needs not be defined

	void Reindex(void);

public:
	unsigned int tmp;				// for public use. Must not be modified by the kernel.
	unsigned int tmp1;				// for public use. Must not be modified by the kernel.

    SoPLA(void);
    SoPLA( const unsigned int iv );
	SoPLA( const unsigned int iv, const bool _type );
    SoPLA( const string s );
    SoPLA( const SoPLA *_pla );			// This is not a copying constructor! Just creates SoPLA with the same dimensions and type
	//~SoPLA(void);

	void clear(void);			// clears all the SoPLA structures
	void clearData(void);

    // setters, getters
	unsigned int inputs(void) const {return inps;};
	void setInputs( const int i );
	list<Cube> *getData() { return &data; };		// returns pointer to data
	list<Cube> &getDataRef() { return data; };		// returns reference to data
	const list<Cube> &getConstDataRef() const { return data; };		// returns const reference to data
    unsigned int getTerms(void) const { return data.size(); };
	string getIName(const unsigned int i) const;
	vector<string> getINames(void) const { return inames; };
	void setINames( const vector<string> _names ) { inames = _names; };
	void setIName(const unsigned int i, const string name);
	bool getType(void) const { return type; };
	void setType(bool _type) { type = _type; };
	bool isDFF(void) const { return DFF; };
	void setDFF(const bool _DFF) { DFF = _DFF; };
	string getName(void) const { return name; };
	void setName( const string _name ) { name = _name; };
	void setGateName( const string _name ) { gatename = _name; };
	string getGateName(void) const { return gatename; };

	list<Cube>::iterator getTerm(const unsigned int i);	// returns iterator to a term with a given index

	
	void RemoveAbsorbed(void);

	// data manipulation
	list<Cube>::iterator AppendTerm( const Cube &t );	// appends a term to the SoPLA
	list<Cube>::iterator AppendTerm( const string s );	// appends a term to the SoPLA
	list<Cube>::iterator DeleteTerm( const list<Cube>::iterator ti );   // Deletes term pointed by iterator. Returns iterator of the next one
	void AppendPLA( const SoPLA &_pla );	// appends a given PLA. Terms are copied to the end
	void Splice( SoPLA &_pla );	// appends a given PLA. Terms are copied to the end, the argument pla is cleared
	void Splice( CubeList &terms );  // appends a given term list. Terms are copied to the end, the argument term list is cleared

	// info functions

	bool empty(void) const;			// returns true if the SoPLA is empty
	unsigned int getLiterals(void);
	unsigned int getGEs(void);		// Returns GEs*2
	void RemoveAllDCCols(void);		// removes all-DC columns from the PLA

	SoPLA *Cofactor( const Cube &t ) const;


};


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