coq-club AT inria.fr
Subject: The Coq mailing list
List archive
- 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).
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.
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` isa 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".Thanks,-- Abhishekhttp://www.cs.cornell.edu/~aa755/
- [Coq-Club] nested inductive termination check, Abhishek Anand, 10/27/2020
- Re: [Coq-Club] nested inductive termination check, Jason Gross, 10/27/2020
- Re: [Coq-Club] nested inductive termination check, Jason Gross, 10/27/2020
- Re: [Coq-Club] nested inductive termination check, Jason Gross, 10/27/2020
Archive powered by MHonArc 2.6.19+.