coq-club AT inria.fr
Subject: The Coq mailing list
List archive
- From: Gaetan Gilbert <gaetan.gilbert AT ens-lyon.fr>
- To: coq-club AT inria.fr
- Subject: Re: [Coq-Club] Defining complex recursive functions
- Date: Wed, 28 Jun 2017 12:16:17 +0200
- Authentication-results: mail3-smtp-sop.national.inria.fr; spf=None smtp.pra=gaetan.gilbert AT ens-lyon.fr; spf=Neutral smtp.mailfrom=gaetan.gilbert AT ens-lyon.fr; spf=None smtp.helo=postmaster AT labbe.ens-lyon.fr
- Ironport-phdr: 9a23:RWz4wB/ri6tLSv9uRHKM819IXTAuvvDOBiVQ1KB42+8cTK2v8tzYMVDF4r011RmSDNqds6oMotGVmpioYXYH75eFvSJKW713fDhBt/8rmRc9CtWOE0zxIa2iRSU7GMNfSA0tpCnjYgBaF8nkelLdvGC54yIMFRXjLwp1Ifn+FpLPg8it2e2//5/ebx9UiDahfLh/MAi4oQLNu8cMnIBsMLwxyhzHontJf+RZ22ZlLk+Nkhj/+8m94odt/zxftPw9+cFAV776f7kjQrxDEDsmKWE169b1uhTFUACC+2ETUmQSkhpPHgjF8BT3VYr/vyfmquZw3jSRMMvrRr42RDui9b9mRgL2hicJNzA382/ZhcJ/g61ZvB2svBl/z5LObYyPKPZzcKHQcNUHTmRBRMZRUClBD5u9YYQVEeUBIfxXr4/grFUPrBu+ARKjC/31yj9Um3T72qI63P4/HgHaxgMgGcgCsHvVrNXxL6gdT/q1zLXTwDrdafNWwi7x6IzIcxAmp/GAR7xwcdDIxEQpCgjLgFKQqYn/MDOU0OQAq2mb7+xhVeKzkWImpQ9xrz6yzckvkonEnp8Zx1/Y+Sljwos4J8e0RFN6bNOmCpdcqT+WO5VuTs4jXW1kojs2xqEYtZKhYSQHx5cqywTCZ/GEc4WF5A/oWvyLLjdinn1lfaqyhxas/kikze3xTs2030xRoSVejNbArG4C1xrI6sSeTvt8/kCh2TCV2wDd8OFIOUE0lazFJJ492rM8i5UevVjZEiL0mkj6lrKae0Qm9+Sy9ejrfKvqqoeZN4BuiwH+Nqoumta4AeQ9KgUOUHKU9vqg1LL5+031WrpKjvwykqbCrp/aP9gbq7WnDA9TyYYv8hK/Djeh0NQeh3UHIkhFdAqdj4f1I1HOPOz4DfCnjluwlzdr3unKMaHlApXQNXfOi6zhfLZ4605E0gU/19Ff55ROCrEAOv3/QEHxtMaLRiM+Zgez2qPsDMh3/oIYQ2OGRKGDY43ItlrdyesiP+CKLKAUvDzwMeRts/HngGMwnxkSfK2j0IELQH2+BbFiMkKfJ3T21IRSWVwWtxYzGbS5wGaJViReMi6/
>threads through the size bound
Essentially you have to do that in some way to prove that the function terminates. Using bounded recursion + proving the fixpoint equation on the resulting function can be seen as doing that. Function and Program are not smart enough to do it.
If you had a version of decompose like [decomp : forall G : Graph, {G' : Graph | size G' < size G}] then you can change the Program definition a bit, then it works. See attached file (the way decomp is defined may not be the smartest possibility but it was easy to do from your axioms).
Gaëtan Gilbert
On 27/06/2017 14:51, Christian Doczkal wrote:
Hello,
I need to define a rather complicated non-structurally recursive
function and I would like to gather some input as to which way i should
proceed.
I know of the following facilities/techniques to define non-structurally
recursive functions:
- Program Fixpoint
- The Function command
- Using Coq.Init.Wf.Fix
- Using an extra Argument of type nat bounding the recursion depth
I will need variable-width recursion (i.e., mapping the function over
lists of smaller arguments). This is not supported by Function. Indeed
the following fails as expected (self contained file attached):
Fail Function foo (G : graph) {measure size G} : nat :=
if property G
then fold_right (fun H m => Nat.max (foo H) m) 0 (decompose G)
else 4.
Program fares little better:
Program Fixpoint foo (G : graph) {measure (size G)} : nat :=
if propertyP G
then fold_right (fun H m => Nat.max (foo H) m) 0 (decompose G)
else 4.
Here I'm asked to prove "size H < size G" without knowing that H is from
"decompose G". Trying to map before folding, I don't even get obligations:
Fail Program Fixpoint foo' (G : graph) {measure (size G)} : nat :=
if propertyP G
then fold_right (fun H m => Nat.max H m) 0 (map foo' (decompose G))
else 4.
I guess that meas that for Program all occurrences of the recursive
function must also be fully applied? Is there a trick to use Program for
variable-width recursion?
Otherwise I guess I'll have to use either use Wf.Fix (providing a
variant of map that threads through the size bound) or use bounded
recursion with an extra argument.
Are there any other facilities/techniques I should try or does anyone
have experience with this kind of function definition? I'm leaning
towards bounded recursion, since this seems to require minimal use of
dependent types and should yield the smallest/cleanest definition
(possibly at the cost a larger proof burden, i.e, to prove the fixpoint
equation and the functional induction principle).
I'd be thankful for any type of input.
Regards,
Christian
PS. Is there a way to Abort a Program Definition/Fixpoint etc. Using
"Abort." on an obligation merely seems to shelf this obligation.
Require Import Program List. Parameter graph : Type. Parameter size : graph -> nat. Parameter property : graph -> bool. Parameter decompose : graph -> list graph. Hypothesis decomp_lt : forall G H, In H (decompose G) -> size H < size G. Fixpoint map_sig_In {A:Type} (l : list A) : list {x : A | In x l}. Proof. destruct l as [|x l]. - exact nil. - simpl. refine (_ :: _). + exists x;left;reflexivity. + refine (map _ (map_sig_In A l)). intros y;exists (proj1_sig y);right;exact (proj2_sig y). Defined. Definition decomp : forall G, list {G' : graph | size G' < size G}. Proof. intros G. refine (map _ (map_sig_In (decompose G))). intros [G' Hsize];exists G'. apply decomp_lt. exact Hsize. Defined. Fail Function foo (G : graph) {measure size G} : nat := if property G then fold_right (fun H m => Nat.max (foo H) m) 0 (decompose G) else 4. Program Fixpoint foo (G : graph) {measure (size G)} : nat := if property G then fold_right (fun G' m => Nat.max (foo (proj1_sig G')) m) 0 (decomp G) else 4. Check foo.
- [Coq-Club] Defining complex recursive functions, Christian Doczkal, 06/27/2017
- Re: [Coq-Club] Defining complex recursive functions, Gaetan Gilbert, 06/28/2017
- Re: [Coq-Club] Defining complex recursive functions, Frédéric Besson, 06/28/2017
- Re: [Coq-Club] Defining complex recursive functions, Christian Doczkal, 06/28/2017
- Re: [Coq-Club] Defining complex recursive functions, Anton Trunov, 06/28/2017
- Re: [Coq-Club] Defining complex recursive functions, Christian Doczkal, 06/28/2017
Archive powered by MHonArc 2.6.18.