代码之家  ›  专栏  ›  技术社区  ›  andreas

为什么在这里要花这么长时间?

coq
  •  4
  • andreas  · 技术社区  · 7 年前

    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 建造师 可以立即看到(没有任何减少)构造函数必须是 eq_refl 在第二种情况下?但之后仍必须减少……)

    建造师 我注意到文档中没有说明该策略将使用哪种减少策略。这种省略是故意的吗?如果你特别想要一种减少策略,那么你应该明确地说你想要哪种减少策略(否则实现可以自由选择任何一种)?

    1 回复  |  直到 7 年前
        1
  •  4
  •   Jason Gross    7 年前

    简单回答:它花时间试图找出你的目标是什么归纳家庭的一部分(两次,在 constructor hnf .

    长话短说:做一点源潜水,看起来像 constructor calls Tactics.any_constructor constructor 1 calls Tactics.constructor_tac Tactics.any_constructor 依次呼叫 Tacmach.New.pf_apply Tacred.reduce_to_quantified_ind 确定归纳类型以计算构造函数,然后调用 依次在每个可能的构造函数上。对于 True ,因为有一个构造函数,所以建议 大约是 ; 我猜时间因此花在了 reduce_to_quantified_ind . Tacred.reduce_to_quantified_ind 反过来,呼叫 reduce_to_ind_gen hnf_constr Time hnf Time constructor 1 都差不多。此外 Time constructor 在手册之后是即时的 . 我不知道是什么策略 hnf公司 内部使用。文档遗漏几乎肯定不是故意的(至少,无论当前策略是什么,我认为都应该出现在脚注中,所以请随时报告错误),但我不清楚 建造师 .