|
| 1 | +------------------------------------------------------------------------ |
| 2 | +-- The Agda standard library |
| 3 | +-- |
| 4 | +-- Annotated reflected syntax. |
| 5 | +-- |
| 6 | +-- NOTE: This file does not check under --without-K due to restrictions |
| 7 | +-- in the termination checker. In particular recursive functions |
| 8 | +-- over a universe of types is not supported by --without-K. |
| 9 | +------------------------------------------------------------------------ |
| 10 | + |
| 11 | +{-# OPTIONS --safe --with-K #-} |
| 12 | + |
| 13 | +module Reflection.Annotated where |
| 14 | + |
| 15 | +open import Level using (Level; 0ℓ; suc; _⊔_) |
| 16 | +open import Category.Applicative using (RawApplicative) |
| 17 | +open import Data.Bool.Base using (Bool; false; true; if_then_else_) |
| 18 | +open import Data.List.Base using (List; []; _∷_) |
| 19 | +open import Data.List.Relation.Unary.All as All using (All; _∷_; []) |
| 20 | +open import Data.Product using (_×_; _,_; proj₁; proj₂) |
| 21 | +open import Data.String.Base using (String) |
| 22 | + |
| 23 | +open import Reflection |
| 24 | +open import Reflection.Universe |
| 25 | + |
| 26 | +open Clause |
| 27 | +open Pattern |
| 28 | +open Sort |
| 29 | + |
| 30 | +------------------------------------------------------------------------ |
| 31 | +-- Annotations and annotated types |
| 32 | + |
| 33 | +-- An Annotation is a type indexed by a reflected term. |
| 34 | +Annotation : ∀ ℓ → Set (suc ℓ) |
| 35 | +Annotation ℓ = ∀ {u} → ⟦ u ⟧ → Set ℓ |
| 36 | + |
| 37 | +-- An annotated type is a family over an Annotation and a reflected term. |
| 38 | +Typeₐ : ∀ ℓ → Univ → Set (suc ℓ) |
| 39 | +Typeₐ ℓ u = Annotation ℓ → ⟦ u ⟧ → Set ℓ |
| 40 | + |
| 41 | +private |
| 42 | + variable |
| 43 | + ℓ : Level |
| 44 | + u : Univ |
| 45 | + Ann Ann₁ Ann₂ : Annotation ℓ |
| 46 | + |
| 47 | +-- ⟪_⟫ packs up an element of an annotated type with a top-level annotation. |
| 48 | +infixr 30 ⟨_⟩_ |
| 49 | +data ⟪_⟫ {u} (Tyₐ : Typeₐ ℓ u) : Typeₐ ℓ u where |
| 50 | + ⟨_⟩_ : ∀ {t} → Ann t → Tyₐ Ann t → ⟪ Tyₐ ⟫ Ann t |
| 51 | + |
| 52 | +ann : {Tyₐ : Typeₐ ℓ u} {t : ⟦ u ⟧} → ⟪ Tyₐ ⟫ Ann t → Ann t |
| 53 | +ann (⟨ α ⟩ _) = α |
| 54 | + |
| 55 | + |
| 56 | +------------------------------------------------------------------------ |
| 57 | +-- Annotated reflected syntax |
| 58 | + |
| 59 | +-- Annotated lists are lists (All) of annotated values. No top-level |
| 60 | +-- annotation added, since we don't want an annotation for every tail |
| 61 | +-- of a list. Instead a top-level annotation is added on the outside. |
| 62 | +-- See Argsₐ. |
| 63 | +Listₐ : Typeₐ ℓ u → Typeₐ ℓ (⟨list⟩ u) |
| 64 | +Listₐ Tyₐ Ann = All (Tyₐ Ann) |
| 65 | + |
| 66 | +-- We define the rest of the annotated types in two variants: |
| 67 | +-- The primed variant which has annotations on subterms, and the |
| 68 | +-- non-primed variant which adds a top-level annotation to the primed |
| 69 | +-- one. |
| 70 | + |
| 71 | +data Absₐ′ (Tyₐ : Typeₐ ℓ u) : Typeₐ ℓ (⟨abs⟩ u) where |
| 72 | + abs : ∀ {t} x → Tyₐ Ann t → Absₐ′ Tyₐ Ann (abs x t) |
| 73 | + |
| 74 | +Absₐ : Typeₐ ℓ u → Typeₐ ℓ (⟨abs⟩ u) |
| 75 | +Absₐ Tyₐ = ⟪ Absₐ′ Tyₐ ⟫ |
| 76 | + |
| 77 | +data Argₐ′ (Tyₐ : Typeₐ ℓ u) : Typeₐ ℓ (⟨arg⟩ u) where |
| 78 | + arg : ∀ {t} i → Tyₐ Ann t → Argₐ′ Tyₐ Ann (arg i t) |
| 79 | + |
| 80 | +Argₐ : Typeₐ ℓ u → Typeₐ ℓ (⟨arg⟩ u) |
| 81 | +Argₐ Tyₐ = ⟪ Argₐ′ Tyₐ ⟫ |
| 82 | + |
| 83 | +data Namedₐ′ (Tyₐ : Typeₐ ℓ u) : Typeₐ ℓ (⟨named⟩ u) where |
| 84 | + _,_ : ∀ {t} x → Tyₐ Ann t → Namedₐ′ Tyₐ Ann (x , t) |
| 85 | + |
| 86 | +Namedₐ : Typeₐ ℓ u → Typeₐ ℓ (⟨named⟩ u) |
| 87 | +Namedₐ Tyₐ = ⟪ Namedₐ′ Tyₐ ⟫ |
| 88 | + |
| 89 | +-- Add a top-level annotation for Args. |
| 90 | +Argsₐ : Typeₐ ℓ u → Typeₐ ℓ (⟨list⟩ (⟨arg⟩ u)) |
| 91 | +Argsₐ Tyₐ = ⟪ Listₐ (Argₐ Tyₐ) ⟫ |
| 92 | + |
| 93 | +mutual |
| 94 | + Termₐ : Typeₐ ℓ ⟨term⟩ |
| 95 | + Termₐ = ⟪ Termₐ′ ⟫ |
| 96 | + |
| 97 | + Patternₐ : Typeₐ ℓ ⟨pat⟩ |
| 98 | + Patternₐ = ⟪ Patternₐ′ ⟫ |
| 99 | + |
| 100 | + Sortₐ : Typeₐ ℓ ⟨sort⟩ |
| 101 | + Sortₐ = ⟪ Sortₐ′ ⟫ |
| 102 | + |
| 103 | + Clauseₐ : Typeₐ ℓ ⟨clause⟩ |
| 104 | + Clauseₐ = ⟪ Clauseₐ′ ⟫ |
| 105 | + |
| 106 | + Clausesₐ : Typeₐ ℓ (⟨list⟩ ⟨clause⟩) |
| 107 | + Clausesₐ = ⟪ Listₐ Clauseₐ ⟫ |
| 108 | + |
| 109 | + Telₐ : Typeₐ ℓ ⟨tel⟩ |
| 110 | + Telₐ = ⟪ Listₐ (Namedₐ (Argₐ Termₐ)) ⟫ |
| 111 | + |
| 112 | + data Termₐ′ {ℓ} : Typeₐ ℓ ⟨term⟩ where |
| 113 | + var : ∀ x {args} → Argsₐ Termₐ Ann args → Termₐ′ Ann (var x args) |
| 114 | + con : ∀ c {args} → Argsₐ Termₐ Ann args → Termₐ′ Ann (con c args) |
| 115 | + def : ∀ f {args} → Argsₐ Termₐ Ann args → Termₐ′ Ann (def f args) |
| 116 | + lam : ∀ v {b} → Absₐ Termₐ Ann b → Termₐ′ Ann (lam v b) |
| 117 | + pat-lam : ∀ {cs args} → Clausesₐ Ann cs → Argsₐ Termₐ Ann args → |
| 118 | + Termₐ′ Ann (pat-lam cs args) |
| 119 | + pi : ∀ {a b} → Argₐ Termₐ Ann a → Absₐ Termₐ Ann b → Termₐ′ Ann (pi a b) |
| 120 | + agda-sort : ∀ {s} → Sortₐ Ann s → Termₐ′ Ann (agda-sort s) |
| 121 | + lit : ∀ l → Termₐ′ Ann (lit l) |
| 122 | + meta : ∀ x {args} → Argsₐ Termₐ Ann args → Termₐ′ Ann (meta x args) |
| 123 | + unknown : Termₐ′ Ann unknown |
| 124 | + |
| 125 | + data Clauseₐ′ {ℓ} : Typeₐ ℓ ⟨clause⟩ where |
| 126 | + clause : ∀ {tel ps t} → Telₐ Ann tel → Argsₐ Patternₐ Ann ps → |
| 127 | + Termₐ Ann t → Clauseₐ′ Ann (clause tel ps t) |
| 128 | + absurd-clause : ∀ {tel ps} → Telₐ Ann tel → Argsₐ Patternₐ Ann ps → |
| 129 | + Clauseₐ′ Ann (absurd-clause tel ps) |
| 130 | + |
| 131 | + data Sortₐ′ {ℓ} : Typeₐ ℓ ⟨sort⟩ where |
| 132 | + set : ∀ {t} → Termₐ Ann t → Sortₐ′ Ann (set t) |
| 133 | + lit : ∀ n → Sortₐ′ Ann (lit n) |
| 134 | + unknown : Sortₐ′ Ann unknown |
| 135 | + |
| 136 | + data Patternₐ′ {ℓ} : Typeₐ ℓ ⟨pat⟩ where |
| 137 | + con : ∀ c {ps} → Argsₐ Patternₐ Ann ps → Patternₐ′ Ann (con c ps) |
| 138 | + dot : ∀ {t} → Termₐ Ann t → Patternₐ′ Ann (dot t) |
| 139 | + var : ∀ x → Patternₐ′ Ann (var x) |
| 140 | + lit : ∀ l → Patternₐ′ Ann (lit l) |
| 141 | + proj : ∀ f → Patternₐ′ Ann (proj f) |
| 142 | + absurd : Patternₐ′ Ann absurd |
| 143 | + |
| 144 | + |
| 145 | +-- Mapping a code in the universe to its corresponding primed and |
| 146 | +-- non-primed annotated type. |
| 147 | + |
| 148 | +mutual |
| 149 | + Annotated′ : Typeₐ ℓ u |
| 150 | + Annotated′ {u = ⟨term⟩} = Termₐ′ |
| 151 | + Annotated′ {u = ⟨pat⟩} = Patternₐ′ |
| 152 | + Annotated′ {u = ⟨sort⟩} = Sortₐ′ |
| 153 | + Annotated′ {u = ⟨clause⟩} = Clauseₐ′ |
| 154 | + Annotated′ {u = ⟨list⟩ u} = Listₐ Annotated |
| 155 | + Annotated′ {u = ⟨arg⟩ u} = Argₐ′ Annotated |
| 156 | + Annotated′ {u = ⟨abs⟩ u} = Absₐ′ Annotated |
| 157 | + Annotated′ {u = ⟨named⟩ u} = Namedₐ′ Annotated |
| 158 | + |
| 159 | + Annotated : Typeₐ ℓ u |
| 160 | + Annotated = ⟪ Annotated′ ⟫ |
| 161 | + |
| 162 | + |
| 163 | +------------------------------------------------------------------------ |
| 164 | +-- Annotating terms |
| 165 | + |
| 166 | +-- An annotation function computes the top-level annotation given a |
| 167 | +-- term annotated at all sub-terms. |
| 168 | +AnnotationFun : Annotation ℓ → Set ℓ |
| 169 | +AnnotationFun Ann = ∀ u {t : ⟦ u ⟧} → Annotated′ Ann t → Ann t |
| 170 | + |
| 171 | + |
| 172 | +-- Given an annotation function we can do the bottom-up traversal of a |
| 173 | +-- reflected term to compute an annotated version. |
| 174 | +module _ (annFun : AnnotationFun Ann) where |
| 175 | + |
| 176 | + private |
| 177 | + annotated : {t : ⟦ u ⟧} → Annotated′ Ann t → Annotated Ann t |
| 178 | + annotated ps = ⟨ annFun _ ps ⟩ ps |
| 179 | + |
| 180 | + mutual |
| 181 | + annotate′ : (t : ⟦ u ⟧) → Annotated′ Ann t |
| 182 | + annotate′ {⟨term⟩} (var x args) = var x (annotate args) |
| 183 | + annotate′ {⟨term⟩} (con c args) = con c (annotate args) |
| 184 | + annotate′ {⟨term⟩} (def f args) = def f (annotate args) |
| 185 | + annotate′ {⟨term⟩} (lam v t) = lam v (annotate t) |
| 186 | + annotate′ {⟨term⟩} (pat-lam cs args) = pat-lam (annotate cs) (annotate args) |
| 187 | + annotate′ {⟨term⟩} (pi a b) = pi (annotate a) (annotate b) |
| 188 | + annotate′ {⟨term⟩} (agda-sort s) = agda-sort (annotate s) |
| 189 | + annotate′ {⟨term⟩} (lit l) = lit l |
| 190 | + annotate′ {⟨term⟩} (meta x args) = meta x (annotate args) |
| 191 | + annotate′ {⟨term⟩} unknown = unknown |
| 192 | + annotate′ {⟨pat⟩} (con c ps) = con c (annotate ps) |
| 193 | + annotate′ {⟨pat⟩} (dot t) = dot (annotate t) |
| 194 | + annotate′ {⟨pat⟩} (var x) = var x |
| 195 | + annotate′ {⟨pat⟩} (lit l) = lit l |
| 196 | + annotate′ {⟨pat⟩} (proj f) = proj f |
| 197 | + annotate′ {⟨pat⟩} absurd = absurd |
| 198 | + annotate′ {⟨sort⟩} (set t) = set (annotate t) |
| 199 | + annotate′ {⟨sort⟩} (lit n) = lit n |
| 200 | + annotate′ {⟨sort⟩} unknown = unknown |
| 201 | + annotate′ {⟨clause⟩} (clause tel ps t) = clause (annotate tel) (annotate ps) (annotate t) |
| 202 | + annotate′ {⟨clause⟩} (absurd-clause tel ps) = absurd-clause (annotate tel) (annotate ps) |
| 203 | + annotate′ {⟨abs⟩ u} (abs x t) = abs x (annotate t) |
| 204 | + annotate′ {⟨arg⟩ u} (arg i t) = arg i (annotate t) |
| 205 | + annotate′ {⟨list⟩ u} [] = [] |
| 206 | + annotate′ {⟨list⟩ u} (x ∷ xs) = annotate x ∷ annotate′ xs |
| 207 | + annotate′ {⟨named⟩ u} (x , t) = x , annotate t |
| 208 | + |
| 209 | + annotate : (t : ⟦ u ⟧) → Annotated Ann t |
| 210 | + annotate t = annotated (annotate′ t) |
| 211 | + |
| 212 | + |
| 213 | +------------------------------------------------------------------------ |
| 214 | +-- Annotation function combinators |
| 215 | + |
| 216 | +-- Mapping over annotations |
| 217 | +mutual |
| 218 | + map′ : ∀ u → (∀ {u} {t : ⟦ u ⟧} → Ann₁ t → Ann₂ t) → {t : ⟦ u ⟧} → Annotated′ Ann₁ t → Annotated′ Ann₂ t |
| 219 | + map′ ⟨term⟩ f (var x args) = var x (map f args) |
| 220 | + map′ ⟨term⟩ f (con c args) = con c (map f args) |
| 221 | + map′ ⟨term⟩ f (def h args) = def h (map f args) |
| 222 | + map′ ⟨term⟩ f (lam v b) = lam v (map f b) |
| 223 | + map′ ⟨term⟩ f (pat-lam cs args) = pat-lam (map f cs) (map f args) |
| 224 | + map′ ⟨term⟩ f (pi a b) = pi (map f a) (map f b) |
| 225 | + map′ ⟨term⟩ f (agda-sort s) = agda-sort (map f s) |
| 226 | + map′ ⟨term⟩ f (lit l) = lit l |
| 227 | + map′ ⟨term⟩ f (meta x args) = meta x (map f args) |
| 228 | + map′ ⟨term⟩ f unknown = unknown |
| 229 | + map′ ⟨pat⟩ f (con c ps) = con c (map f ps) |
| 230 | + map′ ⟨pat⟩ f (dot t) = dot (map f t) |
| 231 | + map′ ⟨pat⟩ f (var x) = var x |
| 232 | + map′ ⟨pat⟩ f (lit l) = lit l |
| 233 | + map′ ⟨pat⟩ f (proj g) = proj g |
| 234 | + map′ ⟨pat⟩ f absurd = absurd |
| 235 | + map′ ⟨sort⟩ f (set t) = set (map f t) |
| 236 | + map′ ⟨sort⟩ f (lit n) = lit n |
| 237 | + map′ ⟨sort⟩ f unknown = unknown |
| 238 | + map′ ⟨clause⟩ f (clause Γ ps args) = clause (map f Γ) (map f ps) (map f args) |
| 239 | + map′ ⟨clause⟩ f (absurd-clause Γ ps) = absurd-clause (map f Γ) (map f ps) |
| 240 | + map′ (⟨list⟩ u) f [] = [] |
| 241 | + map′ (⟨list⟩ u) f (x ∷ xs) = map f x ∷ map′ _ f xs |
| 242 | + map′ (⟨arg⟩ u) f (arg i x) = arg i (map f x) |
| 243 | + map′ (⟨abs⟩ u) f (abs x t) = abs x (map f t) |
| 244 | + map′ (⟨named⟩ u) f (x , t) = x , map f t |
| 245 | + |
| 246 | + map : (∀ {u} {t : ⟦ u ⟧} → Ann₁ t → Ann₂ t) → ∀ {u} {t : ⟦ u ⟧} → Annotated Ann₁ t → Annotated Ann₂ t |
| 247 | + map f {u = u} (⟨ α ⟩ t) = ⟨ f α ⟩ map′ u f t |
| 248 | + |
| 249 | + |
| 250 | +module _ {W : Set ℓ} (ε : W) (_∪_ : W → W → W) where |
| 251 | + |
| 252 | + -- This annotation function does nothing except combine ε's with _∪_. |
| 253 | + -- Lets you skip the boring cases when defining non-dependent |
| 254 | + -- annotation functions by adding a catch-all calling defaultAnn. |
| 255 | + defaultAnn : AnnotationFun (λ _ → W) |
| 256 | + defaultAnn ⟨term⟩ (var x args) = ann args |
| 257 | + defaultAnn ⟨term⟩ (con c args) = ann args |
| 258 | + defaultAnn ⟨term⟩ (def f args) = ann args |
| 259 | + defaultAnn ⟨term⟩ (lam v b) = ann b |
| 260 | + defaultAnn ⟨term⟩ (pat-lam cs args) = ann cs ∪ ann args |
| 261 | + defaultAnn ⟨term⟩ (pi a b) = ann a ∪ ann b |
| 262 | + defaultAnn ⟨term⟩ (agda-sort s) = ann s |
| 263 | + defaultAnn ⟨term⟩ (lit l) = ε |
| 264 | + defaultAnn ⟨term⟩ (meta x args) = ann args |
| 265 | + defaultAnn ⟨term⟩ unknown = ε |
| 266 | + defaultAnn ⟨pat⟩ (con c args) = ann args |
| 267 | + defaultAnn ⟨pat⟩ (dot t) = ann t |
| 268 | + defaultAnn ⟨pat⟩ (var x) = ε |
| 269 | + defaultAnn ⟨pat⟩ (lit l) = ε |
| 270 | + defaultAnn ⟨pat⟩ (proj f) = ε |
| 271 | + defaultAnn ⟨pat⟩ absurd = ε |
| 272 | + defaultAnn ⟨sort⟩ (set t) = ann t |
| 273 | + defaultAnn ⟨sort⟩ (lit n) = ε |
| 274 | + defaultAnn ⟨sort⟩ unknown = ε |
| 275 | + defaultAnn ⟨clause⟩ (clause Γ ps t) = ann Γ ∪ (ann ps ∪ ann t) |
| 276 | + defaultAnn ⟨clause⟩ (absurd-clause Γ ps) = ann Γ ∪ ann ps |
| 277 | + defaultAnn (⟨list⟩ u) [] = ε |
| 278 | + defaultAnn (⟨list⟩ u) (x ∷ xs) = ann x ∪ defaultAnn _ xs |
| 279 | + defaultAnn (⟨arg⟩ u) (arg i x) = ann x |
| 280 | + defaultAnn (⟨abs⟩ u) (abs x t) = ann t |
| 281 | + defaultAnn (⟨named⟩ u) (x , t) = ann t |
| 282 | + |
| 283 | + |
| 284 | +-- Cartisian product of two annotation functions. |
| 285 | +infixr 4 _⊗_ |
| 286 | +_⊗_ : AnnotationFun Ann₁ → AnnotationFun Ann₂ → AnnotationFun (λ t → Ann₁ t × Ann₂ t) |
| 287 | +(f ⊗ g) u t = f u (map′ u proj₁ t) , g u (map′ u proj₂ t) |
| 288 | + |
| 289 | + |
| 290 | +------------------------------------------------------------------------ |
| 291 | +-- Annotation-driven traversal |
| 292 | + |
| 293 | +-- Top-down applicative traversal of an annotated term. Applies an |
| 294 | +-- action (without going into subterms) to terms whose annotation |
| 295 | +-- satisfies a given criterion. Returns an unannotated term. |
| 296 | + |
| 297 | +module Traverse {M : Set → Set} (appl : RawApplicative M) where |
| 298 | + |
| 299 | + open RawApplicative appl renaming (_⊛_ to _<*>_) |
| 300 | + |
| 301 | + module _ (apply? : ∀ {u} {t : ⟦ u ⟧} → Ann t → Bool) |
| 302 | + (action : ∀ {u} {t : ⟦ u ⟧} → Annotated Ann t → M ⟦ u ⟧) where |
| 303 | + |
| 304 | + mutual |
| 305 | + traverse′ : {t : ⟦ u ⟧} → Annotated′ Ann t → M ⟦ u ⟧ |
| 306 | + traverse′ {⟨term⟩} (var x args) = var x <$> traverse args |
| 307 | + traverse′ {⟨term⟩} (con c args) = con c <$> traverse args |
| 308 | + traverse′ {⟨term⟩} (def f args) = def f <$> traverse args |
| 309 | + traverse′ {⟨term⟩} (lam v b) = lam v <$> traverse b |
| 310 | + traverse′ {⟨term⟩} (pat-lam cs args) = pat-lam <$> traverse cs <*> traverse args |
| 311 | + traverse′ {⟨term⟩} (pi a b) = pi <$> traverse a <*> traverse b |
| 312 | + traverse′ {⟨term⟩} (agda-sort s) = agda-sort <$> traverse s |
| 313 | + traverse′ {⟨term⟩} (lit l) = pure (lit l) |
| 314 | + traverse′ {⟨term⟩} (meta x args) = meta x <$> traverse args |
| 315 | + traverse′ {⟨term⟩} unknown = pure unknown |
| 316 | + traverse′ {⟨pat⟩} (con c args) = con c <$> traverse args |
| 317 | + traverse′ {⟨pat⟩} (dot t) = dot <$> traverse t |
| 318 | + traverse′ {⟨pat⟩} (var x) = pure (var x) |
| 319 | + traverse′ {⟨pat⟩} (lit l) = pure (lit l) |
| 320 | + traverse′ {⟨pat⟩} (proj f) = pure (proj f) |
| 321 | + traverse′ {⟨pat⟩} absurd = pure absurd |
| 322 | + traverse′ {⟨sort⟩} (set t) = set <$> traverse t |
| 323 | + traverse′ {⟨sort⟩} (lit n) = pure (lit n) |
| 324 | + traverse′ {⟨sort⟩} unknown = pure unknown |
| 325 | + traverse′ {⟨clause⟩} (clause Γ ps t) = clause <$> traverse Γ <*> traverse ps <*> traverse t |
| 326 | + traverse′ {⟨clause⟩} (absurd-clause Γ ps) = absurd-clause <$> traverse Γ <*> traverse ps |
| 327 | + traverse′ {⟨list⟩ u} [] = pure [] |
| 328 | + traverse′ {⟨list⟩ u} (x ∷ xs) = _∷_ <$> traverse x <*> traverse′ xs |
| 329 | + traverse′ {⟨arg⟩ u} (arg i x) = arg i <$> traverse x |
| 330 | + traverse′ {⟨abs⟩ u} (abs x t) = abs x <$> traverse t |
| 331 | + traverse′ {⟨named⟩ u} (x , t) = x ,_ <$> traverse t |
| 332 | + |
| 333 | + traverse : {t : ⟦ u ⟧} → Annotated Ann t → M ⟦ u ⟧ |
| 334 | + traverse t@(⟨ α ⟩ tₐ) = if apply? α then action t else traverse′ tₐ |
0 commit comments