Reconstructing types from erased bidirectional syntax
| {-# OPTIONS --erasure #-} | |
| module Reconstruct where | |
| open import Data.Unit | |
| open import Data.Product | |
| data Ty : Set where | |
| Π : Ty → Ty → Ty | |
| data Con : Set where | |
| `1 : Con | |
| _∙_ : Con → Ty → Con | |
| variable | |
| Γ : Con | |
| @0 Γ₀ : Con | |
| A B : Ty | |
| @0 A₀ B₀ : Ty | |
| data Mode : Set where | |
| chk inf : Mode | |
| -- Erased annotations | |
| data Tm : Mode → @0 Con → @0 Ty → Set where | |
| q : Tm inf (Γ₀ ∙ A₀) A₀ | |
| _[p] : Tm inf Γ₀ A₀ → Tm inf (Γ₀ ∙ B₀) A₀ | |
| lam : Tm chk (Γ₀ ∙ A₀) B₀ → Tm chk Γ₀ (Π A₀ B₀) | |
| app : Tm inf Γ₀ (Π A₀ B₀) → Tm chk Γ₀ A₀ → Tm inf Γ₀ B₀ | |
| switch : Tm inf Γ₀ A₀ → Tm chk Γ₀ A₀ | |
| ann : (A : Ty) → Tm chk Γ₀ A → Tm inf Γ₀ A | |
| -- Relevant annotations | |
| data TmA : Con → Ty → Set where | |
| qA : TmA (Γ ∙ A) A | |
| _[p]A : TmA Γ A → TmA (Γ ∙ B) A | |
| lamA : TmA (Γ ∙ A) B → TmA Γ (Π A B) | |
| appA : TmA Γ (Π A B) → TmA Γ A → TmA Γ B | |
| data Rel {A : Set} : @0 A → A → Set where | |
| rel : (a : A) → Rel a a | |
| infer : (Γ : Con) → Tm inf Γ A₀ → Σ[ A ∈ Ty ] (Rel A₀ A × TmA Γ A) | |
| check : (Γ : Con) → (A : Ty) → Tm chk Γ A → TmA Γ A | |
| check Γ (Π A B) (lam t) = lamA (check (Γ ∙ A) B t) | |
| check Γ A (switch t) with (infer Γ t) | |
| ... | A , rel _ , t = t | |
| infer (Γ ∙ A) q = A , rel A , qA | |
| infer (Γ ∙ B) (t [p]) with (infer Γ t) | |
| ... | A , rel _ , t' = A , rel A , t' [p]A | |
| infer Γ (app t u) with (infer Γ t) | |
| ... | Π A B , rel _ , t' = B , rel B , appA t' (check Γ A u) | |
| infer Γ (ann A t) = A , rel A , check Γ A t |
参与讨论