Coq 在有限列表上使用FoldL的FoldR

Coq 在有限列表上使用FoldL的FoldR,coq,fold,foldleft,Coq,Fold,Foldleft,我已经了解到,在有限列表中,可以按照以下方式(使用coq)以foldL的形式编写foldR: 现在我想证明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_exte

我已经了解到,在有限列表中,可以按照以下方式(使用coq)以foldL的形式编写foldR:

现在我想证明
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.
引理app_cons{A:Type}: 福尔 (l1:列表A) (l2:列表A) (a:a), l1++a::l2=(l1++[a])++l2。 证明。 介绍。
重写问题在于你的归纳假设:它不够笼统,因为它谈论的是
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

上,你真的需要
函数的可扩展性吗?也许不需要,但我无法避免它来关闭定理…这里有一个没有函数的可扩展性的证明。
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).