如何证明关于列表的定理

时间:2018-01-23 22:26:09

标签: coq coq-tactic

我试图继续证明this practice example是关于对的列表,但似乎不可能。我该如何继续解决这个定理?

Require Import List.

Fixpoint split (A B:Set)(x:list (A*B)) : (list A)*(list B) :=
 match x with
   |nil => (nil, nil)
   |cons (a,b) x1 => let (ta, tb) := split A B x1 in (a::ta, b::tb)
 end.

Theorem split_eq_len : 
forall (A B:Set)(x:list (A*B))(y:list A)(z:list B),(split A B x)=(y,z) -> 
length y = length z.
Proof.
intros A B x.
elim x.
simpl.
intros y z.
intros H.
injection H.
intros H1 H2.
rewrite <- H1.
rewrite <- H2.
reflexivity.
intros hx.
elim hx.
intros a b tx H y z.
simpl.
intro.
destruct (split A B tx).

2 个答案:

答案 0 :(得分:1)

我不想只给你一个证据,但这里有一个提示:

如果您使用inversion H代替injection Hsubst而不是使用等号进行重写(subst采用任何相等v = expr},那么您的证明会更简单一些其中v是变量,并在expr替换v到处;然后清除变量v。)

答案 1 :(得分:0)

让我向您展示可以采取的几个步骤来推进您的证明。 您最终处于此证明状态:

H0 : (a :: l, b :: l0) = (y, z)
============================
length y = length z

此时,yz显然是一些非空列表。因此,injection H0.(或Tej Chajed建议的inversion H0.)可以帮助您解决此问题。

然后你可以将目标改为

length l = length l0

使用简化和重写的组合(这取决于您使用的确切策略,inversion使其更简单)。您可能还会发现f_equal策略非常有用。此时你几乎完成了,因为你现在可以使用你的归纳假设。