[GOAL]
α : Type u
β : α → Type v
l₁ : List (Sigma β)
h₁ : NodupKeys l₁
l₂ : List (Sigma β)
nodupKeys✝ : NodupKeys l₂
H : { entries := l₁, nodupKeys := h₁ }.entries = { entries := l₂, nodupKeys := nodupKeys✝ }.entries
⊢ { entries := l₁, nodupKeys := h₁ } = { entries := l₂, nodupKeys := nodupKeys✝ }
[PROOFSTEP]
congr
[GOAL]
α : Type u
β : α → Type v
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
xs ys : AList β
⊢ Decidable (xs = ys)
[PROOFSTEP]
rw [ext_iff]
[GOAL]
α : Type u
β : α → Type v
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
xs ys : AList β
⊢ Decidable (xs.entries = ys.entries)
[PROOFSTEP]
infer_instance
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : s₁.entries ⊆ s₂.entries
⊢ keys s₁ ⊆ keys s₂
[PROOFSTEP]
intro k hk
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : s₁.entries ⊆ s₂.entries
k : α
hk : k ∈ keys s₁
⊢ k ∈ keys s₂
[PROOFSTEP]
letI : DecidableEq α := Classical.decEq α
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : s₁.entries ⊆ s₂.entries
k : α
hk : k ∈ keys s₁
this : DecidableEq α := Classical.decEq α
⊢ k ∈ keys s₂
[PROOFSTEP]
have := h (mem_lookup_iff.1 (Option.get_mem (lookup_isSome.2 hk)))
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : s₁.entries ⊆ s₂.entries
k : α
hk : k ∈ keys s₁
this✝ : DecidableEq α := Classical.decEq α
this : { fst := k, snd := Option.get (lookup k s₁) (_ : Option.isSome (lookup k s₁) = true) } ∈ s₂.entries
⊢ k ∈ keys s₂
[PROOFSTEP]
rw [← mem_lookup_iff, Option.mem_def] at this
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : s₁.entries ⊆ s₂.entries
k : α
hk : k ∈ keys s₁
this✝¹ : DecidableEq α := Classical.decEq α
this✝ : { fst := k, snd := Option.get (lookup k s₁) (_ : Option.isSome (lookup k s₁) = true) } ∈ s₂.entries
this : lookup k s₂ = some (Option.get (lookup k s₁) (_ : Option.isSome (lookup k s₁) = true))
⊢ k ∈ keys s₂
[PROOFSTEP]
rw [← mem_keys, ← lookup_isSome, this]
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : s₁.entries ⊆ s₂.entries
k : α
hk : k ∈ keys s₁
this✝¹ : DecidableEq α := Classical.decEq α
this✝ : { fst := k, snd := Option.get (lookup k s₁) (_ : Option.isSome (lookup k s₁) = true) } ∈ s₂.entries
this : lookup k s₂ = some (Option.get (lookup k s₁) (_ : Option.isSome (lookup k s₁) = true))
⊢ Option.isSome (some (Option.get (lookup k s₁) (_ : Option.isSome (lookup k s₁) = true))) = true
[PROOFSTEP]
exact Option.isSome_some
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a a' : α
b : β a
s : AList β
⊢ a' ∈ replace a b s ↔ a' ∈ s
[PROOFSTEP]
rw [mem_keys, keys_replace, ← mem_keys]
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a a' : α
s : AList β
⊢ a' ∈ erase a s ↔ a' ≠ a ∧ a' ∈ s
[PROOFSTEP]
rw [mem_keys, keys_erase, s.keys_nodup.mem_erase_iff, ← mem_keys]
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a : α
b : β a
s : AList β
h : ¬a ∈ s
⊢ (insert a b s).entries = { fst := a, snd := b } :: s.entries
[PROOFSTEP]
rw [insert_entries, kerase_of_not_mem_keys h]
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a : α
b : β a
s : AList β
⊢ keys (insert a b s) = a :: List.erase (keys s) a
[PROOFSTEP]
simp [insert, keys, keys_kerase]
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a : α
b : β a
s₁ s₂ : AList β
p : s₁.entries ~ s₂.entries
⊢ (insert a b s₁).entries ~ (insert a b s₂).entries
[PROOFSTEP]
simp only [insert_entries]
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a : α
b : β a
s₁ s₂ : AList β
p : s₁.entries ~ s₂.entries
⊢ { fst := a, snd := b } :: kerase a s₁.entries ~ { fst := a, snd := b } :: kerase a s₂.entries
[PROOFSTEP]
exact p.kinsert s₁.nodupKeys
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a : α
b : β a
s : AList β
⊢ lookup a (insert a b s) = some b
[PROOFSTEP]
simp only [lookup, insert, dlookup_kinsert]
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a : α
s : List (Sigma β)
⊢ lookup a (toAList s) = dlookup a s
[PROOFSTEP]
rw [List.toAList, lookup, dlookup_dedupKeys]
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a : α
b b' : β a
s : AList β
⊢ insert a b' (insert a b s) = insert a b' s
[PROOFSTEP]
ext : 1
[GOAL]
case a
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a : α
b b' : β a
s : AList β
⊢ (insert a b' (insert a b s)).entries = (insert a b' s).entries
[PROOFSTEP]
simp only [AList.insert_entries, List.kerase_cons_eq]
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a a' : α
b : β a
b' : β a'
s : AList β
h : a ≠ a'
⊢ (insert a' b' (insert a b s)).entries ~ (insert a b (insert a' b' s)).entries
[PROOFSTEP]
simp only [insert_entries]
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a a' : α
b : β a
b' : β a'
s : AList β
h : a ≠ a'
⊢ { fst := a', snd := b' } :: kerase a' ({ fst := a, snd := b } :: kerase a s.entries) ~
    { fst := a, snd := b } :: kerase a ({ fst := a', snd := b' } :: kerase a' s.entries)
[PROOFSTEP]
rw [kerase_cons_ne, kerase_cons_ne, kerase_comm] <;> [apply Perm.swap; exact h; exact h.symm]
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a a' : α
b : β a
b' : β a'
s : AList β
h : a ≠ a'
⊢ { fst := a', snd := b' } :: kerase a' ({ fst := a, snd := b } :: kerase a s.entries) ~
    { fst := a, snd := b } :: kerase a ({ fst := a', snd := b' } :: kerase a' s.entries)
[PROOFSTEP]
rw [kerase_cons_ne, kerase_cons_ne, kerase_comm]
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a a' : α
b : β a
b' : β a'
s : AList β
h : a ≠ a'
⊢ { fst := a', snd := b' } :: { fst := a, snd := b } :: kerase a (kerase a' s.entries) ~
    { fst := a, snd := b } :: { fst := a', snd := b' } :: kerase a (kerase a' s.entries)
[PROOFSTEP]
apply Perm.swap
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a a' : α
b : β a
b' : β a'
s : AList β
h : a ≠ a'
⊢ a ≠ { fst := a', snd := b' }.fst
[PROOFSTEP]
exact h
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a a' : α
b : β a
b' : β a'
s : AList β
h : a ≠ a'
⊢ a' ≠ { fst := a, snd := b }.fst
[PROOFSTEP]
exact h.symm
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a : α
b b' : β a
⊢ (insert a b (singleton a b')).entries = (singleton a b).entries
[PROOFSTEP]
simp only [AList.insert_entries, List.kerase_cons_eq, and_self_iff, AList.singleton_entries, heq_iff_eq,
  eq_self_iff_true]
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
c : Sigma β
l : List (Sigma β)
h : NodupKeys (c :: l)
⊢ { entries := c :: l, nodupKeys := h } = insert c.fst c.snd { entries := l, nodupKeys := (_ : NodupKeys l) }
[PROOFSTEP]
simpa [insert] using (kerase_of_not_mem_keys <| not_mem_keys_of_nodupKeys_cons h).symm
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
C : AList β → Sort u_1
H0 : C ∅
IH : (a : α) → (b : β a) → (l : AList β) → ¬a ∈ l → C l → C (insert a b l)
c : Sigma β
l : List (Sigma β)
h : NodupKeys (c :: l)
⊢ C { entries := c :: l, nodupKeys := h }
[PROOFSTEP]
rw [mk_cons_eq_insert]
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
C : AList β → Sort u_1
H0 : C ∅
IH : (a : α) → (b : β a) → (l : AList β) → ¬a ∈ l → C l → C (insert a b l)
c : Sigma β
l : List (Sigma β)
h : NodupKeys (c :: l)
⊢ C (insert c.fst c.snd { entries := l, nodupKeys := (_ : NodupKeys l) })
[PROOFSTEP]
refine' IH _ _ _ _ (insertRec H0 IH _)
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
C : AList β → Sort u_1
H0 : C ∅
IH : (a : α) → (b : β a) → (l : AList β) → ¬a ∈ l → C l → C (insert a b l)
c : Sigma β
l : List (Sigma β)
h : NodupKeys (c :: l)
⊢ ¬c.fst ∈ { entries := l, nodupKeys := (_ : NodupKeys l) }
[PROOFSTEP]
exact not_mem_keys_of_nodupKeys_cons h
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
l : AList β
⊢ True
[PROOFSTEP]
induction l using AList.insertRec
[GOAL]
case H0
α : Type u
β : α → Type v
inst✝ : DecidableEq α
⊢ True
[PROOFSTEP]
trivial
[GOAL]
case IH
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a✝² : α
b✝ : β a✝²
l✝ : AList β
a✝¹ : ¬a✝² ∈ l✝
a✝ : True
⊢ True
[PROOFSTEP]
trivial
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
C : AList β → Sort u_1
H0 : C ∅
IH : (a : α) → (b : β a) → (l : AList β) → ¬a ∈ l → C l → C (insert a b l)
⊢ insertRec H0 IH ∅ = H0
[PROOFSTEP]
change @insertRec α β _ C H0 IH ⟨[], _⟩ = H0
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
C : AList β → Sort u_1
H0 : C ∅
IH : (a : α) → (b : β a) → (l : AList β) → ¬a ∈ l → C l → C (insert a b l)
⊢ insertRec H0 IH { entries := [], nodupKeys := (_ : NodupKeys []) } = H0
[PROOFSTEP]
rw [insertRec]
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
C : AList β → Sort u_1
H0 : C ∅
IH : (a : α) → (b : β a) → (l : AList β) → ¬a ∈ l → C l → C (insert a b l)
c : Sigma β
l : AList β
h : ¬c.fst ∈ l
⊢ insertRec H0 IH (insert c.fst c.snd l) = IH c.fst c.snd l h (insertRec H0 IH l)
[PROOFSTEP]
cases' l with l hl
[GOAL]
case mk
α : Type u
β : α → Type v
inst✝ : DecidableEq α
C : AList β → Sort u_1
H0 : C ∅
IH : (a : α) → (b : β a) → (l : AList β) → ¬a ∈ l → C l → C (insert a b l)
c : Sigma β
l : List (Sigma β)
hl : NodupKeys l
h : ¬c.fst ∈ { entries := l, nodupKeys := hl }
⊢ insertRec H0 IH (insert c.fst c.snd { entries := l, nodupKeys := hl }) =
    IH c.fst c.snd { entries := l, nodupKeys := hl } h (insertRec H0 IH { entries := l, nodupKeys := hl })
[PROOFSTEP]
suffices
  HEq (@insertRec α β _ C H0 IH ⟨c :: l, nodupKeys_cons.2 ⟨h, hl⟩⟩)
    (IH c.1 c.2 ⟨l, hl⟩ h (@insertRec α β _ C H0 IH ⟨l, hl⟩))
  by
  cases c
  apply eq_of_heq
  convert this <;> rw [insert_of_neg h]
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
C : AList β → Sort u_1
H0 : C ∅
IH : (a : α) → (b : β a) → (l : AList β) → ¬a ∈ l → C l → C (insert a b l)
c : Sigma β
l : List (Sigma β)
hl : NodupKeys l
h : ¬c.fst ∈ { entries := l, nodupKeys := hl }
this :
  HEq (insertRec H0 IH { entries := c :: l, nodupKeys := (_ : NodupKeys (c :: l)) })
    (IH c.fst c.snd { entries := l, nodupKeys := hl } h (insertRec H0 IH { entries := l, nodupKeys := hl }))
⊢ insertRec H0 IH (insert c.fst c.snd { entries := l, nodupKeys := hl }) =
    IH c.fst c.snd { entries := l, nodupKeys := hl } h (insertRec H0 IH { entries := l, nodupKeys := hl })
[PROOFSTEP]
cases c
[GOAL]
case mk
α : Type u
β : α → Type v
inst✝ : DecidableEq α
C : AList β → Sort u_1
H0 : C ∅
IH : (a : α) → (b : β a) → (l : AList β) → ¬a ∈ l → C l → C (insert a b l)
l : List (Sigma β)
hl : NodupKeys l
fst✝ : α
snd✝ : β fst✝
h : ¬{ fst := fst✝, snd := snd✝ }.fst ∈ { entries := l, nodupKeys := hl }
this :
  HEq
    (insertRec H0 IH
      { entries := { fst := fst✝, snd := snd✝ } :: l,
        nodupKeys := (_ : NodupKeys ({ fst := fst✝, snd := snd✝ } :: l)) })
    (IH { fst := fst✝, snd := snd✝ }.fst { fst := fst✝, snd := snd✝ }.snd { entries := l, nodupKeys := hl } h
      (insertRec H0 IH { entries := l, nodupKeys := hl }))
⊢ insertRec H0 IH
      (insert { fst := fst✝, snd := snd✝ }.fst { fst := fst✝, snd := snd✝ }.snd { entries := l, nodupKeys := hl }) =
    IH { fst := fst✝, snd := snd✝ }.fst { fst := fst✝, snd := snd✝ }.snd { entries := l, nodupKeys := hl } h
      (insertRec H0 IH { entries := l, nodupKeys := hl })
[PROOFSTEP]
apply eq_of_heq
[GOAL]
case mk.h
α : Type u
β : α → Type v
inst✝ : DecidableEq α
C : AList β → Sort u_1
H0 : C ∅
IH : (a : α) → (b : β a) → (l : AList β) → ¬a ∈ l → C l → C (insert a b l)
l : List (Sigma β)
hl : NodupKeys l
fst✝ : α
snd✝ : β fst✝
h : ¬{ fst := fst✝, snd := snd✝ }.fst ∈ { entries := l, nodupKeys := hl }
this :
  HEq
    (insertRec H0 IH
      { entries := { fst := fst✝, snd := snd✝ } :: l,
        nodupKeys := (_ : NodupKeys ({ fst := fst✝, snd := snd✝ } :: l)) })
    (IH { fst := fst✝, snd := snd✝ }.fst { fst := fst✝, snd := snd✝ }.snd { entries := l, nodupKeys := hl } h
      (insertRec H0 IH { entries := l, nodupKeys := hl }))
⊢ HEq
    (insertRec H0 IH
      (insert { fst := fst✝, snd := snd✝ }.fst { fst := fst✝, snd := snd✝ }.snd { entries := l, nodupKeys := hl }))
    (IH { fst := fst✝, snd := snd✝ }.fst { fst := fst✝, snd := snd✝ }.snd { entries := l, nodupKeys := hl } h
      (insertRec H0 IH { entries := l, nodupKeys := hl }))
[PROOFSTEP]
convert this
[GOAL]
case h.e'_1.h.e'_1.h.e'_3.h
α : Type u
β : α → Type v
inst✝ : DecidableEq α
C : AList β → Sort u_1
H0 : C ∅
IH : (a : α) → (b : β a) → (l : AList β) → ¬a ∈ l → C l → C (insert a b l)
l : List (Sigma β)
hl : NodupKeys l
fst✝ : α
snd✝ : β fst✝
h : ¬{ fst := fst✝, snd := snd✝ }.fst ∈ { entries := l, nodupKeys := hl }
this :
  HEq
    (insertRec H0 IH
      { entries := { fst := fst✝, snd := snd✝ } :: l,
        nodupKeys := (_ : NodupKeys ({ fst := fst✝, snd := snd✝ } :: l)) })
    (IH { fst := fst✝, snd := snd✝ }.fst { fst := fst✝, snd := snd✝ }.snd { entries := l, nodupKeys := hl } h
      (insertRec H0 IH { entries := l, nodupKeys := hl }))
⊢ (insert { fst := fst✝, snd := snd✝ }.fst { fst := fst✝, snd := snd✝ }.snd { entries := l, nodupKeys := hl }).entries =
    { fst := fst✝, snd := snd✝ } :: l
[PROOFSTEP]
rw [insert_of_neg h]
[GOAL]
case h.e'_2.e'_7.h.e'_3.h
α : Type u
β : α → Type v
inst✝ : DecidableEq α
C : AList β → Sort u_1
H0 : C ∅
IH : (a : α) → (b : β a) → (l : AList β) → ¬a ∈ l → C l → C (insert a b l)
l : List (Sigma β)
hl : NodupKeys l
fst✝ : α
snd✝ : β fst✝
h : ¬{ fst := fst✝, snd := snd✝ }.fst ∈ { entries := l, nodupKeys := hl }
this :
  HEq
    (insertRec H0 IH
      { entries := { fst := fst✝, snd := snd✝ } :: l,
        nodupKeys := (_ : NodupKeys ({ fst := fst✝, snd := snd✝ } :: l)) })
    (IH { fst := fst✝, snd := snd✝ }.fst { fst := fst✝, snd := snd✝ }.snd { entries := l, nodupKeys := hl } h
      (insertRec H0 IH { entries := l, nodupKeys := hl }))
e_1✝ :
  C (insert { fst := fst✝, snd := snd✝ }.fst { fst := fst✝, snd := snd✝ }.snd { entries := l, nodupKeys := hl }) =
    C { entries := { fst := fst✝, snd := snd✝ } :: l, nodupKeys := (_ : NodupKeys ({ fst := fst✝, snd := snd✝ } :: l)) }
⊢ (insert { fst := fst✝, snd := snd✝ }.fst { fst := fst✝, snd := snd✝ }.snd { entries := l, nodupKeys := hl }).entries =
    { fst := fst✝, snd := snd✝ } :: l
[PROOFSTEP]
rw [insert_of_neg h]
[GOAL]
case mk
α : Type u
β : α → Type v
inst✝ : DecidableEq α
C : AList β → Sort u_1
H0 : C ∅
IH : (a : α) → (b : β a) → (l : AList β) → ¬a ∈ l → C l → C (insert a b l)
c : Sigma β
l : List (Sigma β)
hl : NodupKeys l
h : ¬c.fst ∈ { entries := l, nodupKeys := hl }
⊢ HEq (insertRec H0 IH { entries := c :: l, nodupKeys := (_ : NodupKeys (c :: l)) })
    (IH c.fst c.snd { entries := l, nodupKeys := hl } h (insertRec H0 IH { entries := l, nodupKeys := hl }))
[PROOFSTEP]
rw [insertRec]
[GOAL]
case mk
α : Type u
β : α → Type v
inst✝ : DecidableEq α
C : AList β → Sort u_1
H0 : C ∅
IH : (a : α) → (b : β a) → (l : AList β) → ¬a ∈ l → C l → C (insert a b l)
c : Sigma β
l : List (Sigma β)
hl : NodupKeys l
h : ¬c.fst ∈ { entries := l, nodupKeys := hl }
⊢ HEq
    (Eq.mpr
      (_ :
        C { entries := c :: l, nodupKeys := (_ : NodupKeys (c :: l)) } =
          C (insert c.fst c.snd { entries := l, nodupKeys := (_ : NodupKeys l) }))
      (IH c.fst c.snd { entries := l, nodupKeys := (_ : NodupKeys l) }
        (_ : ¬c.fst ∈ List.keys { entries := l, nodupKeys := (_ : NodupKeys l) }.entries)
        (insertRec H0 IH { entries := l, nodupKeys := (_ : NodupKeys l) })))
    (IH c.fst c.snd { entries := l, nodupKeys := hl } h (insertRec H0 IH { entries := l, nodupKeys := hl }))
[PROOFSTEP]
apply cast_heq
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a : α
s : AList β
⊢ NodupKeys (kextract a s.entries).snd
[PROOFSTEP]
rw [kextract_eq_dlookup_kerase]
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a : α
s : AList β
⊢ NodupKeys (dlookup a s.entries, kerase a s.entries).snd
[PROOFSTEP]
exact s.nodupKeys.kerase _
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a : α
s : AList β
⊢ extract a s = (lookup a s, erase a s)
[PROOFSTEP]
simp [extract]
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a : α
s : AList β
⊢ dlookup a s.entries = lookup a s ∧
    { entries := kerase a s.entries, nodupKeys := (_ : NodupKeys (kerase a s.entries)) } = erase a s
[PROOFSTEP]
constructor
[GOAL]
case left
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a : α
s : AList β
⊢ dlookup a s.entries = lookup a s
[PROOFSTEP]
rfl
[GOAL]
case right
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a : α
s : AList β
⊢ { entries := kerase a s.entries, nodupKeys := (_ : NodupKeys (kerase a s.entries)) } = erase a s
[PROOFSTEP]
rfl
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s : AList β
⊢ (s ∪ ∅).entries = s.entries
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ s₃ s₄ : AList β
p₁₂ : s₁.entries ~ s₂.entries
p₃₄ : s₃.entries ~ s₄.entries
⊢ (s₁ ∪ s₃).entries ~ (s₂ ∪ s₄).entries
[PROOFSTEP]
simp [p₁₂.kunion s₃.nodupKeys p₃₄]
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a : α
b : β a
s₁ s₂ : AList β
⊢ insert a b (s₁ ∪ s₂) = insert a b s₁ ∪ s₂
[PROOFSTEP]
ext
[GOAL]
case a.a.a
α : Type u
β : α → Type v
inst✝ : DecidableEq α
a : α
b : β a
s₁ s₂ : AList β
n✝ : ℕ
a✝ : Sigma β
⊢ a✝ ∈ get? (insert a b (s₁ ∪ s₂)).entries n✝ ↔ a✝ ∈ get? (insert a b s₁ ∪ s₂).entries n✝
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ s₃ : AList β
⊢ ∀ (x : α) (y : β x), y ∈ dlookup x (s₁ ∪ s₂ ∪ s₃).entries ↔ y ∈ dlookup x (s₁ ∪ (s₂ ∪ s₃)).entries
[PROOFSTEP]
simp [not_or, or_assoc, and_or_left, and_assoc]
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
⊢ ∀ (x : α) (y : β x), y ∈ dlookup x (s₁ ∪ s₂).entries ↔ y ∈ dlookup x (s₂ ∪ s₁).entries
[PROOFSTEP]
intros
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
x✝ : α
y✝ : β x✝
⊢ y✝ ∈ dlookup x✝ (s₁ ∪ s₂).entries ↔ y✝ ∈ dlookup x✝ (s₂ ∪ s₁).entries
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
x✝ : α
y✝ : β x✝
⊢ dlookup x✝ s₁.entries = some y✝ ∨ ¬x✝ ∈ List.keys s₁.entries ∧ dlookup x✝ s₂.entries = some y✝ ↔
    dlookup x✝ s₂.entries = some y✝ ∨ ¬x✝ ∈ List.keys s₂.entries ∧ dlookup x✝ s₁.entries = some y✝
[PROOFSTEP]
constructor
[GOAL]
case mp
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
x✝ : α
y✝ : β x✝
⊢ dlookup x✝ s₁.entries = some y✝ ∨ ¬x✝ ∈ List.keys s₁.entries ∧ dlookup x✝ s₂.entries = some y✝ →
    dlookup x✝ s₂.entries = some y✝ ∨ ¬x✝ ∈ List.keys s₂.entries ∧ dlookup x✝ s₁.entries = some y✝
[PROOFSTEP]
intro h'
[GOAL]
case mpr
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
x✝ : α
y✝ : β x✝
⊢ dlookup x✝ s₂.entries = some y✝ ∨ ¬x✝ ∈ List.keys s₂.entries ∧ dlookup x✝ s₁.entries = some y✝ →
    dlookup x✝ s₁.entries = some y✝ ∨ ¬x✝ ∈ List.keys s₁.entries ∧ dlookup x✝ s₂.entries = some y✝
[PROOFSTEP]
intro h'
[GOAL]
case mp
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
x✝ : α
y✝ : β x✝
h' : dlookup x✝ s₁.entries = some y✝ ∨ ¬x✝ ∈ List.keys s₁.entries ∧ dlookup x✝ s₂.entries = some y✝
⊢ dlookup x✝ s₂.entries = some y✝ ∨ ¬x✝ ∈ List.keys s₂.entries ∧ dlookup x✝ s₁.entries = some y✝
[PROOFSTEP]
cases' h' with h' h'
[GOAL]
case mp.inl
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
x✝ : α
y✝ : β x✝
h' : dlookup x✝ s₁.entries = some y✝
⊢ dlookup x✝ s₂.entries = some y✝ ∨ ¬x✝ ∈ List.keys s₂.entries ∧ dlookup x✝ s₁.entries = some y✝
[PROOFSTEP]
right
[GOAL]
case mp.inl.h
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
x✝ : α
y✝ : β x✝
h' : dlookup x✝ s₁.entries = some y✝
⊢ ¬x✝ ∈ List.keys s₂.entries ∧ dlookup x✝ s₁.entries = some y✝
[PROOFSTEP]
refine' ⟨_, h'⟩
[GOAL]
case mp.inl.h
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
x✝ : α
y✝ : β x✝
h' : dlookup x✝ s₁.entries = some y✝
⊢ ¬x✝ ∈ List.keys s₂.entries
[PROOFSTEP]
apply h
[GOAL]
case mp.inl.h.a
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
x✝ : α
y✝ : β x✝
h' : dlookup x✝ s₁.entries = some y✝
⊢ x✝ ∈ keys s₁
[PROOFSTEP]
rw [keys, ← List.dlookup_isSome, h']
[GOAL]
case mp.inl.h.a
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
x✝ : α
y✝ : β x✝
h' : dlookup x✝ s₁.entries = some y✝
⊢ Option.isSome (some y✝) = true
[PROOFSTEP]
exact rfl
[GOAL]
case mp.inr
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
x✝ : α
y✝ : β x✝
h' : ¬x✝ ∈ List.keys s₁.entries ∧ dlookup x✝ s₂.entries = some y✝
⊢ dlookup x✝ s₂.entries = some y✝ ∨ ¬x✝ ∈ List.keys s₂.entries ∧ dlookup x✝ s₁.entries = some y✝
[PROOFSTEP]
left
[GOAL]
case mp.inr.h
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
x✝ : α
y✝ : β x✝
h' : ¬x✝ ∈ List.keys s₁.entries ∧ dlookup x✝ s₂.entries = some y✝
⊢ dlookup x✝ s₂.entries = some y✝
[PROOFSTEP]
rw [h'.2]
[GOAL]
case mpr
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
x✝ : α
y✝ : β x✝
h' : dlookup x✝ s₂.entries = some y✝ ∨ ¬x✝ ∈ List.keys s₂.entries ∧ dlookup x✝ s₁.entries = some y✝
⊢ dlookup x✝ s₁.entries = some y✝ ∨ ¬x✝ ∈ List.keys s₁.entries ∧ dlookup x✝ s₂.entries = some y✝
[PROOFSTEP]
cases' h' with h' h'
[GOAL]
case mpr.inl
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
x✝ : α
y✝ : β x✝
h' : dlookup x✝ s₂.entries = some y✝
⊢ dlookup x✝ s₁.entries = some y✝ ∨ ¬x✝ ∈ List.keys s₁.entries ∧ dlookup x✝ s₂.entries = some y✝
[PROOFSTEP]
right
[GOAL]
case mpr.inl.h
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
x✝ : α
y✝ : β x✝
h' : dlookup x✝ s₂.entries = some y✝
⊢ ¬x✝ ∈ List.keys s₁.entries ∧ dlookup x✝ s₂.entries = some y✝
[PROOFSTEP]
refine' ⟨_, h'⟩
[GOAL]
case mpr.inl.h
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
x✝ : α
y✝ : β x✝
h' : dlookup x✝ s₂.entries = some y✝
⊢ ¬x✝ ∈ List.keys s₁.entries
[PROOFSTEP]
intro h''
[GOAL]
case mpr.inl.h
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
x✝ : α
y✝ : β x✝
h' : dlookup x✝ s₂.entries = some y✝
h'' : x✝ ∈ List.keys s₁.entries
⊢ False
[PROOFSTEP]
apply h _ h''
[GOAL]
case mpr.inl.h
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
x✝ : α
y✝ : β x✝
h' : dlookup x✝ s₂.entries = some y✝
h'' : x✝ ∈ List.keys s₁.entries
⊢ x✝ ∈ keys s₂
[PROOFSTEP]
rw [keys, ← List.dlookup_isSome, h']
[GOAL]
case mpr.inl.h
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
x✝ : α
y✝ : β x✝
h' : dlookup x✝ s₂.entries = some y✝
h'' : x✝ ∈ List.keys s₁.entries
⊢ Option.isSome (some y✝) = true
[PROOFSTEP]
exact rfl
[GOAL]
case mpr.inr
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
x✝ : α
y✝ : β x✝
h' : ¬x✝ ∈ List.keys s₂.entries ∧ dlookup x✝ s₁.entries = some y✝
⊢ dlookup x✝ s₁.entries = some y✝ ∨ ¬x✝ ∈ List.keys s₁.entries ∧ dlookup x✝ s₂.entries = some y✝
[PROOFSTEP]
left
[GOAL]
case mpr.inr.h
α : Type u
β : α → Type v
inst✝ : DecidableEq α
s₁ s₂ : AList β
h : Disjoint s₁ s₂
x✝ : α
y✝ : β x✝
h' : ¬x✝ ∈ List.keys s₂.entries ∧ dlookup x✝ s₁.entries = some y✝
⊢ dlookup x✝ s₁.entries = some y✝
[PROOFSTEP]
rw [h'.2]


[GOAL]
X Y : MonCat
⊢ FunLike (↑X →* ↑Y) ↑X fun x => ↑Y
[PROOFSTEP]
infer_instance
  -- porting note: added
[GOAL]
G : Type u_1
inst✝ : Group G
⊢ Group ↑(of G)
[PROOFSTEP]
assumption
[GOAL]
⊢ ConcreteCategory CommMonCat
[PROOFSTEP]
dsimp only [CommMonCat]
[GOAL]
⊢ ConcreteCategory (Bundled CommMonoid)
[PROOFSTEP]
infer_instance
[GOAL]
X Y : CommMonCat
⊢ FunLike (↑X →* ↑Y) ↑X fun x => ↑Y
[PROOFSTEP]
infer_instance
  -- porting note: added
[GOAL]
R S : MonCat
i : R ⟶ S
r : ↑R
h : r = 1
⊢ ↑i r = 1
[PROOFSTEP]
simp [h]
[GOAL]
R S : CommMonCat
i : R ⟶ S
r : ↑R
h : r = 1
⊢ ↑i r = 1
[PROOFSTEP]
simp [h]
  -- We verify that when constructing a morphism in `CommMonCat`,
  -- when we construct the `toFun` field, the types are presented as `↑R`.
[GOAL]
R : CommMonCat
x : ↑R
⊢ ↑R
[PROOFSTEP]
match_target (R : Type u)
[GOAL]
R : CommMonCat
x : ↑R
⊢ ↑R
[PROOFSTEP]
guard_hyp x : (R : Type u)
[GOAL]
R : CommMonCat
x : ↑R
⊢ ↑R
[PROOFSTEP]
exact x * x
[GOAL]
R : CommMonCat
⊢ (fun x => x * x) 1 = 1
[PROOFSTEP]
simp
[GOAL]
R : CommMonCat
x y : ↑R
⊢ OneHom.toFun { toFun := fun x => x * x, map_one' := (_ : 1 * 1 = 1) } (x * y) =
    OneHom.toFun { toFun := fun x => x * x, map_one' := (_ : 1 * 1 = 1) } x *
      OneHom.toFun { toFun := fun x => x * x, map_one' := (_ : 1 * 1 = 1) } y
[PROOFSTEP]
dsimp
[GOAL]
R : CommMonCat
x y : ↑R
⊢ x * y * (x * y) = x * x * (y * y)
[PROOFSTEP]
rw [mul_assoc x y (x * y), ← mul_assoc y x y, mul_comm y x, mul_assoc, mul_assoc]
[GOAL]
X✝ Y✝ : Type u
X Y : MonCat
f : X ⟶ Y
x✝ : IsIso ((forget MonCat).map f)
⊢ IsIso f
[PROOFSTEP]
let i := asIso ((forget MonCat).map f)
[GOAL]
X✝ Y✝ : Type u
X Y : MonCat
f : X ⟶ Y
x✝ : IsIso ((forget MonCat).map f)
i : (forget MonCat).obj X ≅ (forget MonCat).obj Y := asIso ((forget MonCat).map f)
⊢ IsIso f
[PROOFSTEP]
let e : X ≃* Y := MulEquiv.mk i.toEquiv (by aesop)
[GOAL]
X✝ Y✝ : Type u
X Y : MonCat
f : X ⟶ Y
x✝ : IsIso ((forget MonCat).map f)
i : (forget MonCat).obj X ≅ (forget MonCat).obj Y := asIso ((forget MonCat).map f)
⊢ ∀ (x y : ↑X), Equiv.toFun i.toEquiv (x * y) = Equiv.toFun i.toEquiv x * Equiv.toFun i.toEquiv y
[PROOFSTEP]
aesop
[GOAL]
X✝ Y✝ : Type u
X Y : MonCat
f : X ⟶ Y
x✝ : IsIso ((forget MonCat).map f)
i : (forget MonCat).obj X ≅ (forget MonCat).obj Y := asIso ((forget MonCat).map f)
e : ↑X ≃* ↑Y := { toEquiv := i.toEquiv, map_mul' := (_ : ∀ (x_1 y : ↑X), ↑f (x_1 * y) = ↑f x_1 * ↑f y) }
⊢ IsIso f
[PROOFSTEP]
exact IsIso.of_iso e.toMonCatIso
[GOAL]
X✝ Y✝ : Type u
X Y : CommMonCat
f : X ⟶ Y
x✝ : IsIso ((forget CommMonCat).map f)
⊢ IsIso f
[PROOFSTEP]
let i := asIso ((forget CommMonCat).map f)
[GOAL]
X✝ Y✝ : Type u
X Y : CommMonCat
f : X ⟶ Y
x✝ : IsIso ((forget CommMonCat).map f)
i : (forget CommMonCat).obj X ≅ (forget CommMonCat).obj Y := asIso ((forget CommMonCat).map f)
⊢ IsIso f
[PROOFSTEP]
let e : X ≃* Y := MulEquiv.mk i.toEquiv (MonoidHom.map_mul (show MonoidHom X Y from f))
[GOAL]
X✝ Y✝ : Type u
X Y : CommMonCat
f : X ⟶ Y
x✝ : IsIso ((forget CommMonCat).map f)
i : (forget CommMonCat).obj X ≅ (forget CommMonCat).obj Y := asIso ((forget CommMonCat).map f)
e : ↑X ≃* ↑Y :=
  { toEquiv := i.toEquiv,
    map_mul' :=
      (_ :
        ∀ (a b : ↑X),
          ↑(let_fun this := f;
                this)
              (a * b) =
            ↑(let_fun this := f;
                  this)
                a *
              ↑(let_fun this := f;
                  this)
                b) }
⊢ IsIso f
[PROOFSTEP]
exact IsIso.of_iso e.toCommMonCatIso


[GOAL]
M : Type u_1
inst✝ : CommMonoid M
src✝ : Group { x // x ∈ IsUnit.submonoid M } := inferInstanceAs (Group { x // x ∈ IsUnit.submonoid M })
a b : { x // x ∈ IsUnit.submonoid M }
⊢ a * b = b * a
[PROOFSTEP]
convert mul_comm a b
[GOAL]
M : Type u_1
inst✝ : Monoid M
S : Submonoid M
a _b : M
x✝¹ : a ∈ {x | ∃ y, x * ↑y = 1}
x✝ : _b ∈ {x | ∃ y, x * ↑y = 1}
a' : { x // x ∈ S }
ha : a * ↑a' = 1
b' : { x // x ∈ S }
hb : _b * ↑b' = 1
⊢ a * _b * ↑(b' * a') = 1
[PROOFSTEP]
simp only [coe_mul, ← mul_assoc, mul_assoc a, hb, mul_one, ha]
[GOAL]
M : Type u_1
inst✝ : Monoid M
S : Submonoid M
⊢ leftInv (leftInv S) ≤ S
[PROOFSTEP]
rintro x ⟨⟨y, z, h₁⟩, h₂ : x * y = 1⟩
[GOAL]
case intro.mk.intro
M : Type u_1
inst✝ : Monoid M
S : Submonoid M
x y : M
z : { x // x ∈ S }
h₁ : y * ↑z = 1
h₂ : x * y = 1
⊢ x ∈ S
[PROOFSTEP]
convert z.prop
[GOAL]
case h.e'_4
M : Type u_1
inst✝ : Monoid M
S : Submonoid M
x y : M
z : { x // x ∈ S }
h₁ : y * ↑z = 1
h₂ : x * y = 1
⊢ x = ↑z
[PROOFSTEP]
rw [← mul_one x, ← h₁, ← mul_assoc, h₂, one_mul]
[GOAL]
M : Type u_1
inst✝ : Monoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
⊢ leftInv (leftInv S) = S
[PROOFSTEP]
refine' le_antisymm S.leftInv_leftInv_le _
[GOAL]
M : Type u_1
inst✝ : Monoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
⊢ S ≤ leftInv (leftInv S)
[PROOFSTEP]
intro x hx
[GOAL]
M : Type u_1
inst✝ : Monoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
x : M
hx : x ∈ S
⊢ x ∈ leftInv (leftInv S)
[PROOFSTEP]
have : x = ((hS hx).unit⁻¹⁻¹ : Mˣ) := by
  rw [inv_inv (hS hx).unit]
  rfl
[GOAL]
M : Type u_1
inst✝ : Monoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
x : M
hx : x ∈ S
⊢ x = ↑(IsUnit.unit (_ : x ∈ IsUnit.submonoid M))⁻¹⁻¹
[PROOFSTEP]
rw [inv_inv (hS hx).unit]
[GOAL]
M : Type u_1
inst✝ : Monoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
x : M
hx : x ∈ S
⊢ x = ↑(IsUnit.unit (_ : x ∈ IsUnit.submonoid M))
[PROOFSTEP]
rfl
[GOAL]
M : Type u_1
inst✝ : Monoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
x : M
hx : x ∈ S
this : x = ↑(IsUnit.unit (_ : x ∈ IsUnit.submonoid M))⁻¹⁻¹
⊢ x ∈ leftInv (leftInv S)
[PROOFSTEP]
rw [this]
[GOAL]
M : Type u_1
inst✝ : Monoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
x : M
hx : x ∈ S
this : x = ↑(IsUnit.unit (_ : x ∈ IsUnit.submonoid M))⁻¹⁻¹
⊢ ↑(IsUnit.unit (_ : x ∈ IsUnit.submonoid M))⁻¹⁻¹ ∈ leftInv (leftInv S)
[PROOFSTEP]
exact S.leftInv.unit_mem_leftInv _ (S.unit_mem_leftInv _ hx)
[GOAL]
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
x : { x // x ∈ leftInv S }
⊢ ↑(fromLeftInv S x) * ↑x = 1
[PROOFSTEP]
rw [mul_comm, mul_fromLeftInv]
[GOAL]
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
a : { x // x ∈ leftInv S }
b : M
⊢ ↑(fromLeftInv S a) = b ↔ ↑a * b = 1
[PROOFSTEP]
rw [← IsUnit.mul_right_inj (leftInv_le_isUnit _ a.prop), S.mul_fromLeftInv, eq_comm]
[GOAL]
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
x y : { x // x ∈ leftInv S }
⊢ ↑(OneHom.toFun { toFun := fromLeftInv S, map_one' := (_ : fromLeftInv S 1 = 1) } (x * y)) =
    ↑(OneHom.toFun { toFun := fromLeftInv S, map_one' := (_ : fromLeftInv S 1 = 1) } x *
        OneHom.toFun { toFun := fromLeftInv S, map_one' := (_ : fromLeftInv S 1 = 1) } y)
[PROOFSTEP]
rw [fromLeftInv_eq_iff, mul_comm x, Submonoid.coe_mul, Submonoid.coe_mul, mul_assoc, ← mul_assoc (x : M),
  mul_fromLeftInv, one_mul, mul_fromLeftInv]
[GOAL]
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
src✝ : { x // x ∈ leftInv S } →* { x // x ∈ S } := fromCommLeftInv S
x : { x // x ∈ S }
⊢ { x // x ∈ leftInv S }
[PROOFSTEP]
choose x' hx using hS x.prop
[GOAL]
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
src✝ : { x // x ∈ leftInv S } →* { x // x ∈ S } := fromCommLeftInv S
x : { x // x ∈ S }
x' : Mˣ
hx : ↑x' = ↑x
⊢ { x // x ∈ leftInv S }
[PROOFSTEP]
exact ⟨x'.inv, x, hx ▸ x'.inv_val⟩
[GOAL]
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
src✝ : { x // x ∈ leftInv S } →* { x // x ∈ S } := fromCommLeftInv S
x : { x // x ∈ leftInv S }
⊢ ↑((fun x =>
          (fun x' hx => { val := x'.inv, property := (_ : ∃ y, x'.inv * ↑y = 1) })
            (Classical.choose (_ : ↑x ∈ IsUnit.submonoid M))
            (_ : ↑(Classical.choose (_ : ↑x ∈ IsUnit.submonoid M)) = ↑x))
        (OneHom.toFun (↑src✝) x)) =
    ↑x
[PROOFSTEP]
dsimp only
[GOAL]
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
src✝ : { x // x ∈ leftInv S } →* { x // x ∈ S } := fromCommLeftInv S
x : { x // x ∈ leftInv S }
⊢ (Classical.choose (_ : ↑(OneHom.toFun (↑(fromCommLeftInv S)) x) ∈ IsUnit.submonoid M)).inv = ↑x
[PROOFSTEP]
generalize_proofs h
[GOAL]
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
src✝ : { x // x ∈ leftInv S } →* { x // x ∈ S } := fromCommLeftInv S
x : { x // x ∈ leftInv S }
h : ↑(OneHom.toFun (↑(fromCommLeftInv S)) x) ∈ IsUnit.submonoid M
⊢ (Classical.choose h).inv = ↑x
[PROOFSTEP]
rw [← h.choose.mul_left_inj]
[GOAL]
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
src✝ : { x // x ∈ leftInv S } →* { x // x ∈ S } := fromCommLeftInv S
x : { x // x ∈ leftInv S }
h : ↑(OneHom.toFun (↑(fromCommLeftInv S)) x) ∈ IsUnit.submonoid M
⊢ (Classical.choose h).inv * ↑(Exists.choose h) = ↑x * ↑(Exists.choose h)
[PROOFSTEP]
conv => rhs; rw [h.choose_spec]
[GOAL]
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
src✝ : { x // x ∈ leftInv S } →* { x // x ∈ S } := fromCommLeftInv S
x : { x // x ∈ leftInv S }
h : ↑(OneHom.toFun (↑(fromCommLeftInv S)) x) ∈ IsUnit.submonoid M
| (Classical.choose h).inv * ↑(Exists.choose h) = ↑x * ↑(Exists.choose h)
[PROOFSTEP]
rhs; rw [h.choose_spec]
[GOAL]
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
src✝ : { x // x ∈ leftInv S } →* { x // x ∈ S } := fromCommLeftInv S
x : { x // x ∈ leftInv S }
h : ↑(OneHom.toFun (↑(fromCommLeftInv S)) x) ∈ IsUnit.submonoid M
| (Classical.choose h).inv * ↑(Exists.choose h) = ↑x * ↑(Exists.choose h)
[PROOFSTEP]
rhs; rw [h.choose_spec]
[GOAL]
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
src✝ : { x // x ∈ leftInv S } →* { x // x ∈ S } := fromCommLeftInv S
x : { x // x ∈ leftInv S }
h : ↑(OneHom.toFun (↑(fromCommLeftInv S)) x) ∈ IsUnit.submonoid M
| (Classical.choose h).inv * ↑(Exists.choose h) = ↑x * ↑(Exists.choose h)
[PROOFSTEP]
rhs
[GOAL]
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
src✝ : { x // x ∈ leftInv S } →* { x // x ∈ S } := fromCommLeftInv S
x : { x // x ∈ leftInv S }
h : ↑(OneHom.toFun (↑(fromCommLeftInv S)) x) ∈ IsUnit.submonoid M
| ↑x * ↑(Exists.choose h)
[PROOFSTEP]
rw [h.choose_spec]
[GOAL]
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
src✝ : { x // x ∈ leftInv S } →* { x // x ∈ S } := fromCommLeftInv S
x : { x // x ∈ leftInv S }
h : ↑(OneHom.toFun (↑(fromCommLeftInv S)) x) ∈ IsUnit.submonoid M
⊢ (Classical.choose h).inv * ↑(Exists.choose h) = ↑x * ↑(OneHom.toFun (↑(fromCommLeftInv S)) x)
[PROOFSTEP]
exact h.choose.inv_val.trans (S.mul_fromLeftInv x).symm
[GOAL]
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
src✝ : { x // x ∈ leftInv S } →* { x // x ∈ S } := fromCommLeftInv S
x : { x // x ∈ S }
⊢ OneHom.toFun (↑src✝)
      ((fun x =>
          (fun x' hx => { val := x'.inv, property := (_ : ∃ y, x'.inv * ↑y = 1) })
            (Classical.choose (_ : ↑x ∈ IsUnit.submonoid M))
            (_ : ↑(Classical.choose (_ : ↑x ∈ IsUnit.submonoid M)) = ↑x))
        x) =
    x
[PROOFSTEP]
dsimp only [fromCommLeftInv]
[GOAL]
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
src✝ : { x // x ∈ leftInv S } →* { x // x ∈ S } := fromCommLeftInv S
x : { x // x ∈ S }
⊢ fromLeftInv S
      { val := (Classical.choose (_ : ↑x ∈ IsUnit.submonoid M)).inv,
        property := (_ : ∃ y, (Classical.choose (_ : ↑x ∈ IsUnit.submonoid M)).inv * ↑y = 1) } =
    x
[PROOFSTEP]
ext
[GOAL]
case a
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
src✝ : { x // x ∈ leftInv S } →* { x // x ∈ S } := fromCommLeftInv S
x : { x // x ∈ S }
⊢ ↑(fromLeftInv S
        { val := (Classical.choose (_ : ↑x ∈ IsUnit.submonoid M)).inv,
          property := (_ : ∃ y, (Classical.choose (_ : ↑x ∈ IsUnit.submonoid M)).inv * ↑y = 1) }) =
    ↑x
[PROOFSTEP]
rw [fromLeftInv_eq_iff]
[GOAL]
case a
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
src✝ : { x // x ∈ leftInv S } →* { x // x ∈ S } := fromCommLeftInv S
x : { x // x ∈ S }
⊢ ↑{ val := (Classical.choose (_ : ↑x ∈ IsUnit.submonoid M)).inv,
          property := (_ : ∃ y, (Classical.choose (_ : ↑x ∈ IsUnit.submonoid M)).inv * ↑y = 1) } *
      ↑x =
    1
[PROOFSTEP]
convert (hS x.prop).choose.inv_val
[GOAL]
case h.e'_2.h.e'_6
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
src✝ : { x // x ∈ leftInv S } →* { x // x ∈ S } := fromCommLeftInv S
x : { x // x ∈ S }
⊢ ↑x = ↑(Exists.choose (_ : ↑x ∈ IsUnit.submonoid M))
[PROOFSTEP]
exact (hS x.prop).choose_spec.symm
[GOAL]
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
x : { x // x ∈ leftInv S }
⊢ ↑(↑(leftInvEquiv S hS) x) * ↑x = 1
[PROOFSTEP]
simpa only [leftInvEquiv_apply, fromCommLeftInv] using fromLeftInv_mul S x
[GOAL]
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
x : { x // x ∈ leftInv S }
⊢ ↑x * ↑(↑(leftInvEquiv S hS) x) = 1
[PROOFSTEP]
simp only [leftInvEquiv_apply, fromCommLeftInv, mul_fromLeftInv]
[GOAL]
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
x : { x // x ∈ S }
⊢ ↑(↑(MulEquiv.symm (leftInvEquiv S hS)) x) * ↑x = 1
[PROOFSTEP]
convert S.mul_leftInvEquiv hS ((S.leftInvEquiv hS).symm x)
[GOAL]
case h.e'_2.h.e'_6.h.e'_3
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
x : { x // x ∈ S }
⊢ x = ↑(leftInvEquiv S hS) (↑(MulEquiv.symm (leftInvEquiv S hS)) x)
[PROOFSTEP]
simp
[GOAL]
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
x : { x // x ∈ S }
⊢ ↑x * ↑(↑(MulEquiv.symm (leftInvEquiv S hS)) x) = 1
[PROOFSTEP]
convert S.leftInvEquiv_mul hS ((S.leftInvEquiv hS).symm x)
[GOAL]
case h.e'_2.h.e'_5.h.e'_3
M : Type u_1
inst✝ : CommMonoid M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
x : { x // x ∈ S }
⊢ x = ↑(leftInvEquiv S hS) (↑(MulEquiv.symm (leftInvEquiv S hS)) x)
[PROOFSTEP]
simp
[GOAL]
M : Type u_1
inst✝ : Group M
S : Submonoid M
x : { x // x ∈ leftInv S }
⊢ ↑(fromLeftInv S x) = (↑x)⁻¹
[PROOFSTEP]
rw [← mul_right_inj (x : M), mul_right_inv, mul_fromLeftInv]
[GOAL]
M : Type u_1
inst✝ : CommGroup M
S : Submonoid M
hS : S ≤ IsUnit.submonoid M
x : { x // x ∈ S }
⊢ ↑(↑(MulEquiv.symm (leftInvEquiv S hS)) x) = (↑x)⁻¹
[PROOFSTEP]
rw [← mul_right_inj (x : M), mul_right_inv, mul_leftInvEquiv_symm]


[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
p : α × β → Prop
⊢ (∃ x, x ∈ s ×ˢ t ∧ p x) ↔ ∃ x, x ∈ s ∧ ∃ y, y ∈ t ∧ p (x, y)
[PROOFSTEP]
simp [and_assoc]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
⊢ s ×ˢ ∅ = ∅
[PROOFSTEP]
ext
[GOAL]
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x✝ : α × β
⊢ x✝ ∈ s ×ˢ ∅ ↔ x✝ ∈ ∅
[PROOFSTEP]
exact and_false_iff _
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
⊢ ∅ ×ˢ t = ∅
[PROOFSTEP]
ext
[GOAL]
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x✝ : α × β
⊢ x✝ ∈ ∅ ×ˢ t ↔ x✝ ∈ ∅
[PROOFSTEP]
exact false_and_iff _
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
⊢ univ ×ˢ univ = univ
[PROOFSTEP]
ext
[GOAL]
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x✝ : α × β
⊢ x✝ ∈ univ ×ˢ univ ↔ x✝ ∈ univ
[PROOFSTEP]
exact true_and_iff _
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t✝ t₁ t₂ : Set β
a : α
b : β
t : Set β
⊢ univ ×ˢ t = Prod.snd ⁻¹' t
[PROOFSTEP]
simp [prod_eq]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s✝ s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
s : Set α
⊢ s ×ˢ univ = Prod.fst ⁻¹' s
[PROOFSTEP]
simp [prod_eq]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
⊢ {a} ×ˢ t = Prod.mk a '' t
[PROOFSTEP]
ext ⟨x, y⟩
[GOAL]
case h.mk
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α
y : β
⊢ (x, y) ∈ {a} ×ˢ t ↔ (x, y) ∈ Prod.mk a '' t
[PROOFSTEP]
simp [and_left_comm, eq_comm]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
⊢ s ×ˢ {b} = (fun a => (a, b)) '' s
[PROOFSTEP]
ext ⟨x, y⟩
[GOAL]
case h.mk
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α
y : β
⊢ (x, y) ∈ s ×ˢ {b} ↔ (x, y) ∈ (fun a => (a, b)) '' s
[PROOFSTEP]
simp [and_left_comm, eq_comm]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
⊢ {a} ×ˢ {b} = {(a, b)}
[PROOFSTEP]
simp
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
⊢ (s₁ ∪ s₂) ×ˢ t = s₁ ×ˢ t ∪ s₂ ×ˢ t
[PROOFSTEP]
ext ⟨x, y⟩
[GOAL]
case h.mk
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α
y : β
⊢ (x, y) ∈ (s₁ ∪ s₂) ×ˢ t ↔ (x, y) ∈ s₁ ×ˢ t ∪ s₂ ×ˢ t
[PROOFSTEP]
simp [or_and_right]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
⊢ s ×ˢ (t₁ ∪ t₂) = s ×ˢ t₁ ∪ s ×ˢ t₂
[PROOFSTEP]
ext ⟨x, y⟩
[GOAL]
case h.mk
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α
y : β
⊢ (x, y) ∈ s ×ˢ (t₁ ∪ t₂) ↔ (x, y) ∈ s ×ˢ t₁ ∪ s ×ˢ t₂
[PROOFSTEP]
simp [and_or_left]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
⊢ (s₁ ∩ s₂) ×ˢ t = s₁ ×ˢ t ∩ s₂ ×ˢ t
[PROOFSTEP]
ext ⟨x, y⟩
[GOAL]
case h.mk
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α
y : β
⊢ (x, y) ∈ (s₁ ∩ s₂) ×ˢ t ↔ (x, y) ∈ s₁ ×ˢ t ∩ s₂ ×ˢ t
[PROOFSTEP]
simp only [← and_and_right, mem_inter_iff, mem_prod]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
⊢ s ×ˢ (t₁ ∩ t₂) = s ×ˢ t₁ ∩ s ×ˢ t₂
[PROOFSTEP]
ext ⟨x, y⟩
[GOAL]
case h.mk
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α
y : β
⊢ (x, y) ∈ s ×ˢ (t₁ ∩ t₂) ↔ (x, y) ∈ s ×ˢ t₁ ∩ s ×ˢ t₂
[PROOFSTEP]
simp only [← and_and_left, mem_inter_iff, mem_prod]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
⊢ s₁ ×ˢ t₁ ∩ s₂ ×ˢ t₂ = (s₁ ∩ s₂) ×ˢ (t₁ ∩ t₂)
[PROOFSTEP]
ext ⟨x, y⟩
[GOAL]
case h.mk
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α
y : β
⊢ (x, y) ∈ s₁ ×ˢ t₁ ∩ s₂ ×ˢ t₂ ↔ (x, y) ∈ (s₁ ∩ s₂) ×ˢ (t₁ ∩ t₂)
[PROOFSTEP]
simp [and_assoc, and_left_comm]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
⊢ Disjoint (s₁ ×ˢ t₁) (s₂ ×ˢ t₂) ↔ Disjoint s₁ s₂ ∨ Disjoint t₁ t₂
[PROOFSTEP]
simp_rw [disjoint_left, mem_prod, not_and_or, Prod.forall, and_imp, ← @forall_or_right α, ← @forall_or_left β, ←
  @forall_or_right (_ ∈ s₁), ← @forall_or_left (_ ∈ t₁)]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
⊢ insert a s ×ˢ t = Prod.mk a '' t ∪ s ×ˢ t
[PROOFSTEP]
ext ⟨x, y⟩
[GOAL]
case h.mk
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α
y : β
⊢ (x, y) ∈ insert a s ×ˢ t ↔ (x, y) ∈ Prod.mk a '' t ∪ s ×ˢ t
[PROOFSTEP]
simp (config := { contextual := true }) [image, iff_def, or_imp, Imp.swap]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
⊢ s ×ˢ insert b t = (fun a => (a, b)) '' s ∪ s ×ˢ t
[PROOFSTEP]
ext
  ⟨x, y⟩
      -- Porting note: was `simp (config := { contextual := true }) [image, iff_def, or_imp, Imp.swap]`
[GOAL]
case h.mk
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α
y : β
⊢ (x, y) ∈ s ×ˢ insert b t ↔ (x, y) ∈ (fun a => (a, b)) '' s ∪ s ×ˢ t
[PROOFSTEP]
simp [image, or_imp]
[GOAL]
case h.mk
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α
y : β
⊢ x ∈ s ∧ (y = b ∨ y ∈ t) ↔ (∃ a, a ∈ s ∧ a = x ∧ b = y) ∨ x ∈ s ∧ y ∈ t
[PROOFSTEP]
refine ⟨fun h => ?_, fun h => ?_⟩
[GOAL]
case h.mk.refine_1
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α
y : β
h : x ∈ s ∧ (y = b ∨ y ∈ t)
⊢ (∃ a, a ∈ s ∧ a = x ∧ b = y) ∨ x ∈ s ∧ y ∈ t
[PROOFSTEP]
obtain ⟨hx, rfl | hy⟩ := h
[GOAL]
case h.mk.refine_1.intro.inl
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a x : α
y : β
hx : x ∈ s
⊢ (∃ a, a ∈ s ∧ a = x ∧ y = y) ∨ x ∈ s ∧ y ∈ t
[PROOFSTEP]
exact Or.inl ⟨x, hx, rfl, rfl⟩
[GOAL]
case h.mk.refine_1.intro.inr
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α
y : β
hx : x ∈ s
hy : y ∈ t
⊢ (∃ a, a ∈ s ∧ a = x ∧ b = y) ∨ x ∈ s ∧ y ∈ t
[PROOFSTEP]
exact Or.inr ⟨hx, hy⟩
[GOAL]
case h.mk.refine_2
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α
y : β
h : (∃ a, a ∈ s ∧ a = x ∧ b = y) ∨ x ∈ s ∧ y ∈ t
⊢ x ∈ s ∧ (y = b ∨ y ∈ t)
[PROOFSTEP]
obtain ⟨x, hx, rfl, rfl⟩ | ⟨hx, hy⟩ := h
[GOAL]
case h.mk.refine_2.inl.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α
hx : x ∈ s
⊢ x ∈ s ∧ (b = b ∨ b ∈ t)
[PROOFSTEP]
exact ⟨hx, Or.inl rfl⟩
[GOAL]
case h.mk.refine_2.inr.intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α
y : β
hx : x ∈ s
hy : y ∈ t
⊢ x ∈ s ∧ (y = b ∨ y ∈ t)
[PROOFSTEP]
exact ⟨hx, Or.inr hy⟩
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
hb : b ∈ t
⊢ (fun a => (a, b)) ⁻¹' s ×ˢ t = s
[PROOFSTEP]
ext a
[GOAL]
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a✝ : α
b : β
hb : b ∈ t
a : α
⊢ a ∈ (fun a => (a, b)) ⁻¹' s ×ˢ t ↔ a ∈ s
[PROOFSTEP]
simp [hb]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
ha : a ∈ s
⊢ Prod.mk a ⁻¹' s ×ˢ t = t
[PROOFSTEP]
ext b
[GOAL]
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b✝ : β
ha : a ∈ s
b : β
⊢ b ∈ Prod.mk a ⁻¹' s ×ˢ t ↔ b ∈ t
[PROOFSTEP]
simp [ha]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
hb : ¬b ∈ t
⊢ (fun a => (a, b)) ⁻¹' s ×ˢ t = ∅
[PROOFSTEP]
ext a
[GOAL]
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a✝ : α
b : β
hb : ¬b ∈ t
a : α
⊢ a ∈ (fun a => (a, b)) ⁻¹' s ×ˢ t ↔ a ∈ ∅
[PROOFSTEP]
simp [hb]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
ha : ¬a ∈ s
⊢ Prod.mk a ⁻¹' s ×ˢ t = ∅
[PROOFSTEP]
ext b
[GOAL]
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b✝ : β
ha : ¬a ∈ s
b : β
⊢ b ∈ Prod.mk a ⁻¹' s ×ˢ t ↔ b ∈ ∅
[PROOFSTEP]
simp [ha]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
inst✝ : DecidablePred fun x => x ∈ t
⊢ (fun a => (a, b)) ⁻¹' s ×ˢ t = if b ∈ t then s else ∅
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
inst✝ : DecidablePred fun x => x ∈ t
h : b ∈ t
⊢ (fun a => (a, b)) ⁻¹' s ×ˢ t = s
[PROOFSTEP]
simp [h]
[GOAL]
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
inst✝ : DecidablePred fun x => x ∈ t
h : ¬b ∈ t
⊢ (fun a => (a, b)) ⁻¹' s ×ˢ t = ∅
[PROOFSTEP]
simp [h]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
inst✝ : DecidablePred fun x => x ∈ s
⊢ Prod.mk a ⁻¹' s ×ˢ t = if a ∈ s then t else ∅
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
inst✝ : DecidablePred fun x => x ∈ s
h : a ∈ s
⊢ Prod.mk a ⁻¹' s ×ˢ t = t
[PROOFSTEP]
simp [h]
[GOAL]
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
inst✝ : DecidablePred fun x => x ∈ s
h : ¬a ∈ s
⊢ Prod.mk a ⁻¹' s ×ˢ t = ∅
[PROOFSTEP]
simp [h]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
inst✝ : DecidablePred fun x => x ∈ t
f : γ → α
⊢ (fun a => (f a, b)) ⁻¹' s ×ˢ t = if b ∈ t then f ⁻¹' s else ∅
[PROOFSTEP]
rw [← mk_preimage_prod_left_eq_if, prod_preimage_left, preimage_preimage]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
inst✝ : DecidablePred fun x => x ∈ s
g : δ → β
⊢ (fun b => (a, g b)) ⁻¹' s ×ˢ t = if a ∈ s then g ⁻¹' t else ∅
[PROOFSTEP]
rw [← mk_preimage_prod_right_eq_if, prod_preimage_right, preimage_preimage]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s✝ s₁ s₂ : Set α
t✝ t₁ t₂ : Set β
a : α
b : β
s : Set α
t : Set β
⊢ Prod.swap ⁻¹' s ×ˢ t = t ×ˢ s
[PROOFSTEP]
ext ⟨x, y⟩
[GOAL]
case h.mk
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s✝ s₁ s₂ : Set α
t✝ t₁ t₂ : Set β
a : α
b : β
s : Set α
t : Set β
x : β
y : α
⊢ (x, y) ∈ Prod.swap ⁻¹' s ×ˢ t ↔ (x, y) ∈ t ×ˢ s
[PROOFSTEP]
simp [and_comm]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s✝ s₁ s₂ : Set α
t✝ t₁ t₂ : Set β
a : α
b : β
s : Set α
t : Set β
⊢ Prod.swap '' s ×ˢ t = t ×ˢ s
[PROOFSTEP]
rw [image_swap_eq_preimage_swap, preimage_swap_prod]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
m₁ : α → γ
m₂ : β → δ
⊢ ∀ (x : γ × δ), x ∈ (m₁ '' s) ×ˢ (m₂ '' t) ↔ x ∈ (fun p => (m₁ p.fst, m₂ p.snd)) '' s ×ˢ t
[PROOFSTEP]
simp [-exists_and_right, exists_and_right.symm, and_left_comm, and_assoc, and_comm]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
m₁ : α → γ
m₂ : β → δ
⊢ ∀ (x : γ × δ), x ∈ range m₁ ×ˢ range m₂ ↔ x ∈ range fun p => (m₁ p.fst, m₂ p.snd)
[PROOFSTEP]
simp [range]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
m₁ : α → γ
⊢ ∀ (x : γ × β), x ∈ range m₁ ×ˢ univ ↔ x ∈ range fun p => (m₁ p.fst, p.snd)
[PROOFSTEP]
simp [range]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
m₂ : β → δ
⊢ ∀ (x : α × δ), x ∈ univ ×ˢ range m₂ ↔ x ∈ range fun p => (p.fst, m₂ p.snd)
[PROOFSTEP]
simp [range]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
f : α → β
g : α → γ
⊢ (range fun x => (f x, g x)) ⊆ range f ×ˢ range g
[PROOFSTEP]
have : (fun x => (f x, g x)) = Prod.map f g ∘ fun x => (x, x) := funext fun x => rfl
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
f : α → β
g : α → γ
this : (fun x => (f x, g x)) = Prod.map f g ∘ fun x => (x, x)
⊢ (range fun x => (f x, g x)) ⊆ range f ×ˢ range g
[PROOFSTEP]
rw [this, ← range_prod_map]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
f : α → β
g : α → γ
this : (fun x => (f x, g x)) = Prod.map f g ∘ fun x => (x, x)
⊢ range (Prod.map f g ∘ fun x => (x, x)) ⊆ range (Prod.map f g)
[PROOFSTEP]
apply range_comp_subset_range
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
⊢ s ×ˢ t = ∅ ↔ s = ∅ ∨ t = ∅
[PROOFSTEP]
simp only [not_nonempty_iff_eq_empty.symm, prod_nonempty_iff, not_and_or]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
W : Set γ
f : α × β → γ
⊢ s ×ˢ t ⊆ f ⁻¹' W ↔ ∀ (a : α) (b : β), a ∈ s → b ∈ t → f (a, b) ∈ W
[PROOFSTEP]
simp [subset_def]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s✝ s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
f : α → β
g : α → γ
s : Set α
⊢ (fun x => (f x, g x)) '' s ⊆ (f '' s) ×ˢ (g '' s)
[PROOFSTEP]
rintro _ ⟨x, hx, rfl⟩
[GOAL]
case intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s✝ s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
f : α → β
g : α → γ
s : Set α
x : α
hx : x ∈ s
⊢ (fun x => (f x, g x)) x ∈ (f '' s) ×ˢ (g '' s)
[PROOFSTEP]
exact mk_mem_prod (mem_image_of_mem f hx) (mem_image_of_mem g hx)
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
hb : b ∈ t
⊢ (fun a => (a, b)) '' s ⊆ s ×ˢ t
[PROOFSTEP]
rintro _ ⟨a, ha, rfl⟩
[GOAL]
case intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a✝ : α
b : β
hb : b ∈ t
a : α
ha : a ∈ s
⊢ (fun a => (a, b)) a ∈ s ×ˢ t
[PROOFSTEP]
exact ⟨ha, hb⟩
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
ha : a ∈ s
⊢ Prod.mk a '' t ⊆ s ×ˢ t
[PROOFSTEP]
rintro _ ⟨b, hb, rfl⟩
[GOAL]
case intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b✝ : β
ha : a ∈ s
b : β
hb : b ∈ t
⊢ (a, b) ∈ s ×ˢ t
[PROOFSTEP]
exact ⟨ha, hb⟩
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
⊢ s ×ˢ t \ s₁ ×ˢ t₁ = s ×ˢ (t \ t₁) ∪ (s \ s₁) ×ˢ t
[PROOFSTEP]
ext x
[GOAL]
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α × β
⊢ x ∈ s ×ˢ t \ s₁ ×ˢ t₁ ↔ x ∈ s ×ˢ (t \ t₁) ∪ (s \ s₁) ×ˢ t
[PROOFSTEP]
by_cases h₁ : x.1 ∈ s₁
[GOAL]
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α × β
h₁ : x.fst ∈ s₁
⊢ x ∈ s ×ˢ t \ s₁ ×ˢ t₁ ↔ x ∈ s ×ˢ (t \ t₁) ∪ (s \ s₁) ×ˢ t
[PROOFSTEP]
by_cases h₂ : x.2 ∈ t₁
[GOAL]
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α × β
h₁ : ¬x.fst ∈ s₁
⊢ x ∈ s ×ˢ t \ s₁ ×ˢ t₁ ↔ x ∈ s ×ˢ (t \ t₁) ∪ (s \ s₁) ×ˢ t
[PROOFSTEP]
by_cases h₂ : x.2 ∈ t₁
[GOAL]
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α × β
h₁ : x.fst ∈ s₁
h₂ : x.snd ∈ t₁
⊢ x ∈ s ×ˢ t \ s₁ ×ˢ t₁ ↔ x ∈ s ×ˢ (t \ t₁) ∪ (s \ s₁) ×ˢ t
[PROOFSTEP]
simp [*]
[GOAL]
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α × β
h₁ : x.fst ∈ s₁
h₂ : ¬x.snd ∈ t₁
⊢ x ∈ s ×ˢ t \ s₁ ×ˢ t₁ ↔ x ∈ s ×ˢ (t \ t₁) ∪ (s \ s₁) ×ˢ t
[PROOFSTEP]
simp [*]
[GOAL]
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α × β
h₁ : ¬x.fst ∈ s₁
h₂ : x.snd ∈ t₁
⊢ x ∈ s ×ˢ t \ s₁ ×ˢ t₁ ↔ x ∈ s ×ˢ (t \ t₁) ∪ (s \ s₁) ×ˢ t
[PROOFSTEP]
simp [*]
[GOAL]
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
x : α × β
h₁ : ¬x.fst ∈ s₁
h₂ : ¬x.snd ∈ t₁
⊢ x ∈ s ×ˢ t \ s₁ ×ˢ t₁ ↔ x ∈ s ×ˢ (t \ t₁) ∪ (s \ s₁) ×ˢ t
[PROOFSTEP]
simp [*]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
⊢ s ×ˢ t ⊆ s₁ ×ˢ t₁ ↔ s ⊆ s₁ ∧ t ⊆ t₁ ∨ s = ∅ ∨ t = ∅
[PROOFSTEP]
cases' (s ×ˢ t).eq_empty_or_nonempty with h h
[GOAL]
case inl
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : s ×ˢ t = ∅
⊢ s ×ˢ t ⊆ s₁ ×ˢ t₁ ↔ s ⊆ s₁ ∧ t ⊆ t₁ ∨ s = ∅ ∨ t = ∅
[PROOFSTEP]
simp [h, prod_eq_empty_iff.1 h]
[GOAL]
case inr
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : Set.Nonempty (s ×ˢ t)
⊢ s ×ˢ t ⊆ s₁ ×ˢ t₁ ↔ s ⊆ s₁ ∧ t ⊆ t₁ ∨ s = ∅ ∨ t = ∅
[PROOFSTEP]
have st : s.Nonempty ∧ t.Nonempty := by rwa [prod_nonempty_iff] at h
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : Set.Nonempty (s ×ˢ t)
⊢ Set.Nonempty s ∧ Set.Nonempty t
[PROOFSTEP]
rwa [prod_nonempty_iff] at h
[GOAL]
case inr
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : Set.Nonempty (s ×ˢ t)
st : Set.Nonempty s ∧ Set.Nonempty t
⊢ s ×ˢ t ⊆ s₁ ×ˢ t₁ ↔ s ⊆ s₁ ∧ t ⊆ t₁ ∨ s = ∅ ∨ t = ∅
[PROOFSTEP]
refine' ⟨fun H => Or.inl ⟨_, _⟩, _⟩
[GOAL]
case inr.refine'_1
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : Set.Nonempty (s ×ˢ t)
st : Set.Nonempty s ∧ Set.Nonempty t
H : s ×ˢ t ⊆ s₁ ×ˢ t₁
⊢ s ⊆ s₁
[PROOFSTEP]
have := image_subset (Prod.fst : α × β → α) H
[GOAL]
case inr.refine'_1
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : Set.Nonempty (s ×ˢ t)
st : Set.Nonempty s ∧ Set.Nonempty t
H : s ×ˢ t ⊆ s₁ ×ˢ t₁
this : Prod.fst '' s ×ˢ t ⊆ Prod.fst '' s₁ ×ˢ t₁
⊢ s ⊆ s₁
[PROOFSTEP]
rwa [fst_image_prod _ st.2, fst_image_prod _ (h.mono H).snd] at this
[GOAL]
case inr.refine'_2
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : Set.Nonempty (s ×ˢ t)
st : Set.Nonempty s ∧ Set.Nonempty t
H : s ×ˢ t ⊆ s₁ ×ˢ t₁
⊢ t ⊆ t₁
[PROOFSTEP]
have := image_subset (Prod.snd : α × β → β) H
[GOAL]
case inr.refine'_2
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : Set.Nonempty (s ×ˢ t)
st : Set.Nonempty s ∧ Set.Nonempty t
H : s ×ˢ t ⊆ s₁ ×ˢ t₁
this : Prod.snd '' s ×ˢ t ⊆ Prod.snd '' s₁ ×ˢ t₁
⊢ t ⊆ t₁
[PROOFSTEP]
rwa [snd_image_prod st.1, snd_image_prod (h.mono H).fst] at this
[GOAL]
case inr.refine'_3
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : Set.Nonempty (s ×ˢ t)
st : Set.Nonempty s ∧ Set.Nonempty t
⊢ s ⊆ s₁ ∧ t ⊆ t₁ ∨ s = ∅ ∨ t = ∅ → s ×ˢ t ⊆ s₁ ×ˢ t₁
[PROOFSTEP]
intro H
[GOAL]
case inr.refine'_3
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : Set.Nonempty (s ×ˢ t)
st : Set.Nonempty s ∧ Set.Nonempty t
H : s ⊆ s₁ ∧ t ⊆ t₁ ∨ s = ∅ ∨ t = ∅
⊢ s ×ˢ t ⊆ s₁ ×ˢ t₁
[PROOFSTEP]
simp only [st.1.ne_empty, st.2.ne_empty, or_false_iff] at H
[GOAL]
case inr.refine'_3
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : Set.Nonempty (s ×ˢ t)
st : Set.Nonempty s ∧ Set.Nonempty t
H : s ⊆ s₁ ∧ t ⊆ t₁
⊢ s ×ˢ t ⊆ s₁ ×ˢ t₁
[PROOFSTEP]
exact prod_mono H.1 H.2
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : Set.Nonempty (s ×ˢ t)
⊢ s ×ˢ t = s₁ ×ˢ t₁ ↔ s = s₁ ∧ t = t₁
[PROOFSTEP]
constructor
[GOAL]
case mp
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : Set.Nonempty (s ×ˢ t)
⊢ s ×ˢ t = s₁ ×ˢ t₁ → s = s₁ ∧ t = t₁
[PROOFSTEP]
intro heq
[GOAL]
case mp
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : Set.Nonempty (s ×ˢ t)
heq : s ×ˢ t = s₁ ×ˢ t₁
⊢ s = s₁ ∧ t = t₁
[PROOFSTEP]
have h₁ : (s₁ ×ˢ t₁ : Set _).Nonempty := by rwa [← heq]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : Set.Nonempty (s ×ˢ t)
heq : s ×ˢ t = s₁ ×ˢ t₁
⊢ Set.Nonempty (s₁ ×ˢ t₁)
[PROOFSTEP]
rwa [← heq]
[GOAL]
case mp
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : Set.Nonempty (s ×ˢ t)
heq : s ×ˢ t = s₁ ×ˢ t₁
h₁ : Set.Nonempty (s₁ ×ˢ t₁)
⊢ s = s₁ ∧ t = t₁
[PROOFSTEP]
rw [prod_nonempty_iff] at h h₁
[GOAL]
case mp
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : Set.Nonempty s ∧ Set.Nonempty t
heq : s ×ˢ t = s₁ ×ˢ t₁
h₁ : Set.Nonempty s₁ ∧ Set.Nonempty t₁
⊢ s = s₁ ∧ t = t₁
[PROOFSTEP]
rw [← fst_image_prod s h.2, ← fst_image_prod s₁ h₁.2, heq, eq_self_iff_true, true_and_iff, ← snd_image_prod h.1 t, ←
  snd_image_prod h₁.1 t₁, heq]
[GOAL]
case mpr
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : Set.Nonempty (s ×ˢ t)
⊢ s = s₁ ∧ t = t₁ → s ×ˢ t = s₁ ×ˢ t₁
[PROOFSTEP]
rintro ⟨rfl, rfl⟩
[GOAL]
case mpr.intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₂ : Set α
t t₂ : Set β
a : α
b : β
h : Set.Nonempty (s ×ˢ t)
⊢ s ×ˢ t = s ×ˢ t
[PROOFSTEP]
rfl
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
⊢ s ×ˢ t = s₁ ×ˢ t₁ ↔ s = s₁ ∧ t = t₁ ∨ (s = ∅ ∨ t = ∅) ∧ (s₁ = ∅ ∨ t₁ = ∅)
[PROOFSTEP]
symm
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
⊢ s = s₁ ∧ t = t₁ ∨ (s = ∅ ∨ t = ∅) ∧ (s₁ = ∅ ∨ t₁ = ∅) ↔ s ×ˢ t = s₁ ×ˢ t₁
[PROOFSTEP]
cases' eq_empty_or_nonempty (s ×ˢ t) with h h
[GOAL]
case inl
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : s ×ˢ t = ∅
⊢ s = s₁ ∧ t = t₁ ∨ (s = ∅ ∨ t = ∅) ∧ (s₁ = ∅ ∨ t₁ = ∅) ↔ s ×ˢ t = s₁ ×ˢ t₁
[PROOFSTEP]
simp_rw [h, @eq_comm _ ∅, prod_eq_empty_iff, prod_eq_empty_iff.mp h, true_and_iff, or_iff_right_iff_imp]
[GOAL]
case inl
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : s ×ˢ t = ∅
⊢ s = s₁ ∧ t = t₁ → s₁ = ∅ ∨ t₁ = ∅
[PROOFSTEP]
rintro ⟨rfl, rfl⟩
[GOAL]
case inl.intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₂ : Set α
t t₂ : Set β
a : α
b : β
h : s ×ˢ t = ∅
⊢ s = ∅ ∨ t = ∅
[PROOFSTEP]
exact prod_eq_empty_iff.mp h
[GOAL]
case inr
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : Set.Nonempty (s ×ˢ t)
⊢ s = s₁ ∧ t = t₁ ∨ (s = ∅ ∨ t = ∅) ∧ (s₁ = ∅ ∨ t₁ = ∅) ↔ s ×ˢ t = s₁ ×ˢ t₁
[PROOFSTEP]
rw [prod_eq_prod_iff_of_nonempty h]
[GOAL]
case inr
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : Set.Nonempty (s ×ˢ t)
⊢ s = s₁ ∧ t = t₁ ∨ (s = ∅ ∨ t = ∅) ∧ (s₁ = ∅ ∨ t₁ = ∅) ↔ s = s₁ ∧ t = t₁
[PROOFSTEP]
rw [nonempty_iff_ne_empty, Ne.def, prod_eq_empty_iff] at h
[GOAL]
case inr
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
h : ¬(s = ∅ ∨ t = ∅)
⊢ s = s₁ ∧ t = t₁ ∨ (s = ∅ ∨ t = ∅) ∧ (s₁ = ∅ ∨ t₁ = ∅) ↔ s = s₁ ∧ t = t₁
[PROOFSTEP]
simp_rw [h, false_and_iff, or_false_iff]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
ht : Set.Nonempty t
⊢ s ×ˢ t = s₁ ×ˢ t ↔ s = s₁
[PROOFSTEP]
simp_rw [prod_eq_prod_iff, ht.ne_empty, and_true_iff, or_iff_left_iff_imp, or_false_iff]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s s₁ s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
ht : Set.Nonempty t
⊢ s = ∅ ∧ s₁ = ∅ → s = s₁
[PROOFSTEP]
rintro ⟨rfl, rfl⟩
[GOAL]
case intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
s₂ : Set α
t t₁ t₂ : Set β
a : α
b : β
ht : Set.Nonempty t
⊢ ∅ = ∅
[PROOFSTEP]
rfl
[GOAL]
α : Type u_1
s t : Set α
x : α
⊢ (x, x) ∈ diagonal α
[PROOFSTEP]
simp [diagonal]
[GOAL]
α : Type u_1
s✝ t s : Set α
⊢ (Prod.map (fun x => ↑x) fun x => ↑x) ⁻¹' diagonal α = diagonal ↑s
[PROOFSTEP]
ext ⟨⟨x, hx⟩, ⟨y, hy⟩⟩
[GOAL]
case h.mk.mk.mk
α : Type u_1
s✝ t s : Set α
x : α
hx : x ∈ s
y : α
hy : y ∈ s
⊢ ({ val := x, property := hx }, { val := y, property := hy }) ∈ (Prod.map (fun x => ↑x) fun x => ↑x) ⁻¹' diagonal α ↔
    ({ val := x, property := hx }, { val := y, property := hy }) ∈ diagonal ↑s
[PROOFSTEP]
simp [Set.diagonal]
[GOAL]
α : Type u_1
s t : Set α
⊢ (range fun x => (x, x)) = diagonal α
[PROOFSTEP]
ext ⟨x, y⟩
[GOAL]
case h.mk
α : Type u_1
s t : Set α
x y : α
⊢ ((x, y) ∈ range fun x => (x, x)) ↔ (x, y) ∈ diagonal α
[PROOFSTEP]
simp [diagonal, eq_comm]
[GOAL]
α : Type u_1
s✝ t : Set α
s : Set (α × α)
⊢ diagonal α ⊆ s ↔ ∀ (x : α), (x, x) ∈ s
[PROOFSTEP]
rw [← range_diag, range_subset_iff]
[GOAL]
α : Type u_1
s✝ t s : Set α
⊢ (fun x => (x, x)) '' s = diagonal α ∩ s ×ˢ s
[PROOFSTEP]
ext x
[GOAL]
case h
α : Type u_1
s✝ t s : Set α
x : α × α
⊢ x ∈ (fun x => (x, x)) '' s ↔ x ∈ diagonal α ∩ s ×ˢ s
[PROOFSTEP]
constructor
[GOAL]
case h.mp
α : Type u_1
s✝ t s : Set α
x : α × α
⊢ x ∈ (fun x => (x, x)) '' s → x ∈ diagonal α ∩ s ×ˢ s
[PROOFSTEP]
rintro ⟨x, hx, rfl⟩
[GOAL]
case h.mp.intro.intro
α : Type u_1
s✝ t s : Set α
x : α
hx : x ∈ s
⊢ (fun x => (x, x)) x ∈ diagonal α ∩ s ×ˢ s
[PROOFSTEP]
exact ⟨rfl, hx, hx⟩
[GOAL]
case h.mpr
α : Type u_1
s✝ t s : Set α
x : α × α
⊢ x ∈ diagonal α ∩ s ×ˢ s → x ∈ (fun x => (x, x)) '' s
[PROOFSTEP]
obtain ⟨x, y⟩ := x
[GOAL]
case h.mpr.mk
α : Type u_1
s✝ t s : Set α
x y : α
⊢ (x, y) ∈ diagonal α ∩ s ×ˢ s → (x, y) ∈ (fun x => (x, x)) '' s
[PROOFSTEP]
rintro ⟨rfl : x = y, h2x⟩
[GOAL]
case h.mpr.mk.intro
α : Type u_1
s✝ t s : Set α
x : α
h2x : (x, x) ∈ s ×ˢ s
⊢ (x, x) ∈ (fun x => (x, x)) '' s
[PROOFSTEP]
exact mem_image_of_mem _ h2x.1
[GOAL]
α : Type u_1
s t : Set α
x : α × α
a : α
⊢ Set.Nonempty (offDiag s) ↔ Set.Nontrivial s
[PROOFSTEP]
simp [offDiag, Set.Nonempty, Set.Nontrivial]
[GOAL]
α : Type u_1
s t : Set α
x : α × α
a : α
⊢ offDiag s = ∅ ↔ Set.Subsingleton s
[PROOFSTEP]
rw [← not_nonempty_iff_eq_empty, ← not_nontrivial_iff, offDiag_nonempty.not]
[GOAL]
α : Type u_1
s t : Set α
x : α × α
a : α
⊢ offDiag ∅ = ∅
[PROOFSTEP]
simp
[GOAL]
α : Type u_1
s t : Set α
x : α × α
a✝ a : α
⊢ offDiag {a} = ∅
[PROOFSTEP]
simp
[GOAL]
α : Type u_1
s t : Set α
x : α × α
a : α
⊢ ∀ (x : α × α), x ∈ offDiag univ ↔ x ∈ (diagonal α)ᶜ
[PROOFSTEP]
simp
[GOAL]
α : Type u_1
s t : Set α
x✝ : α × α
a : α
x : α × α
⊢ x ∈ offDiag (s ∩ t) ↔ x ∈ offDiag s ∩ offDiag t
[PROOFSTEP]
simp only [mem_offDiag, mem_inter_iff]
[GOAL]
α : Type u_1
s t : Set α
x✝ : α × α
a : α
x : α × α
⊢ (x.fst ∈ s ∧ x.fst ∈ t) ∧ (x.snd ∈ s ∧ x.snd ∈ t) ∧ x.fst ≠ x.snd ↔
    (x.fst ∈ s ∧ x.snd ∈ s ∧ x.fst ≠ x.snd) ∧ x.fst ∈ t ∧ x.snd ∈ t ∧ x.fst ≠ x.snd
[PROOFSTEP]
tauto
[GOAL]
α : Type u_1
s t : Set α
x : α × α
a : α
h : Disjoint s t
⊢ offDiag (s ∪ t) = offDiag s ∪ offDiag t ∪ s ×ˢ t ∪ t ×ˢ s
[PROOFSTEP]
ext x
[GOAL]
case h
α : Type u_1
s t : Set α
x✝ : α × α
a : α
h : Disjoint s t
x : α × α
⊢ x ∈ offDiag (s ∪ t) ↔ x ∈ offDiag s ∪ offDiag t ∪ s ×ˢ t ∪ t ×ˢ s
[PROOFSTEP]
simp only [mem_offDiag, mem_union, ne_eq, mem_prod]
[GOAL]
case h
α : Type u_1
s t : Set α
x✝ : α × α
a : α
h : Disjoint s t
x : α × α
⊢ (x.fst ∈ s ∨ x.fst ∈ t) ∧ (x.snd ∈ s ∨ x.snd ∈ t) ∧ ¬x.fst = x.snd ↔
    ((x.fst ∈ s ∧ x.snd ∈ s ∧ ¬x.fst = x.snd ∨ x.fst ∈ t ∧ x.snd ∈ t ∧ ¬x.fst = x.snd) ∨ x.fst ∈ s ∧ x.snd ∈ t) ∨
      x.fst ∈ t ∧ x.snd ∈ s
[PROOFSTEP]
constructor
[GOAL]
case h.mp
α : Type u_1
s t : Set α
x✝ : α × α
a : α
h : Disjoint s t
x : α × α
⊢ (x.fst ∈ s ∨ x.fst ∈ t) ∧ (x.snd ∈ s ∨ x.snd ∈ t) ∧ ¬x.fst = x.snd →
    ((x.fst ∈ s ∧ x.snd ∈ s ∧ ¬x.fst = x.snd ∨ x.fst ∈ t ∧ x.snd ∈ t ∧ ¬x.fst = x.snd) ∨ x.fst ∈ s ∧ x.snd ∈ t) ∨
      x.fst ∈ t ∧ x.snd ∈ s
[PROOFSTEP]
rintro ⟨h0 | h0, h1 | h1, h2⟩
[GOAL]
case h.mp.intro.inl.intro.inl
α : Type u_1
s t : Set α
x✝ : α × α
a : α
h : Disjoint s t
x : α × α
h0 : x.fst ∈ s
h2 : ¬x.fst = x.snd
h1 : x.snd ∈ s
⊢ ((x.fst ∈ s ∧ x.snd ∈ s ∧ ¬x.fst = x.snd ∨ x.fst ∈ t ∧ x.snd ∈ t ∧ ¬x.fst = x.snd) ∨ x.fst ∈ s ∧ x.snd ∈ t) ∨
    x.fst ∈ t ∧ x.snd ∈ s
[PROOFSTEP]
simp [h0, h1, h2]
[GOAL]
case h.mp.intro.inl.intro.inr
α : Type u_1
s t : Set α
x✝ : α × α
a : α
h : Disjoint s t
x : α × α
h0 : x.fst ∈ s
h2 : ¬x.fst = x.snd
h1 : x.snd ∈ t
⊢ ((x.fst ∈ s ∧ x.snd ∈ s ∧ ¬x.fst = x.snd ∨ x.fst ∈ t ∧ x.snd ∈ t ∧ ¬x.fst = x.snd) ∨ x.fst ∈ s ∧ x.snd ∈ t) ∨
    x.fst ∈ t ∧ x.snd ∈ s
[PROOFSTEP]
simp [h0, h1, h2]
[GOAL]
case h.mp.intro.inr.intro.inl
α : Type u_1
s t : Set α
x✝ : α × α
a : α
h : Disjoint s t
x : α × α
h0 : x.fst ∈ t
h2 : ¬x.fst = x.snd
h1 : x.snd ∈ s
⊢ ((x.fst ∈ s ∧ x.snd ∈ s ∧ ¬x.fst = x.snd ∨ x.fst ∈ t ∧ x.snd ∈ t ∧ ¬x.fst = x.snd) ∨ x.fst ∈ s ∧ x.snd ∈ t) ∨
    x.fst ∈ t ∧ x.snd ∈ s
[PROOFSTEP]
simp [h0, h1, h2]
[GOAL]
case h.mp.intro.inr.intro.inr
α : Type u_1
s t : Set α
x✝ : α × α
a : α
h : Disjoint s t
x : α × α
h0 : x.fst ∈ t
h2 : ¬x.fst = x.snd
h1 : x.snd ∈ t
⊢ ((x.fst ∈ s ∧ x.snd ∈ s ∧ ¬x.fst = x.snd ∨ x.fst ∈ t ∧ x.snd ∈ t ∧ ¬x.fst = x.snd) ∨ x.fst ∈ s ∧ x.snd ∈ t) ∨
    x.fst ∈ t ∧ x.snd ∈ s
[PROOFSTEP]
simp [h0, h1, h2]
[GOAL]
case h.mpr
α : Type u_1
s t : Set α
x✝ : α × α
a : α
h : Disjoint s t
x : α × α
⊢ ((x.fst ∈ s ∧ x.snd ∈ s ∧ ¬x.fst = x.snd ∨ x.fst ∈ t ∧ x.snd ∈ t ∧ ¬x.fst = x.snd) ∨ x.fst ∈ s ∧ x.snd ∈ t) ∨
      x.fst ∈ t ∧ x.snd ∈ s →
    (x.fst ∈ s ∨ x.fst ∈ t) ∧ (x.snd ∈ s ∨ x.snd ∈ t) ∧ ¬x.fst = x.snd
[PROOFSTEP]
rintro (((⟨h0, h1, h2⟩ | ⟨h0, h1, h2⟩) | ⟨h0, h1⟩) | ⟨h0, h1⟩)
[GOAL]
case h.mpr.inl.inl.inl.intro.intro
α : Type u_1
s t : Set α
x✝ : α × α
a : α
h : Disjoint s t
x : α × α
h0 : x.fst ∈ s
h1 : x.snd ∈ s
h2 : ¬x.fst = x.snd
⊢ (x.fst ∈ s ∨ x.fst ∈ t) ∧ (x.snd ∈ s ∨ x.snd ∈ t) ∧ ¬x.fst = x.snd
[PROOFSTEP]
simp [*]
[GOAL]
case h.mpr.inl.inl.inr.intro.intro
α : Type u_1
s t : Set α
x✝ : α × α
a : α
h : Disjoint s t
x : α × α
h0 : x.fst ∈ t
h1 : x.snd ∈ t
h2 : ¬x.fst = x.snd
⊢ (x.fst ∈ s ∨ x.fst ∈ t) ∧ (x.snd ∈ s ∨ x.snd ∈ t) ∧ ¬x.fst = x.snd
[PROOFSTEP]
simp [*]
[GOAL]
case h.mpr.inl.inr.intro
α : Type u_1
s t : Set α
x✝ : α × α
a : α
h : Disjoint s t
x : α × α
h0 : x.fst ∈ s
h1 : x.snd ∈ t
⊢ (x.fst ∈ s ∨ x.fst ∈ t) ∧ (x.snd ∈ s ∨ x.snd ∈ t) ∧ ¬x.fst = x.snd
[PROOFSTEP]
simp [*]
[GOAL]
case h.mpr.inr.intro
α : Type u_1
s t : Set α
x✝ : α × α
a : α
h : Disjoint s t
x : α × α
h0 : x.fst ∈ t
h1 : x.snd ∈ s
⊢ (x.fst ∈ s ∨ x.fst ∈ t) ∧ (x.snd ∈ s ∨ x.snd ∈ t) ∧ ¬x.fst = x.snd
[PROOFSTEP]
simp [*]
[GOAL]
case h.mpr.inl.inr.intro
α : Type u_1
s t : Set α
x✝ : α × α
a : α
h : Disjoint s t
x : α × α
h0 : x.fst ∈ s
h1 : x.snd ∈ t
⊢ ¬x.fst = x.snd
[PROOFSTEP]
rintro h3
[GOAL]
case h.mpr.inl.inr.intro
α : Type u_1
s t : Set α
x✝ : α × α
a : α
h : Disjoint s t
x : α × α
h0 : x.fst ∈ s
h1 : x.snd ∈ t
h3 : x.fst = x.snd
⊢ False
[PROOFSTEP]
rw [h3] at h0
[GOAL]
case h.mpr.inl.inr.intro
α : Type u_1
s t : Set α
x✝ : α × α
a : α
h : Disjoint s t
x : α × α
h0 : x.snd ∈ s
h1 : x.snd ∈ t
h3 : x.fst = x.snd
⊢ False
[PROOFSTEP]
exact (Set.disjoint_left.mp h h0 h1)
[GOAL]
case h.mpr.inr.intro
α : Type u_1
s t : Set α
x✝ : α × α
a : α
h : Disjoint s t
x : α × α
h0 : x.fst ∈ t
h1 : x.snd ∈ s
⊢ ¬x.fst = x.snd
[PROOFSTEP]
rintro h3
[GOAL]
case h.mpr.inr.intro
α : Type u_1
s t : Set α
x✝ : α × α
a : α
h : Disjoint s t
x : α × α
h0 : x.fst ∈ t
h1 : x.snd ∈ s
h3 : x.fst = x.snd
⊢ False
[PROOFSTEP]
rw [h3] at h0
[GOAL]
case h.mpr.inr.intro
α : Type u_1
s t : Set α
x✝ : α × α
a : α
h : Disjoint s t
x : α × α
h0 : x.snd ∈ t
h1 : x.snd ∈ s
h3 : x.fst = x.snd
⊢ False
[PROOFSTEP]
exact (Set.disjoint_right.mp h h0 h1).elim
[GOAL]
α : Type u_1
s t : Set α
x : α × α
a : α
ha : ¬a ∈ s
⊢ offDiag (insert a s) = offDiag s ∪ {a} ×ˢ s ∪ s ×ˢ {a}
[PROOFSTEP]
rw [insert_eq, union_comm, offDiag_union, offDiag_singleton, union_empty, union_right_comm]
[GOAL]
α : Type u_1
s t : Set α
x : α × α
a : α
ha : ¬a ∈ s
⊢ Disjoint s {a}
[PROOFSTEP]
rw [disjoint_left]
[GOAL]
α : Type u_1
s t : Set α
x : α × α
a : α
ha : ¬a ∈ s
⊢ ∀ ⦃a_1 : α⦄, a_1 ∈ s → ¬a_1 ∈ {a}
[PROOFSTEP]
rintro b hb (rfl : b = a)
[GOAL]
α : Type u_1
s t : Set α
x : α × α
b : α
hb : b ∈ s
ha : ¬b ∈ s
⊢ False
[PROOFSTEP]
exact ha hb
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
f : (i : ι) → α i
⊢ f ∈ pi univ t ↔ ∀ (i : ι), f i ∈ t i
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
s : (i : ι) → Set (α i)
⊢ pi ∅ s = univ
[PROOFSTEP]
ext
[GOAL]
case h
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
s : (i : ι) → Set (α i)
x✝ : (i : ι) → α i
⊢ x✝ ∈ pi ∅ s ↔ x✝ ∈ univ
[PROOFSTEP]
simp [pi]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
x : (i : ι) → α i
⊢ (x ∈ pi s fun i => t i ∩ t₁ i) ↔ x ∈ pi s t ∩ pi s t₁
[PROOFSTEP]
simp only [forall_and, mem_pi, mem_inter_iff]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
hs : i ∈ s
ht : t i = ∅
⊢ pi s t = ∅
[PROOFSTEP]
ext f
[GOAL]
case h
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
hs : i ∈ s
ht : t i = ∅
f : (i : ι) → α i
⊢ f ∈ pi s t ↔ f ∈ ∅
[PROOFSTEP]
simp only [mem_empty_iff_false, not_forall, iff_false_iff, mem_pi, not_imp]
[GOAL]
case h
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
hs : i ∈ s
ht : t i = ∅
f : (i : ι) → α i
⊢ ∃ x, x ∈ s ∧ ¬f x ∈ t x
[PROOFSTEP]
exact ⟨i, hs, by simp [ht]⟩
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
hs : i ∈ s
ht : t i = ∅
f : (i : ι) → α i
⊢ ¬f i ∈ t i
[PROOFSTEP]
simp [ht]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
⊢ Set.Nonempty (pi s t) ↔ ∀ (i : ι), ∃ x, i ∈ s → x ∈ t i
[PROOFSTEP]
simp [Classical.skolem, Set.Nonempty]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
⊢ Set.Nonempty (pi univ t) ↔ ∀ (i : ι), Set.Nonempty (t i)
[PROOFSTEP]
simp [Classical.skolem, Set.Nonempty]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
⊢ pi s t = ∅ ↔ ∃ i, IsEmpty (α i) ∨ i ∈ s ∧ t i = ∅
[PROOFSTEP]
rw [← not_nonempty_iff_eq_empty, pi_nonempty_iff]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
⊢ (¬∀ (i : ι), ∃ x, i ∈ s → x ∈ t i) ↔ ∃ i, IsEmpty (α i) ∨ i ∈ s ∧ t i = ∅
[PROOFSTEP]
push_neg
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
⊢ (∃ i, ∀ (x : α i), i ∈ s ∧ ¬x ∈ t i) ↔ ∃ i, IsEmpty (α i) ∨ i ∈ s ∧ t i = ∅
[PROOFSTEP]
refine' exists_congr fun i => _
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ i : ι
⊢ (∀ (x : α i), i ∈ s ∧ ¬x ∈ t i) ↔ IsEmpty (α i) ∨ i ∈ s ∧ t i = ∅
[PROOFSTEP]
cases isEmpty_or_nonempty (α i)
[GOAL]
case inl
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ i : ι
h✝ : IsEmpty (α i)
⊢ (∀ (x : α i), i ∈ s ∧ ¬x ∈ t i) ↔ IsEmpty (α i) ∨ i ∈ s ∧ t i = ∅
[PROOFSTEP]
simp [*, forall_and, eq_empty_iff_forall_not_mem]
[GOAL]
case inr
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ i : ι
h✝ : Nonempty (α i)
⊢ (∀ (x : α i), i ∈ s ∧ ¬x ∈ t i) ↔ IsEmpty (α i) ∨ i ∈ s ∧ t i = ∅
[PROOFSTEP]
simp [*, forall_and, eq_empty_iff_forall_not_mem]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
⊢ pi univ t = ∅ ↔ ∃ i, t i = ∅
[PROOFSTEP]
simp [← not_nonempty_iff_eq_empty, univ_pi_nonempty_iff]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
⊢ Disjoint (pi univ t₁) (pi univ t₂) ↔ ∃ i, Disjoint (t₁ i) (t₂ i)
[PROOFSTEP]
simp only [disjoint_iff_inter_eq_empty, ← pi_inter_distrib, univ_pi_eq_empty_iff]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : ∀ (i : ι), Nonempty (α i)
⊢ pi s t = ∅ ↔ ∃ i, i ∈ s ∧ t i = ∅
[PROOFSTEP]
simp [pi_eq_empty_iff]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : ∀ (i : ι), Nonempty (α i)
⊢ Disjoint (pi s t₁) (pi s t₂) ↔ ∃ i, i ∈ s ∧ Disjoint (t₁ i) (t₂ i)
[PROOFSTEP]
simp only [disjoint_iff_inter_eq_empty, ← pi_inter_distrib, pi_eq_empty_iff']
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
f : (i : ι) → α i → β i
⊢ (range fun g i => f i (g i)) = pi univ fun i => range (f i)
[PROOFSTEP]
refine Subset.antisymm ?_ fun x hx => ?_
[GOAL]
case refine_1
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
f : (i : ι) → α i → β i
⊢ (range fun g i => f i (g i)) ⊆ pi univ fun i => range (f i)
[PROOFSTEP]
rintro _ ⟨x, rfl⟩ i -
[GOAL]
case refine_1.intro
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
f : (i : ι) → α i → β i
x : (i : ι) → α i
i : ι
⊢ (fun g i => f i (g i)) x i ∈ (fun i => range (f i)) i
[PROOFSTEP]
exact ⟨x i, rfl⟩
[GOAL]
case refine_2
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
f : (i : ι) → α i → β i
x : (i : ι) → β i
hx : x ∈ pi univ fun i => range (f i)
⊢ x ∈ range fun g i => f i (g i)
[PROOFSTEP]
choose y hy using hx
[GOAL]
case refine_2
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
f : (i : ι) → α i → β i
x : (i : ι) → β i
y : (i : ι) → i ∈ univ → α i
hy : ∀ (i : ι) (a : i ∈ univ), f i (y i a) = x i
⊢ x ∈ range fun g i => f i (g i)
[PROOFSTEP]
exact ⟨fun i => y i trivial, funext fun i => hy i trivial⟩
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i✝ i : ι
s : Set ι
t : (i : ι) → Set (α i)
⊢ pi (insert i s) t = eval i ⁻¹' t i ∩ pi s t
[PROOFSTEP]
ext
[GOAL]
case h
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i✝ i : ι
s : Set ι
t : (i : ι) → Set (α i)
x✝ : (i : ι) → α i
⊢ x✝ ∈ pi (insert i s) t ↔ x✝ ∈ eval i ⁻¹' t i ∩ pi s t
[PROOFSTEP]
simp [pi, or_imp, forall_and]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i✝ i : ι
t : (i : ι) → Set (α i)
⊢ pi {i} t = eval i ⁻¹' t i
[PROOFSTEP]
ext
[GOAL]
case h
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i✝ i : ι
t : (i : ι) → Set (α i)
x✝ : (i : ι) → α i
⊢ x✝ ∈ pi {i} t ↔ x✝ ∈ eval i ⁻¹' t i
[PROOFSTEP]
simp [pi]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
f g : (i : ι) → α i
⊢ (g ∈ pi univ fun i => {f i}) ↔ g ∈ {f}
[PROOFSTEP]
simp [funext_iff]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁✝ t₂✝ : (i : ι) → Set (α i)
i : ι
p : ι → Prop
h : DecidablePred p
s : Set ι
t₁ t₂ : (i : ι) → Set (α i)
⊢ (pi s fun i => if p i then t₁ i else t₂ i) = pi {i | i ∈ s ∧ p i} t₁ ∩ pi {i | i ∈ s ∧ ¬p i} t₂
[PROOFSTEP]
ext f
[GOAL]
case h
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁✝ t₂✝ : (i : ι) → Set (α i)
i : ι
p : ι → Prop
h : DecidablePred p
s : Set ι
t₁ t₂ : (i : ι) → Set (α i)
f : (i : ι) → α i
⊢ (f ∈ pi s fun i => if p i then t₁ i else t₂ i) ↔ f ∈ pi {i | i ∈ s ∧ p i} t₁ ∩ pi {i | i ∈ s ∧ ¬p i} t₂
[PROOFSTEP]
refine' ⟨fun h => _, _⟩
[GOAL]
case h.refine'_1
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁✝ t₂✝ : (i : ι) → Set (α i)
i : ι
p : ι → Prop
h✝ : DecidablePred p
s : Set ι
t₁ t₂ : (i : ι) → Set (α i)
f : (i : ι) → α i
h : f ∈ pi s fun i => if p i then t₁ i else t₂ i
⊢ f ∈ pi {i | i ∈ s ∧ p i} t₁ ∩ pi {i | i ∈ s ∧ ¬p i} t₂
[PROOFSTEP]
constructor
[GOAL]
case h.refine'_1.left
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁✝ t₂✝ : (i : ι) → Set (α i)
i : ι
p : ι → Prop
h✝ : DecidablePred p
s : Set ι
t₁ t₂ : (i : ι) → Set (α i)
f : (i : ι) → α i
h : f ∈ pi s fun i => if p i then t₁ i else t₂ i
⊢ f ∈ pi {i | i ∈ s ∧ p i} t₁
[PROOFSTEP]
rintro i ⟨his, hpi⟩
[GOAL]
case h.refine'_1.left.intro
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁✝ t₂✝ : (i : ι) → Set (α i)
i✝ : ι
p : ι → Prop
h✝ : DecidablePred p
s : Set ι
t₁ t₂ : (i : ι) → Set (α i)
f : (i : ι) → α i
h : f ∈ pi s fun i => if p i then t₁ i else t₂ i
i : ι
his : i ∈ s
hpi : p i
⊢ f i ∈ t₁ i
[PROOFSTEP]
simpa [*] using h i
[GOAL]
case h.refine'_1.right
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁✝ t₂✝ : (i : ι) → Set (α i)
i : ι
p : ι → Prop
h✝ : DecidablePred p
s : Set ι
t₁ t₂ : (i : ι) → Set (α i)
f : (i : ι) → α i
h : f ∈ pi s fun i => if p i then t₁ i else t₂ i
⊢ f ∈ pi {i | i ∈ s ∧ ¬p i} t₂
[PROOFSTEP]
rintro i ⟨his, hpi⟩
[GOAL]
case h.refine'_1.right.intro
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁✝ t₂✝ : (i : ι) → Set (α i)
i✝ : ι
p : ι → Prop
h✝ : DecidablePred p
s : Set ι
t₁ t₂ : (i : ι) → Set (α i)
f : (i : ι) → α i
h : f ∈ pi s fun i => if p i then t₁ i else t₂ i
i : ι
his : i ∈ s
hpi : ¬p i
⊢ f i ∈ t₂ i
[PROOFSTEP]
simpa [*] using h i
[GOAL]
case h.refine'_2
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁✝ t₂✝ : (i : ι) → Set (α i)
i : ι
p : ι → Prop
h : DecidablePred p
s : Set ι
t₁ t₂ : (i : ι) → Set (α i)
f : (i : ι) → α i
⊢ f ∈ pi {i | i ∈ s ∧ p i} t₁ ∩ pi {i | i ∈ s ∧ ¬p i} t₂ → f ∈ pi s fun i => if p i then t₁ i else t₂ i
[PROOFSTEP]
rintro ⟨ht₁, ht₂⟩ i his
[GOAL]
case h.refine'_2.intro
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁✝ t₂✝ : (i : ι) → Set (α i)
i✝ : ι
p : ι → Prop
h : DecidablePred p
s : Set ι
t₁ t₂ : (i : ι) → Set (α i)
f : (i : ι) → α i
ht₁ : f ∈ pi {i | i ∈ s ∧ p i} t₁
ht₂ : f ∈ pi {i | i ∈ s ∧ ¬p i} t₂
i : ι
his : i ∈ s
⊢ f i ∈ (fun i => if p i then t₁ i else t₂ i) i
[PROOFSTEP]
by_cases p i
[GOAL]
case h.refine'_2.intro
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁✝ t₂✝ : (i : ι) → Set (α i)
i✝ : ι
p : ι → Prop
h : DecidablePred p
s : Set ι
t₁ t₂ : (i : ι) → Set (α i)
f : (i : ι) → α i
ht₁ : f ∈ pi {i | i ∈ s ∧ p i} t₁
ht₂ : f ∈ pi {i | i ∈ s ∧ ¬p i} t₂
i : ι
his : i ∈ s
⊢ f i ∈ (fun i => if p i then t₁ i else t₂ i) i
[PROOFSTEP]
by_cases p i
[GOAL]
case pos
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁✝ t₂✝ : (i : ι) → Set (α i)
i✝ : ι
p : ι → Prop
h✝ : DecidablePred p
s : Set ι
t₁ t₂ : (i : ι) → Set (α i)
f : (i : ι) → α i
ht₁ : f ∈ pi {i | i ∈ s ∧ p i} t₁
ht₂ : f ∈ pi {i | i ∈ s ∧ ¬p i} t₂
i : ι
his : i ∈ s
h : p i
⊢ f i ∈ (fun i => if p i then t₁ i else t₂ i) i
[PROOFSTEP]
simp_all
[GOAL]
case neg
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁✝ t₂✝ : (i : ι) → Set (α i)
i✝ : ι
p : ι → Prop
h✝ : DecidablePred p
s : Set ι
t₁ t₂ : (i : ι) → Set (α i)
f : (i : ι) → α i
ht₁ : f ∈ pi {i | i ∈ s ∧ p i} t₁
ht₂ : f ∈ pi {i | i ∈ s ∧ ¬p i} t₂
i : ι
his : i ∈ s
h : ¬p i
⊢ f i ∈ (fun i => if p i then t₁ i else t₂ i) i
[PROOFSTEP]
simp_all
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
⊢ pi (s₁ ∪ s₂) t = pi s₁ t ∩ pi s₂ t
[PROOFSTEP]
simp [pi, or_imp, forall_and, setOf_and]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
s : Set ι
⊢ pi s t ∩ pi sᶜ t = pi univ t
[PROOFSTEP]
rw [← union_pi, union_compl_self]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
hi : ¬i ∈ s
f : (j : ι) → α j
a : α i
t : (j : ι) → α j → Set (β j)
j : ι
hj : j ∈ s
⊢ t j (update f i a j) = t j (f j)
[PROOFSTEP]
rw [update_noteq]
[GOAL]
case h
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
hi : ¬i ∈ s
f : (j : ι) → α j
a : α i
t : (j : ι) → α j → Set (β j)
j : ι
hj : j ∈ s
⊢ j ≠ i
[PROOFSTEP]
exact fun h => hi (h ▸ hj)
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
hi : i ∈ s
f : (j : ι) → α j
a : α i
t : (j : ι) → α j → Set (β j)
⊢ (pi s fun j => t j (update f i a j)) = pi ({i} ∪ s \ {i}) fun j => t j (update f i a j)
[PROOFSTEP]
rw [union_diff_self, union_eq_self_of_subset_left (singleton_subset_iff.2 hi)]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
hi : i ∈ s
f : (j : ι) → α j
a : α i
t : (j : ι) → α j → Set (β j)
⊢ (pi ({i} ∪ s \ {i}) fun j => t j (update f i a j)) = {x | x i ∈ t i a} ∩ pi (s \ {i}) fun j => t j (f j)
[PROOFSTEP]
rw [union_pi, singleton_pi', update_same, pi_update_of_not_mem]
[GOAL]
case hi
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
hi : i ∈ s
f : (j : ι) → α j
a : α i
t : (j : ι) → α j → Set (β j)
⊢ ¬i ∈ s \ {i}
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : ι → Type u_2
β✝ : ι → Type u_3
s s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
inst✝ : DecidableEq ι
β : ι → Type u_4
i : ι
f : (j : ι) → α j
a : α i
t : (j : ι) → α j → Set (β j)
⊢ (pi univ fun j => t j (update f i a j)) = {x | x i ∈ t i a} ∩ pi {i}ᶜ fun j => t j (f j)
[PROOFSTEP]
rw [compl_eq_univ_diff, ← pi_update_of_mem (mem_univ _)]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
inst✝ : DecidableEq ι
i : ι
s : Set (α i)
⊢ pi univ (update (fun j => univ) i s) = eval i ⁻¹' s
[PROOFSTEP]
rw [univ_pi_update i (fun j => (univ : Set (α j))) s fun j t => t, pi_univ, inter_univ, preimage]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
ht : Set.Nonempty (pi s t)
i : ι
⊢ t i ⊆ eval i '' pi s t
[PROOFSTEP]
classical
obtain ⟨f, hf⟩ := ht
refine' fun y hy => ⟨update f i y, fun j hj => _, update_same _ _ _⟩
obtain rfl | hji := eq_or_ne j i <;> simp [*, hf _ hj]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
ht : Set.Nonempty (pi s t)
i : ι
⊢ t i ⊆ eval i '' pi s t
[PROOFSTEP]
obtain ⟨f, hf⟩ := ht
[GOAL]
case intro
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ i : ι
f : (i : ι) → α i
hf : f ∈ pi s t
⊢ t i ⊆ eval i '' pi s t
[PROOFSTEP]
refine' fun y hy => ⟨update f i y, fun j hj => _, update_same _ _ _⟩
[GOAL]
case intro
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ i : ι
f : (i : ι) → α i
hf : f ∈ pi s t
y : α i
hy : y ∈ t i
j : ι
hj : j ∈ s
⊢ update f i y j ∈ t j
[PROOFSTEP]
obtain rfl | hji := eq_or_ne j i
[GOAL]
case intro.inl
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
f : (i : ι) → α i
hf : f ∈ pi s t
j : ι
hj : j ∈ s
y : α j
hy : y ∈ t j
⊢ update f j y j ∈ t j
[PROOFSTEP]
simp [*, hf _ hj]
[GOAL]
case intro.inr
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ i : ι
f : (i : ι) → α i
hf : f ∈ pi s t
y : α i
hy : y ∈ t i
j : ι
hj : j ∈ s
hji : j ≠ i
⊢ update f i y j ∈ t j
[PROOFSTEP]
simp [*, hf _ hj]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
⊢ pi s t₁ ⊆ pi s t₂ ↔ (∀ (i : ι), i ∈ s → t₁ i ⊆ t₂ i) ∨ pi s t₁ = ∅
[PROOFSTEP]
refine' ⟨fun h => or_iff_not_imp_right.2 _, fun h => h.elim pi_mono fun h' => h'.symm ▸ empty_subset _⟩
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
h : pi s t₁ ⊆ pi s t₂
⊢ ¬pi s t₁ = ∅ → ∀ (i : ι), i ∈ s → t₁ i ⊆ t₂ i
[PROOFSTEP]
rw [← Ne.def, ← nonempty_iff_ne_empty]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
h : pi s t₁ ⊆ pi s t₂
⊢ Set.Nonempty (pi s t₁) → ∀ (i : ι), i ∈ s → t₁ i ⊆ t₂ i
[PROOFSTEP]
intro hne i hi
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
h : pi s t₁ ⊆ pi s t₂
hne : Set.Nonempty (pi s t₁)
i : ι
hi : i ∈ s
⊢ t₁ i ⊆ t₂ i
[PROOFSTEP]
simpa only [eval_image_pi hi hne, eval_image_pi hi (hne.mono h)] using image_subset (fun f : ∀ i, α i => f i) h
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
⊢ pi univ t₁ ⊆ pi univ t₂ ↔ (∀ (i : ι), t₁ i ⊆ t₂ i) ∨ ∃ i, t₁ i = ∅
[PROOFSTEP]
simp [pi_subset_pi_iff]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
s : Set (α i)
⊢ eval i ⁻¹' s = pi univ (update (fun i => univ) i s)
[PROOFSTEP]
ext x
[GOAL]
case h
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
s : Set (α i)
x : (x : ι) → α x
⊢ x ∈ eval i ⁻¹' s ↔ x ∈ pi univ (update (fun i => univ) i s)
[PROOFSTEP]
simp [@forall_update_iff _ (fun i => Set (α i)) _ _ _ _ fun i' y => x i' ∈ y]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
s : Set (α i)
⊢ eval i ⁻¹' s = pi {i} (update (fun i => univ) i s)
[PROOFSTEP]
ext
[GOAL]
case h
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
s : Set (α i)
x✝ : (x : ι) → α x
⊢ x✝ ∈ eval i ⁻¹' s ↔ x✝ ∈ pi {i} (update (fun i => univ) i s)
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
f : (i : ι) → α i
hi : i ∈ s
hf : ∀ (j : ι), j ∈ s → j ≠ i → f j ∈ t j
⊢ update f i ⁻¹' pi s t = t i
[PROOFSTEP]
ext x
[GOAL]
case h
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
f : (i : ι) → α i
hi : i ∈ s
hf : ∀ (j : ι), j ∈ s → j ≠ i → f j ∈ t j
x : α i
⊢ x ∈ update f i ⁻¹' pi s t ↔ x ∈ t i
[PROOFSTEP]
refine' ⟨fun h => _, fun hx j hj => _⟩
[GOAL]
case h.refine'_1
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
f : (i : ι) → α i
hi : i ∈ s
hf : ∀ (j : ι), j ∈ s → j ≠ i → f j ∈ t j
x : α i
h : x ∈ update f i ⁻¹' pi s t
⊢ x ∈ t i
[PROOFSTEP]
convert h i hi
[GOAL]
case h.e'_4
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
f : (i : ι) → α i
hi : i ∈ s
hf : ∀ (j : ι), j ∈ s → j ≠ i → f j ∈ t j
x : α i
h : x ∈ update f i ⁻¹' pi s t
⊢ x = update f i x i
[PROOFSTEP]
simp
[GOAL]
case h.refine'_2
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
f : (i : ι) → α i
hi : i ∈ s
hf : ∀ (j : ι), j ∈ s → j ≠ i → f j ∈ t j
x : α i
hx : x ∈ t i
j : ι
hj : j ∈ s
⊢ update f i x j ∈ t j
[PROOFSTEP]
obtain rfl | h := eq_or_ne j i
[GOAL]
case h.refine'_2.inl
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
inst✝ : DecidableEq ι
f : (i : ι) → α i
j : ι
hj hi : j ∈ s
hf : ∀ (j_1 : ι), j_1 ∈ s → j_1 ≠ j → f j_1 ∈ t j_1
x : α j
hx : x ∈ t j
⊢ update f j x j ∈ t j
[PROOFSTEP]
simpa
[GOAL]
case h.refine'_2.inr
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
f : (i : ι) → α i
hi : i ∈ s
hf : ∀ (j : ι), j ∈ s → j ≠ i → f j ∈ t j
x : α i
hx : x ∈ t i
j : ι
hj : j ∈ s
h : j ≠ i
⊢ update f i x j ∈ t j
[PROOFSTEP]
rw [update_noteq h]
[GOAL]
case h.refine'_2.inr
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
f : (i : ι) → α i
hi : i ∈ s
hf : ∀ (j : ι), j ∈ s → j ≠ i → f j ∈ t j
x : α i
hx : x ∈ t i
j : ι
hj : j ∈ s
h : j ≠ i
⊢ f j ∈ t j
[PROOFSTEP]
exact hf j hj h
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i : ι
s : Set ι
inst✝ : DecidablePred fun x => x ∈ s
t : (i : ι) → Set (α i)
⊢ (pi univ fun i => if i ∈ s then t i else univ) = pi s t
[PROOFSTEP]
ext
[GOAL]
case h
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i : ι
s : Set ι
inst✝ : DecidablePred fun x => x ∈ s
t : (i : ι) → Set (α i)
x✝ : (i : ι) → α i
⊢ (x✝ ∈ pi univ fun i => if i ∈ s then t i else univ) ↔ x✝ ∈ pi s t
[PROOFSTEP]
simp_rw [mem_univ_pi]
[GOAL]
case h
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i : ι
s : Set ι
inst✝ : DecidablePred fun x => x ∈ s
t : (i : ι) → Set (α i)
x✝ : (i : ι) → α i
⊢ (∀ (i : ι), x✝ i ∈ if i ∈ s then t i else univ) ↔ x✝ ∈ pi s t
[PROOFSTEP]
refine' forall_congr' fun i => _
[GOAL]
case h
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
s : Set ι
inst✝ : DecidablePred fun x => x ∈ s
t : (i : ι) → Set (α i)
x✝ : (i : ι) → α i
i : ι
⊢ (x✝ i ∈ if i ∈ s then t i else univ) ↔ i ∈ s → x✝ i ∈ t i
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
s : Set ι
inst✝ : DecidablePred fun x => x ∈ s
t : (i : ι) → Set (α i)
x✝ : (i : ι) → α i
i : ι
h : i ∈ s
⊢ x✝ i ∈ t i ↔ i ∈ s → x✝ i ∈ t i
[PROOFSTEP]
simp [h]
[GOAL]
case neg
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
s : Set ι
inst✝ : DecidablePred fun x => x ∈ s
t : (i : ι) → Set (α i)
x✝ : (i : ι) → α i
i : ι
h : ¬i ∈ s
⊢ x✝ i ∈ univ ↔ i ∈ s → x✝ i ∈ t i
[PROOFSTEP]
simp [h]