module Section1 where
-- 1. Introduction
-- ===============
--
-- 1.1. Outline of the formalisation
-- ---------------------------------
--
-- - We formalize terms-in-context, `Γ ⊢ t ∷ A`, as a calculus of proof trees, `Γ ⊢ A`, for
-- implicational logic, i.e., term `t` is seen as a proof tree that derives `A` from the assumptions
-- contained in `Γ`. A notion of equivalence of terms-in-context (including, e.g., β-reduction
-- and η-conversion) is then defined with a conversion relation `_≅_` on these proof trees.
--
-- - We give a Kripke model with an ordered set of worlds and define when a proposition `A` is
-- true for a world `w` in the model, `w ⊩ A`. We also define an extensional equality between
-- objects in the model.
--
-- - We define an interpreter `⟦_⟧` that maps a proof tree in the theory to its semantics in the
-- Kripke model. According to the Curry-Howard correspondence of programs to proofs
-- and types to propositions, the type of the interpreter expresses soundness of the theory of
-- proof trees with respect to the Kripke model. Consequently, the interpreter can be seen
-- as a constructive soundness proof.
--
-- - We also define an inversion function, `reify`, which returns a proof tre corresponding to
-- a given semantic object, yielding—again by the Curry-Howard isomorphism—a
-- completeness proof.
--
-- The inversion function is based on the principle of normalization by evaluation [3].
-- Obviously, for proof trees `M` and `N` with the same semantics, inversion yields the same proof
-- tree `reify ⟦ M ⟧ = reify ⟦ N ⟧`. Consequently, we define a normalization function, `nf`, as
-- the composition of the interpreter and the inversion function. We prove that if `M` is a proof
-- tree, then `M ≅ nf M`; together with the soundness result, this yields a decision algorithm
-- for convertibility. We further show that `nf` returns a proof term in long η-normal form.
--
-- - We prove that the convertibility relation on proof trees is sound and complete. The proof
-- of soundness, i.e., convertible proof trees have the same semantics, is straightforward by
-- induction on the structure of the trees. The completeness proof, i.e., if `⟦ M ⟧` and `⟦ N ⟧` are
-- equal, then `M` and `N` are convertible, uses the fact that `reify ⟦ M ⟧` is exactly the same as
-- `reify ⟦ N ⟧`, and since `M ≅ nf M ≡ reify ⟦ M ⟧` and vice versa for `N`, we get that `M ≅ N`.
--
-- - We define a calculus of simply typed ƛterms, a typed convertibility relation on the terms,
-- and a deterministic reduction, `_⇓_`. We also define an erasure function on proof trees that
-- maps a proof tree `M` into a well-typed term `M ⁻`. For every well-typed term there is at
-- least one proof tree that erases to this term; for defining the semantics of well-typed terms
-- through that of proof trees, it suffices to show that all proof trees that erase to the same
-- well-typed term have the same semantics.
--
-- - Because we know that convertible proof trees have the same semantics, it remains to
-- show that all proof trees that erase to a given well-typed term are convertible. We use an
-- argument due to Streicher [19]: we first prove that if `nf M ⁻` and `nf N ⁻` are the same,
-- then `M ≅ N`. Secondly, we prove that if a proof tree `M` erases to a well-typed term `t`,
-- then `t ⇓ nf M ⁻`. Now, if two proof trees `M` and `N` erase to the same well-typed term
-- `t`, then `t ⇓ nf M ⁻` and `t ⇓ nf N ⁻`. Since the reduction is deterministic we have that
-- `nf M ⁻` and `nf N ⁻` are the same, and hence `M ≅ N`.
--
-- - We prove that the convertibility relation on proof trees is sound and complete, and give
-- a decision algorithm for checking convertibility of two well-typed terms.
--
-- (…)
open import Agda.Builtin.FromString public
using (IsString ; fromString)
open import Data.Bool public
using (Bool ; T ; true ; false ; not)
renaming (_∧_ to and)
open import Data.Empty public
using (⊥)
renaming (⊥-elim to elim⊥)
open import Data.Product public
using (Σ ; _,_ ; _×_ ; proj₁ ; proj₂)
open import Data.Unit public
using (⊤ ; tt)
import Data.String as Str
open Str
using (String)
open import Function public
using (_∘_ ; case_of_ ; flip ; id)
open import Relation.Binary.PropositionalEquality public
using (_≡_ ; _≢_ ; refl ; cong ; subst ; sym ; trans)
renaming (cong₂ to cong²)
open import Relation.Nullary public
using (¬_ ; Dec ; yes ; no)
import Relation.Nullary.Decidable as Decidable
open Decidable using (⌊_⌋) public
open import Relation.Nullary.Negation public
renaming (contradiction to _↯_)
module _ where
data Name : Set where
name : String → Name
module _ where
inj-name : ∀ {s s′} → name s ≡ name s′ → s ≡ s′
inj-name refl = refl
_≟_ : (x x′ : Name) → Dec (x ≡ x′)
name s ≟ name s′ = Decidable.map′ (cong name) inj-name (s Str.≟ s′)
_≠_ : Name → Name → Bool
x ≠ x′ = not ⌊ x ≟ x′ ⌋
instance
str-Name : IsString Name
str-Name = record
{ Constraint = λ s → ⊤
; fromString = λ s → name s
}
module _ where
record Raiseable
{World : Set}
(_⊩◌ : World → Set)
{_⊒_ : World → World → Set} : Set₁ where
field
↑⟨_⟩ : ∀ {w w′} → w′ ⊒ w → w ⊩◌ → w′ ⊩◌
open Raiseable {{…}} public
record Lowerable
{World : Set}
(◌⊩_ : World → Set)
{_⊒_ : World → World → Set} : Set₁ where
field
↓⟨_⟩ : ∀ {w w′} → w′ ⊒ w → ◌⊩ w′ → ◌⊩ w
open Lowerable {{…}} public