module Reflection where
open import Data.Bool as Bool using (Bool); open Bool.Bool
open import Data.List using (List); open Data.List.List
open import Data.Nat as Nat using (ℕ)
open import Function
open import Relation.Binary
open import Relation.Binary.PropositionalEquality
open import Relation.Binary.PropositionalEquality.TrustMe
open import Relation.Nullary
postulate Name : Set
{-# BUILTIN QNAME Name #-}
private
primitive
primQNameEquality : Name → Name → Bool
infix 4 _==_ _≟-Name_
private
_==_ : Name → Name → Bool
_==_ = primQNameEquality
_≟-Name_ : Decidable {A = Name} _≡_
s₁ ≟-Name s₂ with s₁ == s₂
... | true = yes trustMe
... | false = no whatever
where postulate whatever : _
Implicit? = Bool
data Arg A : Set where
arg : (im? : Implicit?) (x : A) → Arg A
{-# BUILTIN ARG Arg #-}
{-# BUILTIN ARGARG arg #-}
data Term : Set where
var : (x : ℕ) (args : List (Arg Term)) → Term
con : (c : Name) (args : List (Arg Term)) → Term
def : (f : Name) (args : List (Arg Term)) → Term
lam : (im? : Implicit?) (t : Term) → Term
pi : (t₁ : Arg Term) (t₂ : Term) → Term
sort : Term
unknown : Term
{-# BUILTIN AGDATERM Term #-}
{-# BUILTIN AGDATERMVAR var #-}
{-# BUILTIN AGDATERMCON con #-}
{-# BUILTIN AGDATERMDEF def #-}
{-# BUILTIN AGDATERMLAM lam #-}
{-# BUILTIN AGDATERMPI pi #-}
{-# BUILTIN AGDATERMSORT sort #-}
{-# BUILTIN AGDATERMUNSUPPORTED unknown #-}
private
arg₁ : ∀ {A im? im?′} {x x′ : A} →
arg im? x ≡ arg im?′ x′ → im? ≡ im?′
arg₁ refl = refl
arg₂ : ∀ {A im? im?′} {x x′ : A} →
arg im? x ≡ arg im?′ x′ → x ≡ x′
arg₂ refl = refl
cons₁ : ∀ {A : Set} {x y} {xs ys : List A} → x ∷ xs ≡ y ∷ ys → x ≡ y
cons₁ refl = refl
cons₂ : ∀ {A : Set} {x y} {xs ys : List A} → x ∷ xs ≡ y ∷ ys → xs ≡ ys
cons₂ refl = refl
var₁ : ∀ {x x′ args args′} → var x args ≡ var x′ args′ → x ≡ x′
var₁ refl = refl
var₂ : ∀ {x x′ args args′} → var x args ≡ var x′ args′ → args ≡ args′
var₂ refl = refl
con₁ : ∀ {c c′ args args′} → con c args ≡ con c′ args′ → c ≡ c′
con₁ refl = refl
con₂ : ∀ {c c′ args args′} → con c args ≡ con c′ args′ → args ≡ args′
con₂ refl = refl
def₁ : ∀ {f f′ args args′} → def f args ≡ def f′ args′ → f ≡ f′
def₁ refl = refl
def₂ : ∀ {f f′ args args′} → def f args ≡ def f′ args′ → args ≡ args′
def₂ refl = refl
lam₁ : ∀ {im? im?′ t t′} → lam im? t ≡ lam im?′ t′ → im? ≡ im?′
lam₁ refl = refl
lam₂ : ∀ {im? im?′ t t′} → lam im? t ≡ lam im?′ t′ → t ≡ t′
lam₂ refl = refl
pi₁ : ∀ {t₁ t₁′ t₂ t₂′} → pi t₁ t₂ ≡ pi t₁′ t₂′ → t₁ ≡ t₁′
pi₁ refl = refl
pi₂ : ∀ {t₁ t₁′ t₂ t₂′} → pi t₁ t₂ ≡ pi t₁′ t₂′ → t₂ ≡ t₂′
pi₂ refl = refl
mutual
infix 4 _≟-Arg_ _≟-Args_ _≟_
_≟-Arg_ : Decidable (_≡_ {A = Arg Term})
arg e a ≟-Arg arg e′ a′ with Bool._≟_ e e′ | a ≟ a′
arg e a ≟-Arg arg .e .a | yes refl | yes refl = yes refl
arg e a ≟-Arg arg e′ a′ | no e≢e′ | _ = no (e≢e′ ∘ arg₁)
arg e a ≟-Arg arg e′ a′ | _ | no a≢a′ = no (a≢a′ ∘ arg₂)
_≟-Args_ : Decidable (_≡_ {A = List (Arg Term)})
[] ≟-Args [] = yes refl
(a ∷ args) ≟-Args (a′ ∷ args′) with a ≟-Arg a′ | args ≟-Args args′
(a ∷ args) ≟-Args (.a ∷ .args) | yes refl | yes refl = yes refl
(a ∷ args) ≟-Args (a′ ∷ args′) | no a≢a′ | _ = no (a≢a′ ∘ cons₁)
(a ∷ args) ≟-Args (a′ ∷ args′) | _ | no args≢args′ = no (args≢args′ ∘ cons₂)
[] ≟-Args (_ ∷ _) = no λ()
(_ ∷ _) ≟-Args [] = no λ()
_≟_ : Decidable (_≡_ {A = Term})
var x args ≟ var x′ args′ with Nat._≟_ x x′ | args ≟-Args args′
var x args ≟ var .x .args | yes refl | yes refl = yes refl
var x args ≟ var x′ args′ | no x≢x′ | _ = no (x≢x′ ∘ var₁)
var x args ≟ var x′ args′ | _ | no args≢args′ = no (args≢args′ ∘ var₂)
con c args ≟ con c′ args′ with c ≟-Name c′ | args ≟-Args args′
con c args ≟ con .c .args | yes refl | yes refl = yes refl
con c args ≟ con c′ args′ | no c≢c′ | _ = no (c≢c′ ∘ con₁)
con c args ≟ con c′ args′ | _ | no args≢args′ = no (args≢args′ ∘ con₂)
def f args ≟ def f′ args′ with f ≟-Name f′ | args ≟-Args args′
def f args ≟ def .f .args | yes refl | yes refl = yes refl
def f args ≟ def f′ args′ | no f≢f′ | _ = no (f≢f′ ∘ def₁)
def f args ≟ def f′ args′ | _ | no args≢args′ = no (args≢args′ ∘ def₂)
lam im? t ≟ lam im?′ t′ with Bool._≟_ im? im?′ | t ≟ t′
lam im? t ≟ lam .im? .t | yes refl | yes refl = yes refl
lam im? t ≟ lam im?′ t′ | no im?≢im?′ | _ = no (im?≢im?′ ∘ lam₁)
lam im? t ≟ lam im?′ t′ | _ | no t≢t′ = no (t≢t′ ∘ lam₂)
pi t₁ t₂ ≟ pi t₁′ t₂′ with t₁ ≟-Arg t₁′ | t₂ ≟ t₂′
pi t₁ t₂ ≟ pi .t₁ .t₂ | yes refl | yes refl = yes refl
pi t₁ t₂ ≟ pi t₁′ t₂′ | no t₁≢t₁′ | _ = no (t₁≢t₁′ ∘ pi₁)
pi t₁ t₂ ≟ pi t₁′ t₂′ | _ | no t₂≢t₂′ = no (t₂≢t₂′ ∘ pi₂)
sort ≟ sort = yes refl
unknown ≟ unknown = yes refl
var x args ≟ con c args′ = no λ()
var x args ≟ def f args′ = no λ()
var x args ≟ lam im? t = no λ()
var x args ≟ pi t₁ t₂ = no λ()
var x args ≟ sort = no λ()
var x args ≟ unknown = no λ()
con c args ≟ var x args′ = no λ()
con c args ≟ def f args′ = no λ()
con c args ≟ lam im? t = no λ()
con c args ≟ pi t₁ t₂ = no λ()
con c args ≟ sort = no λ()
con c args ≟ unknown = no λ()
def f args ≟ var x args′ = no λ()
def f args ≟ con c args′ = no λ()
def f args ≟ lam im? t = no λ()
def f args ≟ pi t₁ t₂ = no λ()
def f args ≟ sort = no λ()
def f args ≟ unknown = no λ()
lam im? t ≟ var x args = no λ()
lam im? t ≟ con c args = no λ()
lam im? t ≟ def f args = no λ()
lam im? t ≟ pi t₁ t₂ = no λ()
lam im? t ≟ sort = no λ()
lam im? t ≟ unknown = no λ()
pi t₁ t₂ ≟ var x args = no λ()
pi t₁ t₂ ≟ con c args = no λ()
pi t₁ t₂ ≟ def f args = no λ()
pi t₁ t₂ ≟ lam im? t = no λ()
pi t₁ t₂ ≟ sort = no λ()
pi t₁ t₂ ≟ unknown = no λ()
sort ≟ var x args = no λ()
sort ≟ con c args = no λ()
sort ≟ def f args = no λ()
sort ≟ lam im? t = no λ()
sort ≟ pi t₁ t₂ = no λ()
sort ≟ unknown = no λ()
unknown ≟ var x args = no λ()
unknown ≟ con c args = no λ()
unknown ≟ def f args = no λ()
unknown ≟ lam im? t = no λ()
unknown ≟ pi t₁ t₂ = no λ()
unknown ≟ sort = no λ()