coq-club AT inria.fr
Subject: The Coq mailing list
List archive
- From: Christian Doczkal <christian.doczkal AT ens-lyon.fr>
- To: coq-club AT inria.fr
- Subject: Re: [Coq-Club] Defining complex recursive functions
- Date: Wed, 28 Jun 2017 18:23:50 +0200
- Authentication-results: mail3-smtp-sop.national.inria.fr; spf=None smtp.pra=christian.doczkal AT ens-lyon.fr; spf=Neutral smtp.mailfrom=christian.doczkal AT ens-lyon.fr; spf=None smtp.helo=postmaster AT labbe.ens-lyon.fr
- Ironport-phdr: 9a23:PBEMqhS1u95ZAwoChPs/8qJKe9psv+yvbD5Q0YIujvd0So/mwa6yZheN2/xhgRfzUJnB7Loc0qyN4v+mATRIyK3CmUhKSIZLWR4BhJdetC0bK+nBN3fGKuX3ZTcxBsVIWQwt1Xi6NU9IBJS2PAWK8TW94jEIBxrwKxd+KPjrFY7OlcS30P2594HObwlSijewZbF/IA+qoQnNq8IbnZZsJqEtxxXTv3BGYf5WxWRmJVKSmxbz+MK994N9/ipTpvws6ddOXb31cKokQ7NYCi8mM30u683wqRbDVwqP6WACXWgQjxFFHhLK7BD+Xpf2ryv6qu9w0zSUMMHqUbw5Xymp4qF2QxHqlSgHLSY0/nzJhMx+jKxVoxyvqBJwzIHWfI6bO+Fzfr/ecN4AWWZNQshcWi5HD4ihb4UPFe0BPeNAooTjp1sOtxq+BRKwBOPu0DBIgGL906M90+s9EADG3xYvH9YTu3nTsNr1NL0SUeGuzKnUzDXMdfVW1S3g54jPbh8goPKMUqh0ccfK10YvERjFgkyUqY3lODOV0P4Bs2aB7+d5U++klmApqwZ0oje1x8csjJHEhoMTylDF6SV12og0JdOgRE59e9GkDIFctyWGN4ZwX8gsQHlotT4nxrAJpZK3ZioHxZY9yxLCavGKcZKE7gz9WOqPOTt0mX1odK6lixuw80Ws0PDwW8eu3FpXrSdJj9/BvW0X2RPJ8MiIUP5981+h2TmR0wDT7flJIUQumqXAMJEu3KQ8mYQVsUTYByP2nEX3jKiQdkk+9Oio8fzrYrTgppCCK495khzyP6sylsClA+k1MBICU3Wa9Om+zrHv41P1TKtSgv0ziKbZsZTaJcoBpq6+Bg9Yypos6xalDzeny9QYgXgHI0hDeB6dkofpPE3BIfH7Dfilh1Shiylkx/bdPrH4BpXMLn/DkLH7cbZz8U5Q0BAzwsxH55JIFrEBJ+r+VVP2tNzBFxM2Lwi0w/v8B9hmzYMfWWePAreDP6/IsF+I4PgvI+iWa4MPtjb9Matt2/m7hngg3FQZYKOB3J0NaXn+EO41DV+eZC/Hgs0ACnsLtwx2YOvhml6LVXYHbHaoXrkg5zg9To6hBpXAT4SFjbqamSOqGZsQaHoQWQPEKmvha4jRA6REUymVOMI0yjE=
Hi,
Thanks for the replies, I had tried something along these lines as well,
albeit not too hard. Your solution (and that of Gaetan) however require
quite a bit of dependent programming.
Further, even on this simple example the definition generated this way
does not look like I want to prove anything about it and, as far as I
can tell, Program does not provide anything corresponding to Function's
"*_eq" lemmas. Fully specifying he behavior using sigma-tyoes is also
not realistic in my case.
I guess that means I'll use bounded recursion.
Cheers,
Christian
On 28/06/17 14:09, Frédéric Besson wrote:
> Hi Christian,
>
> I am far from having a definite opinion.
> Yet, you can guide Program Fixpoint to get stronger proof obligations.
> For instance, here is what you could do:
>
>
> Require Import Program.Tactics.
> Require Import Program.Wf.
> Require Import List.
>
> Variable graph : Type.
> Variable size : graph -> nat.
> Variable propertyP : graph -> bool.
> Variable decompose : forall (g:graph),
> list {g':graph| size g' < size g}.
>
> Program Fixpoint foo' (G : graph) {measure (size G)} : nat :=
> if propertyP G
> then fold_right (fun H m => Nat.max H m) 0 (map (fun gp => foo'
> (proj1_sig gp)) (decompose G))
> else 4.
> Next Obligation.
> apply measure_wf.
> apply PeanoNat.Nat.lt_wf_0.
> Defined.
>
>
> PS: I also often lean towards bounded recursion.
> --
> Frédéric
>
>
>
> On Tue, 2017-06-27 at 14:51 +0200, 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.
- [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.