考慮下面的代碼:爲什麼構造函數在這裏花了很長時間?
Inductive Even : nat -> Prop :=
| EO : Even O
| ESS : forall n, Even n -> Even (S (S n)).
Fixpoint is_even_prop (n : nat) : Prop :=
match n with
| O => True
| S O => False
| S (S n) => is_even_prop n
end.
Theorem is_even_prop_correct : forall n, is_even_prop n -> Even n.
Admitted.
Example Even_5000 : Even 5000.
Proof.
apply is_even_prop_correct.
Time constructor. (* ~0.45 secs *)
Undo.
Time (constructor 1). (* ~0.25 secs *)
Undo.
(* The documentation for constructor says that "constructor 1"
should be the same thing as doing this: *)
Time (apply I). (* ~0 secs *)
Undo.
(* Apparently, if there's only one applicable constructor,
reflexivity falls back on constructor and consequently
takes as much time as that tactic: *)
Time reflexivity. (* Around ~0.45 secs also *)
Undo.
(* If we manually reduce before calling constructor things are
faster, if we use the right reduction strategy: *)
Time (cbv; constructor). (* ~0 secs *)
Undo.
Time (cbn; constructor). (* ~0.5 secs *)
Qed.
Theorem is_even_prop_correct_fast : forall n, is_even_prop n = True -> Even n.
Admitted.
Example Even_5000_fast : Even 5000.
Proof.
apply is_even_prop_correct_fast.
(* Everything here is essentially 0 secs: *)
Time constructor.
Undo.
Time reflexivity.
Undo.
Time (apply eq_refl). Qed.
我只是想看看,如果你能在Prop
而非Set
做反思和偶然發現了這一點。我的問題不是如何正確地進行反思,我只是想知道爲什麼constructor
在第一種情況下比第二種情況慢。 (也許有一些與constructor
做馬上就可以看到(沒有任何減少),構造函數必須在第二種情況下eq_refl
?但它仍然必須降低之後...)
此外,雖然試圖找出constructor
在做什麼我注意到文檔沒有說明策略將使用哪種減少策略。這種疏忽是否是故意的,並且這個想法是,如果你特別想要一種減少策略,你應該明確地說出你想要的減少策略(否則實施可以自由選擇)?
澄清我的'構造器'的減少策略評論:我不是說減少策略必須添加到文檔/規範;相反,我想知道是否有人說(在手冊中)關於一般使用的策略。可能會出現這樣的情況:手冊中的某個地方會說「如果沒有另外說明,cbv將在任何地方使用」,「您不能依賴任何正在使用的特定降低策略,而是使用哪種策略取決於實施細節並根據具體情況決定(有時是動態的)「,或類似的東西。 – cic
...因爲有時這些信息似乎有用(例如,這裏),但同時過度依賴這些低級細節可能會導致非常脆弱的證明腳本。 – cic