module var where
open import indexed
open import Data.Sum hiding (map)
open import Data.List.Base hiding ([_])
open import Data.List.All using (All ; _∷_)
open import Function
open import Agda.Builtin.Equality
_─Scoped : Set → Set₁
I ─Scoped = I → List I → Set
module _ {I : Set} where
data Var : I ─Scoped where
z : {i : I} → [ (i ∷_) ⊢ Var i ]
s : {i j : I} → [ Var i ⟶ (j ∷_) ⊢ Var i ]
infixl 3 _─_
_─_ : {i : I} (Γ : List I) → Var i Γ → List I
_ ∷ Γ ─ z = Γ
σ ∷ Γ ─ s v = σ ∷ (Γ ─ v)
get : {B : I → Set} {i : I} → [ Var i ⟶ All B ⟶ κ (B i) ]
get z (b ∷ _) = b
get (s v) (_ ∷ bs) = get v bs
_<$>_ : {I J : Set} (f : I → J) {i : I} → [ Var i ⟶ Var (f i) ∘ map f ]
f <$> z = z
f <$> s v = s (f <$> v)
record Injective {I J : Set} (f : I → J) : Set where
constructor mkInjective
field inj : ∀ {i₁ i₂} → f i₁ ≡ f i₂ → i₁ ≡ i₂
open Injective public
Injective-inj₁ : ∀ {A B : Set} → Injective ((A → A ⊎ B) ∋ inj₁)
inj Injective-inj₁ refl = refl
Injective-inj₂ : ∀ {A B : Set} → Injective ((B → A ⊎ B) ∋ inj₂)
inj Injective-inj₂ refl = refl
_<$>⁻¹_ : {I J : Set} {f : I → J} → Injective f →
{i : I} → [ Var (f i) ∘ map f ⟶ Var i ]
_<$>⁻¹_ {I} {J} {f} F = go _ refl refl where
go : {i : I} {j : J} (is : List I) {js : List J} →
f i ≡ j → map f is ≡ js → Var j js → Var i is
go [] eq () z
go [] eq () (s v)
go (i ∷ is) eq refl z rewrite inj F eq = z
go (i ∷ is) eq refl (s v) = s (go is eq refl v)
injectˡ : {I : Set} {i : I} (ys : List I) → [ Var i ⟶ (_++ ys) ⊢ Var i ]
injectˡ k z = z
injectˡ k (s v) = s (injectˡ k v)
injectʳ : {I : Set} {i : I} (ys : List I) → [ Var i ⟶ (ys ++_) ⊢ Var i ]
injectʳ [] v = v
injectʳ (y ∷ ys) v = s (injectʳ ys v)