Coq “匹配”能比“重写”快吗`

Coq “匹配”能比“重写”快吗`,coq,coq-tactic,Coq,Coq Tactic,在Coq中编写Ltac时,可能会尝试编写 try match goal with |- context [?x && true] => rewrite andb_true_r end 而不是 try rewrite andb_true_r 不要毫无意义地调用rewrite——这是一个更大策略的内部循环,我们预计在大多数情况下,重写都会失败 但这真的更快吗?或者重写失败的速度和我写的手写的匹配一样快吗?是的!在我的一个战术中,我实现了60%的加速 下面是显示这种行为的另

在Coq中编写
Ltac
时,可能会尝试编写

try match goal with
 |- context [?x && true] => rewrite andb_true_r
end
而不是

try rewrite andb_true_r
不要毫无意义地调用
rewrite
——这是一个更大策略的内部循环,我们预计在大多数情况下,重写都会失败


但这真的更快吗?或者
重写
失败的速度和我写的手写的
匹配
一样快吗?

是的!在我的一个战术中,我实现了60%的加速

下面是显示这种行为的另一个微观基准:

Require Import Coq.Bool.Bool.

Goal forall b, b = true.
intros.
(* Lets create a large goal *)
do 300 rewrite <- orb_false_r with (b := b).
Time do 300 try rewrite orb_true_r.
(* Finished transaction in 2.57 secs (2.431u,0.003s) (successful) *)
Time do 300 try lazymatch goal with |- context [_ || true] => rewrite orb_true_r end.
(* Finished transaction in 0.05 secs (0.05u,0.s) (successful) *)
Abort.
需要导入Coq.Bool.Bool。
全部b的目标,b=正确。
介绍。
(*让我们创建一个大目标*)
300重写重写orb\u true\u r结束。
(*在0.05秒(0.05 U,0.s)内完成交易(成功)*)
中止

基于您的自我回答,Coq对所使用的精确匹配策略非常敏感。注意以下策略之间的差异:

Require Import Coq.Bool.Bool.

Goal forall b, b = true.
  intros.
  (* Create a large goal *)
  do 300 rewrite <- orb_false_r with (b := b).
  Time do 300 try idtac.
  (* Finished transaction in 0.001 secs (0.004u,0.s) (successful) *)
  Time do 300 try match goal with |- context [_ || true] => idtac end.
  (* Finished transaction in 0.108 secs (0.108u,0.s) (successful) *)
  Time do 300 try match goal with |- context [_ || ?b] => constr_eq b true end.
  (* Finished transaction in 3.21 secs (3.208u,0.s) (successful) *)
  Time do 300 try rewrite orb_true_r.
  (* Finished transaction in 2.862 secs (2.863u,0.s) (successful) *)

加速在
setoid_rewrite
中更为明显,在许多情况下,重写模会展开,因此可以不必要地减少目标,一次又一次失败。

基准测试说明了什么?与
rewrite?和b_true_r.
相比,你的意思是什么,但不知何故,整个证明都失败了……你可能想尝试
重写1?和b_true_r.
,因为
重写?和b_true_r.
重写次数尽可能多,可能根本不重写,也就是说,它不会失败。我知道,但我怀疑这会影响
重写
失败的时间。我将澄清这个问题。
rewrite
match
有许多不同的折衷办法,因此根据具体情况,它们可以慢一些,也可以快一些。您是否正在使用香草
重写
?它的速度很慢,您可能想看看ssreflect版本中的匹配如何影响基准测试。在您的示例中,ssr的重写速度大约慢两倍。请注意,该策略称为
setoid\u rewrite
,不是
rewrite\u setoid
。可能值得注意的是
rewrite
不调用
setoid\u rewrite
(通常在
rewrite
单独失败时成功)
setoid_rewrite
在许多情况下也比
rewrite
昂贵得多,因此通常值得避免。文档中说:“此外,所有相应的不固定策略(即自反性、对称性、传递性、替换、重写)当所涉及的关系不是莱布尼茨等式时,它们会退回到前缀对应项。”因此,在某些情况下,它们会退回到
setoid_rewrite
,但您是对的:在这种情况下不是,因为等式是
eq
Goal forall b, b || (fun x => x) true = true.
  intros.
  Fail match goal with |- context [_ || true] => rewrite orb_true_r end.
  rewrite orb_true_r. (* succeeds *)