(ns e2-59-60
  (:use clojure.test)
  (:require [clojurecheck.core :as cc]))

next vs rest: rest returns an empty seq if no more elements exist, next returns nil.

(defn element-of-set? [x xs]
  (cond (empty? xs) false
        (= x (first xs)) true
        :else (element-of-set? x (rest xs))))
(defn adjoin-set [x xs]
  (if (element-of-set? x xs)
      xs
      (cons x xs)))
(defn intersection-set [xs ys]
  (cond (or (empty? xs) (empty? ys)) []
        (element-of-set? (first xs) ys)
          (cons (first xs) (intersection-set (rest xs) ys))
        :else (intersection-set (rest xs) ys)))
(defn union-set [xs ys]
  (distinct (concat xs ys)))
(deftest prop-sets
  (cc/property "element-of-set & adjoin-set"
    [s1 (cc/set (cc/int))
     s2 (cc/set (cc/int))
     i (cc/int)]
    (is (element-of-set? i (adjoin-set i s1)))
    (is (if (or (element-of-set? i s1) (element-of-set? i s2))
            (element-of-set? i (union-set s1 s2))
            true))
    (is (not (element-of-set? i [])))))
(defn adjoin-set2 [x xs]
  (cons x xs))
(defn union-set2 [xs ys]
  (concat xs ys))
(deftest prop-sets2
  (cc/property "element-of-set & adjoin-set"
    [s1 (cc/set (cc/int))
     s2 (cc/set (cc/int))
     i (cc/int)]
    (is (element-of-set? i (adjoin-set2 i s1)))
    (is (if (or (element-of-set? i s1) (element-of-set? i s2))
            (element-of-set? i (union-set2 s1 s2))
            true))))