1-- The union of two functions with disjoint domains is a function on the2-- union of the domains; injectivity needs disjoint images too, and3-- surjectivity passes to the union of the codomains4-- Part of Cumulus, the Grace17 mathematics library.5-- Copyright (c) 2026 Grant Passmore.6-- Released under the Apache License 2.0. See LICENSE in the repository root.7-- Authors: Grant Passmore89module Grace.Cumulus.Set.Function.Union10import Image11import Algebra1213theorem union2.relates (f g x y : Set)14shows relates(f ∪ g, x, y) ↔ relates(f, x, y) ∨ relates(g, x, y)15proof16constructor17 . intro h18have member : (x, y) ∈ f ∪ g := h19havesplit:= union2.membership.forward with member20casessplitwith inF | inG21 . left22exact inF23 . right24exact inG25 . intro h26cases h with inF | inG27 . have member : (x, y) ∈ f := inF28exact union2.left at (x, y), f, g with member29 . have member : (x, y) ∈ g := inG30exact union2.right at (x, y), f, g with member3132theorem FunctionBetween.union_disjoint (f g A B C D : Set)33requires hf : f : A → C34requires hg : g : B → D35requires disjoint : Disjoint(A, B)36shows f ∪ g : A ∪ B → C ∪ D37proof38have fRelation := RelationBetween.monotone with (FunctionBetween.relation with hf), (union2.subset_left at A, B), (union2.subset_left at C, D)39have gRelation := RelationBetween.monotone with (FunctionBetween.relation with hg), (union2.subset_right at A, B), (union2.subset_right at C, D)40have separated := Disjoint.iff.forward with disjoint41have fFunctional := FunctionBetween.functional with hf42have gFunctional := FunctionBetween.functional with hg43have fSubset : f ⊆ (A ∪ B) × (C ∪ D) := fRelation44have gSubset : g ⊆ (A ∪ B) × (C ∪ D) := gRelation45constructor46 . exact union2.subset with fSubset, gSubset47 . constructor48 . intros x y hxy z hxz49have hxy2 := union2.relates.forward with hxy50have hxz2 := union2.relates.forward with hxz51cases hxy2 with fy | gy52 . cases hxz2 with fz | gz53 . exact fFunctional with x, y, fy, z, fz54 . exfalso55have boundsY := FunctionBetween.bounds with hf, fy56have boundsZ := FunctionBetween.bounds with hg, gz57exact separated with x, boundsY.left, boundsZ.left58 . cases hxz2 with fz | gz59 . exfalso60have boundsZ := FunctionBetween.bounds with hf, fz61have boundsY := FunctionBetween.bounds with hg, gy62exact separated with x, boundsZ.left, boundsY.left63 . exact gFunctional with x, y, gy, z, gz64 . intros x hx65havesplit:= union2.membership.forward with hx66casessplitwith hxA | hxB67 . obtain⟨y, hy, related⟩:= FunctionBetween.exists_value with hf, hxA68refine⟨y, (union2.subset_left at C, D with y, hy), ?_⟩69apply union2.relates.backward70left71exact related72 . obtain⟨y, hy, related⟩:= FunctionBetween.exists_value with hg, hxB73refine⟨y, (union2.subset_right at C, D with y, hy), ?_⟩74apply union2.relates.backward75right76exact related7778theorem FunctionBetween.union_apply_left (f g A B C D x : Set)79requires hf : f : A → C80requires hg : g : B → D81requires disjoint : Disjoint(A, B)82requires hx : x ∈ A83shows (f ∪ g)(x) = f(x)84proof85have union := FunctionBetween.union_disjoint with hf, hg, disjoint86have hxU := union2.subset_left at A, B with x, hx87have related := FunctionBetween.relates_apply with hf, hx88have lifted : relates(f ∪ g, x, f(x))89apply union2.relates.backward90left91exact related92exact FunctionBetween.apply_value with union, hxU, lifted9394theorem FunctionBetween.union_apply_right (f g A B C D x : Set)95requires hf : f : A → C96requires hg : g : B → D97requires disjoint : Disjoint(A, B)98requires hx : x ∈ B99shows (f ∪ g)(x) = g(x)100proof101have union := FunctionBetween.union_disjoint with hf, hg, disjoint102have hxU := union2.subset_right at A, B with x, hx103have related := FunctionBetween.relates_apply with hg, hx104have lifted : relates(f ∪ g, x, g(x))105apply union2.relates.backward106right107exact related108exact FunctionBetween.apply_value with union, hxU, lifted109110theorem Injective.union_disjoint (f g A B C D : Set)111requires hf : InjectiveBetween(f, A, C)112requires hg : InjectiveBetween(g, B, D)113requires domains : Disjoint(A, B)114requires codomains : Disjoint(C, D)115shows InjectiveBetween(f ∪ g, A ∪ B, C ∪ D)116proof117have fFunction := Injective.function with hf118have gFunction := Injective.function with hg119have separated := Disjoint.iff.forward with codomains120constructor121 . exact FunctionBetween.union_disjoint with fFunction, gFunction, domains122 . intros x hx y hy z hz hxz hyz123have hxz2 := union2.relates.forward with hxz124have hyz2 := union2.relates.forward with hyz125cases hxz2 with fx | gx126 . cases hyz2 with fy | gy127 . have boundsX := FunctionBetween.bounds with fFunction, fx128have boundsY := FunctionBetween.bounds with fFunction, fy129exact hf.right with x, boundsX.left, y, boundsY.left, z, boundsX.right, fx, fy130 . exfalso131have boundsX := FunctionBetween.bounds with fFunction, fx132have boundsY := FunctionBetween.bounds with gFunction, gy133exact separated with z, boundsX.right, boundsY.right134 . cases hyz2 with fy | gy135 . exfalso136have boundsX := FunctionBetween.bounds with gFunction, gx137have boundsY := FunctionBetween.bounds with fFunction, fy138exact separated with z, boundsY.right, boundsX.right139 . have boundsX := FunctionBetween.bounds with gFunction, gx140have boundsY := FunctionBetween.bounds with gFunction, gy141exact hg.right with x, boundsX.left, y, boundsY.left, z, boundsX.right, gx, gy142143theorem Surjective.union_disjoint (f g A B C D : Set)144requires hf : SurjectiveBetween(f, A, C)145requires hg : SurjectiveBetween(g, B, D)146requires domains : Disjoint(A, B)147shows SurjectiveBetween(f ∪ g, A ∪ B, C ∪ D)148proof149have fFunction := Surjective.function with hf150have gFunction := Surjective.function with hg151constructor152 . exact FunctionBetween.union_disjoint with fFunction, gFunction, domains153 . intros z hz154havesplit:= union2.membership.forward with hz155casessplitwith hzC | hzD156 . obtain⟨x, hx, related⟩:= hf.right with z, hzC157refine⟨x, (union2.subset_left at A, B with x, hx), ?_⟩158apply union2.relates.backward159left160exact related161 . obtain⟨x, hx, related⟩:= hg.right with z, hzD162refine⟨x, (union2.subset_right at A, B with x, hx), ?_⟩163apply union2.relates.backward164right165exact related166167theorem Bijective.union_disjoint (f g A B C D : Set)168requires hf : BijectiveBetween(f, A, C)169requires hg : BijectiveBetween(g, B, D)170requires domains : Disjoint(A, B)171requires codomains : Disjoint(C, D)172shows BijectiveBetween(f ∪ g, A ∪ B, C ∪ D)173proof174constructor175 . exact Injective.union_disjoint with hf.left, hg.left, domains, codomains176 . exact Surjective.union_disjoint with hf.right, hg.right, domains177