; Theory of sets

(define-cond-rule sets-eq-singleton-emp ((x ?Set) (y ?))
  (= x (@set.empty_of_type (@type_of x)))
  (= x (set.singleton y))
  false)

(define-rule sets-member-singleton ((x ?) (y ?))
  (set.member x (set.singleton y))
  (= x y))

(define-cond-rule sets-member-emp ((x ?) (y ?Set))
  (= y (@set.empty_of_type (@type_of y)))
  (set.member x y)
  false)
  
(define-rule sets-subset-elim ((x ?Set) (y ?Set))
  (set.subset x y)
  (= (set.union x y) y))

(define-rule sets-union-comm ((x ?Set) (y ?Set))
  (set.union x y)
  (set.union y x))
(define-rule sets-inter-comm ((x ?Set) (y ?Set))
  (set.inter x y)
  (set.inter y x))

(define-cond-rule sets-inter-emp1 ((x ?Set) (y ?Set))
  (= x (@set.empty_of_type (@type_of x)))
  (set.inter x y)
  x)
(define-cond-rule sets-inter-emp2 ((x ?Set) (y ?Set))
  (= y (@set.empty_of_type (@type_of y)))
  (set.inter x y)
  y)
(define-cond-rule sets-minus-emp1 ((x ?Set) (y ?Set))
  (= x (@set.empty_of_type (@type_of x)))
  (set.minus x y)
  x)
(define-cond-rule sets-minus-emp2 ((x ?Set) (y ?Set))
  (= y (@set.empty_of_type (@type_of y)))
  (set.minus x y)
  x)
(define-cond-rule sets-union-emp1 ((x ?Set) (y ?Set))
  (= x (@set.empty_of_type (@type_of x)))
  (set.union x y)
  y)
(define-cond-rule sets-union-emp2 ((x ?Set) (y ?Set))
  (= y (@set.empty_of_type (@type_of y)))
  (set.union x y)
  x)

(define-rule sets-inter-member ((x ?) (y ?Set) (z ?Set))
  (set.member x (set.inter y z))
  (and (set.member x y) (set.member x z)))
(define-rule sets-minus-member ((x ?) (y ?Set) (z ?Set))
  (set.member x (set.minus y z))
  (and (set.member x y) (not (set.member x z))))
(define-rule sets-union-member ((x ?) (y ?Set) (z ?Set))
  (set.member x (set.union y z))
  (or (set.member x y) (set.member x z)))

(define-rule sets-choose-singleton ((x ?))
  (set.choose (set.singleton x))
  x)

(define-rule sets-minus-self ((x ?Set))
  (set.minus x x)
  (@set.empty_of_type (@type_of x)))

(define-rule sets-is-empty-elim ((x ?Set))
  (set.is_empty x)
  (= x (@set.empty_of_type (@type_of x))))

(define-rule sets-is-singleton-elim ((x ?Set))
  (set.is_singleton x)
  (= x (set.singleton (set.choose x))))
