open import Library
module NfModelCaseTree (Base : Set) where
import Formulas ; open module Form = Formulas Base
import Derivations; open module Der = Derivations Base
data Cover (P : Cxt → Set) (Γ : Cxt) : Set where
returnC : (p : P Γ) → Cover P Γ
falseC : (t : Ne Γ False) → Cover P Γ
orC : ∀{C D} (t : Ne Γ (C ∨ D))
(c : Cover P (Γ ∙ C))
(d : Cover P (Γ ∙ D)) → Cover P Γ
pasteNf : ∀{A} → Cover (Nf' A) →̇ Nf' A
pasteNf (returnC p) = p
pasteNf (falseC t) = falseE t
pasteNf (orC t c d) = orE t (pasteNf c) (pasteNf d)
monC : ∀{P} → (monP : Mon P) → Mon (Cover P)
monC monP τ (returnC p) = returnC (monP τ p)
monC monP τ (falseC t) = falseC (monNe τ t)
monC monP τ (orC t c d) = orC (monNe τ t) (monC monP (lift τ) c)
(monC monP (lift τ) d)
mapC : ∀{P Q} → (P →̇ Q) → (Cover P →̇ Cover Q)
mapC f (returnC p) = returnC (f p)
mapC f (falseC t) = falseC t
mapC f (orC t c d) = orC t (mapC f c) (mapC f d)
joinC : ∀{P} → Cover (Cover P) →̇ Cover P
joinC (returnC p) = p
joinC (falseC t) = falseC t
joinC (orC t c d) = orC t (joinC c) (joinC d)
mapC' : ∀{P Q Γ} → KFun P Q Γ → Cover P Γ → Cover Q Γ
mapC' f (returnC p) = returnC (f id≤ p)
mapC' f (falseC t) = falseC t
mapC' f (orC t c d) = orC t (mapC' (λ τ → f (τ • weak id≤)) c)
(mapC' (λ τ → f (τ • weak id≤)) d)
T⟦_⟧ : (A : Form) (Γ : Cxt) → Set
T⟦ Atom P ⟧ = Nf' (Atom P)
T⟦ True ⟧ Γ = ⊤
T⟦ False ⟧ = Cover λ Δ → ⊥
T⟦ A ∨ B ⟧ = Cover λ Δ → T⟦ A ⟧ Δ ⊎ T⟦ B ⟧ Δ
T⟦ A ∧ B ⟧ Γ = T⟦ A ⟧ Γ × T⟦ B ⟧ Γ
T⟦ A ⇒ B ⟧ Γ = ∀{Δ} (τ : Δ ≤ Γ) → T⟦ A ⟧ Δ → T⟦ B ⟧ Δ
monT : ∀ A → Mon T⟦ A ⟧
monT (Atom P) = monNf
monT True = _
monT False = monC λ τ ()
monT (A ∨ B) = monC λ τ → map-⊎ (monT A τ) (monT B τ)
monT (A ∧ B) τ (a , b) = monT A τ a , monT B τ b
monT (A ⇒ B) τ f σ = f (σ • τ)
mutual
fresh : ∀ {Γ} A → T⟦ A ⟧ (Γ ∙ A)
fresh A = reflect A (hyp top)
reflect : ∀ A → Ne' A →̇ T⟦ A ⟧
reflect (Atom P) t = ne t
reflect True t = _
reflect False t = falseC t
reflect (A ∨ B) t = orC t (returnC (inj₁ (fresh A)))
(returnC (inj₂ (fresh B)))
reflect (A ∧ B) t = reflect A (andE₁ t) , reflect B (andE₂ t)
reflect (A ⇒ B) t τ a = reflect B (impE (monNe τ t) (reify A a))
reify : ∀ A → T⟦ A ⟧ →̇ Nf' A
reify (Atom P) t = t
reify True _ = trueI
reify False = pasteNf ∘ mapC ⊥-elim
reify (A ∨ B) = pasteNf ∘ mapC [ orI₁ ∘ reify A , orI₂ ∘ reify B ]
reify (A ∧ B) (a , b) = andI (reify A a) (reify B b)
reify (A ⇒ B) ⟦f⟧ = impI (reify B (⟦f⟧ (weak id≤) (fresh A)))
paste : ∀ A → Cover T⟦ A ⟧ →̇ T⟦ A ⟧
paste (Atom P) = pasteNf
paste True = _
paste False = joinC
paste (A ∨ B) = joinC
paste (A ∧ B) = < paste A ∘ mapC proj₁ , paste B ∘ mapC proj₂ >
paste (A ⇒ B) c τ a = paste B $ mapC' (λ δ f → f id≤ (monT A δ a)) $ monC (monT (A ⇒ B)) τ c
G⟦_⟧ : ∀ (Γ Δ : Cxt) → Set
G⟦ ε ⟧ Δ = ⊤
G⟦ Γ ∙ A ⟧ Δ = G⟦ Γ ⟧ Δ × T⟦ A ⟧ Δ
monG : ∀{Γ} → Mon G⟦ Γ ⟧
monG {ε} τ _ = _
monG {Γ ∙ A} τ (γ , a) = monG τ γ , monT A τ a
lookup : ∀{Γ A} (x : Hyp A Γ) → G⟦ Γ ⟧ →̇ T⟦ A ⟧
lookup top = proj₂
lookup (pop x) = lookup x ∘ proj₁
orElim : ∀ A B C {Γ} → T⟦ A ∨ B ⟧ Γ → T⟦ A ⇒ C ⟧ Γ → T⟦ B ⇒ C ⟧ Γ → T⟦ C ⟧ Γ
orElim A B C c g h = paste C (mapC' (λ τ → [ g τ , h τ ]) c)
falseElim : ∀ C → T⟦ False ⟧ →̇ T⟦ C ⟧
falseElim C = paste C ∘ mapC ⊥-elim
eval : ∀{A Γ} (t : Γ ⊢ A) → G⟦ Γ ⟧ →̇ T⟦ A ⟧
eval (hyp x) = lookup x
eval (impI t) γ τ a = eval t (monG τ γ , a)
eval (impE t u) γ = eval t γ id≤ (eval u γ)
eval (andI t u) γ = eval t γ , eval u γ
eval (andE₁ t) = proj₁ ∘ eval t
eval (andE₂ t) = proj₂ ∘ eval t
eval (orI₁ t) γ = returnC (inj₁ (eval t γ))
eval (orI₂ t) γ = returnC (inj₂ (eval t γ))
eval (orE {A = A} {B} {C} t u v) γ = orElim A B C (eval t γ)
(λ τ a → eval u (monG τ γ , a))
(λ τ b → eval v (monG τ γ , b))
eval {C} (falseE t) γ = falseElim C (eval t γ)
eval trueI γ = _
ide : ∀ Γ → G⟦ Γ ⟧ Γ
ide ε = _
ide (Γ ∙ A) = monG (weak id≤) (ide Γ) , reflect A (hyp top)
norm : ∀{A} → Tm A →̇ Nf' A
norm t = reify _ (eval t (ide _))