为了理解@keep_learning的答案,我一步一步地浏览了这段代码:
Inductive nostutter {X:Type} : list X -> Prop :=
| ns_nil : nostutter []
| ns_one : forall (x : X), nostutter [x]
| ns_cons: forall (x : X) (h : X) (t : list X), nostutter (h::t) -> x <> h -> nostutter (x::h::t).
Example test_nostutter_4: not (nostutter [3;1;1;4]).
Proof.
intro.
inversion_clear H.
inversion_clear H0.
unfold not in H2.
(* We are here *)
specialize (H2 eq_refl).
apply H2.
Qed.
这是我们在执行specialize之前所拥有的
H1 : 3 <> 1
H : nostutter [1; 4]
H2 : 1 = 1 -> False
============================
False
这是 eq Prop,其构造函数eq_refl
用于specialize:
Inductive eq (A:Type) (x:A) : A -> Prop :=
eq_refl : x = x :>A
where "x = y :> A" := (@eq A x y) : type_scope.
我无法解释,这个命令是如何工作的:
specialize (H2 eq_refl).
我阅读了有关专业参考手册的信息,但是那里的解释太宽泛了。据我了解,H2 中的“1 = 1”表达式满足eq_refl
构造函数,因此 eq 命题为 True。然后它简化了表达式:
True -> False => False
我们得到
H1 : 3 <> 1
H : nostutter [1; 4]
H2 : False
============================
False
有人可以为我提供一个解释正在specialize
做什么的最小示例,以便我可以自由使用它吗?
更新
尝试使用 apply 来模仿 special 的工作原理,我做了以下操作:
Example specialize {A B: Type} (H: A -> B) (a: A): B.
Proof.
apply H in a.
这给出了:
A : Type
B : Type
H : A -> B
a : B
============================
B
几乎相同specialize
,只是假设名称不同。
在 test_nostutter_4 定理中,我尝试了这个并且它起作用了:
remember (@eq_refl nat 1) as Heq.
apply H2 in Heq as H3.
它给了我们:
H1 : 3 <> 1
H : nostutter [1; 4]
H2 : 1 = 1 -> False
Heq : 1 = 1
H3 : False
HeqHeq : Heq = eq_refl
============================
False
这个比较复杂,我们不得不引入一个新的假设 Heq。但是我们得到了我们需要的东西——最后是 H3。
专业化内部是否使用记住之类的东西?或者是否可以用 apply 但不记得来解决它?