{-# OPTIONS --safe --sized-types #-}

module Data.Pred where

open import Data.Var hiding (_<$>_)
open import Data.Environment
open import Agda.Builtin.List
open import Function
open import Relation.Unary using (IUniversal; _⇒_)

private
  variable
    I : Set
    σ : I
    Γ Δ Θ : List I
    T : I ─Scoped

record Pred (T : I ─Scoped) : Set₁ where
  constructor mkPred
  field pred :  σ  ∀[ T σ  const Set ]
open Pred public

record All (𝓟 : Pred T) (Γ : List I) (ρ : (Γ ─Env) T Δ) : Set where
  constructor packᴾ
  field lookupᴾ : (k : Var σ Γ)  pred 𝓟 σ (lookup ρ k)
open All public

private
  variable
    𝓟 : Pred T

_<$>ᴾ_ : {f : {i : I}  T i Δ  T i Θ} 
         (∀ {i} {t : T i Δ}  pred 𝓟 i t  pred 𝓟 i (f t)) 
         {ρ : (Γ ─Env) T Δ}  All 𝓟 Γ ρ  All 𝓟 Γ (f <$> ρ)
lookupᴾ (F <$>ᴾ ρ) k = F (lookupᴾ ρ k)

εᴾ : All 𝓟 [] (([] ─Env) T Δ  ε)
lookupᴾ εᴾ ()

infixl 20 _∙ᴾ_
_∙ᴾ_ :  {ρ : (Γ ─Env) T Δ} {v : T σ Δ}  All 𝓟 Γ ρ  pred 𝓟 σ v  All 𝓟 (σ  Γ) (ρ  v)
lookupᴾ (ρ ∙ᴾ v) z      = v
lookupᴾ (ρ ∙ᴾ v) (s k)  = lookupᴾ ρ k