我有一个类似下面的引理,带有一个更高阶的参数:
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.
我想像rewrite
一样使用它。如果我直接指定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
集的一部分)。但
Lemma this_does_not:
forall (xs : list bool),
map (fun p => negb (negb (fst p))) (combine xs (list_fun xs)) = xs.
Proof.
intros.
rewrite map_fst_combine.
失败
(*
Error:
Found no subterm matching "map (fun p : ?M928 * ?M929 => ?M931 (fst p))
(combine ?M932 ?M933)" in the current goal.
*)
我在这里期待太多,还是有办法让这项工作成功?
答案 0 :(得分:1)
让我们定义组合运算符(或者您可能希望重用Coq.Program.Basics
中定义的运算符):
Definition comp {A B C} (g : B -> C) (f : A -> B) :=
fun x : A => g (f x).
Infix "∘" := comp (at level 90, right associativity).
现在,让我们在构图方面制定map_fst_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 *)
现在我们需要autorewrite
的一些助手引理:
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
和combine
:
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.