-- Note: Turing machines and lambda calculus are NOT equivalent -- models of computation as soon as we go beyond first-order functions ℕ → ℕ -- to higher-order functions (such as functions of type (ℕ → ℕ) → ℕ). -- -- The reason is that a higher-order Turing machine (ℕ → ℕ) → ℕ is given as input -- the source code for a Turing machine of type ℕ → ℕ. -- -- In contrast, a higher-order lambda term of type (ℕ → ℕ) → ℕ is given -- the input function only as a blackbox, without the source code. ---------- -- Peano arithmetic (PA) is a formal system for expressing -- and proving statements about natural numbers. -- Ingredients: -- Z zero -- S succ -- + -- · open import Padova2025.ProgrammingBasics.Naturals.Base open import Padova2025.ProgrammingBasics.Naturals.Arithmetic open import Padova2025.ProvingBasics.Negation open import Padova2025.ProvingBasics.Equality.Base open import Padova2025.ProvingBasics.Connectives.Conjunction open import Padova2025.ProvingBasics.Connectives.Disjunction open import Padova2025.ProvingBasics.Termination.Gas using (𝟙; tt) -- "Fin n" will be an Agda datatype consisting of exactly n many inhabitants. data Fin : ℕ → Set where zero : {n : ℕ} → Fin (succ n) -- "zero is smaller than succ n, for any n" succ : {n : ℕ} → Fin n → Fin (succ n) -- "if x is smaller than n, then succ x is smaller than succ n" module _ where private -- temporary scratch pad example-1 : Fin three example-1 = zero example-2 : Fin three example-2 = succ zero example-3 : Fin three example-3 = succ (succ zero) -- example-4 : Fin three -- example-4 = succ (succ (succ zero)) -- should not and does not work -- Agda datatype of PA terms, more precisely "Term n" will be -- the Agda datatype of PA terms in which the variables 0, 1, ..., n-1 -- may occur. data Term (n : ℕ) : Set where Z : Term n S : Term n → Term n _⊕_ : Term n → Term n → Term n _⊛_ : Term n → Term n → Term n var : Fin n → Term n -- Agda datatype of PA formulas, more precisely "Form n" will be -- the Agda datatype of PA formulas in which the variables 0, 1, ..., n-1 -- may occur. data Form (n : ℕ) : Set where _∧_ : Form n → Form n → Form n _∨_ : Form n → Form n → Form n _⇒_ : Form n → Form n → Form n top : Form n bot : Form n fa : Form (succ n) → Form n -- ∀ ex : Form (succ n) → Form n -- ∃ _≈_ : Term n → Term n → Form n -- Strictly speaking we don't need the _⇒_ constructor, as we could -- also define (α ⇒ β) as (¬ α ∨ β). example-commutativity : Form zero example-commutativity = fa (fa ((var (succ zero) ⊕ var zero) ≈ (var zero ⊕ var (succ zero)))) -- ∀x. ∀y. x + y = y + x -- parse : String → Form n -- parse "∀x. ∀y. x + y = y + x" -- We don't need negation as a constructor, as we can define it: neg : {n : ℕ} → Form n → Form n neg φ = (φ ⇒ bot) -- The formula "∀x. ∀y. x + y = y + x" would be regarded as well-formed, -- but the formula "∀x. ∀y. x + a = y + x" would not. -- Axioms: -- ∀x. Z + x = x -- induction scheme: (P(Z) ∧ (∀n. P(n) ⇒ P(S(n)))) ⇒ ∀n. P(n) -- (one axiom for each formula P) -- ... -- Inference rules: -- P ⊢ P ("from P, we may conclude P") -- P ∧ Q ⊢ P ("from P ∧ Q, we may conclude P") -- ⊤ ⊢ P ∨ ¬ P ("from ⊤, we may conclude the law of excluded middle for P") -- ... data _⊢_ : {n : ℕ} → Form n → Form n → Set where identity : {n : ℕ} {φ : Form n} → φ ⊢ φ conj-elimₗ : {n : ℕ} {α β : Form n} → (α ∧ β) ⊢ α conj-elimᵣ : {n : ℕ} {α β : Form n} → (α ∧ β) ⊢ β cut : {n : ℕ} {α β γ : Form n} → (α ⊢ β) → (β ⊢ γ) → (α ⊢ γ) -- ... -- Let us verify that HA is consistent, i.e. that HA does NOT prove ⊤ ⊢ Z ≈ S Z. -- We do that by exhibiting a model. Env : ℕ → Set Env n = Fin n → ℕ -- "Env n" is the type of environments, specifying an actual value -- for each of the variables 0, ..., n-1. -- "eval φ" should be the Agda truth value of the HA-formula φ. -- For instance, the type "eval example-commutativity" should be inhabited, -- by a witness that addition of natural numbers is commutative. -- In constrast, the type "eval bot" should be empty. eval₀ : {n : ℕ} → Env n → Term n → ℕ eval₀ env Z = zero eval₀ env (S x) = succ (eval₀ env x) eval₀ env (x ⊕ y) = eval₀ env x + eval₀ env y eval₀ env (x ⊛ y) = {!!} eval₀ env (var v) = env v eval : {n : ℕ} → Env n → Form n → Set eval env (φ ∧ ψ) = eval env φ × eval env ψ eval env (φ ∨ ψ) = eval env φ ⊎ eval env ψ eval env (φ ⇒ ψ) = eval env φ → eval env ψ eval env top = 𝟙 -- data 𝟙 : Set where tt : 𝟙 eval env bot = ⊥ eval env (fa φ) = (x : ℕ) → eval (λ { zero → x ; (succ v) → env v }) φ eval env (ex φ) = {!!} eval env (x ≈ y) = eval₀ env x ≡ eval₀ env y -- Let us prove soundness: If PA proves α ⊢ β, then α actually implies β. sound : {n : ℕ} (α β : Form n) (env : Env n) → (α ⊢ β) → (eval env α → eval env β) sound α β env identity = λ z → z sound α β env conj-elimₗ = fst sound α β env conj-elimᵣ = {!!} sound α β env (cut p q) = λ z → sound _ β env q (sound α _ env p z) consistency : ¬ (top ⊢ (Z ≈ S Z)) consistency p with sound _ _ _ p tt ... | () {- ZFC | ZF | \ | IZF | | | | PA | | \ | | HA PRA + QF-TI(ε₀) | | PRA primitive recursive arithmetic---+ The consistency of PA can be proven in: - ZFC, ZF, IZF, ... - PRA + QF-TI(ε₀) "quantifier-free transfinite induction up to ε₀" The consistency of ZFC can be proven in: - PRA + QF-TI(???), where we are currently lacking the technology to describe ??? -} {- example-higher-order-function : (ℕ → ℕ) → ℕ example-higher-order-function f = f three + f four -} -- Possible follow-up projects: -- 1. Define Heyting arithmetic (HA), the constructive variant of Peano arithmetic -- 2. Prove that, if PA proves that some Turing machine terminates, then -- HA also proves that this Turing machine terminates. -- 3. Prove that, if PA proves a formula of the form "∀x ∃y P(x,y)", then -- HA does as well (provided that no further quantifiers appear in P).