Agda-2.3.2.2: test/succeed/TermSplicing.agda
{-# OPTIONS --universe-polymorphism #-}
open import Common.Prelude renaming (Nat to ℕ)
open import Common.Level
open import Common.Reflect
module TermSplicing where
module Library where
data Box {a} (A : Set a) : Set a where
box : A → Box A
record ⊤ : Set where
constructor tt
infixr 5 _×_
record _×_ (A B : Set) : Set where
constructor _,_
field
proj₁ : A
proj₂ : B
[_] : ∀ {A : Set} → A → List A
[ x ] = x ∷ []
replicate : ∀ {A : Set} → ℕ → A → List A
replicate zero x = []
replicate (suc n) x = x ∷ replicate n x
foldr : ∀ {A B : Set} → (A → B → B) → B → List A → B
foldr c n [] = n
foldr c n (x ∷ xs) = c x (foldr c n xs)
foldl : ∀ {A B : Set} → (A → B → A) → A → List B → A
foldl c n [] = n
foldl c n (x ∷ xs) = foldl c (c n x) xs
reverse : ∀ {A : Set} → List A → List A
reverse = foldl (λ rev x → x ∷ rev) []
length : ∀ {A : Set} → List A → ℕ
length = foldr (λ _ → suc) 0
data Maybe (A : Set) : Set where
nothing : Maybe A
just : A → Maybe A
mapMaybe : ∀ {A B : Set} → (A → B) → Maybe A → Maybe B
mapMaybe f (just x) = just (f x)
mapMaybe f nothing = nothing
when : ∀ {A} → Bool → Maybe A → Maybe A
when true x = x
when false _ = nothing
data _≡_ {a} {A : Set a} (x : A) : A -> Set where
refl : x ≡ x
_→⟨_⟩_ : ∀ (A : Set) (n : ℕ) (B : Set) → Set
A →⟨ zero ⟩ B = B
A →⟨ suc n ⟩ B = A → A →⟨ n ⟩ B
open Library
module ReflectLibrary where
lamᵛ : Term → Term
lamᵛ = lam visible
lamʰ : Term → Term
lamʰ = lam hidden
argᵛʳ : ∀{A} → A → Arg A
argᵛʳ = arg visible relevant
argʰʳ : ∀{A} → A → Arg A
argʰʳ = arg hidden relevant
app` : (Args → Term) → (hrs : List (Hiding × Relevance)) → Term →⟨ length hrs ⟩ Term
app` f = go [] where
go : List (Arg Term) → (hrs : List (Hiding × Relevance)) → Term →⟨ length hrs ⟩ Term
go args [] = f (reverse args)
go args ((h , r) ∷ hs) = λ t → go (arg h r t ∷ args) hs
con` : QName → (hrs : List (Hiding × Relevance)) → Term →⟨ length hrs ⟩ Term
con` x = app` (con x)
def` : QName → (hrs : List (Hiding × Relevance)) → Term →⟨ length hrs ⟩ Term
def` x = app` (def x)
var` : ℕ → (hrs : List (Hiding × Relevance)) → Term →⟨ length hrs ⟩ Term
var` x = app` (var x)
coe : ∀ {A : Set} {z : A} n → (Term →⟨ length (replicate n z) ⟩ Term) → Term →⟨ n ⟩ Term
coe zero t = t
coe (suc n) f = λ t → coe n (f t)
con`ⁿʳ : QName → (n : ℕ) → Term →⟨ n ⟩ Term
con`ⁿʳ x n = coe n (app` (con x) (replicate n (visible , relevant)))
def`ⁿʳ : QName → (n : ℕ) → Term →⟨ n ⟩ Term
def`ⁿʳ x n = coe n (app` (def x) (replicate n (visible , relevant)))
var`ⁿʳ : ℕ → (n : ℕ) → Term →⟨ n ⟩ Term
var`ⁿʳ x n = coe n (app` (var x) (replicate n (visible , relevant)))
sort₀ : Sort
sort₀ = lit 0
sort₁ : Sort
sort₁ = lit 1
`Set₀ : Term
`Set₀ = sort sort₀
el₀ : Term → Type
el₀ = el sort₀
-- Builds a type variable (of type Set₀)
``var₀ : ℕ → Args → Type
``var₀ n args = el₀ (var n args)
``Set₀ : Type
``Set₀ = el sort₁ `Set₀
unEl : Type → Term
unEl (el _ tm) = tm
getSort : Type → Sort
getSort (el s _) = s
unArg : ∀ {A} → Arg A → A
unArg (arg _ _ a) = a
`Level : Term
`Level = def (quote Level) []
``Level : Type
``Level = el₀ `Level
`sucLevel : Term → Term
`sucLevel = def`ⁿʳ (quote lsuc) 1
sucSort : Sort → Sort
sucSort s = set (`sucLevel (sort s))
ℕ→Level : ℕ → Level
ℕ→Level zero = lzero
ℕ→Level (suc n) = lsuc (ℕ→Level n)
-- Can't match on Levels anymore
-- Level→ℕ : Level → ℕ
-- Level→ℕ zero = zero
-- Level→ℕ (suc n) = suc (Level→ℕ n)
setLevel : Level → Sort
setLevel ℓ = lit 0 -- (Level→ℕ ℓ)
_==_ : QName → QName → Bool
_==_ = primQNameEquality
decodeSort : Sort → Maybe Level
decodeSort (set (con c [])) = when (quote lzero == c) (just lzero)
decodeSort (set (con c (arg visible relevant s ∷ [])))
= when (quote lsuc == c) (mapMaybe lsuc (decodeSort (set s)))
decodeSort (set (sort s)) = decodeSort s
decodeSort (set _) = nothing
decodeSort (lit n) = just (ℕ→Level n)
decodeSort unknown = nothing
_`⊔`_ : Sort → Sort → Sort
s₁ `⊔` s₂ with decodeSort s₁ | decodeSort s₂
... | just n₁ | just n₂ = setLevel (n₁ ⊔ n₂)
... | _ | _ = set (def (quote _⊔_) (argᵛʳ (sort s₁) ∷ argᵛʳ (sort s₂) ∷ []))
Π : Arg Type → Type → Type
Π t u = el (getSort (unArg t) `⊔` getSort u) (pi t u)
Πᵛʳ : Type → Type → Type
Πᵛʳ t u = el (getSort t `⊔` getSort u) (pi (arg visible relevant t) u)
Πʰʳ : Type → Type → Type
Πʰʳ t u = el (getSort t `⊔` getSort u) (pi (arg hidden relevant t) u)
open ReflectLibrary
`ℕ : Term
`ℕ = def (quote ℕ) []
`ℕOk : (unquote `ℕ) ≡ ℕ
`ℕOk = refl
``ℕ : Type
``ℕ = el₀ `ℕ
idℕ : ℕ → ℕ
idℕ = unquote (lamᵛ (var 0 []))
id : (A : Set) → A → A
id = unquote (lamᵛ (lamᵛ (var 0 [])))
idBox : Box ({A : Set} → A → A)
idBox = box (unquote (lamᵛ (var 0 [])))
-- builds a pair
_`,_ : Term → Term → Term
_`,_ = con`ⁿʳ (quote _,_) 2
`tt : Term
`tt = con (quote tt) []
tuple : List Term → Term
tuple = foldr _`,_ `tt
`refl : Term
`refl = con (quote refl) []
`zero : Term
`zero = con (quote ℕ.zero) []
`[] : Term
`[] = con (quote []) []
_`∷_ : (`x `xs : Term) → Term
_`∷_ = con`ⁿʳ (quote _∷_) 2
`var : (`n `args : Term) → Term
`var = con`ⁿʳ (quote var) 2
`lam : (`hiding `args : Term) → Term
`lam = con`ⁿʳ (quote lam) 2
`visible : Term
`visible = con (quote visible) []
`hidden : Term
`hidden = con (quote hidden) []
`[_`] : Term → Term
`[ x `] = x `∷ `[]
quotedTwice : Term
quotedTwice = `lam `visible (`var `zero `[])
unquoteTwice₂ : ℕ → ℕ
unquoteTwice₂ = unquote (unquote quotedTwice)
unquoteTwice : ℕ → ℕ
unquoteTwice x = unquote (unquote (`var `zero `[]))
id₂ : {A : Set} → A → A
id₂ = unquote (lamᵛ (var 0 []))
id₃ : {A : Set} → A → A
id₃ x = unquote (var 0 [])
module Id {A : Set} (x : A) where
x′ : A
x′ = unquote (var 0 [])
k`ℕ : ℕ → Term
k`ℕ zero = `ℕ
k`ℕ (suc n) = unquote (def (quote k`ℕ) [ argᵛʳ (var 0 []) ]) -- k`ℕ n
test : id ≡ (λ A (x : A) → x)
× unquote `Set₀ ≡ Set
× unquote `ℕ ≡ ℕ
× unquote (lamᵛ (var 0 [])) ≡ (λ (x : Set) → x)
× id ≡ (λ A (x : A) → x)
× unquote `tt ≡ tt
× (λ {A} → Id.x′ {A}) ≡ (λ {A : Set} (x : A) → x)
× unquote (pi (argᵛʳ ``Set₀) ``Set₀) ≡ (Set → Set)
× unquoteTwice ≡ (λ (x : ℕ) → x)
× unquote (k`ℕ 42) ≡ ℕ
× ⊤
test = unquote (tuple (replicate n `refl)) where n = 10
Πⁿ : ℕ → Type → Type
Πⁿ zero t = t
Πⁿ (suc n) t = Π (argʰʳ ``Set₀) (Πⁿ n t)
ƛⁿ : Hiding → ℕ → Term → Term
ƛⁿ h zero t = t
ƛⁿ h (suc n) t = lam h (ƛⁿ h n t)
-- projᵢ : Proj i n
-- projᵢ = proj i n
-- Projᵢ = {A₁ ... Ai ... An : Set} → A₁ → ... → Aᵢ → ... → An → Aᵢ
-- projᵢ = λ {A₁ ... Ai ... An} x₁ ... xᵢ ... xn → xᵢ
Proj : (i n : ℕ) → Term
Proj i n = unEl (Πⁿ n (go n)) where
n∸1 = n ∸ 1
go : ℕ → Type
go zero = ``var₀ ((n + n) ∸ i) []
go (suc m) = Π (argᵛʳ (``var₀ n∸1 [])) (go m)
proj : (i n : ℕ) → Term
proj i n = ƛⁿ visible n (var (n ∸ i) [])
projFull : (i n : ℕ) → Term
projFull i n = ƛⁿ hidden n (proj i n)
ℕ→ℕ : Set
ℕ→ℕ = unquote (unEl (Π (argᵛʳ ``ℕ) ``ℕ))
ℕ→ℕOk : ℕ→ℕ ≡ (ℕ → ℕ)
ℕ→ℕOk = refl
``∀A→A : Type
``∀A→A = Π (argᵛʳ ``Set₀) (``var₀ 0 [])
∀A→A : Set₁
∀A→A = unquote (unEl ``∀A→A)
Proj₁¹ : Set₁
Proj₁¹ = unquote (Proj 1 1)
Proj₁² : Set₁
Proj₁² = unquote (Proj 1 2)
Proj₂² : Set₁
Proj₂² = unquote (Proj 2 2)
proj₃⁵ : unquote (Proj 3 5)
proj₃⁵ _ _ x _ _ = x
proj₃⁵′ : Box (unquote (Proj 3 5))
proj₃⁵′ = box (unquote (proj 3 5))
proj₂⁷ : unquote (Proj 2 7)
proj₂⁷ = unquote (proj 2 7)
test-proj : proj₃⁵′ ≡ box (λ _ _ x _ _ → x)
× Proj₁¹ ≡ ({A : Set} → A → A)
× Proj₁² ≡ ({A₁ A₂ : Set} → A₁ → A₂ → A₁)
× Proj₂² ≡ ({A₁ A₂ : Set} → A₁ → A₂ → A₂)
× unquote (Proj 3 5) ≡ ({A₁ A₂ A₃ A₄ A₅ : Set} → A₁ → A₂ → A₃ → A₄ → A₅ → A₃)
× unquote (projFull 1 1) ≡ (λ {A : Set} (x : A) → x)
× unquote (projFull 1 2) ≡ (λ {A₁ A₂ : Set} (x₁ : A₁) (x₂ : A₂) → x₁)
× unquote (projFull 2 2) ≡ (λ {A₁ A₂ : Set} (x₁ : A₁) (x₂ : A₂) → x₂)
× ∀A→A ≡ (∀ (A : Set) → A)
× ⊤
test-proj = unquote (tuple (replicate n `refl)) where n = 9
module Test where
data Squash (A : Set) : Set where
squash : unquote (unEl (Π (arg visible irrelevant (``var₀ 0 [])) (el₀ (def (quote Squash) (argᵛʳ (var 1 []) ∷ [])))))
data Squash (A : Set) : Set where
squash : .A → Squash A
`Squash : Term → Term
`Squash = def`ⁿʳ (quote Squash) 1
squash-type : Type
squash-type = Π (arg visible irrelevant (``var₀ 0 [])) (el₀ (`Squash (var 1 [])))
test-squash : ∀ {A} → (.A → Squash A) ≡ unquote (unEl squash-type)
test-squash = refl
`∀ℓ→Setℓ : Type
`∀ℓ→Setℓ = Πᵛʳ ``Level (el₀ (sort (set (var 0 []))))