对称关系的反演在Coq中变为循环

时间:2014-07-16 08:24:46

标签: coq symmetric inversion

在Coq中n m : nat与偶数相邻的一种可能方式是从0和2开始以归纳方式定义该关系。

Inductive adj_ev : nat -> nat -> Prop :=
| ae_0 : adj_ev 0 2
| ae_1 : forall ( n m : nat ), adj_ev n m -> adj_ev m ( S ( S m ) )
| ae_2 : forall ( n m : nat ), adj_ev n m -> adj_ev m n.

ae_0表示0和2是偶数偶数。 ae_1指出,如果某些n m : nat与偶数相邻,则mm + 2也是如此。使用这两个构造函数,我们可以覆盖所有相邻的偶数,直到无穷大。可是等等!当且仅当n时,这适用于mn < m。所以我们需要最后一个构造函数ae_2来翻转关系中的任何给定数字对。

现在我已经定义了关系,我想对它进行一些健全性检查以确保它有效。例如,我知道1和3不是偶数偶数,我也知道adj_ev 1 3永远不能从我定义adj_ev的方式获得。所以我肯定证明 ~ ( adj_ev 1 3 ),对吧?

Theorem test' : ~ ( adj_ev 1 3 ).
unfold not. intros H.
inversion H. inversion H0.

经过几次反转后,我很快陷入了无限循环。这就像我问Coq,“nm如何相邻甚至?” Coq回答“好吧,也许mn相邻甚至......”然后我问,“mn如何相邻甚至?” Coq说“好吧,也许nm相邻甚至......”无限。

一般问题是,当你有一个归纳定义的对称关系R时,很容易证明R保持它确实占有的位置,但很难证明它不存在它没有。在这种情况下,或许有一个比inversion更好的策略来解除矛盾,但我不确定它可能是什么。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

首先,我尝试了induction一些额外的方程式,但这还不够。

Goal forall n1 n2, adj_ev n1 n2 -> n1 = 1 -> n2 = 3 -> False.
Proof. induction 1. Abort.

我设法通过首先证明两个相邻的偶数是偶数来证明你的定理。

启用等价关系重写。

Require Import Coq.Setoids.Setoid.

使用firstorder时关闭校对搜索。只允许简化。

Set Firstorder Depth 0.

创建提示数据库Hints,以便与autoautorewriteautounfold一起使用。

Create HintDb Hints.

常用战术的简写。

Ltac simplify := repeat (firstorder || subst || autorewrite with Hints in *).

Inductive even : nat -> Prop :=
  | even_0 : even 0
  | even_S : forall n1, even n1 -> even (S (S n1)).

足够简单。

Conjecture C1 : even 0 <-> True.
Conjecture C2 : even 1 <-> False.
Conjecture C3 : forall n1, even (S (S n1)) <-> even n1.

Hint Rewrite C1 C2 C3 : Hints.

Theorem T1 : forall n1 n2, adj_ev n1 n2 -> even n1 /\ even n2.
Proof. induction 1; simplify. Qed.

Goal ~ adj_ev 1 3. Proof. intro H1. apply T1 in H1. simplify. Qed.

你也可以定义

Definition least : (nat -> Prop) -> nat -> Prop := fun p1 n1 => p1 n1 /\ (forall n2, p1 n2 -> n2 >= n1).

Definition greatest : (nat -> Prop) -> nat -> Prop := fun p1 n1 => p1 n1 /\ (forall n2, p1 n2 -> n2 <= n1).

Definition even : nat -> Prop := fun n1 => exists n2, n1 = 2 * n2.

Definition least_greater_even : nat -> nat -> Prop := fun n1 => least (fun n2 => n2 > n1 /\ even n2).

Definition greatest_less_even : nat -> nat -> Prop := fun n1 => greatest (fun n2 => n2 < n1 /\ even n2).

Definition adjacent_even : nat -> nat -> Prop := fun n1 n2 => least_greater_even n1 n2 /\ greatest_less_even n2 n1 \/ greatest_less_even n1 n2 /\ least_greater_even n2 n1.

并从那里开始工作。还有其他方法可以定义谓词。

Inductive adj_ev : nat -> nat -> Prop :=
  | adj_ev_0_2 : adj_ev 0 2
  | adj_ev_2_0 : adj_ev 2 0
  | adj_ev_S_S : forall n1 n2, adj_ev n1 n2 -> adj_ev (S (S n1)) (S (S n2)).

Goal ~ adj_ev 1 3. Proof. inversion 1. Qed.