{-# OPTIONS --safe #-}
module Choose.Indexed where
open import Prelude
open import Data.Vec
private variable n m k : ℕ
data Choice : ℕ → ℕ → Type where
done : Choice zero zero
keep : Choice n m → Choice (suc n) (suc m)
drop : Choice n m → Choice n (suc m)
Choose : Type → ℕ → ℕ → Type
Choose A n m = Choice n m → A
choose : Vec A m → Choose (Vec A n) n m
choose _ done = []
choose (x ∷ xs) (drop i) = choose xs i
choose (x ∷ xs) (keep i) = x ∷ choose xs i
sub : Vec A (suc n) → Vec (Vec A n) n
sub {n = zero} _ = []
sub {n = suc _} (x ∷ xs) = xs ∷ vmap (x ∷_) (sub xs)
up : Choose A k m → Choose (Vec A k) (suc k) m
up {k = zero} _ _ = []
up {k = suc k} xs (drop i) = up (xs ∘ drop) i
up {k = suc k} xs (keep i) = xs (drop i) ∷ up (xs ∘ keep) i
up-nat : ∀ (f : A → B) (xs : Choose A n m) i → up (f ∘ xs) i ≡ vmap f (up xs i)
up-nat {n = zero} _ _ _ = refl
up-nat {n = suc _} f xs (drop i) = up-nat f (xs ∘ drop) i
up-nat {n = suc _} f xs (keep i) =
cong (f (xs (drop i)) ∷_) (up-nat f (xs ∘ keep) i)
up-sub : ∀ n (xs : Vec A m) (i : Choice (suc n) m)
→ up (choose xs) i ≡ sub (choose xs i)
up-sub zero _ _ = refl
up-sub (suc n) (x ∷ xs) (drop i) = up-sub (suc n) xs i
up-sub (suc n) (x ∷ xs) (keep i) =
cong
(choose xs i ∷_)
(up-nat (x ∷_) (choose xs) i ; cong (vmap (x ∷_)) (up-sub n xs i))
open import Choose
using (⟨_⟩; ⟨⟩; _**_)
renaming (Choose to Choose′)
lookup : Choose′ A n m → Choose A n m
lookup ⟨ x ⟩ _ = x
lookup (xs ** ys) (drop i) = lookup xs i
lookup (xs ** ys) (keep i) = lookup ys i