Skip to Content.
Sympa Menu

coq-club - [Coq-Club] Defining complex recursive functions

coq-club AT inria.fr

Subject: The Coq mailing list

List archive

[Coq-Club] Defining complex recursive functions


Chronological Thread 
  • From: Christian Doczkal <christian.doczkal AT ens-lyon.fr>
  • To: coq-club AT inria.fr
  • Subject: [Coq-Club] Defining complex recursive functions
  • Date: Tue, 27 Jun 2017 14:51:15 +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:qyObChVIozUMBk7/N6mlDPPXnTfV8LGtZVwlr6E/grcLSJyIuqrYbBSEt8tkgFKBZ4jH8fUM07OQ6PG/HzRYqb+681k6OKRWUBEEjchE1ycBO+WiTXPBEfjxciYhF95DXlI2t1uyMExSBdqsLwaK+i764jEdAAjwOhRoLerpBIHSk9631+ev8JHPfglEnjSwbLdwIRmssQndqtQdjJd/JKo21hbHuGZDdf5MxWNvK1KTnhL86dm18ZV+7SleuO8v+tBZX6nicKs2UbJXDDI9M2Ao/8LrrgXMTRGO5nQHTGoblAdDDhXf4xH7WpfxtTb6tvZ41SKHM8D6Uaw4VDK/5KptVRTmijoINyQh/W/Xl8J+kqFVrhyvqBNw34HZe4SVOOZkc67HYd8XS2hMU8BMXCJBGIO8aI4PAvIfMOZYtYn9pkAOrQe/BQa2AuPk1zFGhnjq0qw70OQuCwXG1xEnEt0SsHTUttT1NLwOUeC01qbIyy/PYO5R2Tjh6YnIcQouofWXUL1ud8rR0lAjFwfFj1WXr4zpJT2V1v4UvmWd8uFuW+Wvi2s9pAFwpDii3sYsio/IhoIJ0FzF+yt5zYAoLtO7UE52ecOoHZRMuy2ANYZ7QNkuT3xptSs40LEKp4C3cDYSxJg6yBPTd+aLfoqK7x75SeqcLy10iG9mdb6igRu57FKuxffmVsau1VZHtipFncfItnAKzxHT7tKIReBm8Ui/wzqAyQbT6vpdLUAwlavbLJghzqQ+lpoJqUjDHyn2l1vqjKKOa0kp9fSk5/7lb7jkvJOQKo55hwPkPqgwhMCzH/w0Mg0UUGia/eS82qfj/Ur8QLhSkvI2krPZsJHBJcQHp662GQlV3pw+5Ba4Ezin0dcYkmMDLF9eZh2HiZPpN0jKIPH4Cve/hU6gkDlxx/zeJL3uHo3NLmTfkLfmZbty90lcyBMqwd9D45JUF6oOLenoWk7xsdzYFgU2Pxa1w+bhEtV915kRVXiBAq+DY+vutgqD4ftqKO2RbqcUviz8Ir4r/a3Al3g8zHQdZ6iywZoebjiUGf90IEydKS7ngs0ACnsLtwx4QOvhml6LVRZeYW33W7M74Hc1EtT1Xs/4WomxjenZj2+AFZpMazUeBw==

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 Recdef Program List.

Parameter graph : Type.
Parameter size : graph -> nat.
Parameter property : graph -> bool.
Parameter decompose : graph -> list graph.
Parameter dec1 : graph -> graph.
Hypothesis decomp_lt : forall G H, In H (decompose G) -> size H < size G.
Hypothesis dec1_lt : forall G, property G = true -> size (dec1 G) < size G.

(** Needed since Program ignores boolean case splits *)
Lemma propertyP (G : graph) : {property G = true} + {property G = false}.
Proof. case (property G); firstorder. Qed.

Module FixedWidth.

Function foo (G : graph) {measure size G} : nat := 
  if (property G) then foo (dec1 G) else 4.
Proof.
  intros. now apply dec1_lt. 
Qed.

Program Fixpoint bar (G : graph) {measure (size G)} : nat := 
  if (property G) then bar (dec1 G) else 4.
Next Obligation. 
intros. apply dec1_lt. (* missing assumption [property G] *) 
Abort.
Admitted. (* Is there a way to abort a Program definition? *)

Program Fixpoint bar' (G : graph) {measure (size G)} : nat := 
  if (propertyP G) then bar' (dec1 G) else 4.
Next Obligation.
now apply dec1_lt.
Qed.

End FixedWidth.

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 propertyP G 
  then fold_right (fun H m => Nat.max (foo H) m) 0 (decompose G)
  else 4.
Next Obligation.
(* missing [In H (decompose G)] *)
Admitted.

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.



Archive powered by MHonArc 2.6.18.

Top of Page