1-- Finite list supports and finiteness of their subsets (ZF).2-- 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.Cardinal.ListSupport8import Sum9import Core.List1011def listSupport {C : Set} (xs : List(C)) →Set12| List.nil =>∅13| List.cons(x, tail) => insert(x, listSupport(tail))1415theorem listSupport.nil (C : Set)16shows listSupport{C}([]) =∅17proof18simp [listSupport]1920theorem listSupport.cons (C x : Set) (xs : List(C))21requires hx : x ∈ C22shows listSupport{C}(x :: xs) = insert(x, listSupport{C}(xs))23proof24simp [listSupport]2526theorem Finite.insert (A x : Set)27requires finite : Finite(A)28shows Finite(insert(x, A))29proof30have casesX : x ∈ A ∨¬(x ∈ A) bytauto31cases casesX with member | fresh32 . have same : insert(x, A) = A33ext y34simp35 rwa same36 . obtain⟨n, natural, equinumerous⟩:= finite37obtain⟨f, bijective⟩:= equinumerous38have nFresh := membership.irreflexive at n39have extended := adjoinMap.bijective with bijective, fresh, nFresh40have successor := natural.successor_as_insert with natural41have nextNat := Naturals.constructor.succ with natural42have cardinality : HasCardinality(insert(x, A), succ(n))43unfold HasCardinality44refine⟨nextNat, ?_⟩45witness adjoinMap(f, x, n)46 rwa successor47exact Finite.from_cardinality with cardinality4849theorem listSupport.subset (C : Set) (xs : List(C))50shows listSupport{C}(xs) ⊆ C51proof52induction xs53| List.nil =>54rw listSupport55exact empty.subset56| List.cons(x, tail) using ih =>57rw listSupport58have member : x ∈ C byassumption59simp6061theorem listSupport.append (C : Set) (ys xs : List(C))62shows listSupport{C}(ListOps.append{C}(ys, xs)) = listSupport{C}(xs) ∪ listSupport{C}(ys)63proof64induction xs65| List.nil =>66simp [ListOps.append, listSupport]67ext x68simp69| List.cons(x, tail) using ih =>70simp [ListOps.append, listSupport, ih]71ext y72simp7374-- Remove the head if it is present; recurse on a subset of the tail support.75theorem listSupport.finite_subsets (C : Set) (xs : List(C))76shows∀ S, S ⊆ listSupport{C}(xs) → Finite(S)77proof78induction xs79| List.nil =>80intros S subset81rw listSupport at subset82have equal : S =∅83apply Subset.antisymmetric with subset84exact empty.subset85rw equal86exact Finite.empty87| List.cons(x, tail) using ih =>88intros S subset89rw listSupport at subset90have casesX : x ∈ S ∨¬(x ∈ S) bytauto91cases casesX with member | absent92 . have restSubset : S ∖ {x} ⊆ listSupport{C}(tail) bysimp93have restFinite := ih with S ∖ {x}, restSubset94have restored : insert(x, S ∖ {x}) = S95ext y96have equalityCases : y = x ∨ y ≠ x bytauto97cases equalityCases with equal | distinct98 . rw equal99haveleft:= insert.self at x, S ∖ {x}100tauto101 . settlewith insert.membership, difference.membership, singleton.membership102have finite := Finite.insert at S ∖ {x}, x with restFinite103 rwa restored at finite104 . have restSubset : S ⊆ listSupport{C}(tail) bysimp105exact ih with S, restSubset106107theorem listSupport.finite (C : Set) (xs : List(C))108shows Finite(listSupport{C}(xs))109proof110have subsets := listSupport.finite_subsets at C, xs111have reflexive : listSupport{C}(xs) ⊆ listSupport{C}(xs) bysimp [Subset]112exact subsets with listSupport{C}(xs), reflexive113114-- List every value on a natural prefix, without choosing from any family.115theorem FunctionBetween.list_cover_prefix (n : Nat)116shows∀ f, ∀ D, ∀ C, FunctionBetween(f, D, C) → n ⊆ D →117∃ xs, List(C, xs) ∧ (∀ i ∈ n, f(i) ∈ listSupport{C}(xs))118proof119induction n120| zero =>121intros f D C function subset122have nil : List(C, []) bytypecheck123refine⟨[], nil, ?_⟩124intros i hi125have emptyMember : i ∈∅by rwa ← nat.zero126simp127| succ(k) using ih =>128intros f D C function subset129have successor := natural.successor_as_insert at k withassumption130have kIn : k ∈ succ(k) bysimp131have prefixSubset : k ⊆ D bysimp132have kInD : k ∈ D bysimp133have valueIn := FunctionBetween.apply_closed with function, kInD134obtain⟨xs, listX, covers⟩:= ih with f, D, C, function, prefixSubset135have listNext : List(C, f(k) :: xs) bytypecheck136refine⟨f(k) :: xs, listNext, ?_⟩137intros i hi138rw successor at hi139have alternatives := insert.membership.forward with hi140rw listSupport141cases alternatives with equal | previous142 . rw equal143exact insert.self144 . have old := covers with i, previous145exact insert.contains with old146147theorem Finite.list_cover (S : Set)148requires finite : Finite(S)149shows∃ xs, List(S, xs) ∧ S ⊆ listSupport{S}(xs)150proof151obtain⟨n, natural, equinumerous⟩:= finite152obtain⟨f, bijective⟩:= equinumerous153have inverse := converse.function_of_bijective with bijective154have injective := Bijective.injective with bijective155have function := Injective.function with injective156have reflexive : n ⊆ n bysimp [Subset]157have enumeration := FunctionBetween.list_cover_prefix with natural158obtain⟨xs, listX, covers⟩:= enumeration with converse(f, S, n), n, S, inverse, reflexive159refine⟨xs, listX, ?_⟩160intros x hx161have indexIn := FunctionBetween.apply_closed with function, hx162have recovered := Bijective.inverse_apply with bijective, hx163have member := covers with f(x), indexIn164 rwa recovered at member165166theorem Finite.subset (S T : Set)167requires finite : Finite(T)168requires subset : S ⊆ T169shows Finite(S)170proof171obtain⟨xs, listX, covers⟩:= Finite.list_cover with finite172have included := Subset.transitive with subset, covers173have subsets := listSupport.finite_subsets with listX174exact subsets with S, included175176theorem List.weaken (C D : Set) (xs : List(C))177requires subset : C ⊆ D178shows List(D, xs)179proof180induction xs181| List.nil =>typecheck182| List.cons(x, tail) using ih =>183have member := subset with x, assumption184typecheck185186theorem listSupport.change_carrier (C D : Set) (xs : List(C))187requires subset : C ⊆ D188shows listSupport{C}(xs) = listSupport(D, xs)189proof190induction xs191| List.nil =>simp [listSupport]192| List.cons(x, tail) using ih =>193have listD := List.weaken with*194have member := subset with x195simp [listSupport, ih]196197theorem Finite.cover_in (S C : Set)198requires finite : Finite(S)199requires subset : S ⊆ C200shows∃ xs, List(C, xs) ∧ S ⊆ listSupport{C}(xs)201proof202obtain⟨xs, listX, covers⟩:= Finite.list_cover with finite203have listC := List.weaken at S, C, xs with*204have same := listSupport.change_carrier at S, C, xs with*205rw same at covers206refine⟨xs, listC, covers⟩207208theorem Finite.union (S T : Set)209requiresleft : Finite(S)210requiresright : Finite(T)211shows Finite(S ∪ T)212proof213have subsetS := union2.subset_left at S, T214have subsetT := union2.subset_right at S, T215obtain⟨xs, listX, coverX⟩:= Finite.cover_in withleft, subsetS216obtain⟨ys, listY, coverY⟩:= Finite.cover_in withright, subsetT217have combined : List(S ∪ T, ListOps.append{S ∪ T}(ys, xs)) bytypecheck218have equation := listSupport.append at S ∪ T, ys, xs with*219have covered : S ∪ T ⊆ listSupport{S ∪ T}(ListOps.append{S ∪ T}(ys, xs))220rw equation221simp [Subset, union2.membership]222have subsets := listSupport.finite_subsets with combined223exact subsets with S ∪ T, covered224