Skip to Content.
Sympa Menu

coq-club - Re: [Coq-Club] Question about fold and, probably, inductive definitions

coq-club AT inria.fr

Subject: The Coq mailing list

List archive

Re: [Coq-Club] Question about fold and, probably, inductive definitions


Chronological Thread 
  • From: Cedric Auger <sedrikov AT gmail.com>
  • To: "coq-club AT inria.fr" <coq-club AT inria.fr>
  • Subject: Re: [Coq-Club] Question about fold and, probably, inductive definitions
  • Date: Mon, 1 Feb 2016 17:25:45 +0100
  • Authentication-results: mail3-smtp-sop.national.inria.fr; spf=None smtp.pra=sedrikov AT gmail.com; spf=Pass smtp.mailfrom=sedrikov AT gmail.com; spf=None smtp.helo=postmaster AT mail-ig0-f174.google.com
  • Ironport-phdr: 9a23:sEIWUR3wR52nbMn6smDT+DRfVm0co7zxezQtwd8ZsegTLPad9pjvdHbS+e9qxAeQG96LtLQd0qGM7ujJYi8p39WoiDg6aptCVhsI2409vjcLJ4q7M3D9N+PgdCcgHc5PBxdP9nC/NlVJSo6lPwWB6kO74TNaIBjjLw09fr2zQd6NyZ3unLrvs7ToICx2xxOFKYtoKxu3qQiD/uI3uqBFbpgL9x3Sv3FTcP5Xz247bXianhL7+9vitMU7q3cY6Lod8JsKWqLjOq88ULZwDTI8Mmlz6teh/U3IShLK7X8BWE0XlABJCk7L9kepcI32t37Ru+Zn2SLSFND5QKp8DS+v471qSxj2oCgCPj89tmrQj5oj3+pgvBu9qkknkMbva4aPOa8mcw==

I even tend to be a little more "extreme" when I write fixpoints:
when I write a fixpoint, I almost always try to have the indices of the inductive as arguments only (that is almost the minimal set of arguments which do not change between recursive calls).


I almost always determine which arguments change between calls and make only those required as arguments.

Thus, when I analyze

​​   Definition fold_right A B (f: B → A → A) :
      forall n, A -> list B n -> A :=
    fix go n a L :=
    match L with
    | nil _ => a
    | cons x t => f x (go _ a t)
    end.

I even see that the "a" argument does not need to be an argument of the fixpoint, and I tend to rather write:

​​​   Definition fold_right A B (f: B → A → A) (a : A) :
      forall n, list B n -> A :=
    fix go n L :=
    match L with
    | nil _ => a
    | cons x t => f x (go _ t)
    end.
​​
​And for fold_left, I tend to use:​

​​​​   Definition fold_left A B (f: B → A → A) :
      forall n, list B n -> A -> A :=
    fix go n L :=
    match L with
    | nil _ => fun a => a
    | cons x t => fun a => go _ t (f x a)
    end.

or

​   Definition fold_left A B (f: B → A → A) :
      forall n, list B n -> A -> A :=
    fix go n L :=
    fun a =>
    match L with
    | nil _ => a
    | cons x t => go _ t (f x a)
    end.

With this way to write things, it is always obvious on which arguments recursion is performed, and minimizes the number of arguments to write in recursive calls.


2016-02-01 13:27 GMT+01:00 Ilmārs Cīrulis <ilmars.cirulis AT gmail.com>:
So that's the difference I missed.
 
Thank you very much!

On Mon, Feb 1, 2016 at 1:28 PM, Robbert Krebbers <mailinglists AT robbertkrebbers.nl> wrote:
On 02/01/2016 12:16 PM, Ilmārs Cīrulis wrote:
Fixpoint fold_right A B n (f: B → A → A) (a: A) (L: list B n): A :=
   match L with
   | nil _ => a
   | cons x t => f x (fold_right f a t)
   end.
You have to write this function in a slightly different way so as to convince Coq that f remains constant during each recursive call:

​​
  Definition fold_right A B (f: B → A → A) :
      forall n, A -> list B n -> A :=
    fix go n a L :=
    match L with
    | nil _ => a
    | cons x t => f x (go _ a t)
    end.

Now f is no longer an argument of the fix.

List.fold_right is written in this way too.





Archive powered by MHonArc 2.6.18.

Top of Page