coq-club AT inria.fr
Subject: The Coq mailing list
List archive
Re: [Coq-Club] Problem defining a function using lexicographic combinations and then wf-annotation
chronological Thread
- From: "Harley D. Eades III" <harley.eades AT gmail.com>
- To: AUGER C�dric <sedrikov AT gmail.com>
- Cc: coq-club AT inria.fr
- Subject: Re: [Coq-Club] Problem defining a function using lexicographic combinations and then wf-annotation
- Date: Sat, 17 Mar 2012 12:33:21 -0500
Hi Auger.
On Fri, Mar 16, 2012 at 5:36 AM, AUGER Cédric <sedrikov AT gmail.com> wrote:
Le Fri, 16 Mar 2012 01:45:58 -0500,
"Harley D. Eades III" <harley.eades AT gmail.com> a écrit :
At least that is the error message, althought I don't see particular
> Hello.
>
> I am trying to define a function using the well-founded annotation for
> function definitions.
>
> Here is a simple example illustrating both my problem and what I am
> attempting:
>
> Inductive ord : (nat * nat) -> (nat * nat) -> Prop :=
> Â | ord_red1 : forall n n' m m',
> Â Â n < m -> ord (n, n') (m, m')
> Â | ord_red2 : forall n n' m',
> Â Â n' < m' -> ord (n, n') (n, m').
>
> Function ack (p : nat*nat) {wf ord p } : nat :=
> Â match p with
> Â Â | (0, n) => (S n)
> Â Â | (S m, 0) => ack (m,1)
> Â Â | (S m, S n) => ack(m, ack(S m, n))
> Â end.
>
> Keep in mind that this is just an example. Â The function I ultimately
> want to define is more complex
> than this example.
>
> The main problem is that the above function is rejected by Coq. Â I
> believe it is because I am not allowed
> to use nested recursive calls in the body of a function; as in the
> last branch of ack.
reason to forbid it.
I agree. Â I don't see any profound theoretical reason for this. Â It doesn't seem to compromise
consistency. Â Maybe it has to do with making "Function" definitions as simple to reason about as possible. Â I amÂ
not sure.
Â
Do you know of the Acc predicate? In fact, it is what is behind "wf
>
> My question is, does anyone know of a way around this? Â I really want
> to be able to use the well-founded annotation, because
> the function I really want to define would be very difficult any
> other way.
annotations"; so using it explicitly can help.
I didn't know of this before now. Â Thanks for telling me! Â Your example
below helped a ton. Â After reading this i went and read a bunch on accessibilityÂ
predicates. Â I managed to get my function defined using "Program Fixpoint" andÂ
then actually understanding what I was supposed to do. Â :-)
Â
If you don't know of this predicate, you should take a look at it.
At each place you use "wf annotations", you can use "fix"; in fact,
>
> In this case I might be able to use 'fix' to get around the above
> problem, but I am wondering if there are any other ways, because
> doing it using 'fix' essentially makes using the wf-annotation
> pointless. Â Also, my ultimate goal is not possible using 'fix', at
> least I think it is.
"Function" is not part of the Coq "core" language, it is something
built using fix (and the Acc predicate).
Right, I know that now. Â Thanks again for this. Â It helped a lot!
Thanks,
Harley
Â
So with Acc, that would give:
>
> If anyone wants to know what this "ultimate" function is I will post
> it.
>
> Thanks,
> Harley
=============================================
Set Implicit Arguments.
Fixpoint ack (p : nat*nat) (H:Acc ord p) : nat :=
Inductive ord : (nat * nat) -> (nat * nat) -> Prop :=
 | ord_red1 : forall n n' m m',
  n < m -> ord (n, n') (m, m')
 | ord_red2 : forall n n' m',
  n' < m' -> ord (n, n') (n, m').
 let ack := match H with Acc_intro H => fun p Ho => ack (H p Ho) end in
 match p as p0 return (forall p, ord p p0 -> nat) -> nat with
  | (0, n) => fun _ => (S n)
  | (S m, 0) => fun ack => ack (m,1) (ord_red1 _ _ (le_n _))
  | (S m, S n) => fun ack =>
   ack (m, ack (S m, n) (ord_red2 _ (le_n _))) (ord_red1 _ _ (le_n
_)) end ack.
Lemma rec : forall p, Acc ord p.
Proof.
 assert (K : forall y, (forall z, z < y -> forall n, Acc ord (z, n)) ->
      forall n, Acc ord (y, n)).
 intros.
 induction n; split; intros; inversion H0; clear H0; subst; auto.
 inversion H3.
 assert (K := le_S_n _ _ H3); clear H3.
 induction K; auto.
 apply IHK; clear - IHn; destruct IHn; apply H; right; left.
 intros [m]; induction m; apply K; clear K; intros;
 inversion H; clear H; subst; auto.
 now destruct (IHm 0); apply H; left.
Qed.
Definition Ack := fun p => ack (rec p).
================================================
If you find "ack" definition being ugly, you can also use tactics to
manage the proof handling.
Fixpoint ack (p : nat*nat) (H:Acc ord p) : nat.
refine (
 let ack := _ in
 match p as p0 return (forall p, ord p p0 -> nat) -> nat with
  | (0, n) => fun _ => (S n)
  | (S m, 0) => fun ack => ack (m,1) _
  | (S m, S n) => fun ack =>
   ack (m, ack (S m, n) _) _
 end ack
).
Proof.
 (*Your proofs here*)
Defined.
Some last remarks:
→ if you want to compute "rec" must be transparent
 (ie. Defined terminated, not Qed terminated)
→ If you build terms using tactics, I strongly recommend:
 → build only Prop habitants with tactics
  (ie. avoid « Definition zero : nat. left. Defined. »)
 → if you want to compute/unfold definitions, abstract
  the Prop contents of the term you are building
  (using the abstract tactic)
 → Try to apply the previous two points to the "rec"
  definition.
→ if you use the abstract tactic, clean your hypothesis
 before (in particular, never keep a fixpoint not
 fully applied before proceding, since it will
 be generalized, and will make guardedness fail)
- [Coq-Club] Problem defining a function using lexicographic combinations and then wf-annotation, Harley D. Eades III
- Re: [Coq-Club] Problem defining a function using lexicographic combinations and then wf-annotation, Arthur Charguéraud
- Re: [Coq-Club] Problem defining a function using lexicographic combinations and then wf-annotation,
AUGER Cédric
- Re: [Coq-Club] Problem defining a function using lexicographic combinations and then wf-annotation, Harley D. Eades III
Archive powered by MhonArc 2.6.16.