open import Library
module DanvyShiftResetLiftable where
data Base : Set where
α β : Base
open import Formulas Base
open import Derivations Base
record M (R A : Cxt → Set) (Γ : Cxt) : Set where
constructor shift
field run : KFun (KFun A R) R Γ
open M
reset : ∀{A} → M A A →̇ A
reset m = m .run id≤ λ τ → id
return : ∀{R A} → □ A →̇ M R A
return x .run τ k = k id≤ (x τ)
return' : ∀{R A} → □ A →̇ M R (□ A)
return' x .run τ k = k id≤ λ τ₁ → x (τ₁ • τ)
_>>=_ : ∀{R A B Γ} (m : M R A Γ) (f : KFun A (M R B) Γ) → M R B Γ
(m >>= f) .run σ k = m .run σ λ τ a → f (τ • σ) a .run id≤ λ τ′ → k (τ′ • τ)
_<$>_ : ∀{R A B} (f : A →̇ B) → M R A →̇ M R B
(f <$> m) .run σ k = m .run σ λ τ → k τ ∘ f
_<&>_ : ∀{R A B Γ} (m : M R A Γ) (f : A →̇ B) → M R B Γ
(m <&> f) .run σ k = m .run σ λ τ → k τ ∘ f
K$ : ∀{R A B} → KFun A B →̇ KFun (M R A) (M R B)
K$ f τ m .run σ k = m .run σ λ τ′ a → k τ′ (f (τ′ • (σ • τ)) a)
M' : (X : Cxt → Set) (Γ : Cxt) → Set
M' X Γ = ∀ {C} → M (Nf' C) X Γ
T⟦_⟧ : (A : Form) (Γ : Cxt) → Set
T⟦ Atom P ⟧ = □ (Nf' (Atom P))
T⟦ True ⟧ Γ = ⊤
T⟦ False ⟧ Γ = ⊥
T⟦ A ∨ B ⟧ Γ = T⟦ A ⟧ Γ ⊎ T⟦ B ⟧ Γ
T⟦ A ∧ B ⟧ Γ = T⟦ A ⟧ Γ × T⟦ B ⟧ Γ
T⟦ A ⇒ B ⟧ Γ = ∀{Δ} (τ : Δ ≤ Γ) → T⟦ A ⟧ Δ → M' T⟦ B ⟧ Δ
monT : ∀ A → Mon T⟦ A ⟧
monT (Atom P) = mon□
monT True = _
monT False τ ()
monT (A ∨ B) τ = map-⊎ (monT A τ) (monT B τ)
monT (A ∧ B) τ (a , b) = monT A τ a , monT B τ b
monT (A ⇒ B) τ f σ = f (σ • τ)
fresh : ∀{A Γ} → □ (Ne' A) (Γ ∙ A)
fresh τ′ = hyp (monH τ′ top)
mutual
reflect : ∀ A → □ (Ne' A) →̇ M' T⟦ A ⟧
reflect (Atom P) t = return' (ne ∘′ t)
reflect True t = return _
reflect False t = shift λ τ k → falseE (t τ)
reflect (A ∨ B) t = shift λ τ k → orE (t τ)
(reset (K$ k (weak id≤) (inj₁ <$> reflect A fresh)))
(reset (K$ k (weak id≤) (inj₂ <$> reflect B fresh)))
reflect (A ∧ B) t =
reflect A ( andE₁ ∘ t ) >>= λ τ a →
reflect B (mon□ {Ne' B} τ (andE₂ ∘ t)) >>= λ τ′ b →
return λ τ₁ → monT A (τ₁ • τ′) a , monT B τ₁ b
reflect (A ⇒ B) t = return' λ τ a → reflect B λ τ′ → impE (t (τ′ • τ)) (reify A a τ′)
reify : ∀ A → T⟦ A ⟧ →̇ □ (Nf' A)
reify (Atom P) t = t
reify True _ τ = trueI
reify False ()
reify (A ∨ B) (inj₁ a) τ = orI₁ (reify A a τ)
reify (A ∨ B) (inj₂ b) τ = orI₂ (reify B b τ)
reify (A ∧ B) (a , b) τ = andI (reify A a τ) (reify B b τ)
reify (A ⇒ B) f τ = impI $ reset $
reflect A fresh >>= λ τ′ a →
f (τ′ • weak τ) a <&> λ b →
reify B b id≤
record ◇ (G : Cxt → Set) (Γ : Cxt) : Set where
constructor dia; field
{Δ} : Cxt
τ : Γ ≤ Δ
γ : G Δ
mon◇ : ∀{P} → Mon (◇ P)
mon◇ τ′ (dia τ p) = dia (τ′ • τ) p
module Monad◇ where
return◇ : ∀{P} → P →̇ ◇ P
return◇ = dia id≤
join◇ : ∀{P} → ◇ (◇ P) →̇ ◇ P
join◇ (dia τ d) = mon◇ τ d
map◇ : ∀{P Q} → (P →̇ Q) → ◇ P →̇ ◇ Q
map◇ f (dia τ p) = dia τ (f p)
G⟦_⟧ : ∀ (Γ Δ : Cxt) → Set
G⟦ ε ⟧ _ = ⊤
G⟦ Γ ∙ A ⟧ = ◇ λ Δ → G⟦ Γ ⟧ Δ × T⟦ A ⟧ Δ
monG : ∀{Γ} → Mon G⟦ Γ ⟧
monG {ε} τ _ = _
monG {Γ ∙ A} τ γ = mon◇ τ γ
ext : ∀ A {Γ Δ₁ Δ} →
(τ : Δ ≤ Δ₁) (γ : G⟦ Γ ⟧ Δ₁) →
(a : T⟦ A ⟧ Δ) →
□ G⟦ Γ ∙ A ⟧ Δ
ext A τ γ a τ′ = dia τ′ (monG τ γ , a)
fundH : ∀{A Γ} (x : Hyp A Γ) → G⟦ Γ ⟧ →̇ □ T⟦ A ⟧
fundH {A} top (dia τ′ (_ , a)) τ = monT A (τ • τ′) a
fundH (pop x) (dia τ′ (γ , _)) τ = fundH x γ (τ • τ′)
fund : ∀{Γ A} (t : Γ ⊢ A) → G⟦ Γ ⟧ →̇ M' T⟦ A ⟧
fund (hyp {A} x) γ = return (fundH x γ)
fund (impI {A} t) γ = return' λ τ a → fund t (ext A τ γ a id≤)
fund (impE t u) γ =
fund t γ >>= λ τ f →
fund u (monG τ γ) >>= λ τ′ a →
f τ′ a
fund (andI {A} {B} t u) γ =
fund t γ >>= λ τ a →
fund u (monG τ γ) >>= λ τ′ b →
return λ τ₁ → monT A (τ₁ • τ′) a , monT B τ₁ b
fund (andE₁ t) γ = proj₁ <$> fund t γ
fund (andE₂ t) γ = proj₂ <$> fund t γ
fund (orI₁ t) γ = inj₁ <$> fund t γ
fund (orI₂ t) γ = inj₂ <$> fund t γ
fund (orE {A} {B} t u v) γ = fund t γ >>= λ τ →
[ (λ a → fund u (ext A τ γ a id≤))
, (λ b → fund v (ext B τ γ b id≤))
]
fund (falseE t) γ = fund t γ >>= λ τ ()
fund trueI γ = return _
ide : ∀ Γ → □ (M' G⟦ Γ ⟧) Γ
ide ε τ = return _
ide (Γ ∙ A) τ =
ide Γ (τ • weak id≤) >>= λ τ₁ γ →
reflect A (mon□ (τ₁ • τ) fresh) >>= λ τ₂ a →
return (ext A τ₂ γ a)
norm : ∀{A Γ} (t : Γ ⊢ A) → Nf Γ A
norm {A} {Γ} t = reset $
ide Γ id≤ >>= λ _ γ →
fund t γ <&> λ a →
reify A a id≤
idD : (A : Form) → ε ⊢ (A ⇒ A)
idD A = impI (hyp top)
test : let A = Atom α; B = Atom β in Nf ε (A ∨ B ⇒ A ∨ B)
test = norm (idD (Atom α ∨ Atom β))
test2 = norm (idD (Atom α ∨ Atom β ∨ Atom α))
test3 = norm (idD False)