Skip to Content.
Sympa Menu

coq-club - Re: [Coq-Club] nested inductive termination check

coq-club AT inria.fr

Subject: The Coq mailing list

List archive

Re: [Coq-Club] nested inductive termination check


Chronological Thread 
  • From: Jason Gross <jasongross9 AT gmail.com>
  • To: coq-club <coq-club AT inria.fr>
  • Subject: Re: [Coq-Club] nested inductive termination check
  • Date: Mon, 26 Oct 2020 20:25:45 -0400
  • Authentication-results: mail2-smtp-roc.national.inria.fr; spf=None smtp.pra=jasongross9 AT gmail.com; spf=Pass smtp.mailfrom=jasongross9 AT gmail.com; spf=None smtp.helo=postmaster AT mail-ed1-f46.google.com
  • Ironport-phdr: 9a23:lhRfkhcNVDCdK88ojNWcyAe0lGMj4u6mDksu8pMizoh2WeGdxcS+Zx7h7PlgxGXEQZ/co6odzbaP7OawCSdZsN6oizMrSNR0TRgLiMEbzUQLIfWuLgnFFsPsdDEwB89YVVVorDmROElRH9viNRWJ+iXhpTEdFQ/iOgVrO+/7BpDdj9it1+C15pbffxhEiCCybL9vLhi6twbcu8oZjYd/Lqs61wfErGZPd+lK321jOEidnwz75se+/Z5j9zpftvc8/MNeUqv0Yro1Q6VAADspL2466svrtQLeTQSU/XsTTn8WkhtTDAfb6hzxQ4r8vTH7tup53ymaINH2QLUpUjms86tnVBnlgzoBOjUk8m/Yl9ZwgbpUrxKvpRNxw4DaboKIOvRgYqzQZskVSXZbU8tLSyBNHoGxYo0SBOQBJ+ZYqIz9qkMKoxSkHgmsA+XvwSJJiH/s2q06yP8hGhzB0QwiBd0Oq3PUrNP6NKcIVuC117LIwDHYYvNZ3Dfy8onIchQ7rf6QWrJwdNPcxE8yHAzKklues5bqPy+J1usTqWib6fJtWOahhWMntw18rSSiy8cshIXXiI8YyU7I+DtlzIs7OdC1SUp2bNGrHpdMqSyUN4l7T8IiTWxnpCs0xb4Lt5ClcSUM1Z8pyRnfa/mdfIiJ5BLuTPqeITBihHJjZr2/gxKy/VK+xeLhS8m51ktBoCldktTUqHwByxje5tKER/Z95EutxyqD2gPJ5uxLIE05k7fQJYQ7zb4qjJUTtFzOHi/ol0Xyi6+bbkAk9fKp6+Tje7npuIKTO5JthgHwPakjm9azAes/MggJUGib/fqz2Kf/8k3+RbVGlvw2kq/Hv5DGPckXuLK1DgtP3osg6xuzFSmq3MgbkHUdI19IeQqLj43zNFHPJPD4A+2/g1OpkDpzxfDJJKbhApLLLnjMirfheq1961VYxQcowtBf4ohbCrAFIP7pRkDxs9nYAgcjMwOo2+bnFMl91oQGVG2TBa+ZKbrevkOM5uIyOOaBf5QVuTb4K/g9/fHil345mVkHfamox5Qbcn64Hu41a3meNHHrm5IKFXoA9l41S/Wvg1mfWxZSYWyzVuQy/GdoJpihCNLhT5uqhvSuxiCgBdUCZGldDVaDC3DzbNSsVPIFaSbUKchkxG9XHYO9QpMsgEn9/DTxzKBqe7KNp38o8Kn73d0w3NX90BE/8TsuUpaY2mCJCmx4xyYGG2Fw06d4rkhwjFyE1Pog2qAKJZlo//pMFzwCG9vE1eUjUoL9XwvAepGCT1P0Goz3UwF0dco4xpo1W2g4Htyjih7Z2C/zWu0akrWKANo/9aeOhnU=

Alternatively, if you don't want to change the definition of [tree], you can make your fixpoint recursive on the tree type rather than the list type:
Require Import Coq.Lists.List.
Import ListNotations.
Open Scope list_scope.
Inductive tree :=
| node (data : bool) (children : list tree).

(* put this in a section so the guard checker can see through through the fixpoint by inlining [f] into the body before doing guard checking *)
Section flat_map_with_tl.
  Context {A B : Type} (f : A -> list A -> list B).
  Fixpoint flat_map_with_tl (l : list A) : list B
    := match l with
       | [] => []
       | x :: t => f x t ++ flat_map_with_tl t
       end.
End flat_map_with_tl.

Fixpoint nodesWithCont' (t : tree) (tl : list tree) : list (tree * list tree)
  := match t with
     | node d children
       => [(node d children, tl)] ++ flat_map_with_tl nodesWithCont' children
     end.
Definition nodesWithCont (nodes : list tree) : list (tree * list tree)
  := flat_map_with_tl nodesWithCont' nodes.

On Mon, Oct 26, 2020 at 8:17 PM Jason Gross <jasongross9 AT gmail.com> wrote:
To answer your practical question, this works:
Require Import Coq.Lists.List.
Import ListNotations.
Open Scope list_scope.
Inductive tree :=
| node (data : bool) (children : list_tree)
with list_tree :=
| nil
| cons (x : tree) (xs : list_tree).

Fixpoint nodesWithCont (nodes : list_tree): list (tree * list_tree)
  := match nodes with
     | nil => []
     | cons (node d children) tl
       => [(node d children, tl)] ++ nodesWithCont children ++ nodesWithCont tl
     end.

(Presumably you can use notations or coercions to make this not too unpleasant.)

As far as your theoretical question, I'm not aware of any such issues; I'd suggest opening a feature request and seeing what the devs say.

On Mon, Oct 26, 2020 at 7:19 PM Abhishek Anand <abhishek.anand.iitg AT gmail.com> wrote:
It is surprising to me that in the fixpoint below, Coq cannot figure out that `children` is
a subterm of nodes. Theoretically, it seems that as long as a term is produced by peeling off one or more constructors (and doing nothing else), it should be considered a subterm. Are there some soundness or practicality issues in supporting such fixpoints?
Meanwhile, is there a way to write the fixpoint below without complicating the definition too much?

Require Import Coq.Lists.List.
Import ListNotations.

Inductive tree :=
| node (data: bool) (children: list tree).

Fixpoint nodesWithCont (nodes: list tree): list (tree* list tree) :=
   match nodes with
   | [] => []
   | (node d children)::tl =>  [(node d children, tl)] ++ (nodesWithCont children)++
                                                       nodesWithCont tl
   end.

Error: Recursive call to nodesWithCont has principal argument equal to "children" instead of
"tl".




Archive powered by MHonArc 2.6.19+.

Top of Page