diff --git a/util/rewrite_facilities.v b/util/rewrite_facilities.v new file mode 100644 index 0000000000000000000000000000000000000000..870c3093758c5bc0a0e74bc02da2c6de72d3d9ef --- /dev/null +++ b/util/rewrite_facilities.v @@ -0,0 +1,106 @@ +From mathcomp Require Import ssreflect ssrbool eqtype ssrnat seq path fintype bigop. + +(** * Rewriting *) +(** In this file we prove a few lemmas + that simplify work with rewriting. *) +Section RewriteFacilities. + + Lemma diseq: + forall {X : Type} (p : X -> Prop) (x y : X), + ~ p x -> p y -> x <> y. + Proof. intros ? ? ? ? NP P EQ; subst; auto. Qed. + + + Lemma eqprop_to_eqbool {X : eqType} {a b : X}: a = b -> a == b. + Proof. by intros; apply/eqP. Qed. + + Lemma eqbool_true {X : eqType} {a b : X}: a == b -> a == b = true. + Proof. by move =>/eqP EQ; subst b; rewrite eq_refl. Qed. + + Lemma eqbool_false {X : eqType} {a b : X}: a != b -> a == b = false. + Proof. by apply negbTE. Qed. + + + Lemma eqbool_to_eqprop {X : eqType} {a b : X}: a == b -> a = b. + Proof. by intros; apply/eqP. Qed. + + Lemma neqprop_to_neqbool {X : eqType} {a b : X}: a <> b -> a != b. + Proof. by intros; apply/eqP. Qed. + + Lemma neqbool_to_neqprop {X : eqType} {a b : X}: a != b -> a <> b. + Proof. by intros; apply/eqP. Qed. + + Lemma neq_sym {X : eqType} {a b : X}: + a != b -> b != a. + Proof. + intros NEQ; apply/eqP; intros EQ; + subst b; move: NEQ => /eqP NEQ; auto. Qed. + + Lemma neq_antirefl {X : eqType} {a : X}: + (a != a) = false. + Proof. by apply/eqP. Qed. + + + Lemma option_inj_eq {X : eqType} {a b : X}: + a == b -> Some a == Some b. + Proof. by move => /eqP EQ; apply/eqP; rewrite EQ. Qed. + + Lemma option_inj_neq {X : eqType} {a b : X}: + a != b -> Some a != Some b. + Proof. + by move => /eqP NEQ; + apply/eqP; intros CONTR; + apply: NEQ; inversion_clear CONTR. Qed. + + (** Example *) + (* As a motivation for this file, we consider the following example. *) + Section Example. + + (* Let X be an arbitrary type ... *) + Context {X : eqType}. + + (* ... f be an arbitrary function [bool -> bool] ... *) + Variable f : bool -> bool. + + (* ... p be an arbitrary predicate on X ... *) + Variable p : X -> Prop. + + (* ... and let a and b be two elements of X such that ... *) + Variables a b : X. + + (* ... p holds for a and doesn't hold for b. *) + Hypothesis H_pa : p a. + Hypothesis H_npb : ~ p b. + + (* The following examples are commented out + to expose the insides of the proofs. *) + + (* + (* Simplifying some relatively sophisticated + expressions can be quite tedious. *) + Goal f ((a == b) && f false) = f false. + Proof. + (* Things like simpl/compute make no sense here. *) + (* One can use [replace] to generate a new goal. *) + replace (a == b) with false; last first. + (* However, this leads to a "loss of focus". Moreover, + the resulting goal is not so trivial to prove. *) + { apply/eqP; rewrite eq_sym eqbF_neg. + by apply/eqP; intros EQ; subst b; apply H_npb. } + by rewrite Bool.andb_false_l. + Admitted. + *) + + (* + (* The second attempt. *) + Goal f ((a == b) && f false) = f false. + (* With the lemmas above one can compose multiple + transformations in a single rewrite. *) + by rewrite (eqbool_false (neq_sym (neqprop_to_neqbool (diseq _ _ _ H_npb H_pa)))) + Bool.andb_false_l. + Qed. + *) + + End Example. + +End RewriteFacilities.