add a GetV-to-GetL transformer
[~helmut/bidiragda.git] / LiftGet.agda
1 module LiftGet where
2
3 open import Data.Unit using (⊤ ; tt)
4 open import Data.Nat using (ℕ ; suc)
5 open import Data.Vec using (Vec ; toList ; fromList) renaming ([] to []V ; _∷_ to _∷V_ ; map to mapV)
6 open import Data.List using (List ; [] ; _∷_ ; length ; replicate ; map)
7 open import Data.List.Properties using (length-map)
8 open import Data.Product using (∃ ; _,_ ; proj₁ ; proj₂)
9 open import Function using (_∘_ ; flip ; const)
10 open import Relation.Binary.Core using (_≡_)
11 open import Relation.Binary.PropositionalEquality using (_≗_ ; sym ; cong ; refl ; subst ; trans ; proof-irrelevance)
12 open Relation.Binary.PropositionalEquality.≡-Reasoning using (begin_ ; _≡⟨_⟩_ ; _∎)
13
14 import FreeTheorems
15 open import Generic using (length-replicate ; subst-cong ; subst-fromList ; subst-subst ; toList-fromList ; toList-subst)
16 open FreeTheorems.ListList using (get-type) renaming (free-theorem to free-theoremL ; Get to GetL ; module Get to GetL)
17 open FreeTheorems.VecVec using () renaming (get-type to getV-type ; Get to GetV ; module Get to GetV)
18
19 getVec-to-getList : {getlen : ℕ → ℕ} → (getV-type getlen) → get-type
20 getVec-to-getList get = toList ∘ get ∘ fromList
21
22 fromList∘map : {α β : Set} → (f : α → β) → (l : List α) → fromList (map f l) ≡ subst (Vec β) (sym (length-map f l)) (mapV f (fromList l))
23 fromList∘map f []       = refl
24 fromList∘map f (x ∷ xs) rewrite fromList∘map f xs = trans (subst-cong (Vec _) (_∷V_ (f x)) (sym (length-map f xs)) (mapV f (fromList xs)))
25                                                           (cong (flip (subst (Vec _)) (f x ∷V mapV f (fromList xs))) (proof-irrelevance (cong suc (sym (length-map f xs)))
26                                                                                                                                         (sym (cong suc (length-map f xs)))))
27
28 toList∘map : {α β : Set} {n : ℕ} → (f : α → β) → (v : Vec α n) → toList (mapV f v) ≡ map f (toList v)
29 toList∘map f []V       = refl
30 toList∘map f (x ∷V xs) = cong (_∷_ (f x)) (toList∘map f xs)
31
32 GetV-to-GetL : GetV → GetL
33 GetV-to-GetL getrecord = record { get = toList ∘ get ∘ fromList; free-theorem = ft }
34   where open GetV getrecord
35         ft : {α β : Set} → (f : α → β) → (xs : List α) → toList (get (fromList (map f xs))) ≡ map f (toList (get (fromList xs)))
36         ft f xs = begin
37           toList (get (fromList (map f xs)))
38             ≡⟨ cong (toList ∘ get) (fromList∘map f xs) ⟩
39           toList (get (subst (Vec _) (sym (length-map f xs)) (mapV f (fromList xs))))
40             ≡⟨ cong toList (subst-cong (Vec _) get (sym (length-map f xs)) (mapV f (fromList xs))) ⟩
41           toList (subst (Vec _) (cong getlen (sym (length-map f xs))) (get (mapV f (fromList xs))))
42             ≡⟨ toList-subst (get (mapV f (fromList xs))) (cong getlen (sym (length-map f xs))) ⟩
43           toList (get (mapV f (fromList xs)))
44             ≡⟨ cong toList (free-theorem f (fromList xs)) ⟩
45           toList (mapV f (get (fromList xs)))
46             ≡⟨ toList∘map f (get (fromList xs)) ⟩
47           map f (toList (get (fromList xs))) ∎
48
49 getList-to-getlen : get-type → ℕ → ℕ
50 getList-to-getlen get = length ∘ get ∘ flip replicate tt
51
52 replicate-length : {A : Set} → (l : List A) → map (const tt) l ≡ replicate (length l) tt
53 replicate-length [] = refl
54 replicate-length (_ ∷ l) = cong (_∷_ tt) (replicate-length l)
55
56 getList-length : (get : get-type) → {B : Set} → (l : List B) → length (get l) ≡ getList-to-getlen get (length l)
57 getList-length get l = begin
58   length (get l)
59     ≡⟨ sym (length-map (const tt) (get l)) ⟩
60   length (map (const tt) (get l))
61     ≡⟨ cong length (sym (free-theoremL get (const tt) l)) ⟩
62   length (get (map (const tt) l))
63     ≡⟨ cong (length ∘ get) (replicate-length l) ⟩
64   length (get (replicate (length l) tt)) ∎
65
66 length-toList : {A : Set} {n : ℕ} → (v : Vec A n) → length (toList v) ≡ n
67 length-toList []V = refl
68 length-toList (x ∷V xs) = cong suc (length-toList xs) 
69
70 getList-to-getVec-length-property : (get : get-type) → {C : Set} → {m : ℕ} → (v : Vec C m) → length (get (toList v)) ≡ length (get (replicate m tt))
71 getList-to-getVec-length-property get {_} {m} v = begin
72     length (get (toList v))
73       ≡⟨ getList-length get (toList v) ⟩
74     length (get (replicate (length (toList v)) tt))
75       ≡⟨ cong (length ∘ get ∘ flip replicate tt) (length-toList v) ⟩
76     length (get (replicate m tt)) ∎
77
78 getList-to-getVec : get-type → ∃ λ (getlen : ℕ → ℕ) → (getV-type getlen)
79 getList-to-getVec get = getlen , get'
80   where getlen : ℕ → ℕ
81         getlen = getList-to-getlen get
82         get' : {C : Set} {m : ℕ} → Vec C m → Vec C (getlen m)
83         get' {C} v = subst (Vec C) (getList-to-getVec-length-property get v) (fromList (get (toList v)))
84
85 get-commut-1 : (get : get-type) {A : Set} → (l : List A) → fromList (get l) ≡ subst (Vec A) (sym (getList-length get l)) (proj₂ (getList-to-getVec get) (fromList l))
86 get-commut-1 get {A} l = begin
87   fromList (get l)
88     ≡⟨ sym (subst-fromList (cong get (toList-fromList l))) ⟩
89   subst (Vec A) (cong length (cong get (toList-fromList l))) (fromList (get (toList (fromList l))))
90     ≡⟨ cong (flip (subst (Vec A)) (fromList (get (toList (fromList l))))) (proof-irrelevance (cong length (cong get (toList-fromList l))) (trans p p')) ⟩
91   subst (Vec A) (trans p p') (fromList (get (toList (fromList l))))
92     ≡⟨ sym (subst-subst (Vec A) p p' (fromList (get (toList (fromList l))))) ⟩
93   subst (Vec A) p' (subst (Vec A) p (fromList (get (toList (fromList l)))))
94     ≡⟨ refl ⟩
95   subst (Vec A) p' (proj₂ (getList-to-getVec get) (fromList l)) ∎
96     where p : length (get (toList (fromList l))) ≡ length (get (replicate (length l) tt))
97           p = getList-to-getVec-length-property get (fromList l)
98           p' : length (get (replicate (length l) tt)) ≡ length (get l)
99           p' = sym (getList-length get l)
100
101 get-trafo-1 : (get : get-type) → {B : Set} → getVec-to-getList (proj₂ (getList-to-getVec get)) {B} ≗ get {B}
102 get-trafo-1 get {B} l = begin
103   getVec-to-getList (proj₂ (getList-to-getVec get)) l
104     ≡⟨ refl ⟩
105   toList (proj₂ (getList-to-getVec get) (fromList l))
106     ≡⟨ refl ⟩
107   toList (subst (Vec B) (getList-to-getVec-length-property get (fromList l)) (fromList (get (toList (fromList l)))))
108     ≡⟨ toList-subst (fromList (get (toList (fromList l)))) (getList-to-getVec-length-property get (fromList l)) ⟩
109   toList (fromList (get (toList (fromList l))))
110     ≡⟨ toList-fromList (get (toList (fromList l))) ⟩
111   get (toList (fromList l))
112     ≡⟨ cong get (toList-fromList l) ⟩
113   get l ∎
114
115 vec-len : {A : Set} {n : ℕ} → Vec A n → ℕ
116 vec-len {_} {n} _ = n
117
118 fromList-toList : {A : Set} {n : ℕ} → (v : Vec A n) → fromList (toList v) ≡ subst (Vec A) (sym (length-toList v)) v
119 fromList-toList     []V       = refl
120 fromList-toList {A} (x ∷V xs) = begin
121   x ∷V fromList (toList xs)
122     ≡⟨ cong (_∷V_ x) (fromList-toList xs) ⟩
123   x ∷V subst (Vec A) (sym (length-toList xs)) xs
124     ≡⟨ subst-cong (Vec A) (_∷V_ x) (sym (length-toList xs)) xs ⟩
125   subst (Vec A) (cong suc (sym (length-toList xs))) (x ∷V xs)
126     ≡⟨ cong (λ p →  subst (Vec A) p (x ∷V xs)) (proof-irrelevance (cong suc (sym (length-toList xs))) (sym (cong suc (length-toList xs)))) ⟩
127   subst (Vec A) (sym (length-toList (x ∷V xs))) (x ∷V xs) ∎
128
129 get-commut-2 : (getlen : ℕ → ℕ) → (get : getV-type getlen) → {B : Set} {n : ℕ} → (toList ∘ get {B} {n}) ≗ (getVec-to-getList get) ∘ toList
130 get-commut-2 getlen get {B} v = begin
131   toList (get v)
132     ≡⟨ sym (toList-subst (get v) (cong getlen (sym (length-toList v)))) ⟩
133   toList (subst (Vec B) (cong getlen (sym (length-toList v))) (get v))
134     ≡⟨ cong toList (sym (subst-cong (Vec B) get (sym (length-toList v)) v)) ⟩
135   toList (get (subst (Vec B) (sym (length-toList v)) v))
136     ≡⟨ cong (toList ∘ get) (sym (fromList-toList v)) ⟩
137   toList (get (fromList (toList v))) ∎
138
139 get-trafo-2-getlen : (getlen : ℕ → ℕ) → (get : getV-type getlen) → proj₁ (getList-to-getVec (getVec-to-getList get)) ≗ getlen
140 get-trafo-2-getlen getlen get n = begin
141   proj₁ (getList-to-getVec (getVec-to-getList get)) n
142     ≡⟨ refl ⟩
143   length (toList (get (fromList (replicate n tt))))
144     ≡⟨ length-toList (get (fromList (replicate n tt))) ⟩
145   vec-len (get (fromList (replicate n tt)))
146     ≡⟨ cong getlen (length-replicate n) ⟩
147   getlen n ∎
148
149 get-trafo-2-get : (getlen : ℕ → ℕ) → (get : getV-type getlen) → {B : Set} {n : ℕ} → proj₂ (getList-to-getVec (getVec-to-getList get)) ≗ subst (Vec B) (sym (get-trafo-2-getlen getlen get n)) ∘ get
150 get-trafo-2-get getlen get {B} {n} v = begin
151   proj₂ (getList-to-getVec (getVec-to-getList get)) v
152     ≡⟨ refl ⟩
153   subst (Vec B) p (fromList (toList (get (fromList (toList v)))))
154     ≡⟨ cong (subst (Vec B) p) (fromList-toList (get (fromList (toList v)))) ⟩
155   subst (Vec B) p (subst (Vec B) p' (get (fromList (toList v))))
156     ≡⟨ subst-subst (Vec B) p' p (get (fromList (toList v))) ⟩
157   subst (Vec B) (trans p' p) (get (fromList (toList v)))
158     ≡⟨ cong (subst (Vec B) (trans p' p) ∘ get) (fromList-toList v) ⟩
159   subst (Vec B) (trans p' p) (get (subst (Vec B) (sym (length-toList v)) v))
160     ≡⟨ cong (subst (Vec B) (trans p' p)) (subst-cong (Vec B) get (sym (length-toList v)) v) ⟩
161   subst (Vec B) (trans p' p) (subst (Vec B) (cong getlen (sym (length-toList v))) (get v))
162     ≡⟨ subst-subst (Vec B) (cong getlen (sym (length-toList v))) (trans p' p) (get v) ⟩
163   subst (Vec B) (trans (cong getlen (sym (length-toList v))) (trans p' p)) (get v)
164     ≡⟨ cong (flip (subst (Vec B)) (get v)) (proof-irrelevance (trans (cong getlen (sym (length-toList v))) (trans p' p)) p'') ⟩
165   subst (Vec B) p'' (get v) ∎
166     where n' : ℕ
167           n' = length (toList (get (fromList (replicate n tt))))
168           p : length (toList (get (fromList (toList v)))) ≡ n'
169           p = getList-to-getVec-length-property (getVec-to-getList get) v
170           p' : getlen (length (toList v)) ≡ length (toList (get (fromList (toList v))))
171           p' = sym (length-toList (get (fromList (toList v))))
172           p'' : getlen n ≡ n'
173           p'' = sym (get-trafo-2-getlen getlen get (vec-len v))