import java.util.Set;
import java.util.HashSet;
import java.util.TreeSet;
import java.util.LinkedHashSet;

class SetEquality {

    public static void main(String[] args) {
        Set a, b, c, d, e, f, g;
        a = new HashSet<>();       // elements unordered (therefore not sorted)
        b = new TreeSet<>();       // elements sorted by natural order
        c = new LinkedHashSet<>(); // elements sorted by insertion order
        d = new HashSet<>();
        e = new HashSet<>();       // this set will be left empty throughout
        f = new TreeSet<>();
        g = new TreeSet<>();
        
        a.add(1);   a.add(2);
        b.add(2);   b.add(1);   b.add(1); // no-op; element already in set
        c.add(2);   c.add(1);
        f.add(1);   f.add(2);   f.add(3);
        g.add(1);   g.add(2);   g.add(3);   g.add(4);
        
        System.out.println("a = b?\t" + a.equals(b));                   // true
        System.out.println("a = c?\t" + a.equals(c));                   // true
        System.out.println("b = c?\t" + b.equals(c));                   // true
        
        System.out.println("Size of b = " + b.size());                  // 2
        
        /*  a = [1, 2]
            b = [1, 2]
            c = [2, 1] */
        System.out.printf("a = %s\nb = %s\nc = %s\n", a, b, c);
        
        /* You can show "The set A = {φ} is not a null set because set φ is
           the element of the set." */
        d.add(e);
        System.out.println("Set containing empty set d = " + d);
        System.out.println("Size of d = " + d.size());

        /* Java's Set Interface provides a "containsAll" method that can check
            whether a provided set is a subset of another. This can be used
            to show Theorem 1. */
        System.out.println("Theorem 1: The null set φ is a subset of every"
                + " set.");
        System.out.println("a ∈ φ?\t" + a.containsAll(e));  // true
        
        /* "containsAll" can also be used to show Theorem 2 ("e). */
        System.out.println("Theorem 2: Every set is a "
                + "subset of itself i.e., A ⊆ A.");
        System.out.println("a ⊆ a?\t" + a.containsAll(a));  // true
        
        /* Demonstration of Theorem 3 */
        System.out.println("Theorem 3: If A ⊆ B and B ⊆ C, then A ⊆ C.");
        System.out.print("a ⊆ f?\t" + f.containsAll(a));    // true
        System.out.println("\t\ta = " + a);                 // a = [1, 2]
        System.out.print("f ⊆ g?\t" + g.containsAll(f));    // true
        System.out.println("\t\tf = " + f);                 // f = [1, 2, 3]
        System.out.print("a ⊆ g?\t" + g.containsAll(a));    // true
        System.out.println("\t\tg = " + g);                 // g = [1, 2, 3, 4]
        
        /* Demonstration of Theorem 4 */
        System.out.println("Theorem 4: If A ⊆ B, B ⊆ C, C ⊆ A, then A = C.");
        System.out.println("a ⊆ c?\t" + c.containsAll(a));  // true
        System.out.println("c ⊆ a?\t" + a.containsAll(c));  // true
        System.out.println("a = c?\t" + a.equals(c));       // true
        
        /* Demonstration of Theorem 5 */
        System.out.println("Theorem 5: If A ⊂ φ, then A = φ.");
        System.out.println("e ⊂ φ?\t" + 
                (new HashSet<>()).containsAll(e));          // true
        System.out.println("e = φ?\t" + 
                (new HashSet<>()).equals(e));               // true
        
        /* We can use the Set interface's "addAll" and "retainAll" methods 
            to demonstrate Theorem 6. */
        System.out.println("Theorem 6: If a ⊆ f, then a ∩ f = a and "
                + "a ∪ f = f.");
        System.out.println("(a = " + a + ") ⊆ (f = " + f + ")?\t" + 
                f.containsAll(a));                          // true
        
        f.retainAll(a);
        System.out.println("a ∩ f = " + f + " = a?\t" + f.equals(a));   // true
        // retainAll modified f so we must put the "3" back in.
        f.add(3);
        
        a.addAll(f);
        System.out.println("a ∪ f = " + a + " = f?\t" + a.equals(f));   // true
    }
    
}
