Coq 二阶重写统一

Coq 二阶重写统一,coq,unification,rewriting,Coq,Unification,Rewriting,我有一个引理,如下所示,带有一个高阶参数: Require Import Coq.Lists.List. Lemma map_fst_combine: forall A B C (f : A -> C) (xs : list A) (ys : list B), length xs = length ys -> map (fun p => f (fst p)) (combine xs ys) = map f xs. Proof. induction xs; i

我有一个引理,如下所示,带有一个高阶参数:

Require Import Coq.Lists.List.

Lemma map_fst_combine:
  forall A B C (f : A -> C) (xs : list A) (ys : list B),
  length xs = length ys ->
  map (fun p => f (fst p)) (combine xs ys) = map f xs. 
Proof.
  induction xs; intros.
  * destruct ys; try inversion H.
    simpl. auto.
  * destruct ys; try inversion H.
    simpl. rewrite IHxs; auto.
Qed.
我想将此用作
重写
。如果我直接指定
f
,它会起作用:

Parameter list_fun : forall {A}, list A -> list A.
Parameter length_list_fun : forall A (xs : list A), length (list_fun xs) = length xs.

Lemma this_works:
  forall (xs : list bool),
  map (fun p => negb (negb (fst p))) (combine xs (list_fun xs)) =  xs.
Proof.
  intros.
  rewrite map_fst_combine with (f := fun x => negb (negb x))
    by (symmetry; apply length_list_fun).
Admitted. 
但是我真的不想这样做(在我的例子中,我想使用这个引理作为
autorewrite
集合的一部分)。但是

失败于

(* 
Error:
Found no subterm matching "map (fun p : ?M928 * ?M929 => ?M931 (fst p))
                             (combine ?M932 ?M933)" in the current goal.
*)

我在这里的期望值是否过高,或者是否有办法实现这一点?

让我们定义合成运算符(或者您可能希望重用在中定义的运算符):

现在,让我们从组成的角度来推导
map\u fst\u combine
引理:

Lemma map_fst_combine:
  forall A B C (f : A -> C) (xs : list A) (ys : list B),
  length xs = length ys ->
  map (f ∘ fst) (combine xs ys) = map f xs.
Admitted.   (* the proof remains the same *)
现在我们需要一些辅助引理,用于
自动重新编写

Lemma map_comp_lassoc A B C D xs (f : A -> B) (g : B -> C) (h : C -> D) :
  map (fun x => h (g (f x))) xs = map ((h ∘ g) ∘ f) xs.
Proof. reflexivity. Qed.

Lemma map_comp_lassoc' A B C D E xs (f : A -> B) (g : B -> C) (h : C -> D) (i : D -> E) :
  map (i ∘ (fun x => h (g (f x)))) xs = map ((i ∘ h) ∘ (fun x => g (f x))) xs.
Proof. reflexivity. Qed.
有以下提示

Hint Rewrite map_comp_lassoc map_comp_lassoc' map_fst_combine : mapdb.
我们能够进行自动重写,并摆脱
fst
组合

Lemma autorewrite_works xs :
  map (fun p => negb (negb (fst p))) (combine xs (list_fun xs)) = xs.
Proof.
  autorewrite with mapdb.
  (* 1st subgoal: map (negb ∘ negb) xs = xs *)
Admitted.

Lemma autorewrite_works' xs :
  map (fun p => negb (negb (negb (negb (fst p))))) (combine xs (list_fun xs)) = xs.
Proof.
  autorewrite with mapdb.
  (* 1st subgoal: map (((negb ∘ negb) ∘ negb) ∘ negb) xs = xs *)
Admitted.

对你来说,定义复合算子并用它重新构造你的引理是可行的吗?如果你有一个引理
。。。map(f o fst)(combine xs ys)=map f xs。
您可以使用它重写
map(negb o negb o fst)(combine xs(list_fun xs))=xs。
,其中
o
定义comp(ab:Type)(g:B->C)(f:A->B):A->C:=fun x=>g(f:x).
我还应该补充一点,我们需要将
o
与之保持关联。在自动重写的环境中,这需要根据
o
重写所有内容……不确定这是否有效。或者可能是一组重写提示,将
f(fst x)
重写为
(f o fst)x
,然后也将
f o(g o fst)
重写为
(f o g)o fst
,以将
fst
冒泡出来?
Hint Rewrite map_comp_lassoc map_comp_lassoc' map_fst_combine : mapdb.
Lemma autorewrite_works xs :
  map (fun p => negb (negb (fst p))) (combine xs (list_fun xs)) = xs.
Proof.
  autorewrite with mapdb.
  (* 1st subgoal: map (negb ∘ negb) xs = xs *)
Admitted.

Lemma autorewrite_works' xs :
  map (fun p => negb (negb (negb (negb (fst p))))) (combine xs (list_fun xs)) = xs.
Proof.
  autorewrite with mapdb.
  (* 1st subgoal: map (((negb ∘ negb) ∘ negb) ∘ negb) xs = xs *)
Admitted.