1-- Lists as finite sequences: a function on a natural number n is the2-- entry map of a list of length n, read through the coefficient window3-- Part of Cumulus, the Grace17 mathematics library.4-- Copyright (c) 2026 Grant Passmore.5-- Released under the Apache License 2.0. See LICENSE in the repository root.6-- Authors: Grant Passmore78module Grace.Cumulus.List.Sequence9import Algebra.IndexedLists1011-- The window laws need the values only at the positions read.12theorem coefficientWindow.closed_below (A f : Set, start n : Nat)13requires values : ∀ k, Nat(k) → k < n → f(start + k) ∈ A14shows List(A, coefficientWindow(f, start, n))15proof16induction n generalizing start17| zero =>18intros start startNat values19rw coefficientWindow20typecheck21| succ(k) using ih =>22intros start startNat values23have zeroNat : Nat(0) bytypecheck24have below : 0 < succ(k) byarith25have head := values with0, zeroNat, below26rw add.right_unit at head27have shifted : ∀ j, Nat(j) → j < k → f(succ(start) + j) ∈ A28intros j jNat bound29have successorNat : Nat(succ(j)) bytypecheck30have bound2 : succ(j) < succ(k) byarith31have value := values with succ(j), successorNat, bound232have shift : succ(start) + j = start + succ(j) bysimp [add, add.succ_right]33rw shift34exact value35have tail := ih with succ(start), shifted36rw coefficientWindow37typecheck3839theorem coefficientWindow.length_below (A f : Set, start n : Nat)40requires values : ∀ k, Nat(k) → k < n → f(start + k) ∈ A41shows length{A}(coefficientWindow(f, start, n)) = n42proof43induction n generalizing start44| zero =>45intros start startNat values46rw [coefficientWindow, length.nil]47rfl48| succ(k) using ih =>49intros start startNat values50have zeroNat : Nat(0) bytypecheck51have below : 0 < succ(k) byarith52have head := values with0, zeroNat, below53rw add.right_unit at head54have shifted : ∀ j, Nat(j) → j < k → f(succ(start) + j) ∈ A55intros j jNat bound56have successorNat : Nat(succ(j)) bytypecheck57have bound2 : succ(j) < succ(k) byarith58have value := values with succ(j), successorNat, bound259have shift : succ(start) + j = start + succ(j) bysimp [add, add.succ_right]60rw shift61exact value62have tail := coefficientWindow.closed_below at A, f, succ(start), k with shifted63have length := ih with succ(start), shifted64rw [coefficientWindow, length.cons, length]65rfl6667theorem coefficientWindow.coefficient_below (A z f : Set, start n k : Nat)68requires values : ∀ j, Nat(j) → j < n → f(start + j) ∈ A69requires bound : k < n70shows listCoefficient{A}(z, coefficientWindow(f, start, n), k) = f(start + k)71proof72induction n generalizing start k73| zero =>74intros start k startNat kNat values bound75exfalso76arith77| succ(t) using ih =>78intros start k startNat kNat values bound79have zeroNat : Nat(0) bytypecheck80have below : 0 < succ(t) byarith81have head := values with0, zeroNat, below82rw add.right_unit at head83have shifted : ∀ j, Nat(j) → j < t → f(succ(start) + j) ∈ A84intros j jNat jBound85have successorNat : Nat(succ(j)) bytypecheck86have bound2 : succ(j) < succ(t) byarith87have value := values with succ(j), successorNat, bound288have shift : succ(start) + j = start + succ(j) bysimp [add, add.succ_right]89rw shift90exact value91have tail := coefficientWindow.closed_below at A, f, succ(start), t with shifted92have shape := natural.zero_or_successor at k with*93cases shape with zero | successor94 . rw [zero, coefficientWindow, listCoefficient.zero, add.right_unit]95rfl96 . obtain⟨r, rNat, equal⟩:= successor97rw equal at bound98have smaller : r < t byarith99have result := ih with succ(start), r, rNat, shifted, smaller100have shift : succ(start) + r = start + succ(r) bysimp [add, add.succ_right]101rw [equal, coefficientWindow, listCoefficient.succ, result, shift]102rfl103104-- Every function on a natural number n into A is the entry map of a list105-- of length n.106theorem List.of_function (A f z : Set, n : Nat)107requires function : f : n → A108shows∃ xs, List(A, xs) ∧ length{A}(xs) = n ∧109 (∀ k, Nat(k) → k < n → listCoefficient{A}(z, xs, k) = f(k))110proof111have values : ∀ k, Nat(k) → k < n → f(0+ k) ∈ A112intros k kNat bound113have member := membership.of_Less with kNat, bound114have shift : 0+ k = k115rw add.commutative116exact add.right_unit117rw shift118exact FunctionBetween.apply_closed with function, member119witness coefficientWindow(f, 0, n)120have closed := coefficientWindow.closed_below with values121have length := coefficientWindow.length_below with values122refine⟨closed, length, ?_⟩123intros k kNat bound124have entry := coefficientWindow.coefficient_below at A, z, f, 0, n, k with values, bound125have shift : 0+ k = k126rw add.commutative127exact add.right_unit128 rwa shift at entry129