FoldR 在有限列表上使用 FoldL
FoldR using FoldL on finite lists
我读过 here 在有限列表上可以通过以下方式(使用 coq)以 foldL 的形式编写 foldR:
Fixpoint fold {A : Type} {B : Type} (f : A -> B -> B) (v : B) (l : list A) :=
match l with
| nil => v
| x :: xs => f x (fold f v xs)
end.
Fixpoint foldL {A : Type} {B : Type} (f : B -> A -> B) (v : B) (l : list A) :=
match l with
| nil => v
| x :: xs => foldL f (f v x) xs
end.
Definition fold' {A B : Type} (f : B -> A -> A) (a : A) (xs : list B) :=
foldL (fun g b x => g (f b x)) id xs a.
现在我想证明 fold
和 fold'
是相等的:
Theorem fold_eq_fold' {A : Type} {B : Type} :
forall
(f : B -> A -> A)
(v : A),
fold f v = fold' f v.
Proof.
intros.
unfold fold'.
apply functional_extensionality.
intros.
induction x; intros; simpl in *.
- trivial.
- rewrite IHx.
Abort.
但我无法关闭这个定理。
有人可以帮我吗?
编辑
感谢 Meven Lennon-Bertrand 的回答,我能够关闭定理:
Lemma app_cons {A: Type} :
forall
(l1 : list A)
(l2 : list A)
(a : A),
l1 ++ a :: l2 = (l1 ++ [a]) ++ l2.
Proof.
intros.
rewrite <- app_assoc.
trivial.
Qed.
Theorem fold_eq_fold' {A : Type} {B : Type} :
forall
(f : B -> A -> A)
(a : A)
(l : list B),
fold f a l = fold' f a l.
Proof.
intros.
unfold fold'.
change id with (fun x => fold f x nil).
change l with (nil ++ l) at 1.
generalize (@nil B).
induction l; intros; simpl.
- rewrite app_nil_r. trivial.
- rewrite app_cons. rewrite IHl.
assert((fun x : A => fold f x (l0 ++ [a0])) = (fun x : A => fold f (f a0 x) l0)).
+ apply functional_extensionality; intros.
induction l0; simpl.
* trivial.
* rewrite IHl0. trivial.
+ rewrite H. trivial.
Qed.
问题出在你的归纳假设上:它不够笼统,因为它谈论的是 id
,这对你的第二个目标没有用。你可以用这样的东西使它足够通用:
Theorem fold_eq_fold' {A : Type} {B : Type} :
forall
(f : B -> A -> A)
(a : A)
(l : list B),
fold f a l = fold' f a l.
Proof.
intros.
unfold fold'.
change id with (fun x => fold f x nil).
change l with (nil ++ l) at 1.
generalize (@nil B).
这为您提供了一个更通用的目标,您的目标是 nil
的特例。现在通过 l
.
上的归纳应该更容易处理这个问题
我读过 here 在有限列表上可以通过以下方式(使用 coq)以 foldL 的形式编写 foldR:
Fixpoint fold {A : Type} {B : Type} (f : A -> B -> B) (v : B) (l : list A) :=
match l with
| nil => v
| x :: xs => f x (fold f v xs)
end.
Fixpoint foldL {A : Type} {B : Type} (f : B -> A -> B) (v : B) (l : list A) :=
match l with
| nil => v
| x :: xs => foldL f (f v x) xs
end.
Definition fold' {A B : Type} (f : B -> A -> A) (a : A) (xs : list B) :=
foldL (fun g b x => g (f b x)) id xs a.
现在我想证明 fold
和 fold'
是相等的:
Theorem fold_eq_fold' {A : Type} {B : Type} :
forall
(f : B -> A -> A)
(v : A),
fold f v = fold' f v.
Proof.
intros.
unfold fold'.
apply functional_extensionality.
intros.
induction x; intros; simpl in *.
- trivial.
- rewrite IHx.
Abort.
但我无法关闭这个定理。
有人可以帮我吗?
编辑
感谢 Meven Lennon-Bertrand 的回答,我能够关闭定理:
Lemma app_cons {A: Type} :
forall
(l1 : list A)
(l2 : list A)
(a : A),
l1 ++ a :: l2 = (l1 ++ [a]) ++ l2.
Proof.
intros.
rewrite <- app_assoc.
trivial.
Qed.
Theorem fold_eq_fold' {A : Type} {B : Type} :
forall
(f : B -> A -> A)
(a : A)
(l : list B),
fold f a l = fold' f a l.
Proof.
intros.
unfold fold'.
change id with (fun x => fold f x nil).
change l with (nil ++ l) at 1.
generalize (@nil B).
induction l; intros; simpl.
- rewrite app_nil_r. trivial.
- rewrite app_cons. rewrite IHl.
assert((fun x : A => fold f x (l0 ++ [a0])) = (fun x : A => fold f (f a0 x) l0)).
+ apply functional_extensionality; intros.
induction l0; simpl.
* trivial.
* rewrite IHl0. trivial.
+ rewrite H. trivial.
Qed.
问题出在你的归纳假设上:它不够笼统,因为它谈论的是 id
,这对你的第二个目标没有用。你可以用这样的东西使它足够通用:
Theorem fold_eq_fold' {A : Type} {B : Type} :
forall
(f : B -> A -> A)
(a : A)
(l : list B),
fold f a l = fold' f a l.
Proof.
intros.
unfold fold'.
change id with (fun x => fold f x nil).
change l with (nil ++ l) at 1.
generalize (@nil B).
这为您提供了一个更通用的目标,您的目标是 nil
的特例。现在通过 l
.