/*****************************************************************************

  CSE 235 - Discrete Mathematics
   Fall 2005
   set.h - header file for set ADT

    You may add any member functions that you wish
    but DO NOT modify the naming conventions or method
    parameters already present here.  You may write
    additional classes/structures as you wish, but
    be sure to use good OOP style and include them in
    your makefile.


*****************************************************************************/

#include <iostream>
#include <fstream>
using namespace std;

class set
{
   private:
    
   public:

    // The default constructor.  Constructs an empty set.
    set(); 

    // The destructor.  deallocates dynamic memory.
    ~set();

    // Constructor that generates a set of size n with values
    // 1, 2, 3, ..., n
    set(int n);

    // The copy constructor.
    set(const set &S);

    // Overloaded assignment operator.
    set& operator =(const set &S);

    //-----------------------------------------------------------------------
    // Empty an existing set, allocates memory for a set of size n
    void init_set(int n);

    // Returns the cardinality of the set
    int Cardinality() const; 

    // Return true if x is an element of the set
    bool IsIn(int x) const;
        
    bool IsEmpty() const;
    
    //adds x to the set if it is not already an element
    void AddElement(int x);
    
    //removes x from the set if it is an element
    void TossElement(int x);
    
    // This should return the i-th ordered element for 
    // i = 0, 1, ..., |S| - 1
    // so that GetElement(0) returns the least element
    // GetElement(1) returns the 2nd least element, etc.
    // It should return 0 if out of range.
    int GetElement(int i) const;

    //-----------------------------------------------------------------------
    // Overload the >> operator (Read a set from a file)            
    // This method has been done for you, but you will need to implement    
    // a similar method for overloading the << operator         
    // The format of the flat file is:                      
    //      n                           
    //      L
    // where :
    // 'n' is the number of elements in the set and, 
    // L is a list of labels (ascii chracters) on a single line
    //
    // Example:  
    // The file
    // 8 
    // 82 31 28 483 1003 123 1 3
    // represents the set {1, 2, 28, 31, 82, 123, 483, 1003}
    //
    
      friend istream& operator >>(istream &in, set &S);

    //-----------------------------------------------------------------------
    // Similar to the overloaded >> above, but this takes as an argument    
    // the filename, so the details, like the filestreams, etc,         
    // are left to the class.                       
    // So if S is of type set, a user can do:               
    //      S.read("foo").                         
    // and it will read a set in from file "foo".                  

    void read(char *thefile);

    //-----------------------------------------------------------------------
    // Overload the << operator                     
    // Write a set to a file in the same format as 'read' above.        

    friend ostream& operator <<(ostream &out, const set &S);

    //-----------------------------------------------------------------------
    // Similar to the overloaded << above, but this takes as an argument    
    // the filename, so the details, like the filestreams, etc,         
    // are left to the class.                       

    void write(char *thefile) const;


};

/*
    Each of the following should return a set object that is the union, 
    intersection, difference, and symmetric difference respectively.
*/

set Union(set A, set B);
set Intersection(set A, set B);
set SetMinus(set A, set B);
set SymmDiff(set A, set B);

/*
    These next two functions will return a set similar to the 
    Cartesian product.

    SetProduct is the set of all *unique* products of pairs of 
    elements from each set.
      { (a*b) | a \in A, b \in B }

    SetSum is the set of all *unique* sums of pairs of 
    elements from each set.
      { (a+b) | a \in A, b \in B }

*/

set SetProduct(set A, set B);
set SetSum(set A, set B);

/*
    Each of the following should return true if A is a (subset, equal to 
    respectively) of B
*/

bool IsSubset(set A, set B);
bool IsEqual(set A, set B);


