{-# OPTIONS --safe --without-K #-}
open import Prelude renaming (Any to AnyL)
module Utils.Reflection.Term where
open import Utils.Reflection.Core
open import Utils.Reflection.Eq
record Cxt : Set where
constructor _,_
pattern
field
len : ℕ
context : List (String × Arg Term)
private
_∷cxt_ : String × Arg Term → Cxt → Cxt
e ∷cxt (n , Γ) = (suc n , e ∷ Γ)
_++cxt_ : List (String × Arg Term) → Cxt → Cxt
es ++cxt (n , Γ) = (length es + n , es <> Γ)
Action : Set → Set
Action A = Cxt → A → A
Finder : Set → Set
Finder A = Cxt → A → Bool
record Actions : Set where
field
onVar : Action ℕ
onMeta : Action Meta
onCon : Action Name
onDef : Action Name
defaultActions : Actions
defaultActions .Actions.onVar _ = id
defaultActions .Actions.onMeta _ = id
defaultActions .Actions.onCon _ = id
defaultActions .Actions.onDef _ = id
module _ (actions : Actions) where
open Actions actions
traverseTerm : Action Term
traverseSort : Action Sort
traversePattern : Action Pattern
traverseArgs : Action (List (Arg Term))
traverseArg : Action (Arg Term)
traversePats : Action (List (Arg Pattern))
traverseAbs : Arg Term → Action (Abs Term)
traverseClauses : Action Clauses
traverseClause : Action Clause
traverseTel : Action (List (String × Arg Term))
traverseTerm Γ (var x args) = var (onVar Γ x) (traverseArgs Γ args)
traverseTerm Γ (con c args) = con (onCon Γ c) (traverseArgs Γ args)
traverseTerm Γ (def f args) = def (onDef Γ f) (traverseArgs Γ args)
traverseTerm Γ (lam v t) = lam v (traverseAbs (arg (arg-info v (modality relevant quantity-ω)) unknown) Γ t)
traverseTerm Γ (pat-lam cs args) = pat-lam (traverseClauses Γ cs) (traverseArgs Γ args)
traverseTerm Γ (pi a b) = pi (traverseArg Γ a) (traverseAbs a Γ b)
traverseTerm Γ (agda-sort s) = agda-sort (traverseSort Γ s)
traverseTerm Γ (meta x args) = meta (onMeta Γ x) (traverseArgs Γ args)
traverseTerm Γ t@(lit l) = t
traverseTerm Γ t@unknown = t
traverseSort Γ (set t) = set (traverseTerm Γ t)
traverseSort Γ (prop t) = prop (traverseTerm Γ t)
traverseSort Γ t = t
traversePattern Γ (con c ps) = con (onCon Γ c) (traversePats Γ ps)
traversePattern Γ (dot t) = dot (traverseTerm Γ t)
traversePattern Γ (var x) = var (onVar Γ x)
traversePattern Γ (absurd x) = absurd (onVar Γ x)
traversePattern Γ t = t
traversePats Γ [] = []
traversePats Γ ((arg i p) ∷ pats) = arg i (traversePattern Γ p) ∷ traversePats Γ pats
traverseArg Γ (arg i x) = arg i (traverseTerm Γ x)
traverseArgs Γ [] = []
traverseArgs Γ (x ∷ args) = traverseArg Γ x ∷ traverseArgs Γ args
traverseAbs ty Γ (abs x t) = abs x (traverseTerm ((x , ty) ∷cxt Γ) t)
traverseClause Γ (clause tel ps t) =
clause (traverseTel Γ tel)
(traversePats (reverse tel ++cxt Γ) ps)
(traverseTerm (reverse tel ++cxt Γ) t)
traverseClause Γ (absurd-clause tel ps) =
absurd-clause (traverseTel Γ tel)
(traversePats (reverse tel ++cxt Γ) ps)
traverseClauses Γ [] = []
traverseClauses Γ (x ∷ cls) = traverseClause Γ x ∷ traverseClauses Γ cls
traverseTel Γ [] = []
traverseTel Γ ((s , t) ∷ tel) = (s , traverseArg Γ t) ∷ traverseTel ((s , t) ∷cxt Γ) tel
anyVisibleTerm : (Cxt → Term → Bool) → Cxt → Term → Bool
anyVisibleTerm f Γ t = if f Γ t then true else
case t of λ where
(var _ args) → any visibleTrue args
(con _ args) → any visibleTrue args
(def _ args) → any visibleTrue args
(lam v (abs s x)) → anyVisibleTerm f ((s , arg (arg-info v (modality relevant quantity-ω)) unknown) ∷cxt Γ) x
(pat-lam cs args) → any visibleTrue args
(`Π[ s ∶ arg i x ] y) → anyVisibleTerm f Γ x ∨ anyVisibleTerm f ((s , arg i x) ∷cxt Γ) y
(meta _ xs) → any visibleTrue xs
_ → false
where visibleTrue : (Arg _) → Bool
visibleTrue a = isVisible a ∧ f Γ (unArg a)
anyTerm : (Cxt → Term → Bool) → Cxt → Term → Bool
anyTerm f Γ t = if f Γ t then true
else case t of λ where
(var _ args) → any (f Γ ∘ unArg) args
(con _ args) → any (f Γ ∘ unArg) args
(def _ args) → any (f Γ ∘ unArg) args
(lam v (abs s x)) → anyTerm f ((s , arg (arg-info v (modality relevant quantity-ω)) unknown) ∷cxt Γ) x
(pat-lam cs args) → any (f Γ ∘ unArg) args
(`Π[ s ∶ arg i x ] y) → anyTerm f Γ x ∨ anyTerm f ((s , arg i x) ∷cxt Γ) y
(meta _ xs) → any (f Γ ∘ unArg) xs
_ → false
anyPat : (Pattern → Bool) → Pattern → Bool
anyPat f p = if (f p) then true
else case p of λ where
(con c ps) → any (f ∘ unArg) ps
_ → false
weaken : ℕ → ℕ → Term → Term
weaken from by = traverseTerm (record defaultActions
{onVar = λ Γ x →
if x <? (Cxt.len Γ + from)
then x
else x + by}) (0 , [])
weakenTel : ℕ → ℕ → Telescope → Telescope
weakenTel from by [] = []
weakenTel from by (x ∷ tel) = bimap id (fmap (weaken from by)) x ∷
weakenTel (suc from) by tel
strengthen : ℕ → ℕ → Term → Term
strengthen from by = traverseTerm (record defaultActions
{onVar = λ Γ x →
if x <? (Cxt.len Γ + from)
then x
else x ∸ by}) (0 , [])
prependToType : Telescope → Type → Type
prependToType [] `B = `B
prependToType ((s , `A) ∷ `T) `B = `Π[ s ∶ `A ] prependToType `T `B
prependToTerm : Telescope → Term → Term
prependToTerm [] `t = `t
prependToTerm ((s , `A) ∷ `T) `t =
lam (getVisibility `A) (abs s (prependToTerm `T `t))
`Levels : ℕ → Telescope
`Levels n = duplicate n ("ℓ" , hArg `Level)
vUnknowns : ℕ → Args Term
vUnknowns = flip duplicate (vArg unknown)
hUnknowns : ℕ → Args Term
hUnknowns = flip duplicate (hArg unknown)
private
ΠToTelescope : Type → Telescope × Type
ΠToTelescope (`Π[ s ∶ a ] b) = let T , A = ΠToTelescope b in (s , a) ∷ T , A
ΠToTelescope t = [] , t
TelescopeToΠ : Type → Telescope → Type
TelescopeToΠ `B [] = `B
TelescopeToΠ `B ((s , `A) ∷ T) = `Π[ s ∶ `A ] TelescopeToΠ `B T
instance
TelescopeToContext : Coercion' Telescope Context
⇑_ ⦃ TelescopeToContext ⦄ = map snd
TypeToTelescope : Coercion' Type (Telescope × Type)
⇑_ ⦃ TypeToTelescope ⦄ = ΠToTelescope
TelescopeToType : Coercion' (Telescope × Type) Type
⇑_ ⦃ TelescopeToType ⦄ (T , `A) = TelescopeToΠ `A T
splitType : ℕ → Type → Telescope × Type
splitType zero x = [] , x
splitType (suc n) (`Π[ s ∶ a ] b) =
let tel , c = splitType n b in (s , a) ∷ tel , c
splitType _ a = [] , a
dropType : ℕ → Type → Type
dropType n = snd ∘ splitType n
forgetTypes : Telescope → Telescope
forgetTypes = map $ bimap id (λ `A → arg (getArgInfo `A) unknown)
endsIn : Type → Name → Bool
endsIn (def f _) u = f == u
endsIn (`Π[ _ ∶ _ ] b) u = endsIn b u
endsIn _ u = false
unConflictType : Type → Type
unConflictType t = unconflict [] t
where
mostElem : String → ℕ → List (String × ℕ)
→ ℕ × (List (String × ℕ))
mostElem x n [] = n , [ (x , n) ]
mostElem x m ((s , n) ∷ ss) =
if x == s then
if m ≤? n then
(suc n) , (s , suc n) ∷ ss
else
(m , (s , m) ∷ ss)
else
let n' , ss' = mostElem x m ss
in n' , (s , n) ∷ ss'
unconflict : List (String × ℕ) → Type → Type
unconflict ss (`Π[ s ∶ a ] x) =
let cs = ⇑ s
cs' = removeLast (lenTrailingNat cs) cs
n , ss' = mostElem (⇑ cs') (fromMaybe 0 (trailingNat cs)) ss
ns = if n == 0 then "" else show n
in `Π[ ⇑ cs' <> ns ∶ a ] unconflict ss' x
unconflict _ t = t
renameTypeBy : Type → List String → Type
renameTypeBy (`Π[ _ ∶ a ] x) (s ∷ ss) = `Π[ s ∶ a ] (renameTypeBy x ss)
renameTypeBy t _ = t
renameTelBy : Telescope → List String → Telescope
renameTelBy ((_ , x) ∷ tel) (s ∷ ss) = (s , x) ∷ renameTelBy tel ss
renameTelBy tel _ = tel