(defclass s3t ()
  ((element-list :initarg :element-list :initform '() :accessor set-el)))

(defmethod s3t-insert ((s s3t) elt)
  (if (member elt (set-el s))
      (format t "Failed to insert ~A into the set.
	         All elements must be unique.  ~A
		 is already present in set~%" elt elt)
      (setf (set-el s) (cons elt (set-el s)))))

(defmethod s3t-difference ((s1 s3t) (s2 s3t))
  (set-difference (set-el s1) (set-el s2)))

(defmethod s3t-union ((s1 s3t) (s2 s3t))
  (union (set-el s1) (set-el s2)))

(defmethod s3t-intersection ((s1 s3t) (s2 s3t))
  (intersection (set-el s1) (set-el s2)))

(defmethod s3t-cartesion-product ((s1 s3t) (s2 s3t))
  (set-cross (set-el s1) (set-el s2)))

;; cartesian product helper...computes cart of two lists
(defun set-cross (s1 s2)
  (let ((res nil))
    (dolist (e s1)
      (dolist (f s2)
	(push (cons e f) res)))
    (reverse res)))

(defmethod s3t-member ((s s3t) elt)
  (member elt (set-el s)))

(defmethod s3t-compliment ((s s3t) (universe s3t))
  (s3t-difference universe s))
