在Coq中对我自己的==运算符使用重写策略

时间:2019-05-12 13:19:24

标签: coq

我正试图直接从领域公理中证明简单的领域属性。在对Coq的本机字段支持(like this one)进行了一些实验之后,我认为最好写下10个公理并使其独立。当我需要将rewrite与我自己的==运算符一起使用时遇到了困难,这自然不起作用。我意识到我必须添加一些公理,证明我的==是自反的,对称的和可传递的,但是我想知道这是否是全部?还是有更简单的方法可以将rewrite与用户定义的==一起使用?这是我的Coq代码:

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).

Lemma mul_0_l: forall v, (0 * v == 0).
Proof.
  intros v.
  specialize add_id1 with (0 * v).
  intros H.

至此,我有了假设H : 0 * v + 0 == 0 * v和目标 0 * v == 0。当我尝试rewrite H时,它自然会失败。

2 个答案:

答案 0 :(得分:4)

对于广义重写(具有任意关系的重写):

  1. 导入Setoid(它会加载一个覆盖rewrite策略的插件)。

  2. 将您的关系声明为等价关系(技术上rewrite也适用于较弱的假设,例如仅适用于传递性假设,但您还需要逐步处理更细粒度的关系层次结构3)。

  3. 将您的操作(addmul等)声明为对该操作的尊重(例如,添加等效值必须得到等效值) 。这也需要Morphism模块。

您需要执行第3步来重写子表达式。

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) *)

答案 1 :(得分:0)

这里是基于@ Li-yao Xia的完整解决方案,以防其他用户从中受益:

(***********)
(* 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.