1-- Images and preimages of functions and their algebra2-- Part of Cumulus, the Grace17 mathematics library.3-- Copyright (c) 2026 Grant Passmore.4-- Released under the Apache License 2.0. See LICENSE in the repository root.5-- Authors: Grant Passmore67module Grace.Cumulus.Set.Function.Image8import Function9import Algebra1011-- The preimage of Y under a function with domain A.12def functionPreimage (f A Y : Set) : Set:= { x ∈ A | f(x) ∈ Y }1314theorem functionPreimage.subset (f A Y : Set)15shows functionPreimage(f, A, Y) ⊆ A16proof17intros x hx18simp [functionPreimage.membership] at hx19exact hx.left2021theorem functionPreimage.of_apply (f A Y x : Set)22requires hx : x ∈ A23requires value : f(x) ∈ Y24shows x ∈ functionPreimage(f, A, Y)25proof26simp [functionPreimage.membership]2728-- Images2930theorem functionImage.empty (f B : Set)31shows functionImage(f, ∅, B) =∅32proof33ext y34constructor35 . intro hy36simp [functionImage.membership] at hy37 . intro hy38exfalso39 simpa using hy4041theorem functionImage.monotone (f A B S T : Set)42requires h : S ⊆ T43shows functionImage(f, S, B) ⊆ functionImage(f, T, B)44proof45intros y hy46simp [functionImage.membership] at hy47obtain⟨inB, x, hx, shape⟩:= hy48simp [functionImage.membership]49constructor50 . exact inB51 . refine⟨x, (h with x, hx), shape⟩5253theorem functionImage.union2 (f A B S T : Set)54shows functionImage(f, S ∪ T, B) = functionImage(f, S, B) ∪ functionImage(f, T, B)55proof56ext y57constructor58 . intro hy59simp [functionImage.membership] at hy60obtain⟨inB, x, hx, shape⟩:= hy61simp [union2.membership] at hx62simp [union2.membership]63cases hx with hS | hT64 . left65simp [functionImage.membership]66exact⟨inB, x, hS, shape⟩67 . right68simp [functionImage.membership]69exact⟨inB, x, hT, shape⟩70 . intro hy71simp [union2.membership] at hy72cases hy with hS | hT73 . exact functionImage.monotone at f, A, B, S, S ∪ T with (union2.subset_left at S, T), y, hS74 . exact functionImage.monotone at f, A, B, T, S ∪ T with (union2.subset_right at S, T), y, hT7576theorem functionImage.intersection_subset (f A B S T : Set)77shows functionImage(f, S ∩ T, B) ⊆ functionImage(f, S, B) ∩ functionImage(f, T, B)78proof79apply Subset.intersection_iff.backward80constructor81 . exact functionImage.monotone at f, A, B, S ∩ T, S with (intersection.subset_left at S, T)82 . exact functionImage.monotone at f, A, B, S ∩ T, T with (intersection.subset_right at S, T)8384theorem Injective.apply_cancel (f A B x y : Set)85requires injective : InjectiveBetween(f, A, B)86requires hx : x ∈ A87requires hy : y ∈ A88requires same : f(x) = f(y)89shows x = y90proof91have function := injective.left92have valueB := FunctionBetween.apply_closed with function, hx93have hxz := FunctionBetween.relates_apply with function, hx94have hyz := FunctionBetween.relates_apply with function, hy95rw← same at hyz96exact Injective.cancel with injective, hx, hy, valueB, hxz, hyz9798theorem functionImage.intersection_of_injective (f A B S T : Set)99requires injective : InjectiveBetween(f, A, B)100requires hS : S ⊆ A101requires hT : T ⊆ A102shows functionImage(f, S ∩ T, B) = functionImage(f, S, B) ∩ functionImage(f, T, B)103proof104apply Subset.antisymmetric105 . exact functionImage.intersection_subset at f, A, B, S, T106 . intros y hy107simp [intersection.membership] at hy108obtain⟨inS, inT⟩:= hy109simp [functionImage.membership] at inS110simp [functionImage.membership] at inT111obtain⟨inB, x, hx, shapeX⟩:= inS112obtain⟨inB2, z, hz, shapeZ⟩:= inT113have hxA : x ∈ A := hS with x, hx114have hzA : z ∈ A := hT with z, hz115have agree : f(x) = f(z)116rw [← shapeX, ← shapeZ]117rfl118have same := Injective.apply_cancel with injective, hxA, hzA, agree119simp [functionImage.membership]120constructor121 . exact inB122 . witness x123constructor124 . simp [intersection.membership]125 . exact shapeX126127theorem functionImage.difference_subset (f A B S T : Set)128shows functionImage(f, S, B) ∖ functionImage(f, T, B) ⊆ functionImage(f, S ∖ T, B)129proof130intros y hy131simp [difference.membership] at hy132obtain⟨inS, notT⟩:= hy133simp [functionImage.membership] at inS134obtain⟨inB, x, hx, shape⟩:= inS135simp [functionImage.membership]136constructor137 . exact inB138 . witness x139constructor140 . simp [difference.membership]141constructor142 . exact hx143 . intro inT144apply notT145simp [functionImage.membership]146exact⟨inB, x, inT, shape⟩147 . exact shape148149theorem functionImage.subset_iff (f A B S Y : Set)150shows functionImage(f, S, B) ⊆ Y ↔∀ x ∈ S, f(x) ∈ B → f(x) ∈ Y151proof152constructor153 . intros h x hx valueB154have member : f(x) ∈ functionImage(f, S, B) bysimp [functionImage.membership]155exact h with f(x), member156 . intros h y hy157simp [functionImage.membership] at hy158obtain⟨inB, x, hx, shape⟩:= hy159rw shape160rw shape at inB161exact h with x, hx, inB162163-- Preimages164165theorem functionPreimage.empty (f A : Set)166shows functionPreimage(f, A, ∅) =∅167proof168ext x169simp [functionPreimage.membership]170171theorem functionPreimage.codomain (f A B : Set)172requires function : f : A → B173shows functionPreimage(f, A, B) = A174proof175ext x176constructor177 . intro hx178exact functionPreimage.subset at f, A, B with x, hx179 . intro hx180exact functionPreimage.of_apply with hx, (FunctionBetween.apply_closed with function, hx)181182theorem functionPreimage.monotone (f A Y Z : Set)183requires h : Y ⊆ Z184shows functionPreimage(f, A, Y) ⊆ functionPreimage(f, A, Z)185proof186intros x hx187simp [functionPreimage.membership] at hx188simp [functionPreimage.membership]189190theorem functionPreimage.union2 (f A Y Z : Set)191shows functionPreimage(f, A, Y ∪ Z) = functionPreimage(f, A, Y) ∪ functionPreimage(f, A, Z)192proof193ext x194simp [functionPreimage.membership, union2.membership]195196theorem functionPreimage.intersection (f A Y Z : Set)197shows functionPreimage(f, A, Y ∩ Z) = functionPreimage(f, A, Y) ∩ functionPreimage(f, A, Z)198proof199ext x200simp [functionPreimage.membership, intersection.membership]201202theorem functionPreimage.difference (f A Y Z : Set)203shows functionPreimage(f, A, Y ∖ Z) = functionPreimage(f, A, Y) ∖ functionPreimage(f, A, Z)204proof205ext x206simp [functionPreimage.membership, difference.membership]207208theorem functionPreimage.complement (f A B Y : Set)209requires function : f : A → B210shows functionPreimage(f, A, B ∖ Y) = A ∖ functionPreimage(f, A, Y)211proof212have whole := functionPreimage.codomain with function213rw [functionPreimage.difference, whole]214rfl215216-- Images and preimages together217218theorem functionImage.preimage_subset (f A B Y : Set)219shows functionImage(f, functionPreimage(f, A, Y), B) ⊆ Y220proof221intros y hy222simp [functionImage.membership] at hy223obtain⟨inB, x, hx, shape⟩:= hy224simp [functionPreimage.membership] at hx225rw shape226exact hx.right227228theorem functionImage.preimage_of_subset (f A B Y : Set)229requires function : f : A → B230requires h : Y ⊆ functionImage(f, A, B)231shows functionImage(f, functionPreimage(f, A, Y), B) = Y232proof233apply Subset.antisymmetric234 . exact functionImage.preimage_subset at f, A, B, Y235 . intros y hy236have inImage : y ∈ functionImage(f, A, B) := h with y, hy237simp [functionImage.membership] at inImage238obtain⟨inB, x, hx, shape⟩:= inImage239simp [functionImage.membership]240constructor241 . exact inB242 . witness x243constructor244 . simp [functionPreimage.membership]245 . exact shape246247theorem functionPreimage.image_superset (f A B S : Set)248requires function : f : A → B249requires hS : S ⊆ A250shows S ⊆ functionPreimage(f, A, functionImage(f, S, B))251proof252intros x hx253simp [functionPreimage.membership]254constructor255 . exact hS with x, hx256 . have value := FunctionBetween.apply_closed with function, (hS with x, hx)257simp [functionImage.membership]258259theorem functionPreimage.image_of_injective (f A B S : Set)260requires injective : InjectiveBetween(f, A, B)261requires hS : S ⊆ A262shows functionPreimage(f, A, functionImage(f, S, B)) = S263proof264have function := injective.left265apply Subset.antisymmetric266 . intros x hx267simp [functionPreimage.membership] at hx268obtain⟨hxA, inImage⟩:= hx269simp [functionImage.membership] at inImage270obtain⟨inB, z, hz, shape⟩:= inImage271have same := Injective.apply_cancel with injective, hxA, (hS with z, hz), shape272 rwa same273 . exact functionPreimage.image_superset with function, hS274275theorem functionImage.compose (g f A B C S : Set)276requires fFunction : f : A → B277requires gFunction : g : B → C278requires hS : S ⊆ A279shows functionImage(compose(g, f, A, B, C), S, C) = functionImage(g, functionImage(f, S, B), C)280proof281have composed := compose.function with fFunction, gFunction282ext y283constructor284 . intro hy285simp [functionImage.membership] at hy286obtain⟨inC, x, hx, shape⟩:= hy287have hxA : x ∈ A := hS with x, hx288have step := compose.apply with fFunction, gFunction, hxA289simp [functionImage.membership]290constructor291 . exact inC292 . witness f(x)293constructor294 . have value := FunctionBetween.apply_closed with fFunction, hxA295simp [functionImage.membership]296exact⟨value, x, hx, rfl⟩297 . rw [shape, step]298rfl299 . intro hy300simp [functionImage.membership] at hy301obtain⟨inC, z, hz, shape⟩:= hy302simp [functionImage.membership] at hz303obtain⟨inB, x, hx, shapeZ⟩:= hz304have hxA : x ∈ A := hS with x, hx305have step := compose.apply with fFunction, gFunction, hxA306simp [functionImage.membership]307constructor308 . exact inC309 . witness x310constructor311 . exact hx312 . rw [shape, shapeZ, step]313rfl314315theorem functionPreimage.compose (g f A B C Z : Set)316requires fFunction : f : A → B317requires gFunction : g : B → C318shows functionPreimage(compose(g, f, A, B, C), A, Z) = functionPreimage(f, A, functionPreimage(g, B, Z))319proof320ext x321constructor322 . intro hx323simp [functionPreimage.membership] at hx324obtain⟨hxA, value⟩:= hx325have step := compose.apply with fFunction, gFunction, hxA326rw step at value327have inB := FunctionBetween.apply_closed with fFunction, hxA328simp [functionPreimage.membership]329 . intro hx330simp [functionPreimage.membership] at hx331obtain⟨hxA, inner⟩:= hx332simp [functionPreimage.membership] at inner333have step := compose.apply with fFunction, gFunction, hxA334simp [functionPreimage.membership]335336theorem functionImage.identity_of_subset (A S : Set)337requires hS : S ⊆ A338shows functionImage(identity(A), S, A) = S339proof340ext y341constructor342 . intro hy343simp [functionImage.membership] at hy344obtain⟨inA, x, hx, shape⟩:= hy345have fixed := identity.apply with (hS with x, hx)346 rwa [shape, fixed]347 . intro hy348simp [functionImage.membership]349constructor350 . exact hS with y, hy351 . witness y352constructor353 . exact hy354 . symm355exact identity.apply with (hS with y, hy)356357-- An injection is a bijection onto its image.358theorem Injective.corestrict (f A B : Set)359requires injective : InjectiveBetween(f, A, B)360shows InjectiveBetween(f, A, functionImage(f, A, B))361proof362have function := Injective.function with injective363constructor364 . exact functionImage.corestrict with function365 . intros x hx y hy z hz hxz hyz366have hzB := functionImage.subset at f, A, B with z, hz367exact injective.right with x, hx, y, hy, z, hzB, hxz, hyz368369-- Restricting an injection keeps it injective, with the same image.370theorem restrict.injective (f A B S : Set)371requires injective : InjectiveBetween(f, A, B)372requires subset : S ⊆ A373shows InjectiveBetween(restrict(f, S), S, B)374proof375have function := Injective.function with injective376have closed : ∀ x ∈ S, f(x) ∈ B377intros x hx378exact FunctionBetween.apply_closed with function, (subset with x, hx)379have restricted := restrict.function with function, subset, closed380constructor381 . exact restricted382 . intros x hx y hy z hz hxz hyz383have valueX := FunctionBetween.apply_value with restricted, hx, hxz384have valueY := FunctionBetween.apply_value with restricted, hy, hyz385have stepX := restrict.apply with function, subset, closed, hx386have stepY := restrict.apply with function, subset, closed, hy387have same : f(x) = f(y) bycc388exact Injective.apply_cancel with injective, (subset with x, hx), (subset with y, hy), same389390theorem functionImage.restrict (f A B S : Set)391requires function : f : A → B392requires subset : S ⊆ A393shows functionImage(restrict(f, S), S, B) = functionImage(f, S, B)394proof395have closed : ∀ x ∈ S, f(x) ∈ B396intros x hx397exact FunctionBetween.apply_closed with function, (subset with x, hx)398ext y399constructor400 . intro hy401simp [functionImage.membership] at hy402obtain⟨inB, x, hx, shape⟩:= hy403have step := restrict.apply with function, subset, closed, hx404rw step at shape405simp [functionImage.membership]406constructor407 . exact inB408 . refine⟨x, hx, shape⟩409 . intro hy410simp [functionImage.membership] at hy411obtain⟨inB, x, hx, shape⟩:= hy412have step := restrict.apply with function, subset, closed, hx413rw← step at shape414simp [functionImage.membership]415constructor416 . exact inB417 . refine⟨x, hx, shape⟩418419theorem functionImage.insert (f A B x S : Set)420requires function : f : A → B421requires hx : x ∈ A422shows functionImage(f, insert(x, S), B) = insert(f(x), functionImage(f, S, B))423proof424have value := FunctionBetween.apply_closed with function, hx425ext y426constructor427 . intro hy428simp [functionImage.membership] at hy429obtain⟨inB, z, hz, shape⟩:= hy430havesplit:= insert.membership.forward with hz431apply insert.membership.backward432casessplitwith same | inS433 . left434rw [shape, same]435rfl436 . right437simp [functionImage.membership]438constructor439 . exact inB440 . refine⟨z, inS, shape⟩441 . intro hy442havesplit:= insert.membership.forward with hy443casessplitwith same | inImage444 . have inserted : x ∈ insert(x, S)445apply insert.membership.backward446left447rfl448rw same449simp [functionImage.membership]450constructor451 . exact value452 . witness x453constructor454 . exact inserted455 . rfl456 . simp [functionImage.membership] at inImage457obtain⟨inB, z, hz, shape⟩:= inImage458have inserted : z ∈ insert(x, S)459apply insert.membership.backward460right461exact hz462simp [functionImage.membership]463constructor464 . exact inB465 . refine⟨z, inserted, shape⟩466