256 lines
5.7 KiB
Coq
256 lines
5.7 KiB
Coq
|
|
From Coq Require Import Arith.Arith.
|
||
|
|
From Coq Require Import Bool.Bool.
|
||
|
|
From Coq Require Import Logic.FunctionalExtensionality.
|
||
|
|
From Coq Require Import Lists.List.
|
||
|
|
From Coq Require Import Strings.String.
|
||
|
|
Import ListNotations.
|
||
|
|
Set Default Goal Selector "!".
|
||
|
|
|
||
|
|
Definition total_map (A : Type) := string -> A.
|
||
|
|
|
||
|
|
Definition t_empty {A : Type} (v : A) : total_map A :=
|
||
|
|
(fun _ => v).
|
||
|
|
|
||
|
|
Definition t_update {A : Type} (m : total_map A)
|
||
|
|
(x : string) (v : A) :=
|
||
|
|
fun x' => if String.eqb x x' then v else m x'.
|
||
|
|
|
||
|
|
Definition examplemap :=
|
||
|
|
t_update (t_update (t_empty false) "foo" true) "bar" true.
|
||
|
|
|
||
|
|
Notation "'_' '!->' v" := (t_empty v) (at level 100, right associativity).
|
||
|
|
|
||
|
|
Example example_empty := (_ !-> false).
|
||
|
|
|
||
|
|
Notation "x '!->' v ';' m" := (t_update m x v)
|
||
|
|
(at level 100, v at next level, right associativity).
|
||
|
|
|
||
|
|
Definition examplemap' :=
|
||
|
|
( "bar" !-> true;
|
||
|
|
"foo" !-> true;
|
||
|
|
_ !-> false
|
||
|
|
).
|
||
|
|
|
||
|
|
Lemma t_apply_empty : forall (A : Type) (x : string) (v : A),
|
||
|
|
(_ !-> v) x = v.
|
||
|
|
Proof.
|
||
|
|
intros A x v.
|
||
|
|
reflexivity.
|
||
|
|
Qed.
|
||
|
|
|
||
|
|
Lemma t_update_eq : forall (A : Type) (m : total_map A) x v,
|
||
|
|
(x !-> v ; m) x = v.
|
||
|
|
Proof.
|
||
|
|
intros A m x v.
|
||
|
|
unfold t_update.
|
||
|
|
rewrite String.eqb_refl.
|
||
|
|
reflexivity.
|
||
|
|
Qed.
|
||
|
|
|
||
|
|
Theorem t_update_neq : forall (A : Type) (m : total_map A) x1 x2 v,
|
||
|
|
x1 <> x2 ->
|
||
|
|
(x1 !-> v ; m) x2 = m x2.
|
||
|
|
Proof.
|
||
|
|
intros A m x1 x2 v H.
|
||
|
|
unfold t_update.
|
||
|
|
rewrite <- String.eqb_neq in H.
|
||
|
|
rewrite H.
|
||
|
|
reflexivity.
|
||
|
|
Qed.
|
||
|
|
|
||
|
|
Lemma t_update_shadow : forall (A : Type) (m : total_map A) x v1 v2,
|
||
|
|
(x !-> v2 ; x !-> v1 ; m) = (x !-> v2 ; m).
|
||
|
|
Proof.
|
||
|
|
intros A m x v1 v2.
|
||
|
|
unfold t_update.
|
||
|
|
apply functional_extensionality_dep.
|
||
|
|
intros x'.
|
||
|
|
destruct (x =? x')%string ; reflexivity.
|
||
|
|
Qed.
|
||
|
|
|
||
|
|
Theorem t_update_same : forall (A : Type) (m : total_map A) x,
|
||
|
|
(x !-> m x ; m) = m.
|
||
|
|
Proof.
|
||
|
|
intros A m x.
|
||
|
|
apply functional_extensionality.
|
||
|
|
intros x'.
|
||
|
|
destruct (eqb_spec x x').
|
||
|
|
- rewrite e.
|
||
|
|
unfold t_update.
|
||
|
|
rewrite eqb_refl.
|
||
|
|
reflexivity.
|
||
|
|
- unfold t_update.
|
||
|
|
apply eqb_neq in n.
|
||
|
|
rewrite n.
|
||
|
|
reflexivity.
|
||
|
|
Qed.
|
||
|
|
|
||
|
|
Theorem t_update_permute : forall (A : Type) (m : total_map A)
|
||
|
|
v1 v2 x1 x2,
|
||
|
|
x2 <> x1 ->
|
||
|
|
(x1 !-> v1 ; x2 !-> v2 ; m)
|
||
|
|
=
|
||
|
|
(x2 !-> v2 ; x1 !-> v1 ; m).
|
||
|
|
Proof.
|
||
|
|
intros A m v1 v2 x1 x2 H.
|
||
|
|
apply functional_extensionality.
|
||
|
|
intros x.
|
||
|
|
destruct (eqb_spec x x1).
|
||
|
|
- unfold t_update.
|
||
|
|
rewrite e.
|
||
|
|
rewrite eqb_refl.
|
||
|
|
rewrite (proj2 (eqb_neq x2 x1) H).
|
||
|
|
reflexivity.
|
||
|
|
- unfold t_update.
|
||
|
|
rewrite eqb_sym.
|
||
|
|
rewrite (proj2 (eqb_neq x x1) n).
|
||
|
|
reflexivity.
|
||
|
|
Qed.
|
||
|
|
|
||
|
|
Definition partial_map (A : Type) := total_map (option A).
|
||
|
|
|
||
|
|
Definition empty {A : Type} : partial_map A :=
|
||
|
|
t_empty None.
|
||
|
|
|
||
|
|
Definition update {A : Type} (m : partial_map A)
|
||
|
|
(x : string) (v : A) :=
|
||
|
|
(x !-> Some v ; m).
|
||
|
|
|
||
|
|
Notation "x '|->' v ';' m" := (update m x v)
|
||
|
|
(at level 100, v at next level, right associativity).
|
||
|
|
|
||
|
|
Notation "x '|->' v" := (update empty x v)
|
||
|
|
(at level 100).
|
||
|
|
|
||
|
|
Definition examplepmap :=
|
||
|
|
("Church" |-> true ; "Turing" |-> false).
|
||
|
|
|
||
|
|
Lemma apply_empty : forall (A : Type) (x : string),
|
||
|
|
@empty A x = None.
|
||
|
|
Proof.
|
||
|
|
intros.
|
||
|
|
unfold empty.
|
||
|
|
rewrite t_apply_empty.
|
||
|
|
reflexivity.
|
||
|
|
Qed.
|
||
|
|
|
||
|
|
Lemma update_eq : forall (A : Type) (m : partial_map A) x v,
|
||
|
|
(x |-> v ; m) x = Some v.
|
||
|
|
Proof.
|
||
|
|
intros.
|
||
|
|
unfold update.
|
||
|
|
rewrite t_update_eq.
|
||
|
|
reflexivity.
|
||
|
|
Qed.
|
||
|
|
|
||
|
|
#[global] Hint Resolve update_eq : core.
|
||
|
|
|
||
|
|
Theorem update_neq : forall (A : Type) (m : partial_map A) x1 x2 v,
|
||
|
|
x2 <> x1 ->
|
||
|
|
(x2 |-> v ; m) x1 = m x1.
|
||
|
|
Proof.
|
||
|
|
intros A m x1 x2 v H.
|
||
|
|
unfold update.
|
||
|
|
rewrite t_update_neq.
|
||
|
|
- reflexivity.
|
||
|
|
- apply H.
|
||
|
|
Qed.
|
||
|
|
|
||
|
|
Lemma update_shadow : forall (A : Type) (m : partial_map A) x v1 v2,
|
||
|
|
(x |-> v2 ; x |-> v1 ; m) = (x |-> v2 ; m).
|
||
|
|
Proof.
|
||
|
|
intros.
|
||
|
|
unfold update.
|
||
|
|
rewrite t_update_shadow.
|
||
|
|
reflexivity.
|
||
|
|
Qed.
|
||
|
|
|
||
|
|
Theorem update_same : forall (A : Type) (m : partial_map A) x v,
|
||
|
|
m x = Some v ->
|
||
|
|
(x |-> v ; m) = m.
|
||
|
|
Proof.
|
||
|
|
intros.
|
||
|
|
unfold update.
|
||
|
|
rewrite <- H.
|
||
|
|
apply t_update_same.
|
||
|
|
Qed.
|
||
|
|
|
||
|
|
Theorem update_permute : forall (A : Type) (m : partial_map A)
|
||
|
|
x1 x2 v1 v2,
|
||
|
|
x2 <> x1 ->
|
||
|
|
(x1 |-> v1 ; x2 |-> v2 ; m) = (x2 |-> v2 ; x1 |-> v1 ; m).
|
||
|
|
intros A m x1 x2 v1 v2.
|
||
|
|
unfold update.
|
||
|
|
apply t_update_permute.
|
||
|
|
Qed.
|
||
|
|
|
||
|
|
Definition includedin {A : Type} (m m' : partial_map A) :=
|
||
|
|
forall x v, m x = Some v -> m' x = Some v.
|
||
|
|
|
||
|
|
Lemma includedin_update : forall (A : Type) (m m' : partial_map A)
|
||
|
|
(x : string) (vx : A),
|
||
|
|
includedin m m' ->
|
||
|
|
includedin (x |-> vx ; m) (x |-> vx ; m').
|
||
|
|
Proof.
|
||
|
|
unfold includedin.
|
||
|
|
intros A m m' x vx H.
|
||
|
|
intros y vy.
|
||
|
|
destruct (eqb_spec x y) as [Hxy | Hxy].
|
||
|
|
- rewrite Hxy.
|
||
|
|
rewrite update_eq.
|
||
|
|
rewrite update_eq.
|
||
|
|
intro H1 ; apply H1.
|
||
|
|
- rewrite update_neq.
|
||
|
|
+ rewrite update_neq.
|
||
|
|
* apply H.
|
||
|
|
* apply Hxy.
|
||
|
|
+ apply Hxy.
|
||
|
|
Qed.
|
||
|
|
|
||
|
|
Definition propositional_extensionality : Prop :=
|
||
|
|
forall (P Q : Prop), (P <-> Q) -> P = Q.
|
||
|
|
|
||
|
|
Theorem pe_implies_or_eq :
|
||
|
|
propositional_extensionality ->
|
||
|
|
forall (P Q : Prop), (P \/ Q) = (Q \/ P).
|
||
|
|
Proof.
|
||
|
|
intros.
|
||
|
|
apply H.
|
||
|
|
split.
|
||
|
|
- intros [HP | HQ].
|
||
|
|
+ right. apply HP.
|
||
|
|
+ left. apply HQ.
|
||
|
|
- intros [HQ | HP].
|
||
|
|
+ right. apply HQ.
|
||
|
|
+ left. apply HP.
|
||
|
|
Qed.
|
||
|
|
|
||
|
|
Lemma pe_implies_true_eq :
|
||
|
|
propositional_extensionality ->
|
||
|
|
forall (P : Prop), P -> True = P.
|
||
|
|
Proof.
|
||
|
|
intros PE P H.
|
||
|
|
apply PE.
|
||
|
|
split.
|
||
|
|
- intros _.
|
||
|
|
apply H.
|
||
|
|
- intros _.
|
||
|
|
apply I.
|
||
|
|
Qed.
|
||
|
|
|
||
|
|
Definition proof_irrelevance : Prop :=
|
||
|
|
forall (P : Prop) (pf1 pf2 : P), pf1 = pf2.
|
||
|
|
|
||
|
|
Theorem pe_implies_pi :
|
||
|
|
propositional_extensionality -> proof_irrelevance.
|
||
|
|
Proof.
|
||
|
|
intros PE P pf1 pf2.
|
||
|
|
apply (pe_implies_true_eq PE) in pf1 as H.
|
||
|
|
revert pf1 pf2.
|
||
|
|
rewrite <- H.
|
||
|
|
intros pf1 pf2.
|
||
|
|
destruct pf1.
|
||
|
|
destruct pf2.
|
||
|
|
reflexivity.
|
||
|
|
Qed.
|