Use rewrite tactic with my own == operator in Coq

流过昼夜 提交于 2019-12-01 09:56:33

For generalized rewriting (rewriting with arbitrary relations):

  1. Import Setoid (which loads a plugin which overrides the rewrite tactic).

  2. Declare your relation as an equivalence relation (technically rewrite also works with weaker assumptions, say with only transitive ones, but you would also need to work with a much more fine grained hierarchy of relations in step 3).

  3. Declare your operations (add, mul, etc.) as being respectful of that operation (e.g., adding equivalent values must result in equivalent values). This also requires the Morphism module.

You need step 3 to rewrite subexpressions.

Require Import Setoid Morphisms.

(* eq, add, etc. *)

Declare Instance Equivalence_eq : Equivalence eq.
Declare Instance Proper_add : Proper (eq ==> eq ==> eq) add.
Declare Instance Proper_mul : Proper (eq ==> eq ==> eq) mul.
(* etc. *)

Lemma mul_0_l: forall v, (0 * v == 0).
Proof.
  intros v.
  specialize add_id1 with (0 * v).
  intros H.
  rewrite <- H. (* Rewrite toplevel expression (allowed by Equivalence_eq) *)
  rewrite <- H. (* Rewrite subexpression (allowed by Proper_add and Equivalence_eq) *)

Here is a complete solution based on @Li-yao Xia, in case other users can benefit from it:

(***********)
(* IMPORTS *)
(***********)
Require Import Setoid Morphisms.

Variable (F:Type).
Variable (zero:F).
Variable (one :F).  
Variable (add: F -> F -> F).
Variable (mul: F -> F -> F).
Variable (opposite: F -> F).
Variable (inverse : F -> F).
Variable (eq: F -> F -> Prop).

Axiom add_assoc: forall (a b c : F), (eq (add (add a b) c) (add a (add b c))).
Axiom mul_assoc: forall (a b c : F), (eq (mul (mul a b) c) (mul a (mul b c))).

Axiom add_comm : forall (a b : F), (eq (add a b) (add b a)).
Axiom mul_comm : forall (a b : F), (eq (mul a b) (mul b a)).

Axiom distr1 : forall (a b c : F), (eq (mul a (add b c)) (add (mul a b) (mul a c))).
Axiom distr2 : forall (a b c : F), (eq (mul (add a b) c) (add (mul a c) (mul b c))).

Axiom add_id1 : forall (a : F), (eq (add a zero) a).
Axiom mul_id1 : forall (a : F), (eq (mul a  one) a).
Axiom add_id2 : forall (a : F), (eq (add zero a) a).
Axiom mul_id2 : forall (a : F), (eq (mul one  a) a).

Axiom add_inv1 : forall (a : F), exists b, (eq (add a b) zero).
Axiom add_inv2 : forall (a : F), exists b, (eq (add b a) zero).

Axiom mul_inv1 : forall (a : F), exists b, (eq (mul a b) one).
Axiom mul_inv2 : forall (a : F), exists b, (eq (mul b a) one).

(*******************)
(* Field notations *)
(*******************)
Notation "0" := zero.
Notation "1" :=  one.
Infix    "+" :=  add.
Infix    "*" :=  mul.
(*******************)
(* Field notations *)
(*******************)
Infix "==" := eq (at level 70, no associativity).

(****************)
(* eq, add, mul *)
(****************)
Declare Instance Equivalence_eq : Equivalence eq.
Declare Instance Proper_add : Proper (eq ==> eq ==> eq) add.
Declare Instance Proper_mul : Proper (eq ==> eq ==> eq) mul.

(**********************)
(* forall v, 0*v == 0 *)
(**********************)
Lemma mul_0_l: forall v, (0 * v == 0).
Proof.
  intros v.
  assert(0 * v == 0 * v + 0) as H1.
  { specialize add_id1 with (0 * v). intros H1. rewrite H1. reflexivity. }
  rewrite H1.
  specialize add_inv1 with (0 * v). intros H2. destruct H2 as [minus_0_v H2].
  assert (0 * v + 0 == 0 * v + (0 * v + minus_0_v)) as H3.
  { rewrite H2. reflexivity. }
  rewrite H3.
  assert ((0 * v + (0 * v + minus_0_v)) == ((0 * v + 0 * v) + minus_0_v)) as H4.
  { specialize add_assoc with (a:=0*v) (b:= 0*v) (c:=minus_0_v). intros H4. rewrite H4. reflexivity. }
  rewrite H4.
  assert (0 * v + 0 * v == (0 + 0) * v) as H5.
  { specialize distr2 with (a:=0) (b:=0) (c:=v). intros H5. rewrite H5. reflexivity. }
  rewrite H5.
  assert (0 + 0 == 0) as H6.
  { specialize add_id1 with (a:=0). intros H6. assumption. } 
  rewrite H6.
  assumption.
Qed.
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!