1-- Singletons, pairs, power sets, unions of families, and products:2-- the basic set constructions and their laws3-- Part of Cumulus, the Grace17 mathematics library.4-- Copyright (c) 2026 Grant Passmore.5-- Released under the Apache License 2.0. See LICENSE in the repository root.6-- Authors: Grant Passmore78module Grace.Cumulus.Set.Powerset9import Algebra1011-- Singletons and pairs1213theorem singleton.subset_iff (x A : Set)14shows {x} ⊆ A ↔ x ∈ A15proof16constructor17 . intro h18exact h with x, (singleton.self at x)19 . intros h y hy20simp [singleton.membership] at hy21 rwa hy2223theorem singleton.injective (x y : Set)24requires h : {x} = {y}25shows x = y26proof27have member : x ∈ {y}28rw← h29exact singleton.self30 simpa [singleton.membership] using member3132theorem singleton.eq_iff (x y : Set)33shows {x} = {y} ↔ x = y34proof35constructor36 . intro h37exact singleton.injective with h38 . intro h39rw h40rfl4142theorem subset_singleton.cases (Y x : Set)43requires h : Y ⊆ {x}44shows Y =∅∨ Y = {x}45proof46by_contra neither47have nonempty : Y ≠∅48intro hY49apply neither50left51exact hY52obtain⟨y, hy⟩:= Nonempty.of_ne_empty with nonempty53have hyx : y ∈ {x} := h with y, hy54simp [singleton.membership] at hyx55apply neither56right57ext z58constructor59 . intro hz60exact h with z, hz61 . intro hz62simp [singleton.membership] at hz63 rwa [hz, ← hyx]6465theorem pair.commutative (x y : Set)66shows {x, y} = {y, x}67proof68ext z69simp7071theorem pair.eq_union2 (x y : Set)72shows {x, y} = {x} ∪ {y}73proof74ext z75simp7677theorem pair.self (x : Set)78shows {x, x} = {x}79proof80ext z81simp8283theorem pair.subset_iff (x y A : Set)84shows {x, y} ⊆ A ↔ x ∈ A ∧ y ∈ A85proof86constructor87 . intro h88constructor89 . exact h with x, (pair.left at x, y)90 . exact h with y, (pair.right at x, y)91 . intros h z hz92simpat hz93cases hz with hx | hy94 . rw hx95exact h.left96 . rw hy97exact h.right9899theorem singleton.subset_pair (x y : Set)100shows {x} ⊆ {x, y}101proof102simp103104theorem pair.cancel_right (a b c : Set)105requires h : {a, c} = {b, c}106shows a = b107proof108have member : a ∈ {b, c}109rw← h110exact pair.left111simpat member112cases member with hab | hac113 . exact hab114 . have other : b ∈ {a, c}115rw h116exact pair.left117simpat other118cases other with hba | hbc119 . symm120exact hba121 . rw [hac, hbc]122rfl123124theorem singleton.eq_pair_iff (x a b : Set)125shows {x} = {a, b} ↔ x = a ∧ x = b126proof127constructor128 . intro h129have inA : a ∈ {x}130rw h131exact pair.left132have inB : b ∈ {x}133rw h134exact pair.right135simp [singleton.membership] at inA136simp [singleton.membership] at inB137constructor138 . symm139exact inA140 . symm141exact inB142 . intro h143rw [← h.left, ← h.right]144 symm145exact pair.self146147theorem difference.singleton_membership (z A x : Set)148shows z ∈ A ∖ {x} ↔ z ∈ A ∧ z ≠ x149proof150simp [difference.membership, singleton.membership]151152theorem difference.singleton_of_absent (A x : Set)153requires h : ¬(x ∈ A)154shows A ∖ {x} = A155proof156ext z157simp [difference.membership, singleton.membership]158159-- Power sets160161theorem powerset.self (A : Set)162shows A ∈𝒫(A)163proof164exact powerset.membership_iff.backward with (Subset.reflexive at A)165166theorem powerset.empty_member (A : Set)167shows∅∈𝒫(A)168proof169exact powerset.membership_iff.backward with (empty.subset at A)170171theorem powerset.subset_iff (A B : Set)172shows𝒫(A) ⊆𝒫(B) ↔ A ⊆ B173proof174constructor175 . intro h176have member : A ∈𝒫(B) := h with A, (powerset.self at A)177 simpa [powerset.membership_iff] using member178 . intro h179exact powerset.monotone with h180181theorem powerset.injective (A B : Set)182requires h : 𝒫(A) =𝒫(B)183shows A = B184proof185apply Subset.antisymmetric186 . exact powerset.subset_iff.forward with (Subset.of_eq with h)187 . symm at h188exact powerset.subset_iff.forward with (Subset.of_eq with h)189190theorem powerset.intersection (A B : Set)191shows𝒫(A ∩ B) =𝒫(A) ∩𝒫(B)192proof193ext z194simp [powerset.membership_iff, intersection.membership, Subset.intersection_iff]195196theorem powerset.union2_subset (A B : Set)197shows𝒫(A) ∪𝒫(B) ⊆𝒫(A ∪ B)198proof199intros z hz200simp [union2.membership, powerset.membership_iff] at hz201simp [powerset.membership_iff]202203theorem powerset.union_subset (A : Set)204shows A ⊆𝒫(⋃(A))205proof206intros z hz207simp [powerset.membership_iff]208intros w hw209exact union.contains with hz, hw210211theorem powerset.union (A : Set)212shows⋃(𝒫(A)) = A213proof214apply Subset.antisymmetric215 . apply union.subset216intros z hz217 simpa [powerset.membership_iff] using hz218 . intros z hz219exact union.contains with (powerset.self at A), hz220221-- Unions of families222223theorem union.membership (x S : Set)224shows x ∈⋃(S) ↔∃ A ∈ S, x ∈ A225proof226simp [set.union]227228theorem union.subset_of_member (A S : Set)229requires h : A ∈ S230shows A ⊆⋃(S)231proof232intros z hz233exact union.contains with h, hz234235theorem union.monotone (S T : Set)236requires h : S ⊆ T237shows⋃(S) ⊆⋃(T)238proof239apply union.subset240intros A hA241exact union.subset_of_member with (h with A, hA)242243theorem union.pair (A B : Set)244shows⋃({A, B}) = A ∪ B245proof246apply Subset.antisymmetric247 . apply union.subset248intros C hC249simpat hC250cases hC with hA | hB251 . rw hA252exact union2.subset_left253 . rw hB254exact union2.subset_right255 . intros z hz256simp [union2.membership] at hz257cases hz with hA | hB258 . exact union.contains with (pair.left at A, B), hA259 . exact union.contains with (pair.right at A, B), hB260261theorem union.union2 (S T : Set)262shows⋃(S ∪ T) =⋃(S) ∪⋃(T)263proof264apply Subset.antisymmetric265 . apply union.subset266intros A hA267simp [union2.membership] at hA268cases hA with hS | hT269 . exact union2.subset_of_subset_left with (union.subset_of_member with hS)270 . exact union2.subset_of_subset_right with (union.subset_of_member with hT)271 . apply union2.subset272 . exact union.monotone with (union2.subset_left at S, T)273 . exact union.monotone with (union2.subset_right at S, T)274275theorem union.intersection_subset (S T : Set)276shows⋃(S ∩ T) ⊆⋃(S) ∩⋃(T)277proof278apply Subset.intersection_iff.backward279constructor280 . exact union.monotone with (intersection.subset_left at S, T)281 . exact union.monotone with (intersection.subset_right at S, T)282283theorem union.eq_empty_iff (S : Set)284shows⋃(S) =∅↔∀ A ∈ S, A =∅285proof286constructor287 . intros h A hA288apply Subset.empty_iff.forward289rw← h290exact union.subset_of_member with hA291 . intro h292apply Subset.empty_iff.forward293apply union.subset294intros A hA295have empty : A =∅:= h with A, hA296rw empty297exact Subset.reflexive298299theorem union.subset_powerset (S A : Set)300requires h : S ⊆𝒫(A)301shows⋃(S) ⊆ A302proof303apply union.subset304intros B hB305have member : B ∈𝒫(A) := h with B, hB306 simpa [powerset.membership_iff] using member307308-- Products309310theorem product.pair_membership (x y A B : Set)311shows (x, y) ∈ A × B ↔ x ∈ A ∧ y ∈ B312proof313constructor314 . intro h315simp [product.membership] at h316obtain⟨bound, a, ha, b, hb, equation⟩:= h317obtain⟨hxa, hyb⟩:= orderedPair.injective with equation318rw [hxa, hyb]319constructor320 . exact ha321 . exact hb322 . intro h323exact product.pair with h.left, h.right324325theorem product.left_empty (B : Set)326shows∅× B =∅327proof328ext p329constructor330 . intro hp331simp [product.membership] at hp332 . intro hp333exact empty.subset at∅× B with p, hp334335theorem product.right_empty (A : Set)336shows A ×∅=∅337proof338ext p339constructor340 . intro hp341simp [product.membership] at hp342 . intro hp343exact empty.subset at A ×∅with p, hp344345theorem product.eq_empty_iff (A B : Set)346shows A × B =∅↔ A =∅∨ B =∅347proof348constructor349 . intro h350by_contra neither351have hA : A ≠∅352intro hA353apply neither354left355exact hA356have hB : B ≠∅357intro hB358apply neither359right360exact hB361obtain⟨a, ha⟩:= Nonempty.of_ne_empty with hA362obtain⟨b, hb⟩:= Nonempty.of_ne_empty with hB363have member : (a, b) ∈ A × B := product.pair with ha, hb364rw h at member365 simpa using member366 . intro h367cases h with hA | hB368 . rw hA369exact product.left_empty370 . rw hB371exact product.right_empty372373theorem product.union2_left (A B C : Set)374shows (A ∪ B) × C = (A × C) ∪ (B × C)375proof376ext p377constructor378 . intro hp379simp [product.membership] at hp380obtain⟨bound, a, ha, c, hc, equation⟩:= hp381rw equation382simp [union2.membership] at ha383simp [union2.membership]384cases ha with hA | hB385 . left386exact product.pair with hA, hc387 . right388exact product.pair with hB, hc389 . intro hp390simp [union2.membership] at hp391cases hp with hAC | hBC392 . exact product.monotone at A, C, A ∪ B, C with (union2.subset_left at A, B), (Subset.reflexive at C), p, hAC393 . exact product.monotone at B, C, A ∪ B, C with (union2.subset_right at A, B), (Subset.reflexive at C), p, hBC394395theorem product.union2_right (A B C : Set)396shows A × (B ∪ C) = (A × B) ∪ (A × C)397proof398ext p399constructor400 . intro hp401simp [product.membership] at hp402obtain⟨bound, a, ha, b, hb, equation⟩:= hp403rw equation404simp [union2.membership] at hb405simp [union2.membership]406cases hb with hB | hC407 . left408exact product.pair with ha, hB409 . right410exact product.pair with ha, hC411 . intro hp412simp [union2.membership] at hp413cases hp with hAB | hAC414 . exact product.monotone at A, B, A, B ∪ C with (Subset.reflexive at A), (union2.subset_left at B, C), p, hAB415 . exact product.monotone at A, C, A, B ∪ C with (Subset.reflexive at A), (union2.subset_right at B, C), p, hAC416417theorem product.difference_left (A B C : Set)418shows (A ∖ B) × C = (A × C) ∖ (B × C)419proof420ext p421constructor422 . intro hp423obtain⟨_, a, ha, c, hc, rfl⟩:= product.membership.forward with hp424obtain⟨inA, notInB⟩:= difference.membership.forward with ha425apply difference.membership.backward426constructor427 . exact product.pair with inA, hc428 . intro inB429have coordinates := product.pair_membership.forward with inB430exact notInB with coordinates.left431 . intro hp432obtain⟨inAC, notInBC⟩:= difference.membership.forward with hp433obtain⟨_, a, ha, c, hc, rfl⟩:= product.membership.forward with inAC434have notInB : ¬a ∈ B435intro inB436exact notInBC with (product.pair with inB, hc)437have inDifference := difference.membership.backward with⟨ha, notInB⟩438exact product.pair with inDifference, hc439440theorem product.symmetricDifference_left (A B C : Set)441shows (A △ B) × C = (A × C) △ (B × C)442proof443unfold symmetricDifference444rw [product.union2_left, product.difference_left, product.difference_left]445rfl446447theorem product.intersection (A B C D : Set)448shows (A ∩ B) × (C ∩ D) = (A × C) ∩ (B × D)449proof450ext p451constructor452 . intro hp453simp [product.membership] at hp454obtain⟨bound, a, ha, c, hc, equation⟩:= hp455rw equation456simp [intersection.membership] at ha457simp [intersection.membership] at hc458simp [intersection.membership]459constructor460 . exact product.pair with ha.left, hc.left461 . exact product.pair with ha.right, hc.right462 . intro hp463simp [intersection.membership] at hp464obtain⟨hAC, hBD⟩:= hp465simp [product.membership] at hAC466obtain⟨bound, a, ha, c, hc, equation⟩:= hAC467rw equation at hBD468rw equation469have coordinates := product.pair_membership.forward with hBD470apply product.pair471 . simp [intersection.membership]472 . simp [intersection.membership]473474-- Products with disjoint factors are disjoint.475theorem product.disjoint_of_right (A B C D : Set)476requires disjoint : Disjoint(B, D)477shows Disjoint(A × B, C × D)478proof479have separated := Disjoint.iff.forward with disjoint480apply Disjoint.iff.backward481intros p hp hp2482obtain⟨bound, x, hx, y, hy, shape⟩:= product.membership.forward with hp483rw shape at hp2484have coordinates := product.pair_membership.forward with hp2485exact separated with y, hy, coordinates.right486487theorem product.disjoint_of_left (A B C D : Set)488requires disjoint : Disjoint(A, C)489shows Disjoint(A × B, C × D)490proof491have separated := Disjoint.iff.forward with disjoint492apply Disjoint.iff.backward493intros p hp hp2494obtain⟨bound, x, hx, y, hy, shape⟩:= product.membership.forward with hp495rw shape at hp2496have coordinates := product.pair_membership.forward with hp2497exact separated with x, hx, coordinates.left498499theorem product.subset_of_nonempty (A B C D : Set)500requires nonempty : Nonempty(A × B)501requires h : A × B ⊆ C × D502shows A ⊆ C ∧ B ⊆ D503proof504obtain⟨p, hp⟩:= nonempty505simp [product.membership] at hp506obtain⟨bound, a, ha, b, hb, equation⟩:= hp507constructor508 . intros x hx509have member : (x, b) ∈ C × D := h with (x, b), (product.pair with hx, hb)510have coordinates := product.pair_membership.forward with member511exact coordinates.left512 . intros y hy513have member : (a, y) ∈ C × D := h with (a, y), (product.pair with ha, hy)514have coordinates := product.pair_membership.forward with member515exact coordinates.right516517theorem product.singleton (x y : Set)518shows {x} × {y} = {(x, y)}519proof520ext p521constructor522 . intro hp523simp [product.membership] at hp524obtain⟨bound, a, ha, b, hb, equation⟩:= hp525simp [singleton.membership] at ha526simp [singleton.membership] at hb527rw [equation, ha, hb]528exact singleton.self529 . intro hp530simp [singleton.membership] at hp531rw hp532exact product.pair with (singleton.self at x), (singleton.self at y)533