1-- Lifting a Kuhn simplex of the lower cube to one whose far-wall face2-- restricts back to it: the base gains the value p − 1 at the last3-- coordinate and the permutation sends 0 there first4-- 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.FixedPoint.KuhnLift10import KuhnWallSimplex1112def liftBase (m q b : Set) : Set:= b ∪ constantFunction({m}, ℕ, q)1314def liftPerm (m u : Set) : Set:= unrotated(succ(m), u ∪ constantFunction({m}, {m}, m))1516theorem successor.as_union (m : Nat)17shows m ∪ {m} = succ(m)18proof19have asInsert := natural.successor_as_insert at m20have unfolded : insert(m, m) = {m} ∪ m21unfold insert22rfl23rw [asInsert, unfolded]24exact union2.commutative2526theorem liftBase.function (m q : Nat) (b : Set)27requires baseFunction : b : m → ℕ28shows liftBase(m, q, b) : succ(m) → ℕ29proof30have qNat : Nat(q) bytypecheck31have qIn := nat.omega.forward with qNat32have constant := constantFunction.function at {m}, ℕ, q with qIn33have disjoint := cubeExtend.disjoint at m34have union := FunctionBetween.union_disjoint with baseFunction, constant, disjoint35have domain := successor.as_union at m36have codomain := union2.idempotent at ℕ37rw [domain, codomain] at union38have same : liftBase(m, q, b) = b ∪ constantFunction({m}, ℕ, q)39unfold liftBase40rfl41 rwa same4243theorem liftBase.apply_below (m q : Nat) (b j : Set)44requires baseFunction : b : m → ℕ45requires hj : j ∈ m46shows liftBase(m, q, b)(j) = b(j)47proof48have qNat : Nat(q) bytypecheck49have qIn := nat.omega.forward with qNat50have constant := constantFunction.function at {m}, ℕ, q with qIn51have disjoint := cubeExtend.disjoint at m52have same : liftBase(m, q, b) = b ∪ constantFunction({m}, ℕ, q)53unfold liftBase54rfl55rw same56exact FunctionBetween.union_apply_left with baseFunction, constant, disjoint, hj5758theorem liftBase.apply_top (m q : Nat) (b : Set)59requires baseFunction : b : m → ℕ60shows liftBase(m, q, b)(m) = q61proof62have qNat : Nat(q) bytypecheck63have qIn := nat.omega.forward with qNat64have constant := constantFunction.function at {m}, ℕ, q with qIn65have disjoint := cubeExtend.disjoint at m66have mIn : m ∈ {m}67apply singleton.membership.backward68rfl69have same : liftBase(m, q, b) = b ∪ constantFunction({m}, ℕ, q)70unfold liftBase71rfl72rw same73have value := FunctionBetween.union_apply_right with baseFunction, constant, disjoint, mIn74rw value75exact constantFunction.apply with mIn, qIn7677theorem liftBase.restrict (m q : Nat) (b : Set)78requires baseFunction : b : m → ℕ79shows restrict(liftBase(m, q, b), m) = b80proof81have lifted := liftBase.function at m, q, b with baseFunction82have mSubset := successor.subset at m83have restricted := restrict.domain_function with lifted, mSubset84apply FunctionBetween.ext with restricted, baseFunction85intros j hj86have value := restrict.domain_apply with lifted, mSubset, hj87rw value88exact liftBase.apply_below with baseFunction, hj8990theorem constantFunction.bijective_singleton (a : Set)91shows BijectiveBetween(constantFunction({a}, {a}, a), {a}, {a})92proof93have aIn : a ∈ {a}94apply singleton.membership.backward95rfl96have function := constantFunction.function at {a}, {a}, a with aIn97constructor98 . apply Injective.of_cancel with function99intros x hx y hy same100have xEq := singleton.membership.forward with hx101have yEq := singleton.membership.forward with hy102rw [xEq, yEq]103rfl104 . constructor105 . exact function106 . intros y hy107have yEq := singleton.membership.forward with hy108witness a109constructor110 . exact aIn111 . have edge := FunctionBetween.relates_apply with function, aIn112have value := constantFunction.apply with aIn, aIn113rw value at edge114 rwa yEq115116theorem liftPerm.union_bijective (m : Nat) (u : Set)117requires updBijective : BijectiveBetween(u, m, m)118shows BijectiveBetween(u ∪ constantFunction({m}, {m}, m), succ(m), succ(m))119proof120have single := constantFunction.bijective_singleton at m121have disjoint := cubeExtend.disjoint at m122have union := Bijective.union_disjoint with updBijective, single, disjoint, disjoint123have domain := successor.as_union at m124 rwa domain at union125126theorem liftPerm.bijective (m : Nat) (u : Set)127requires updBijective : BijectiveBetween(u, m, m)128shows BijectiveBetween(liftPerm(m, u), succ(m), succ(m))129proof130have union := liftPerm.union_bijective with updBijective131have same : liftPerm(m, u) = unrotated(succ(m), u ∪ constantFunction({m}, {m}, m))132unfold liftPerm133rfl134rw same135exact unrotated.bijective with union136137theorem liftPerm.zero (m : Nat) (u : Set)138requires updBijective : BijectiveBetween(u, m, m)139shows liftPerm(m, u)(0) = m140proof141have union := liftPerm.union_bijective with updBijective142have uFunction := Injective.function with (Bijective.injective with updBijective)143have mIn : m ∈ {m}144apply singleton.membership.backward145rfl146have constant := constantFunction.function at {m}, {m}, m with mIn147have disjoint := cubeExtend.disjoint at m148have mInSucc := bootstrap.succ.self at m149have top : succ(m) = succ(m) byrfl150have same : liftPerm(m, u) = unrotated(succ(m), u ∪ constantFunction({m}, {m}, m))151unfold liftPerm152rfl153rw same154have wrap := unrotated.wrap with union, mInSucc, top155rw wrap156have value := FunctionBetween.union_apply_right with uFunction, constant, disjoint, mIn157rw value158exact constantFunction.apply with mIn, mIn159160theorem liftPerm.step (m : Nat) (u l : Set)161requires updBijective : BijectiveBetween(u, m, m)162requires hl : l ∈ m163shows liftPerm(m, u)(succ(l)) = u(l)164proof165have union := liftPerm.union_bijective with updBijective166have uFunction := Injective.function with (Bijective.injective with updBijective)167have mIn : m ∈ {m}168apply singleton.membership.backward169rfl170have constant := constantFunction.function at {m}, {m}, m with mIn171have disjoint := cubeExtend.disjoint at m172have lIn := membership.into_successor with hl173have lNat := natural.member at m with hl174have lLess := Less.of_membership with hl175have sLess : succ(l) < succ(m) byarith176have sIn := membership.of_Less with sLess177have same : liftPerm(m, u) = unrotated(succ(m), u ∪ constantFunction({m}, {m}, m))178unfold liftPerm179rfl180rw same181have step := unrotated.step with union, lIn, sIn182rw step183exact FunctionBetween.union_apply_left with uFunction, constant, disjoint, hl184185theorem wallPerm.lift (m : Nat) (u : Set)186requires updBijective : BijectiveBetween(u, m, m)187shows wallPerm(m, liftPerm(m, u)) = u188proof189have lifted := liftPerm.bijective with updBijective190have zero := liftPerm.zero with updBijective191have wallBijective := wallPerm.bijective with lifted, zero192have wallFunction := Injective.function with (Bijective.injective with wallBijective)193have uFunction := Injective.function with (Bijective.injective with updBijective)194apply FunctionBetween.ext with wallFunction, uFunction195intros l hl196have value := wallPerm.value with lifted, hl197rw value198exact liftPerm.step with updBijective, hl199200theorem kuhnSimplex.lift_in_family (m q : Nat) (b u : Set)201requires baseFunction : b : m → ℕ202requires bounds : ∀ j ∈ m, b(j) < succ(q)203requires updBijective : BijectiveBetween(u, m, m)204shows kuhnSimplex(succ(m), liftBase(m, q, b), liftPerm(m, u)) ∈ kuhnSimplices(succ(q), succ(m))205proof206have liftFunction := liftBase.function at m, q, b with baseFunction207have lifted := liftPerm.bijective with updBijective208have liftBounds : ∀ j ∈ succ(m), liftBase(m, q, b)(j) < succ(q)209intros j hj210havesplit:= bootstrap.succ.membership.forward with hj211casessplitwith below | same212 . have value := liftBase.apply_below at m, q, b, j with baseFunction, below213rw value214exact bounds with below215 . rw same216have value := liftBase.apply_top at m, q, b with baseFunction217rw value218arith219exact kuhnSimplex.in_family with liftFunction, lifted, liftBounds220221-- Every vertex but the bottom of the lifted simplex lies on the far wall.222theorem kuhnSimplex.lift_top_wall (m q : Nat) (b u x : Set)223requires baseFunction : b : m → ℕ224requires updBijective : BijectiveBetween(u, m, m)225requires hx : x ∈ kuhnSimplex(succ(m), liftBase(m, q, b), liftPerm(m, u)) ∖226 {kuhnVertex(succ(m), liftBase(m, q, b), liftPerm(m, u))(0)}227shows x(m) = succ(q)228proof229have liftFunction := liftBase.function at m, q, b with baseFunction230have mIn := bootstrap.succ.self at m231have parts := difference.singleton_membership.forward with hx232obtain⟨inSpace, i, hi, shape⟩:= kuhnSimplex.membership.forward with parts.left233have iNat := natural.member at succ(succ(m)) with hi234have zeroInI : 0∈ i235havesplit:= natural.zero_or_successor with iNat236casessplitwith zero | successor237 . exfalso238apply parts.right239rw [shape, zero]240rfl241 . obtain⟨k, kNat, iEq⟩:= successor242rw iEq243have less : 0 < succ(k) byarith244exact membership.of_Less with less245have zero := liftPerm.zero with updBijective246have raisedM : m ∈ raised(succ(m), liftPerm(m, u), i)247apply raised.membership.backward248constructor249 . exact mIn250 . witness0251constructor252 . exact zeroInI253 . symm254exact zero255have coordinate := kuhnVertex.coordinate at succ(m), liftBase(m, q, b), liftPerm(m, u), i, m with liftFunction, hi, mIn256have one := indicator.member with raisedM257have top := liftBase.apply_top at m, q, b with baseFunction258rw [shape, coordinate, one, top]259exact add.right_one260