Coq 展开后折叠

Coq 展开后折叠,coq,Coq,我对折叠长度的定义如下: Inductive list (X: Type) : Type := | nil : list X | cons : X -> list X -> list X. Arguments nil {X}. Arguments cons {X} _ _. Notation "x :: y" := (cons x y) (at level 60, right associativity). Notation "[

我对折叠长度的定义如下:

Inductive list (X: Type) : Type :=
  | nil : list X
  | cons : X -> list X -> list X.

Arguments nil {X}.
Arguments cons {X} _ _.

Notation "x :: y" := (cons x y)
                     (at level 60, right associativity).
Notation "[ ]" := nil.

Fixpoint fold {X Y:Type} (f: X -> Y -> Y) (l:list X) (b:Y) : Y :=
  match l with
  | nil => b
  | h :: t => f h (fold f t b)
  end.

Definition fold_length {X : Type} (l : list X) : nat :=
  fold (fun _ n => S n) l 0.
  X : Type
  n : X
  l' : list X
  IHl' : fold_length l' = length l'
  ============================
   S (fold (fun (_ : X) (n0 : nat) => S n0) l' 0) = S (length l')
我必须证明一个定理,到目前为止,这是我的代码:

Theorem fold_length_correct : forall X (l : list X),
  fold_length l = length l.
Proof.
  intros X l.
  induction l as [| n l' IHl'].
  - simpl.
    unfold fold_length.
    simpl.
    reflexivity.
  - simpl.
    unfold fold_length.
    simpl.
现在,我的目标如下:

Inductive list (X: Type) : Type :=
  | nil : list X
  | cons : X -> list X -> list X.

Arguments nil {X}.
Arguments cons {X} _ _.

Notation "x :: y" := (cons x y)
                     (at level 60, right associativity).
Notation "[ ]" := nil.

Fixpoint fold {X Y:Type} (f: X -> Y -> Y) (l:list X) (b:Y) : Y :=
  match l with
  | nil => b
  | h :: t => f h (fold f t b)
  end.

Definition fold_length {X : Type} (l : list X) : nat :=
  fold (fun _ n => S n) l 0.
  X : Type
  n : X
  l' : list X
  IHl' : fold_length l' = length l'
  ============================
   S (fold (fun (_ : X) (n0 : nat) => S n0) l' 0) = S (length l')
现在我想使用fold_length的定义将表达式fold fun X:n0:nat=>sn0 l'0转换为fold_length l'。在Coq中有没有一种方法可以做到这一点在Coq中似乎有一种叫做折叠战术的东西。这能实现吗


另外,是否有一种方法可以证明上述定理而不使用展开和折叠策略?

回答第一个问题,是的,这里可以使用折叠策略将等式的左侧替换为S fold_length l'。通常,对于函数f,fold f的功能不足以检测它可以折叠什么。但是如果你指定了整个术语,比如这里的fold_length l',它就起作用了


关于你的第二个问题,请注意,如果所涉及的术语等同于一些简化,那么像自反性或假设这样的策略就可以得出结论。这里,归纳法的基本情况可以是自反性。对于第二种情况,假设fold是List.fold\u right,siml可以在不展开的情况下惊人地简化,您也不需要在此处展开或折叠。

要回答您的第一个问题,是的,这里可以使用折叠策略将等式的左侧替换为S fold\u length l'。通常,对于函数f,fold f的功能不足以检测它可以折叠什么。但是如果你指定了整个术语,比如这里的fold_length l',它就起作用了


关于你的第二个问题,请注意,如果所涉及的术语等同于一些简化,那么像自反性或假设这样的策略就可以得出结论。这里,归纳法的基本情况可以是自反性。对于第二种情况,假设fold是List.fold\u right,siml可以在不展开的情况下惊人地简化,您也不需要在此处展开或折叠。

您可以立即重写rewrite@ejgallego,谢谢。所以像fold这样的东西不能在这里使用?fold是什么?恐怕它不在房间里。请提供一个包含正确导入和定义的完整示例。@Sibi如下所述,YMMV在大多数情况下,折叠通常不足以很好地工作,但通常需要防止自身展开,而不是重新折叠。在Coq中控制缩减有点复杂,您可以使用siml标志(请参阅手册)或部署其他自定义解决方案,如mathcomp的nosimpl。@gallais谢谢,我现在已经使其独立@ejgallego感谢您的宝贵意见。您可以将其改写为立即重写@ejgallego谢谢。所以像fold这样的东西不能在这里使用?fold是什么?恐怕它不在房间里。请提供一个包含正确导入和定义的完整示例。@Sibi如下所述,YMMV在大多数情况下,折叠通常不足以很好地工作,但通常需要防止自身展开,而不是重新折叠。在Coq中控制缩减有点复杂,您可以使用siml标志(请参阅手册)或部署其他自定义解决方案,如mathcomp的nosimpl。@gallais谢谢,我现在已经使其独立@谢谢你的宝贵意见。