\import Data.List \import Meta \import Paths \import Paths.Meta \import Data.Fin \import Data.SubList \func shift-index {A : \Set} {a b : List A} (sublist : SubList a b) (ind : Index a) : Fin (length b) \elim a, b, sublist, ind | :: x xs, :: y ys, sublist-match p sublist, zero => zero | :: x xs, :: y ys, sublist-match p sublist, suc ind => suc (shift-index sublist ind) | l, :: y ys, sublist-skip sublist, ind => suc (shift-index sublist ind) \module Shifts \where { \func proof {A : \Set} {a b : List A} {point : A} (sublist : SubList a b) (ind : Index a) (p : point = a !! ind) : point = b !! shift-index sublist ind \elim a, b, sublist, ind, p | :: x xs, :: y ys, sublist-match p sublist, zero, idp => p | :: x xs, :: y ys, sublist-match p sublist, suc ind, idp => proof sublist ind idp | nil, :: y ys, sublist-skip sublist, ind, idp => proof sublist ind idp | :: x a, :: y b, sublist-skip sublist, ind, idp => proof sublist ind idp \lemma over-identity {A : \Set} {a : List A} (ind : Index a) : shift-index SubList.identity ind = ind \elim a, ind | :: a a1, zero => idp | :: a a1, suc ind => pmap fsuc (over-identity ind) \lemma over-skip {A : \Set} {a b : List A} {point' : A} (sublist : SubList a b) (ind : Index a) : shift-index {_} {_} {point' :: b} (sublist-skip sublist) ind = suc (shift-index sublist ind) \elim a | :: x a => idp | nil => idp \lemma over-shrink {A : \Set} {x : A} {a b : List A} (sublist : SubList (x :: a) b) (ind : Index a) : shift-index (SubList.shrink sublist) ind = shift-index sublist (fsuc ind) \elim a, b, sublist | nil, :: y b, sublist-match p1 sublist => idp | :: a a1, :: y b, sublist-match p1 sublist => idp | :: a a1, :: y b, sublist-skip sublist => rewrite (over-shrink sublist ind) idp \lemma over-right-single {A : \Set} {a b : List A} (ind : Index a) : shift-index (SubList.extend-right-single SubList.identity) ind = expand-fin-left {A} {a} {b} ind \elim a, ind | :: a a1, 0 => idp | :: a a1, suc ind => pmap fsuc (over-right-single ind) \lemma over-left-single {A : \Set} {a b : List A} (ind : Index b) : shift-index {A} {b} {a ++ b} SubList.id+left ind = expand-fin-right ind \elim a | nil => over-identity _ | :: a a1 => rewrite over-skip (pmap fsuc (over-left-single ind)) \lemma over-right-both {A : \Set} {a b c : List A} (sublist : SubList a b) (fin : Index c) : shift-index (SubList.extend-right-both sublist) (expand-fin-right fin) = expand-fin-right fin \elim a, b, c, sublist, fin | nil, nil, :: a c, sublist-nil, 0 => idp | nil, nil, :: a c, sublist-nil, suc fin => pmap fsuc (over-right-both sublist-nil fin) | :: x a, :: y b, c, sublist-match p sublist, fin => pmap fsuc (over-right-both sublist fin) | nil, :: y b, :: a c, sublist-skip sublist, 0 => pmap fsuc (over-right-both sublist 0) | nil, :: y b, :: a c, sublist-skip sublist, suc fin => pmap fsuc (over-right-both {_} {_} {_} {:: a c} sublist (suc fin)) | :: a a1, :: y b, c, sublist-skip sublist, fin => pmap fsuc (over-right-both sublist fin) \lemma right-extension {A : \Set} {a b : List A} (ind : Index a) : \Sigma (eq : (a !! ind) = (a ++ b) !! expand-fin-left ind) ((shift-index SubList.id+right ind, proof SubList.id+right ind idp) = {\Sigma (ind' : Fin (length (a ++ b))) (a !! ind = (a ++ b) !! ind')} (expand-fin-left ind, eq)) \elim a, ind | :: a a1, 0 => (idp, ext idp) | :: a a1, suc ind => \have sig => right-extension {_} {a1} {b} ind \in (sig.1, ext (pmap fsuc (pmap __.1 sig.2))) \lemma left-extension-generic {A : \Set} {a b : List A} {point : A} (ind : Index b) {point-eq : point = b !! ind} : \Sigma (eq2 : point = (a ++ b) !! expand-fin-right ind) ((shift-index (SubList.extend-left-single SubList.identity ) ind, proof (SubList.extend-left-single SubList.identity) ind point-eq) = {\Sigma (ind' : Fin (length (a ++ b))) (point = (a ++ b) !! ind')} (expand-fin-right ind, eq2)) \elim a, point-eq | nil, idp => (idp, ext (over-identity ind)) | :: a a1, idp => \have sig => left-extension-generic {_} {a1} {b} ind {idp} \in (sig.1, ext (later (rewrite over-skip (pmap fsuc (pmap __.1 sig.2))))) \lemma left-extension {A : \Set} {a b : List A} (ind : Index b) : (shift-index {A} {b} {a ++ b} SubList.id+left ind, proof SubList.id+left ind idp) = {\Sigma (ind' : Fin (length (a ++ b))) (b !! ind = (a ++ b) !! ind')} (expand-fin-right ind, inv (expand-fin-right.correct {_} {a} ind)) => ext (over-left-single ind) \func right-both-after-expand-left {A : \Set} {a b c : List A} (sublist : SubList a b) (index : Index a) : shift-index (SubList.extend-right-both sublist {c}) (expand-fin-left index) = shift-index (SubList.extend-right-single SubList.identity) (shift-index sublist index) \elim a, b, sublist, index | :: x a, :: y b, sublist-match p sublist, 0 => idp | :: x a, :: y b, sublist-match p sublist, suc index => pmap fsuc (right-both-after-expand-left sublist index) | :: a a1, :: y b, sublist-skip sublist, index => pmap fsuc (right-both-after-expand-left sublist index) \func right-both-after-expand-right {A : \Set} {a b : List A} (sublist : SubList a b) {c : List A} (index : Index c) : shift-index (SubList.extend-right-both sublist {c}) (expand-fin-right index) = shift-index (SubList.extend-left-single SubList.identity) index \elim a, b, sublist, c, index | nil, nil, sublist-nil, :: a c, index => idp | :: x a, :: y b, sublist-match p sublist, :: a1 c, 0 => pmap fsuc (right-both-after-expand-right sublist 0) | :: x a, :: y b, sublist-match idp sublist, :: a1 c, suc index => pmap fsuc (right-both-after-expand-right sublist {:: a1 c} (fsuc index)) | nil, :: y b, sublist-skip sublist, :: a1 c, ind => pmap fsuc (right-both-after-expand-right sublist {:: a1 c} ind) | :: a a2, :: y b, sublist-skip sublist, :: a1 c, ind => pmap fsuc (right-both-after-expand-right sublist {:: a1 c} ind) }