在证明中破坏n之后,我被困在以下几点:
1 subgoal
n : nat
X : Type
h : X
t : list X
n' : nat
E : n = S n'
H' : length t = n'
IHl : length t = n -> nth_error t n = None
______________________________________(1/1)
nth_error t n' = None
我想使用IHl进行重写,但这是不可能的。我该如何构成IH1和H'才有意义并证明该定理?
答案 0 :(得分:3)
我只是想详细说明@Arthur的答案。
我能够使用以下脚本重现您的目标:
Require Import List.
Lemma toto (n : nat) (X : Type) (l : list nat) : length l = n -> nth_error l n = None.
Proof.
induction l as [ | h t IHl].
case_eq n.
simpl; auto.
simpl; discriminate.
case_eq n.
simpl; discriminate.
intros n' E.
simpl; intros E'; injection E'; clear E'; intros H'.
我同意这个目标无法得到证明。现在,如果您改为使用以下文本(必须替换Proof
和induction
行)来证明,则可以证明(我已选中)。
Proof.
revert n.
induction l as [ | h t IHl]; intros n.
区别在于归纳假设现在具有以下陈述。
forall n : nat, length t = n -> nth_error t n = None
发生了什么事?在第一个(错误的)变体中,您尝试为长度等于精确n的所有列表证明一条语句,因为n
在通过归纳开始证明之前是固定的。在第二个(正确的)变体中,您尝试证明所有列表l
的语句,并且该语句接受任何n
,只要length l = n
。
在第一个变体中,n
是固定的,并且相等性length l = n
将l
限制为长度恰好为n
的那些。在第二种情况下,首先选择l
,并且n
不固定,但是等式length l = n
限制n
遵循l
的长度。 / p>
这称为“加载归纳”,因为语句forall n, length l = n -> nth_error l n = None
(在加载时)比您尝试在第一个变体中证明的语句(仅针对一个特定的n
)要强,但令人惊讶的是,它更容易证明。
答案 1 :(得分:0)
您不能,因为归纳假设还不够笼统。这是一条更容易证明的声明:
forall (X : Type) (t : list X), nth_error t (length t) = None