{-# OPTIONS --without-K --rewriting #-}
module Pi.Common.ListFinLListEquiv where
open import lib.Base
open import lib.types.Nat using (_+_; O<S; <-ap-S; <-has-all-paths) renaming (_<_ to _<N_)
open import lib.types.Sigma
open import lib.PathGroupoid
open import lib.types.Fin
open import lib.Equivalence
open import lib.types.List
open import Pi.Common.Extra
open import Pi.Common.Arithmetic
open import Pi.Common.InequalityEquiv
open import Pi.Common.ListN renaming (_++_ to _++ℕ_)
open import Pi.Common.LList
module _ {n : ℕ} where
toLList : List (Fin n) -> (LList n)
toLList nil = nil , nil
toLList (x :: l) =
let rec-l , rec-p = toLList l
in ((x . fst) ∷ rec-l) , ((x .fst) :⟨ –> <N≃< (x .snd) ⟩: rec-p)
fromLList : (LList n) -> List (Fin n)
fromLList (nil , nil) = nil
fromLList ((x ∷ fst) , (.x :⟨ px ⟩: snd)) = (x , (<– <N≃< px)) :: fromLList (fst , snd)
abstract
toLList∘fromLList : (l : LList n) → toLList (fromLList l) == l
toLList∘fromLList (nil , nil) = idp
toLList∘fromLList ((x ∷ l) , (.x :⟨ x₁ ⟩: lp)) =
LList-eq (head+tail idp (ap fst (toLList∘fromLList (l , lp))))
fromLList∘toLList : (l : List (Fin n)) → fromLList (toLList l) == l
fromLList∘toLList nil = idp
fromLList∘toLList ((x , xp) :: l) = List=-out ((pair= idp (<-has-all-paths _ xp)) , fromLList∘toLList l)
List≃LList : List (Fin n) ≃ (LList n)
List≃LList = equiv toLList fromLList toLList∘fromLList fromLList∘toLList
fromLList-++ : (l r : LList n) -> (fromLList l ++ fromLList r) == fromLList (((l .fst) ++ℕ (r .fst)) , (>>-++ (l .snd) (r .snd)))
fromLList-++ (nil , nil) r = idp
fromLList-++ ((x ∷ l) , (.x :⟨ x₁ ⟩: lp)) r = List=-out (idp , (fromLList-++ (l , lp) r))
fromLList-++-w : (l r m : LList n) -> ((l .fst) ++ℕ (r .fst) == m .fst) -> (fromLList l ++ fromLList r) == (fromLList m)
fromLList-++-w l r m p =
let m' = ((l .fst) ++ℕ (r .fst)) , (>>-++ (l .snd) (r .snd))
lemma = LList-eq {_} {m'} {m} p
in fromLList-++ l r ∙ ap fromLList lemma
toLList-++ : (l r : List (Fin n)) -> (toLList (l ++ r)) .fst == ((toLList l) .fst) ++ℕ ((toLList r) .fst)
toLList-++ nil r = idp
toLList-++ (x :: l) r =
let rec = toLList-++ l r
in head+tail idp rec
rev-reverse : (l : List (Fin n)) -> LList-rev (toLList (reverse l)) == (toLList l)
rev-reverse nil = idp
rev-reverse (x :: l) =
let rec = rev-reverse l
in LList-eq ((ap rev (toLList-++ (reverse l) (x :: nil)) ∙ rev-++ (fst (toLList (reverse l))) ((x .fst) ∷ nil)) ∙ head+tail idp (ap fst rec))