Skip to Content.
Sympa Menu

coq-club - Re: [Coq-Club] Turning Non-Primitive Recursive Function into Primitive Recursive Function

coq-club AT inria.fr

Subject: The Coq mailing list

List archive

Re: [Coq-Club] Turning Non-Primitive Recursive Function into Primitive Recursive Function


Chronological Thread 
  • From: mukesh tiwari <mukeshtiwari.iiitm AT gmail.com>
  • To: coq-club AT inria.fr
  • Subject: Re: [Coq-Club] Turning Non-Primitive Recursive Function into Primitive Recursive Function
  • Date: Fri, 19 May 2023 20:18:42 +0100
  • Authentication-results: mail2-smtp-roc.national.inria.fr; spf=None smtp.pra=mukeshtiwari.iiitm AT gmail.com; spf=Pass smtp.mailfrom=mukeshtiwari.iiitm AT gmail.com; spf=None smtp.helo=postmaster AT mail-lj1-f175.google.com
  • Ironport-data: A9a23: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
  • Ironport-hdrordr: A9a23:6ndft65yZvs9/UMibQPXwPfXdLJyesId70hD6qkXc20sTiX4rb HWoB1/73XJYVkqKRQdcLy7Scu9qDbnhP1ICOoqXItKPjOW3FdARbsKheDfKn/bexEWndQtsp uIHZIObuEYzmIXsS852mSF+hobr+VvOZrHudvj
  • Ironport-phdr: A9a23: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 BExjQR6bKIm8zK+uz8K
  • Ironport-sdr: 6467cb9f_ZEBWuVban6t2ibFy1Np+IZrsV87TFhIwAxmR7sjarXn6oWA oKsSYivhkLwvZXMIv2vsm0cBkFWsjC9KFozcLOw==

"Both for programming and for mathematics, I'd rather use well-founded
recursion than nat-valued fuel. "

Agree but there are few cases, e.g., if you want to evaluate a
function inside the Coq itself, then well-founded functions may not
reduce due to some opaque proof terms (at least this is my
experience). In one project, I wanted to evaluate the SHA256 hash [1]
inside the Coq itself and therefore picked the fuel based solution,
rather than well-founded.

Best,
Mukesh

[1]
https://github.com/mukeshtiwari/Formally_Verified_Verifiable_Group_Generator/blob/main/src/Sha256.v#L879

On Fri, May 19, 2023 at 6:07 PM Xavier Leroy
<xavier.leroy AT college-de-france.fr> wrote:
>
> On Fri, May 19, 2023 at 6:45 PM mukesh tiwari
> <mukeshtiwari.iiitm AT gmail.com> wrote:
>>
>> Thanks Yannick and Mario! I was somehow under a (flawed) assumption
>> that functions that computes fuel were alway primitive recursive, but
>> it may or may not be the case. So my understanding is: theoretically
>> it is possible to turn an non-primitive recursive function into a
>> primitive recursive function (Kleene's normal form theorem) by means
>> of using nat as a fuel, but computing the fuel may be as complicated
>> as computing the original function, i.e., it may not be primitive
>> recursive. I also came up with a counterexample for my flawed
>> assumption: I can write a division function on natural numbers using
>> the subtraction function (I know it is not a great way to write
>> division function):
>>
>> Theorem nat_div : nat -> forall (b : nat),
>> 0 < b -> nat * nat.
>> Proof.
>> intro a.
>> cut (Acc lt a);
>> [revert a |].
>> +
>> refine(fix nat_div a (acc : Acc lt a) {struct acc} :
>> forall b : nat, 0 < b -> nat * nat :=
>> match acc with
>> | Acc_intro _ f => fun b Ha =>
>> match (lt_eq_lt_dec a b) with
>> | inleft Hb =>
>> match Hb with
>> | left Hc => (0, a)
>> | right Hc => (1, 0)
>> end
>> | inright Hb =>
>> match nat_div (a - b) _ b Ha with
>> | (q, r) => (S q, r)
>> end
>> end
>> end).
>> assert (Hc : (a - b) < a).
>> abstract nia.
>> exact (f (a - b) Hc).
>> +
>> eapply lt_wf.
>> Defined.
>>
>> But if I want to turn this into a primitive recursive function by
>> means of fuel, then computing fuel itself requires a division
>> function.
>
>
> Not in this case. You can always over-approximate how much fuel you need.
> In this case taking "a" as the fuel should suffice.
>
>
>>
>> In conclusion, theoretically it is possible but there could
>> be a situation where it is not a very good idea for programming
>> (constructive mathematics?).
>
>
> Both for programming and for mathematics, I'd rather use well-founded
> recursion than nat-valued fuel. Think of well-founded recursion as
> recursing on a fuel that is a proof of accessibility in an order of your
> choice. This gives more flexibility than recursing on silly Peano natural
> numbers. In particular, because you can choose the order, proving
> accessibility is generally easier than proving the existence of a large
> enough nat-valued fuel.
>
> For what it's worth...
>
> - Xavier Leroy
>
>
>
>
>>
>>
>>
>> Best,
>> Mukesh
>>
>>
>>
>> On Thu, May 18, 2023 at 7:12 PM Yannick Forster <yannick AT yforster.de>
>> wrote:
>> >
>> > Sure, computing the fuel is not going to be primitive recursive because
>> > the fuel is large. But given a defined Coq (or any other constructive
>> > type theory) function f : nat -> nat it can be turned into a primitive
>> > recursive function f' : nat -> nat -> nat such that f' n x = S v, then
>> > for all n' >= n, f' n x = S v and forall x, exists n, f' n x = S (f x).
>> >
>> > Here, f' is a primitive recursive function expecting fuel n and an
>> > argument x, and then computes f for large enough fuel (and else returns
>> > 0). The n might, as you say, have to be very large, but constructing f'
>> > is always possible.
>> >
>> >
>> > On 18 May 2023 20:04:06 Mario Carneiro <di.gama AT gmail.com> wrote:
>> >>
>> >> This doesn't sound quite correct. While Kleene's T tells you that for
>> >> any terminating computation there is *some* bound for the fuel you need
>> >> to compute the value, the bound itself might be quite large, and so you
>> >> are reduced to computing very fast growing functions, to compute the
>> >> initial fuel value you use to power the rest of the computation. These
>> >> functions need just as much "power" from the theory as the original
>> >> recursion did. There are functions which are not primitive recursive,
>> >> like the ackermann function, and if you rewrite them to use a fuel
>> >> variable you will need to supply a function which grows about as fast
>> >> as the ackermann function to get the initial fuel value, and that
>> >> function is also not primitive recursive.
>> >>
>> >> Now, Ackermann's function is computable in Coq because it has higher
>> >> order functions and hence goes beyond the traditional conception of
>> >> primitive recursive function, but I think you might still need more
>> >> than just N-indexed inductions to get the full power of Coq terminating
>> >> functions. There are inductive types with a much larger rank than N
>> >> around, and I don't think you can get epsilon_0 induction simply by
>> >> composing inductions of rank omega.
>> >>
>> >> On Thu, May 18, 2023 at 1:48 PM Yannick Forster <yannick AT yforster.de>
>> >> wrote:
>> >>>
>> >>> Hi Mukesh,
>> >>>
>> >>> in computability theory this intuition is behind Kleene's normal form
>> >>> theorem: https://en.m.wikipedia.org/wiki/Kleene%27s_T_predicate
>> >>>
>> >>> You can prove the normal form theorem for computable functions in Coq
>> >>> when defining them using some model of computation. But since given
>> >>> any concrete Coq function (over natural numbers or some suitable
>> >>> datatype isomorphic to numbers) you could have implemented it as a
>> >>> function in a model of computation provided enough time and endurance,
>> >>> this means you can re-write any definable Coq function as a fueled
>> >>> primitive recursive function, yes.
>> >>>
>> >>> Best
>> >>> Yannick
>> >>>
>> >>> On 18 May 2023 19:35:56 mukesh tiwari <mukeshtiwari.iiitm AT gmail.com>
>> >>> wrote:
>> >>>
>> >>>> Hi everyone,
>> >>>>
>> >>>> Is it always possible to turn a non-primitive (terminating) recursive
>> >>>> function into a primitive recursive function by passing a natural
>> >>>> number as a fuel? If so, is there any formal underpinning for this,
>> >>>> i.e., turning a non-primitive (terminating) recursive function into a
>> >>>> primitive recursive function by passing a natural number, or is it
>> >>>> just obvious? My intuition says it's true but I am very keen to see
>> >>>> some formal reasoning.
>> >>>>
>> >>>> For example, I can write a function that computes a byte list from a
>> >>>> (binary) natural number like this [1] (I call it non-primitive
>> >>>> (terminating) recursive function but I may not be correct with my
>> >>>> terminology):
>> >>>>
>> >>>> Definition length_byte_list_without_guard : N -> list byte.
>> >>>> Proof.
>> >>>> intro np.
>> >>>> cut (Acc lt (N.to_nat np));
>> >>>> [revert np |].
>> >>>> +
>> >>>> refine(fix length_byte_list_without_guard np (acc : Acc lt
>> >>>> (N.to_nat np))
>> >>>> {struct acc} :=
>> >>>> match acc with
>> >>>> | Acc_intro _ f =>
>> >>>> match (np <? 256) as npp
>> >>>> return _ = npp -> _
>> >>>> with
>> >>>> | true => fun Ha => List.cons (np_total np Ha) List.nil
>> >>>> | false => fun Ha =>
>> >>>> let r := N.modulo np 256 in
>> >>>> let t := N.div np 256 in
>> >>>> List.cons (np_total r _) (length_byte_list_without_guard
>> >>>> t _)
>> >>>> end eq_refl
>> >>>> end).
>> >>>> ++
>> >>>> apply N.ltb_lt, (nmod_256 np).
>> >>>> ++
>> >>>> apply N.ltb_ge in Ha.
>> >>>> assert (Hc : (N.to_nat t < N.to_nat np)%nat).
>> >>>> unfold t. rewrite N2Nat.inj_div.
>> >>>> eapply Nat.div_lt; try abstract nia.
>> >>>> exact (f (N.to_nat t) Hc).
>> >>>> +
>> >>>> apply lt_wf.
>> >>>> Defined.
>> >>>>
>> >>>> But I can also write the same function by passing a natural number [2]
>> >>>> (from top level,
>> >>>> I just need to ensure the right amount of fuel):
>> >>>>
>> >>>> Fixpoint byte_list_from_N_fuel (n : nat) (up : N) : list byte :=
>> >>>> match n with
>> >>>> | 0%nat => [np_total (N.modulo up 256) (nmod_256_dec up)]
>> >>>> | S n' =>
>> >>>> let r := N.modulo up 256 in
>> >>>> let t := N.div up 256 in
>> >>>> List.cons (np_total r (nmod_256_dec up)) (byte_list_from_N_fuel
>> >>>> n' t)
>> >>>> end.
>> >>>>
>> >>>> Best,
>> >>>> Mukesh
>> >>>>
>> >>>> [1]
>> >>>> https://github.com/mukeshtiwari/Coq-automation/blob/master/Opaque.v#L75
>> >>>> [2]
>> >>>> https://github.com/mukeshtiwari/Formally_Verified_Verifiable_Group_Generator/blob/main/src/Sha256.v#L239
>> >>>
>> >>>
>> >



Archive powered by MHonArc 2.6.19+.

Top of Page