|
| 1 | +/- |
| 2 | +Copyright (c) 2025 Thomas Waring. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Thomas Waring |
| 5 | +-/ |
| 6 | + |
| 7 | +module |
| 8 | + |
| 9 | +public import Cslib.Init |
| 10 | +public import Mathlib.Data.FunLike.Basic |
| 11 | +public import Mathlib.Data.Set.Image |
| 12 | +public import Mathlib.Order.TypeTags |
| 13 | + |
| 14 | +@[expose] public section |
| 15 | + |
| 16 | +/-! # Propositions and theories |
| 17 | +
|
| 18 | +## Main definitions |
| 19 | +
|
| 20 | +- `Proposition` : the type of propositions over a given type of atom. This type has a `Bot` |
| 21 | +instance whenever `Atom` does, and a `Top` whenever `Atom` is inhabited. |
| 22 | +- `Theory` : set of `Proposition`. |
| 23 | +- `IsIntuitionistic` : a theory is intuitionistic if it contains the principle of explosion. |
| 24 | +- `IsClassical` : an intuitionistic theory is classical if it further contains double negation |
| 25 | +elimination. |
| 26 | +- `Proposition.map`, `Theory.map` : a map between `Atom` types extends to a map between |
| 27 | +propositions and theories. |
| 28 | +- `Theory.intuitionisticCompletion` : the freely generated intuitionistic theory extending a given |
| 29 | +theory. |
| 30 | +
|
| 31 | +## Notation |
| 32 | +
|
| 33 | +We introduce notation for the logical connectives: `⊥ ⊤ ⋏ ⋎ ⟶ ~` for, respectively, falsum, verum, |
| 34 | +conjunction, disjunction, implication and negation. |
| 35 | +-/ |
| 36 | + |
| 37 | +universe u |
| 38 | + |
| 39 | +variable {Atom : Type u} [DecidableEq Atom] |
| 40 | + |
| 41 | +namespace Cslib.Logic.PL |
| 42 | + |
| 43 | +/-- Propositions. -/ |
| 44 | +inductive Proposition (Atom : Type u) : Type u where |
| 45 | + /-- Propositional atoms -/ |
| 46 | + | atom (x : Atom) |
| 47 | + /-- Conjunction -/ |
| 48 | + | and (a b : Proposition Atom) |
| 49 | + /-- Disjunction -/ |
| 50 | + | or (a b : Proposition Atom) |
| 51 | + /-- Implication -/ |
| 52 | + | impl (a b : Proposition Atom) |
| 53 | +deriving DecidableEq, BEq |
| 54 | + |
| 55 | +instance instBotProposition [Bot Atom] : Bot (Proposition Atom) := ⟨.atom ⊥⟩ |
| 56 | +instance instInhabitedOfBot [Bot Atom] : Inhabited Atom := ⟨⊥⟩ |
| 57 | + |
| 58 | +/-- We view negation as a defined connective ~A := A → ⊥ -/ |
| 59 | +abbrev Proposition.neg [Bot Atom] : Proposition Atom → Proposition Atom := (Proposition.impl · ⊥) |
| 60 | + |
| 61 | +/-- A fixed choice of a derivable proposition (of course any two are equivalent). -/ |
| 62 | +abbrev Proposition.top [Inhabited Atom] : Proposition Atom := impl (.atom default) (.atom default) |
| 63 | + |
| 64 | +instance instTopProposition [Inhabited Atom] : Top (Proposition Atom) := ⟨.top⟩ |
| 65 | + |
| 66 | +example [Bot Atom] : (⊤ : Proposition Atom) = Proposition.impl ⊥ ⊥ := rfl |
| 67 | + |
| 68 | +@[inherit_doc] scoped infix:36 " ∧ " => Proposition.and |
| 69 | +@[inherit_doc] scoped infix:35 " ∨ " => Proposition.or |
| 70 | +@[inherit_doc] scoped infix:30 " → " => Proposition.impl |
| 71 | +@[inherit_doc] scoped prefix:40 " ¬ " => Proposition.neg |
| 72 | + |
| 73 | +/-- A function on atoms induces a function on propositions. -/ |
| 74 | +def Proposition.map {Atom Atom' : Type u} (f : Atom → Atom') : Proposition Atom → Proposition Atom' |
| 75 | + | atom x => atom (f x) |
| 76 | + | and A B => (A.map f) ∧ (B.map f) |
| 77 | + | or A B => (A.map f) ∨ (B.map f) |
| 78 | + | impl A B => (A.map f) → (B.map f) |
| 79 | + |
| 80 | +instance {Atom Atom' : Type u} : FunLike (Atom → Atom') (Proposition Atom) (Proposition Atom') where |
| 81 | + coe := Proposition.map |
| 82 | + coe_injective' f f' h := by |
| 83 | + ext x |
| 84 | + have : (Proposition.atom x).map f = (Proposition.atom x).map f' := |
| 85 | + congrFun h (Proposition.atom x) |
| 86 | + grind [Proposition.map] |
| 87 | + |
| 88 | +/-- Theories are arbitrary sets of propositions. -/ |
| 89 | +abbrev Theory (Atom) := Set (Proposition Atom) |
| 90 | + |
| 91 | +namespace Theory |
| 92 | + |
| 93 | +/-- Extend `Proposition.map` to theories. -/ |
| 94 | +def map {Atom Atom' : Type u} (f : Atom → Atom') : Theory Atom → Theory Atom' := |
| 95 | + Set.image (Proposition.map f) |
| 96 | + |
| 97 | +instance {Atom Atom' : Type u} : FunLike (Atom → Atom') (Theory Atom) (Theory Atom') where |
| 98 | + coe := Theory.map |
| 99 | + coe_injective' f f' h := by |
| 100 | + ext x |
| 101 | + have : Theory.map f {Proposition.atom x} = Theory.map f' {Proposition.atom x} := |
| 102 | + congrFun h {Proposition.atom x} |
| 103 | + simpa [Theory.map, Proposition.map] using this |
| 104 | + |
| 105 | +/-- The empty theory corresponds to minimal propositional logic. -/ |
| 106 | +abbrev MPL : Theory (Atom) := ∅ |
| 107 | + |
| 108 | +/-- Intuitionistic propositional logic adds the principle of explosion (ex falso quodlibet). -/ |
| 109 | +abbrev IPL [Bot Atom] : Theory Atom := |
| 110 | + Set.range (⊥ → ·) |
| 111 | + |
| 112 | +/-- Classical logic further adds double negation elimination. -/ |
| 113 | +abbrev CPL [Bot Atom] : Theory Atom := |
| 114 | + Set.range (fun (A : Proposition Atom) ↦ ¬¬A → A) |
| 115 | + |
| 116 | +/-- A theory is intuitionistic if it validates ex falso quodlibet. -/ |
| 117 | +@[scoped grind] |
| 118 | +class IsIntuitionistic [Bot Atom] (T : Theory Atom) where |
| 119 | + efq (A : Proposition Atom) : (⊥ → A) ∈ T |
| 120 | + |
| 121 | +omit [DecidableEq Atom] in |
| 122 | +@[scoped grind =] |
| 123 | +theorem isIntuitionisticIff [Bot Atom] (T : Theory Atom) : IsIntuitionistic T ↔ IPL ⊆ T := by grind |
| 124 | + |
| 125 | +/-- A theory is classical if it validates double-negation elimination. -/ |
| 126 | +@[scoped grind] |
| 127 | +class IsClassical [Bot Atom] (T : Theory Atom) where |
| 128 | + dne (A : Proposition Atom) : (¬¬A → A) ∈ T |
| 129 | + |
| 130 | +omit [DecidableEq Atom] in |
| 131 | +@[scoped grind =] |
| 132 | +theorem isClassicalIff [Bot Atom] (T : Theory Atom) : IsClassical T ↔ CPL ⊆ T := by grind |
| 133 | + |
| 134 | +instance instIsIntuitionisticIPL [Bot Atom] : IsIntuitionistic (Atom := Atom) IPL where |
| 135 | + efq A := Set.mem_range.mpr ⟨A, rfl⟩ |
| 136 | + |
| 137 | +instance instIsClassicalCPL [Bot Atom] : IsClassical (Atom := Atom) CPL where |
| 138 | + dne A := Set.mem_range.mpr ⟨A, rfl⟩ |
| 139 | + |
| 140 | +omit [DecidableEq Atom] in |
| 141 | +@[scoped grind →] |
| 142 | +theorem instIsIntuitionisticExtention [Bot Atom] {T T' : Theory Atom} [IsIntuitionistic T] |
| 143 | + (h : T ⊆ T') : IsIntuitionistic T' := by grind |
| 144 | + |
| 145 | +omit [DecidableEq Atom] in |
| 146 | +@[scoped grind →] |
| 147 | +theorem instIsClassicalExtention [Bot Atom] {T T' : Theory Atom} [IsClassical T] (h : T ⊆ T') : |
| 148 | + IsClassical T' := by grind |
| 149 | + |
| 150 | +/-- Attach a bottom element to a theory `T`, and the principle of explosion for that bottom. -/ |
| 151 | +@[reducible] |
| 152 | +def intuitionisticCompletion (T : Theory Atom) : Theory (WithBot Atom) := |
| 153 | + T.map (WithBot.some) ∪ IPL |
| 154 | + |
| 155 | +instance instIsIntuitionisticIntuitionisticCompletion (T : Theory Atom) : |
| 156 | + IsIntuitionistic T.intuitionisticCompletion := by grind |
| 157 | + |
| 158 | +end Cslib.Logic.PL.Theory |
0 commit comments