Пытаясь понять ответ @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.
Вот то, что мы имеем перед исключением, специализируемся
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).
Я читал про специализацию в справочном руководстве, но объяснение там слишком широкое. Насколько я понимаю, он видит, что выражение "1 = 1" в H2 удовлетворяет конструктору eq_refl
и, следовательно, утверждение eq верно. Тогда это упрощает выражение:
True -> False => False
И мы получаем
H1 : 3 <> 1
H : nostutter [1; 4]
H2 : False
============================
False
Может ли кто-нибудь дать мне минимальный пример с объяснением того, что делает specialize
, чтобы я мог свободно его использовать?
Обновление
Пытаясь имитировать, как работает specialize, используя apply, я сделал следующее:
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, но не помните?