{-# OPTIONS --safe --sized-types #-} open import Relation.Binary using (Decidable) open import Relation.Binary.PropositionalEquality open import Generic.Syntax module Generic.Scopecheck {E I : Set} (_≟I_ : Decidable {A = I} _≡_) where open import Category.Monad open import Level open import Size open import Data.List.Base using (List; []; _∷_) open import Data.List.Relation.Unary.All using (All; []; _∷_) open import Data.List.Relation.Unary.All.Properties using () renaming (++⁺ to _++_) open import Data.Product open import Data.String using (String; _≟_) open import Data.Sum import Data.Sum.Categorical.Left as SC open import Function open import Relation.Nullary open import Data.Var hiding (_<$>_) private variable σ : I Γ Δ : List I i : Size A : Set Names : List I → Set Names = All (const String) WithNames : (I → Set) → List I → I ─Scoped WithNames T [] j Γ = T j WithNames T Δ j Γ = Names Δ × T j data Raw (d : Desc I) : Size → I → Set where `var : E → String → Raw d (↑ i) σ `con : ⟦ d ⟧ (WithNames (Raw d i)) σ [] → Raw d (↑ i) σ data Error : Set where OutOfScope : Error WrongSort : (σ τ : I) → σ ≢ τ → Error private Fail : Set → Set Fail A = (Error × E × String) ⊎ A fail : Error → E → String → Fail A fail err e str = inj₁ (err , e , str) open RawMonad (SC.monad (Error × E × String) zero) instance _ = rawIApplicative toVar : E → String → ∀ σ Γ → Names Γ → Fail (Var σ Γ) toVar e x σ [] [] = fail OutOfScope e x toVar e x σ (τ ∷ Γ) (y ∷ scp) with x ≟ y | σ ≟I τ ... | yes _ | yes refl = pure z ... | yes _ | no ¬eq = fail (WrongSort σ τ ¬eq) e x ... | no ¬p | _ = s <$> toVar e x σ Γ scp module _ {d : Desc I} where toTm : Names Γ → Raw d i σ → Fail (Tm d i σ Γ) toScope : Names Γ → ∀ Δ σ → WithNames (Raw d i) Δ σ [] → Fail (Scope (Tm d i) Δ σ Γ) toTm scp (`var e v) = `var <$> toVar e v _ _ scp toTm scp (`con b) = `con <$> mapA d (toScope scp) b toScope scp [] σ b = toTm scp b toScope scp Δ@(_ ∷ _) σ (bnd , b) = toTm (bnd ++ scp) b