open import Library
module DanvyShiftReset where
data Base : Set where
α β : Base
open import Formulas Base
open import Derivations Base
record M (A B C : Cxt → Set) (Γ : Cxt) : Set where
field run : KFun (KFun C B) A Γ
open M
return : ∀{X A} → □ A →̇ M X X A
return x .run τ k = k id≤ (x τ)
return' : ∀{X A} → □ A →̇ M X X (□ A)
return' x .run τ k = k id≤ λ τ₁ → x (τ₁ • τ)
_>>=_ : ∀{X Y Z A B Γ} (m : M X Y A Γ) (f : KFun A (M Y Z B) Γ) → M X Z B Γ
(m >>= f) .run σ k = m .run σ λ τ a → f (τ • σ) a .run id≤ λ τ′ → k (τ′ • τ)
_<$>_ : ∀{X Y A B} (f : A →̇ B) → M X Y A →̇ M X Y B
(f <$> m) .run σ k = m .run σ λ τ → k τ ∘ f
K$ : ∀{X Y A B} → KFun A B →̇ KFun (M X Y A) (M X Y B)
K$ f τ m .run σ k = m .run σ λ τ′ a → k τ′ (f (τ′ • (σ • τ)) a)
shift' : ∀{X Y A Γ} (f : KFun (KFun A Y) X Γ) → M X Y A Γ
shift' f .run σ k = f σ k
shift : ∀{X Y A Γ} (f : KFun (KFun A Y) (M X Y Y) Γ) → M X Y A Γ
shift f .run σ k = f σ k .run id≤ λ τ → id
reset' : ∀{Y A} → M A Y Y →̇ A
reset' m = m .run id≤ λ τ → id
reset : ∀{X Y A} → M A Y Y →̇ M X X A
reset m .run σ k = k id≤ (m .run σ λ τ → id)
M' : (X : Cxt → Set) (Γ : Cxt) → Set
M' X Γ = ∀ {C} → M (Nf' C) (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) = monNf
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 (σ • τ)
mutual
reflect : ∀{Γ} A (t : Ne Γ A) → M' T⟦ A ⟧ Γ
reflect (Atom P) t = return λ τ → ne (monNe τ t)
reflect True t = return _
reflect False t = shift' λ τ k → falseE (monNe τ t)
reflect (A ∨ B) t = shift' λ τ k → orE (monNe τ t)
(reset' (K$ k (weak id≤) (inj₁ <$> reflect A (hyp top))))
(reset' (K$ k (weak id≤) (inj₂ <$> reflect B (hyp top))))
reflect (A ∧ B) t =
reflect A (andE₁ t ) >>= λ τ a →
reflect B (andE₂ (monNe τ t)) >>= λ τ′ b →
return λ τ₁ → monT A (τ₁ • τ′) a , monT B τ₁ b
reflect (A ⇒ B) t = return' λ τ a → reflect B (impE (monNe τ t) (reify A a))
reify : ∀{Γ} A (⟦f⟧ : 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 (hyp top) >>= λ τ a →
reify B <$> f (τ • weak id≤) a
G⟦_⟧ : ∀ (Γ Δ : Cxt) → Set
G⟦ ε ⟧ Δ = ⊤
G⟦ Γ ∙ A ⟧ Δ = G⟦ Γ ⟧ Δ × T⟦ A ⟧ Δ
monG : ∀{Γ} → Mon G⟦ Γ ⟧
monG {ε} τ _ = _
monG {Γ ∙ A} τ (γ , a) = monG τ γ , monT A τ a
fundH : ∀{Γ Δ A} (x : Hyp A Γ) (γ : G⟦ Γ ⟧ Δ) → T⟦ A ⟧ Δ
fundH top = proj₂
fundH (pop x) = fundH x ∘ proj₁
fund : ∀{Γ A} (t : Γ ⊢ A) {Δ} (γ : G⟦ Γ ⟧ Δ) → M' T⟦ A ⟧ Δ
fund (hyp {A} x) γ = return λ τ → monT A τ (fundH x γ)
fund (impI t) γ = return' λ τ a → fund t (monG τ γ , a)
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 t u v) γ = fund t γ >>= λ τ →
[ (λ a → fund u (monG τ γ , a))
, (λ b → fund v (monG τ γ , b))
]
fund (falseE t) γ = fund t γ >>= λ τ ()
fund trueI γ = return _
ide : ∀ Γ → □ (M' G⟦ Γ ⟧) Γ
ide ε τ = return _
ide (Γ ∙ A) τ =
ide Γ (τ • weak id≤) >>= λ τ₁ γ →
reflect A (monNe (τ₁ • τ) (hyp top)) >>= λ τ₂ a →
return λ τ₃ → monG (τ₃ • τ₂) γ , monT A τ₃ a
norm : ∀{A Γ} (t : Γ ⊢ A) → Nf Γ A
norm {A} {Γ} t = reset' $
ide Γ id≤ >>= λ _ γ →
reify A <$> fund t γ
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 α))