1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
|
(**
Here is a simple formalization of intuitionistic logic to illustrate the use of
extructures. We're going to see how we can obtain the basic structural rules of
intuitionistic logic for free simply by representing the contexts of assumptions
as sets rather than lists. First, we import the main libraries.
*)
Require Import Coq.Strings.String. (* For atomic formulas *)
From HB Require Import structures.
From mathcomp Require Import all_ssreflect.
From deriving Require Import deriving.
From extructures Require Import ord fset fmap.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Open Scope fset_scope.
(**
A formula is built up by combining atomic formulas with conjunction, disjunction
and implication.
*)
Notation atomic := string.
Inductive formula : Type :=
| Atom of atomic
| Conj of formula & formula
| Disj of formula & formula
| Impl of formula & formula.
Coercion Atom : atomic >-> formula.
Declare Scope formula_scope.
Bind Scope formula_scope with formula.
Delimit Scope formula_scope with form.
Notation "A ∧ B" := (Conj A B)
(at level 65, left associativity) : formula_scope.
Notation "A ∨ B" := (Disj A B)
(at level 67, left associativity) : formula_scope.
Notation "A → B" := (Impl A B)
(at level 70, right associativity) : formula_scope.
(**
To store formulas in sets, they need to have an order relation. We use the
deriving library to define instances of Ord for the formula type.
*)
Definition formula_indDef := [indDef for formula_rect].
Canonical formula_indType := IndType formula formula_indDef.
Definition formula_hasDecEq := [derive hasDecEq for formula].
HB.instance Definition _ := formula_hasDecEq.
Definition formula_hasChoice := [derive hasChoice for formula].
#[hnf] HB.instance Definition _ := formula_hasChoice.
Definition formula_hasOrd := [derive hasOrd for formula].
(* FIXME: This is taking way too long. *)
#[hnf] HB.instance Definition _ := formula_hasOrd.
Notation context := {fset formula}.
Implicit Types X Y Z : atomic.
Implicit Types A B C : formula.
Implicit Types Γ Δ : context.
(**
Here is the definition of the entailment relation. Γ ⊢ A means that the formula
A holds assuming the hypotheses in Γ. Note the use of the set insertion
operation A |: Γ to extend the context in ImplI.
*)
Reserved Notation "Γ ⊢ A" (at level 80).
Inductive entails : {fset formula} -> formula -> Prop :=
| Ax Γ A :
A \in Γ ->
Γ ⊢ A
| ConjI Γ A B :
Γ ⊢ A ->
Γ ⊢ B ->
Γ ⊢ A ∧ B
| ConjEL Γ A B :
Γ ⊢ A ∧ B ->
Γ ⊢ A
| ConjER Γ A B :
Γ ⊢ A ∧ B ->
Γ ⊢ B
| DisjIL Γ A B :
Γ ⊢ A ->
Γ ⊢ A ∨ B
| DisjIR Γ A B :
Γ ⊢ B ->
Γ ⊢ A ∨ B
| DisjE Γ A B C :
Γ ⊢ A ∨ B ->
Γ ⊢ A → C ->
Γ ⊢ B → C ->
Γ ⊢ C
| ImplI Γ A B :
A |: Γ ⊢ B ->
Γ ⊢ A → B
| ImplE Γ A B :
Γ ⊢ A → B ->
Γ ⊢ A ->
Γ ⊢ B
where "Γ ⊢ A" := (entails Γ A).
#[local] Hint Constructors entails : core.
(**
The entailment relation satisfies the structural rules of contraction, exchange
and weakening. The proof of weakening follows by induction on the entailment
derivation. Contraction and weakening, on the other hand, can be proved with
basic properties of the set union operator: idempotence and commutativity. If
contexts were represented as lists, these properties would fail, and the proofs
would need induction too.
*)
Lemma contraction Γ A : Γ :|: Γ ⊢ A -> Γ ⊢ A.
Proof. by rewrite fsetUid. Qed.
Lemma exchange Γ Δ A : Γ :|: Δ ⊢ A -> Δ :|: Γ ⊢ A.
Proof. by rewrite fsetUC. Qed.
Lemma weakening Γ Δ A : Γ ⊢ A -> Γ :|: Δ ⊢ A.
Proof.
elim: Γ A /; eauto 2.
- move=> Γ A Ain; have: A \in Γ :|: Δ by rewrite in_fsetU Ain.
by eauto.
- by move=> Γ A B C; rewrite -!fsetUA; eauto.
Qed.
(**
Next, let us consider the soundness of the logic. Given a valuation ρ, a finite
map from atomic formulas to propositions, each formula A corresponds to a
proposition `F⟦A⟧^ρ.
*)
Reserved Notation "`F⟦ A ⟧^" (format "`F⟦ A ⟧^").
Implicit Types ρ : {fmap string -> Prop}.
Fixpoint formula_den A ρ : Prop :=
match A with
| Atom a => if ρ a is Some P then P else False
| A ∧ B => `F⟦A⟧^ρ /\ `F⟦B⟧^ρ
| A ∨ B => `F⟦A⟧^ρ \/ `F⟦B⟧^ρ
| A → B => `F⟦A⟧^ρ -> `F⟦B⟧^ρ
end%form
where "`F⟦ A ⟧^" := (formula_den A).
(**
Valuations are extensional: if ρ1 and ρ2 agree on each atomic formula, noted ρ1
=1 ρ2, then ρ1 = ρ2. The extructures lemma eq_fmap allows us to convert back
and forth between ρ1 =1 ρ2 and ρ1 = ρ2. It provides a short proof of the
following result, which says that the interpretation of a formula A depends only
on the interpretation of atomic formulas.
*)
Lemma eq_formula_den A ρ1 ρ2 : ρ1 =1 ρ2 -> `F⟦A⟧^ρ1 = `F⟦A⟧^ρ2.
Proof. by move/eq_fmap=> ->. Qed.
(**
If we only consider atomic formulas that actually appear in A, we can strengthen
this result a little bit. However, the proof becomes more involved.
*)
Fixpoint atoms A : {fset atomic} :=
match A with
| Atom X => fset1 X
| A ∧ B => atoms A :|: atoms B
| A ∨ B => atoms A :|: atoms B
| A → B => atoms A :|: atoms B
end%form.
Lemma in_eq_formula_den A ρ1 ρ2 :
{in atoms A, ρ1 =1 ρ2} -> `F⟦A⟧^ρ1 = `F⟦A⟧^ρ2.
Proof.
move: {-1}(atoms A) (fsubsetxx (atoms A)) => Xs.
by elim: A => /= [X|A IHA B IHB|A IHA B IHB|A IHA B IHB] AXs ρ12;
do ?[move: AXs; rewrite fsubUset; case/andP => ??];
rewrite ?ρ12 // ?IHA ?IHB // -fsub1set.
Qed.
(**
We lift the interpretation of formulas to contexts. Sets in extructures coerce
to sequences, which allows us to write the following definition.
*)
Definition context_den Γ ρ := foldr and True [seq `F⟦A⟧^ρ | A <- Γ].
Notation "`C⟦ Γ ⟧^" := (context_den Γ) (format "`C⟦ Γ ⟧^").
(**
This definition is equivalent to the following one, which is easier to use to
prove soundness.
*)
Lemma context_denP Γ ρ : `C⟦Γ⟧^ρ <-> {in Γ, forall A, `F⟦A⟧^ρ}.
Proof.
rewrite -[mem Γ]/(mem (val Γ)) /context_den /=.
elim: (val Γ) => /= [|A {}Γ ->]; split => // [[HA HΓ] B|].
rewrite inE; case/orP=> [/eqP -> //|]; exact: HΓ.
by move=> HΓ; split=> [|B Bin]; apply: HΓ; rewrite inE ?eqxx // Bin orbT.
Qed.
(**
Once again, we can prove two extensionality lemmas for the interpretation of
contexts. The first one follows by eq_fmap, whereas the second one requires a
more detailed argument.
*)
Lemma eq_context_den Γ ρ1 ρ2 : ρ1 =1 ρ2 -> `C⟦Γ⟧^ρ1 = `C⟦Γ⟧^ρ2.
Proof. by move/eq_fmap=> ->. Qed.
Definition ctx_atoms Γ : {fset string} :=
\bigcup_(A <- Γ) atoms A.
Lemma in_eq_context_den Γ ρ1 ρ2 :
{in ctx_atoms Γ, ρ1 =1 ρ2} -> `C⟦Γ⟧^ρ1 = `C⟦Γ⟧^ρ2.
Proof.
move: {-1}(ctx_atoms Γ) (fsubsetxx (ctx_atoms Γ)) => Xs.
rewrite /ctx_atoms /context_den.
elim: (val Γ) => //= A {}Γ IH; rewrite big_cons fsubUset.
case/andP=> subA subΓ ρ12; rewrite IH //.
suff /in_eq_formula_den -> : {in atoms A, ρ1 =1 ρ2} by [].
move=> X Xin; apply: ρ12; exact: (fsubsetP subA).
Qed.
(**
We can now state the soundness result of the logic.
*)
Lemma soundness Γ A : Γ ⊢ A -> forall ρ, `C⟦Γ⟧^ρ -> `F⟦A⟧^ρ.
Proof.
move=> ΓA ρ /context_denP; elim: Γ A / ΓA => //=; eauto.
- by move=> ??? _ IH HΓ; case: IH.
- by move=> ??? _ IH HΓ; case: IH.
- by move=> ???? _ IHor _ IH1 _ IH2 HΓ; case: IHor; eauto.
- move=> ??? _ IH HΓ HA; apply: IH.
move=> C /fsetU1P [-> //|]; exact: HΓ.
Qed.
|