Imports
/- Copyright (c) 2024 Joseph Tooby-Smith. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Joseph Tooby-Smith -/ module public import Mathlib.Algebra.GroupWithZero.Nat public import Mathlib.Algebra.Order.Group.Nat public import Mathlib.Data.Fin.SuccPred

List lemmas

@[expose] public sectionlemma insertIdx_map {I J : Type} (f : I J) : (i : ) (r : List I) (r0 : I) (List.insertIdx r i r0).map f = List.insertIdx (r.map f) i (f r0) I:TypeJ:Typef:I Jr0:IList.map f ([].insertIdx 0 r0) = (List.map f []).insertIdx 0 (f r0) I:TypeJ:Typef:I Jr0:IList.map f ([].insertIdx 0 r0) = (List.map f []).insertIdx 0 (f r0) All goals completed! 🐙 I:TypeJ:Typef:I Jn:r0:IList.map f ([].insertIdx (n + 1) r0) = (List.map f []).insertIdx (n + 1) (f r0) I:TypeJ:Typef:I Jn:r0:IList.map f ([].insertIdx (n + 1) r0) = (List.map f []).insertIdx (n + 1) (f r0) All goals completed! 🐙 I:TypeJ:Typef:I Ja:Ias:List Ir0:IList.map f ((a :: as).insertIdx 0 r0) = (List.map f (a :: as)).insertIdx 0 (f r0) I:TypeJ:Typef:I Ja:Ias:List Ir0:IList.map f ((a :: as).insertIdx 0 r0) = (List.map f (a :: as)).insertIdx 0 (f r0) All goals completed! 🐙 I:TypeJ:Typef:I Jn:a:Ias:List Ir0:IList.map f ((a :: as).insertIdx (n + 1) r0) = (List.map f (a :: as)).insertIdx (n + 1) (f r0) I:TypeJ:Typef:I Jn:a:Ias:List Ir0:IList.map f ((a :: as).insertIdx (n + 1) r0) = (List.map f (a :: as)).insertIdx (n + 1) (f r0) I:TypeJ:Typef:I Jn:a:Ias:List Ir0:IList.map f (as.insertIdx n r0) = (List.map f as).insertIdx n (f r0) All goals completed! 🐙lemma eraseIdx_sorted {I : Type} (le : I I Prop) : (r : List I) (n : ) List.Pairwise le r List.Pairwise le (r.eraseIdx n) I:Typele:I I Propx✝¹:x✝:List.Pairwise le []List.Pairwise le ([].eraseIdx x✝¹) I:Typele:I I Propx✝¹:x✝:List.Pairwise le []List.Pairwise le ([].eraseIdx x✝¹) All goals completed! 🐙 I:Typele:I I Propa:Ias:List Ih:List.Pairwise le (a :: as)List.Pairwise le ((a :: as).eraseIdx 0) I:Typele:I I Propa:Ias:List Ih:List.Pairwise le (a :: as)List.Pairwise le ((a :: as).eraseIdx 0) I:Typele:I I Propa:Ias:List Ih:List.Pairwise le (a :: as)List.Pairwise le as I:Typele:I I Propa:Ias:List Ih:(∀ (a' : I), a' as le a a') List.Pairwise le asList.Pairwise le as All goals completed! 🐙 I:Typele:I I Propa:Ias:List In:h:List.Pairwise le (a :: as)List.Pairwise le ((a :: as).eraseIdx (n + 1)) I:Typele:I I Propa:Ias:List In:h:List.Pairwise le (a :: as)List.Pairwise le ((a :: as).eraseIdx (n + 1)) I:Typele:I I Propa:Ias:List In:h:List.Pairwise le (a :: as)(∀ (a' : I), a' as.eraseIdx n le a a') List.Pairwise le (as.eraseIdx n) I:Typele:I I Propa:Ias:List In:h:(∀ (a' : I), a' as le a a') List.Pairwise le as(∀ (a' : I), a' as.eraseIdx n le a a') List.Pairwise le (as.eraseIdx n) I:Typele:I I Propa:Ias:List In:h:(∀ (a' : I), a' as le a a') List.Pairwise le as (a' : I), a' as.eraseIdx n le a a' I:Typele:I I Propa:Ias:List In:h:(∀ (a' : I), a' as le a a') List.Pairwise le asb:Ihb:b as.eraseIdx nle a b I:Typele:I I Propa:Ias:List In:h:(∀ (a' : I), a' as le a a') List.Pairwise le asb:Ihb:b as.eraseIdx nb as All goals completed! 🐙I:Typei:Ia1:Ias:List In:hn:n + 1 < (a1 :: as).lengthh:¬a1 as as.Nodupi = a1 i as i as[n] (i = a1 i as) ¬i = as[n] I:Typei:Ia1:Ias:List In:hn:n + 1 < (a1 :: as).lengthh:¬a1 as as.Nodupi = a1 i as ¬i = as[n] (i = a1 i as) ¬i = as[n] I:Typei:Ia1:Ias:List In:hn:n + 1 < (a1 :: as).lengthleft:¬a1 asright:as.Nodupi = a1 i as ¬i = as[n] (i = a1 i as) ¬i = as[n] I:Typei:Ia1:Ias:List In:hn:n + 1 < (a1 :: as).lengthleft:¬a1 asright:as.Nodupi = a1 i as ¬i = as[n] (i = a1 i as) ¬i = as[n]I:Typei:Ia1:Ias:List In:hn:n + 1 < (a1 :: as).lengthleft:¬a1 asright:as.Nodup(i = a1 i as) ¬i = as[n] i = a1 i as ¬i = as[n] I:Typei:Ia1:Ias:List In:hn:n + 1 < (a1 :: as).lengthleft:¬a1 asright:as.Nodupi = a1 i as ¬i = as[n] (i = a1 i as) ¬i = as[n] I:Typei:Ia1:Ias:List In:hn:n + 1 < (a1 :: as).lengthleft:¬a1 asright:as.Nodupa:i = a1 i as ¬i = as[n](i = a1 i as) ¬i = as[n] cases a with I:Typei:Ia1:Ias:List In:hn:n + 1 < (a1 :: as).lengthleft:¬a1 asright:as.Noduph:i = a1(i = a1 i as) ¬i = as[n] I:Typei:Ias:List In:right:as.Noduphn:n + 1 < (i :: as).lengthleft:¬i as(i = i i as) ¬i = as[n] I:Typei:Ias:List In:right:as.Noduphn:n + 1 < (i :: as).lengthleft:¬i as¬i = as[n] I:Typei:Ias:List In:right:as.Noduphn:n + 1 < (i :: as).lengthleft:¬i asi = as[n] False I:Typei:Ias:List In:right:as.Noduphn:n + 1 < (i :: as).lengthleft:¬i asa:i = as[n]False All goals completed! 🐙 I:Typei:Ia1:Ias:List In:hn:n + 1 < (a1 :: as).lengthleft:¬a1 asright:as.Noduph_1:i as ¬i = as[n](i = a1 i as) ¬i = as[n] All goals completed! 🐙 I:Typei:Ia1:Ias:List In:hn:n + 1 < (a1 :: as).lengthleft:¬a1 asright:as.Nodup(i = a1 i as) ¬i = as[n] i = a1 i as ¬i = as[n] I:Typei:Ia1:Ias:List In:hn:n + 1 < (a1 :: as).lengthleft:¬a1 asright:as.Nodupa:(i = a1 i as) ¬i = as[n]i = a1 i as ¬i = as[n] All goals completed! 🐙lemma insertIdx_eq_take_drop {I : Type} (i : I) : (r : List I) (n : Fin r.length.succ) List.insertIdx r n i = List.take n r ++ i :: r.drop n I:Typei:I[].insertIdx (↑0) i = List.take 0 [] ++ i :: List.drop 0 [] I:Typei:I[].insertIdx (↑0) i = List.take 0 [] ++ i :: List.drop 0 [] All goals completed! 🐙 I:Typei:Ia:Ias:List I(a :: as).insertIdx (↑0) i = List.take (↑0) (a :: as) ++ i :: List.drop (↑0) (a :: as) I:Typei:Ia:Ias:List I(a :: as).insertIdx (↑0) i = List.take (↑0) (a :: as) ++ i :: List.drop (↑0) (a :: as) All goals completed! 🐙 I:Typei:Ia:Ias:List In:h:n + 1 < (a :: as).length.succ(a :: as).insertIdx (↑n + 1, h) i = List.take (↑n + 1, h) (a :: as) ++ i :: List.drop (↑n + 1, h) (a :: as) I:Typei:Ia:Ias:List In:h:n + 1 < (a :: as).length.succ(a :: as).insertIdx (↑n + 1, h) i = List.take (↑n + 1, h) (a :: as) ++ i :: List.drop (↑n + 1, h) (a :: as) I:Typei:Ia:Ias:List In:h:n + 1 < (a :: as).length.succas.insertIdx n i = List.take n as ++ i :: List.drop n as All goals completed! 🐙@[simp] lemma insertIdx_length_fin {I : Type} (i : I) : (r : List I) (n : Fin r.length.succ) (List.insertIdx r n i).length = r.length.succ I:Typei:I([].insertIdx (↑0) i).length = [].length.succ I:Typei:I([].insertIdx (↑0) i).length = [].length.succ All goals completed! 🐙 I:Typei:Ia:Ias:List I((a :: as).insertIdx (↑0) i).length = (a :: as).length.succ I:Typei:Ia:Ias:List I((a :: as).insertIdx (↑0) i).length = (a :: as).length.succ All goals completed! 🐙 I:Typei:Ia:Ias:List In:h:n + 1 < (a :: as).length.succ((a :: as).insertIdx (↑n + 1, h) i).length = (a :: as).length.succ I:Typei:Ia:Ias:List In:h:n + 1 < (a :: as).length.succ((a :: as).insertIdx (↑n + 1, h) i).length = (a :: as).length.succ I:Typei:Ia:Ias:List In:h:n + 1 < (a :: as).length.succ(as.insertIdx n i).length = as.length + 1 All goals completed! 🐙@[simp] lemma insertIdx_getElem_fin {I : Type} (i : I) : (r : List I) (k : Fin r.length.succ) (m : Fin r.length) (List.insertIdx r k i)[(k.succAbove m).val] = r[m.val] I:Typei:Im:Fin [].length([].insertIdx (↑0) i)[(succAbove 0 m)] = [][m] I:Typei:Im:Fin [].length([].insertIdx (↑0) i)[(succAbove 0 m)] = [][m] All goals completed! 🐙 I:Typei:Ia:Ias:List Im:Fin (a :: as).length((a :: as).insertIdx (↑0) i)[(succAbove 0 m)] = (a :: as)[m] I:Typei:Ia:Ias:List Im:Fin (a :: as).length((a :: as).insertIdx (↑0) i)[(succAbove 0 m)] = (a :: as)[m] All goals completed! 🐙 I:Typei:Ia:Ias:List In:h:n + 1 < (a :: as).length.succh0:0 < (a :: as).length((a :: as).insertIdx (↑n + 1, h) i)[(n + 1, h.succAbove 0, h0)] = (a :: as)[0, h0] I:Typei:Ia:Ias:List In:h:n + 1 < (a :: as).length.succh0:0 < (a :: as).length((a :: as).insertIdx (↑n + 1, h) i)[(n + 1, h.succAbove 0, h0)] = (a :: as)[0, h0] All goals completed! 🐙 I:Typei:Ia:Ias:List In:h:n + 1 < (a :: as).length.succm:hm:m + 1 < (a :: as).length((a :: as).insertIdx (↑n + 1, h) i)[(n + 1, h.succAbove m + 1, hm)] = (a :: as)[m + 1, hm] I:Typei:Ia:Ias:List In:h:n + 1 < (a :: as).length.succm:hm:m + 1 < (a :: as).length((a :: as).insertIdx (↑n + 1, h) i)[(n + 1, h.succAbove m + 1, hm)] = (a :: as)[m + 1, hm] I:Typei:Ia:Ias:List In:h:n + 1 < (a :: as).length.succm:hm:m + 1 < (a :: as).length(a :: as.insertIdx n i)[(n + 1, h.succAbove m + 1, hm)] = as[m] conv_rhs => I:Typei:Ia:Ias:List In:h:n + 1 < (a :: as).length.succm:hm:m + 1 < (a :: as).length| (as.insertIdx (↑n, ) i)[(n, .succAbove m, )] I:Typei:Ia:Ias:List In:h:n + 1 < (a :: as).length.succm:hm:m + 1 < (a :: as).length(a :: as.insertIdx n i)[(if m < n then m + 1, else m + 1 + 1, )] = (as.insertIdx n i)[(if m < n then m, else m + 1, )] I:Typei:Ia:Ias:List In:h:n + 1 < (a :: as).length.succm:hm:m + 1 < (a :: as).lengthh✝:m < n(a :: as.insertIdx n i)[m + 1, ] = (as.insertIdx n i)[m, ]I:Typei:Ia:Ias:List In:h:n + 1 < (a :: as).length.succm:hm:m + 1 < (a :: as).lengthh✝:¬m < n(a :: as.insertIdx n i)[m + 1 + 1, ] = (as.insertIdx n i)[m + 1, ] I:Typei:Ia:Ias:List In:h:n + 1 < (a :: as).length.succm:hm:m + 1 < (a :: as).lengthh✝:m < n(a :: as.insertIdx n i)[m + 1, ] = (as.insertIdx n i)[m, ] All goals completed! 🐙 I:Typei:Ia:Ias:List In:h:n + 1 < (a :: as).length.succm:hm:m + 1 < (a :: as).lengthh✝:¬m < n(a :: as.insertIdx n i)[m + 1 + 1, ] = (as.insertIdx n i)[m + 1, ] All goals completed! 🐙lemma insertIdx_eraseIdx_fin {I : Type} : (r : List I) (k : Fin r.length) (List.eraseIdx r k).insertIdx k r[k] = r I:Typek:Fin [].length([].eraseIdx k).insertIdx k [][k] = [] I:Typek:Fin [].length([].eraseIdx k).insertIdx k [][k] = [] All goals completed! 🐙 I:Typea:Ias:List Ih:0 < (a :: as).length((a :: as).eraseIdx 0, h).insertIdx (↑0, h) (a :: as)[0, h] = a :: as I:Typea:Ias:List Ih:0 < (a :: as).length((a :: as).eraseIdx 0, h).insertIdx (↑0, h) (a :: as)[0, h] = a :: as All goals completed! 🐙 I:Typea:Ias:List In:h:n + 1 < (a :: as).length((a :: as).eraseIdx n + 1, h).insertIdx (↑n + 1, h) (a :: as)[n + 1, h] = a :: as I:Typea:Ias:List In:h:n + 1 < (a :: as).length((a :: as).eraseIdx n + 1, h).insertIdx (↑n + 1, h) (a :: as)[n + 1, h] = a :: as I:Typea:Ias:List In:h:n + 1 < (a :: as).length(as.eraseIdx n).insertIdx n as[n] = as All goals completed! 🐙lemma insertIdx_length_fst_append {I : Type} (φ : I) : (φs φs' : List I) List.insertIdx (φs ++ φs') φs.length φ = (φs ++ φ :: φs') I:Typeφ:Iφs':List I([] ++ φs').insertIdx [].length φ = [] ++ φ :: φs' I:Typeφ:Iφs':List I([] ++ φs').insertIdx [].length φ = [] ++ φ :: φs' All goals completed! 🐙 I:Typeφ:Iφ':Iφs:List Iφs':List I(φ' :: φs ++ φs').insertIdx (φ' :: φs).length φ = φ' :: φs ++ φ :: φs' I:Typeφ:Iφ':Iφs:List Iφs':List I(φ' :: φs ++ φs').insertIdx (φ' :: φs).length φ = φ' :: φs ++ φ :: φs' I:Typeφ:Iφ':Iφs:List Iφs':List I(φs ++ φs').insertIdx φs.length φ = φs ++ φ :: φs' All goals completed! 🐙lemma get_eq_insertIdx_succAbove {I : Type} (i : I) (r : List I) (k : Fin r.length.succ) : r.get = (List.insertIdx r k i).get (finCongr (insertIdx_length_fin i r k).symm) k.succAbove := I:Typei:Ir:List Ik:Fin r.length.succr.get = (r.insertIdx (↑k) i).get (finCongr ) k.succAbove I:Typei✝:Ir:List Ik:Fin r.length.succi:Fin r.lengthr.get i = ((r.insertIdx (↑k) i✝).get (finCongr ) k.succAbove) i All goals completed! 🐙lemma take_insert_same {I : Type} (i : I) : (n : ) (r : List I) List.take n (List.insertIdx r n i) = List.take n r I:Typei:Ix✝:List IList.take 0 (x✝.insertIdx 0 i) = List.take 0 x✝ I:Typei:Ix✝:List IList.take 0 (x✝.insertIdx 0 i) = List.take 0 x✝ All goals completed! 🐙 I:Typei:In✝:List.take (n✝ + 1) ([].insertIdx (n✝ + 1) i) = List.take (n✝ + 1) [] I:Typei:In✝:List.take (n✝ + 1) ([].insertIdx (n✝ + 1) i) = List.take (n✝ + 1) [] All goals completed! 🐙 I:Typei:In:a:Ias:List IList.take (n + 1) ((a :: as).insertIdx (n + 1) i) = List.take (n + 1) (a :: as) I:Typei:In:a:Ias:List IList.take (n + 1) ((a :: as).insertIdx (n + 1) i) = List.take (n + 1) (a :: as) I:Typei:In:a:Ias:List IList.take n (as.insertIdx n i) = List.take n as All goals completed! 🐙lemma take_eraseIdx_same {I : Type} : (n : ) (r : List I) List.take n (List.eraseIdx r n) = List.take n r I:Typex✝:List IList.take 0 (x✝.eraseIdx 0) = List.take 0 x✝ I:Typex✝:List IList.take 0 (x✝.eraseIdx 0) = List.take 0 x✝ All goals completed! 🐙 I:Typen✝:List.take (n✝ + 1) ([].eraseIdx (n✝ + 1)) = List.take (n✝ + 1) [] I:Typen✝:List.take (n✝ + 1) ([].eraseIdx (n✝ + 1)) = List.take (n✝ + 1) [] All goals completed! 🐙 I:Typen:a:Ias:List IList.take (n + 1) ((a :: as).eraseIdx (n + 1)) = List.take (n + 1) (a :: as) I:Typen:a:Ias:List IList.take (n + 1) ((a :: as).eraseIdx (n + 1)) = List.take (n + 1) (a :: as) I:Typen:a:Ias:List IList.take n (as.eraseIdx n) = List.take n as All goals completed! 🐙I:Typex✝¹:List Ix✝:0 < x✝¹.lengthx✝¹.head :: x✝¹.tail = x✝¹ All goals completed! 🐙 I:Typen:hn:n + 1 < [].length[][n + 1] :: List.drop (n + 1) ([].eraseIdx (n + 1)) = List.drop (n + 1) [] I:Typen:hn:n + 1 < [].length[][n + 1] :: List.drop (n + 1) ([].eraseIdx (n + 1)) = List.drop (n + 1) [] All goals completed! 🐙 I:Typen:a:Ias:List Ihn:n + 1 < (a :: as).length(a :: as)[n + 1] :: List.drop (n + 1) ((a :: as).eraseIdx (n + 1)) = List.drop (n + 1) (a :: as) I:Typen:a:Ias:List Ihn:n + 1 < (a :: as).length(a :: as)[n + 1] :: List.drop (n + 1) ((a :: as).eraseIdx (n + 1)) = List.drop (n + 1) (a :: as) I:Typen:a:Ias:List Ihn:n + 1 < (a :: as).lengthas[n] :: List.drop n (as.eraseIdx n) = List.drop n as All goals completed! 🐙lemma take_insert_gt {I : Type} (i : I) : (n m : ) (h : n < m) (r : List I) List.take n (List.insertIdx r m i) = List.take n r I:Typei:Ix✝¹:0 < 0x✝:List IList.take 0 (x✝.insertIdx 0 i) = List.take 0 x✝ I:Typei:Ix✝¹:0 < 0x✝:List IList.take 0 (x✝.insertIdx 0 i) = List.take 0 x✝ All goals completed! 🐙 I:Typei:Im:x✝¹:0 < m + 1x✝:List IList.take 0 (x✝.insertIdx (m + 1) i) = List.take 0 x✝ I:Typei:Im:x✝¹:0 < m + 1x✝:List IList.take 0 (x✝.insertIdx (m + 1) i) = List.take 0 x✝ All goals completed! 🐙 I:Typei:In:m:x✝:n + 1 < m + 1List.take (n + 1) ([].insertIdx (m + 1) i) = List.take (n + 1) [] I:Typei:In:m:x✝:n + 1 < m + 1List.take (n + 1) ([].insertIdx (m + 1) i) = List.take (n + 1) [] All goals completed! 🐙 I:Typei:In:m:h:n + 1 < m + 1a:Ias:List IList.take (n + 1) ((a :: as).insertIdx (m + 1) i) = List.take (n + 1) (a :: as) I:Typei:In:m:h:n + 1 < m + 1a:Ias:List IList.take (n + 1) ((a :: as).insertIdx (m + 1) i) = List.take (n + 1) (a :: as) I:Typei:In:m:h:n + 1 < m + 1a:Ias:List IList.take n (as.insertIdx m i) = List.take n as All goals completed! 🐙I:Typei:In:m:h:m + 1 n + 1a:Ias:List Ihm:m + 1 (a :: as).lengthhp:(i :: a :: List.take n as).Perm (a :: i :: List.take n as)(a :: List.take (n + 1) (as.insertIdx m i)).Perm (i :: a :: List.take n as) I:Typei:In:m:h:m + 1 n + 1a:Ias:List Ihm:m + 1 (a :: as).lengthhp:(i :: a :: List.take n as).Perm (a :: i :: List.take n as)(a :: List.take (n + 1) (as.insertIdx m i)).Perm (a :: i :: List.take n as) I:Typei:In:m:h:m + 1 n + 1a:Ias:List Ihm:m + 1 (a :: as).lengthhp:(i :: a :: List.take n as).Perm (a :: i :: List.take n as)(List.take (n + 1) (as.insertIdx m i)).Perm (i :: List.take n as) All goals completed! 🐙