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: Yannick Forster <yannick AT yforster.de>
  • To: <coq-club AT inria.fr>
  • Subject: Re: [Coq-Club] Turning Non-Primitive Recursive Function into Primitive Recursive Function
  • Date: Thu, 18 May 2023 20:11:51 +0200
  • Authentication-results: mail3-smtp-sop.national.inria.fr; spf=None smtp.pra=yannick AT yforster.de; spf=Pass smtp.mailfrom=yannick AT yforster.de; spf=None smtp.helo=postmaster AT himalia.uberspace.de
  • Ironport-data: A9a23:C3tAuKMT4NPr78bvrR3Kk8FynXyQoLVcMsEvi/4bfWQNrUp21mMEm zMXCjjSPvaCZWCjLd9+PtvnoxtXsZ/SnYQyS3M5pCpnJ55ogZqcVI7Bdi8cHAvLc5adFBo/h yk6QoOdRCzhZiaE/n9BCpC48T8mk/vgqoPUUIbsIjp2SRJvVBAvgBdin/9RqoNziLBVOSvU0 T/Ji5OZYAfNNwJcaDpOsPre8UM355wehRtB1rAATaAT1LPhvyJNZH4vDfnZB2f1RIBSAtm7S 47rpF1u1j6xE78FU7tJo56jGqE4aua60Tum1hK6b5Ofbi1q/UTe5EqU2M00Mi+7gx3R9zx4J U4kWZaYEW/FNYWU8AgRvoUx/4iT8sSq9ZeeSUVTv/B/wGXXXV38zNB/PH0zJIBF/u94JXkS8 /UxfWVlghCr34pawZq7S+xlgsUqatThMZkEonhrwHfVAJ7KQ7iaE/iMv4EehWpuwJkUQ54yZ OJBAdZrRAXJZRtOMVQ/GZw5hvy0i2O5fzAwRFe9+PRruTKOnFIZPL7FMN7LQeyDZ+9psl+nj UPsz0neBisiK4nKodaC2ivw37SWwksXQrk6H7qhs/VunVe73X0WEBRQVF2hoPD/hFTWZj5EA 0wV/yMqrKF06UamVMLlVha15nKJ1vIBZzZOO/wUzhGC77vk3wOACzUARzFlcIAgveZjEFTGy WS1t9/uADVutpicRnSc6qqYoFuO1c49cDRqicgsEFFt3jXznG0gpk+WFIcyS8ZZmvWkRWCpm 1hmuQBk3+17sCId60ms1Xzq6w9AS7DJTws84gTeGH+v4xlifIeuasqk5DA3DMqszq7DFTFtX 1Bex6ByCdzi6rnc/BFhuM1XQNmUCw+taVUwe2JHEZg77CiK8HW+Z41W6zwWDB43YppfJW+zO x+J6F45CHpv0J2CMPMfj2WZVphC8EQcPYiNug38MIsXOPCdiifaoXkGibGsM5DFyRR1yvhgU XtqWduyAHABGL8vwz+8R48gPUwDmEgDKZfobcmil3yPiOPODEN5vJ9fbzNimMhls/LUyOgUm v4DX/a3J+J3ALWiM3KJr9RDRb3IRFBiba3LRwVsXrbrCmJb9KsJUpc9GJtxJdI3rLcfjerS4 HC2V2lRzVe11zWNKhyHZjonIPnjVIp25yBzdyE9H0ea6156a6aW7YAba8QWe5sj/7dd1vJad aQOVPiBJfVtcQ753QohQ6PzlrE/SyTztzmyZ3KkRBMdY69fQxf4/464Xwn3qwgLICmFleo/h LyCizHeEIsIHD5mB8eLa8CU7kiQuEIFk7lYRHr4Idh0eWTt/rN1Kif3sOQFHsEUJTjHxRqYz wymOggZruzzvIMFytnFqqSapYOPEeElPE5lM0TEzLSxbw/2w3GCxNJebeO2YjztbmP416G8b +FzzfunEvkmnk5PgrVsAYRQ0qMyyNv+lYB0lj0+Mi3wUG2qLbd8Ll2t/8pF7PRNz4AEnzqGY BuE/90CNIiZPM/gLkUqGzMkSea9hNU0gTjZ6MonLHrqvBFX+KW1amQMHh2uphEEEp5LHtIE+ 8kDtvQSyTSDsTsxE9Pfjilr52WGdXMBdKM8t6AlOozgiyt161dGZJaHKD36z6+eT9B2NmgrP T6mq67QjJtMxkf5UiQSFFqc+cF/lJgxqBRx41taHGuwm/3BmvMT9z9AwwQdFwh64E1O7LNuB zJNKUZwG5Srwx5po8pyB0aXBABLAUyiyHzbklcmujXQcBi1azbrMmY4BOeq+XIZ+UJ6ehxw3 umR6EThYAbQUPDB5AkAcm87lKW7Vv10zBPIp+6/FcfcH5UaXyvsspXzWUU28SnYEeEDr2yZg 9ky5+thS7zJBQhJqY0BNoSq/7AxSheFGW98fc9c7J45RWHyRBzi2BylCVyARcdWFvmbrW66E 5NPI+xMZTSf1QGPjDcSOvcMKZBwnNov2tswSpH5LkEosYmk8zlbi7PL1y3EnGRwac5focU8D YLwdjy5DW2bg0VPqVLNtMVpPmmZY8EOQQ/BgNCO7+QCEqwcvNFWcU0d1qW+u1OXOlBF+y24k RziZaiM6cBf0qVpwpXRF5tcCzWOKd/cUPqC9CaxuY9safLNKcL/iBMHmGL4Pgh5PaojZPovr O6j6OXI5ULiuKo6d0v7mJPbTqlA2piUbdpta8nyKCFXoDuGVMrS+CA8wmGfK6IYoOMFs4PjD 0G9ZdCrfNEYZ8ZFyTcHI2JCGhIaEOLsYr2muSq5qO+WBwMA1RDcaumq7mLtcXoRYxpg10cS0 eMok63GChFkQIVw6NssB/BjCpt5KRn+U6Y8bMX4vjTeAmTAbpZufFf9vUJI1N0JIiDs/AXGD VbtVxb5bg+utbuOwNwxX0laoEgMFHgk6QUvVht1xjO14gxWyEYXI+MHKokLENdYn0QeEX0+i C7lNAMfNMk2YdiIndgQLjgussdzy9Hi4uvEGwE=
  • Ironport-hdrordr: A9a23:U4Ah867n3vvIuw7Z+wPXwALXdLJyesId70hD6qkQc3Zom62j5q STdZEgpGTJYVkqN03I9ersBEDEexLhHP1OkOws1NWZMjUO0VHAROoSlbcKgQeBJ8SUzJ8+6U 4PScRD4ZHLfDtHpPe/2xOgG9IshPKO68mT9IDj5kYodhtyY6Vsqzx0EwCBDyRNNW97LKt8L4 CE7s5L4wCrf28aB/7Lf0U4Yw==
  • Ironport-phdr: A9a23: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 Mffi9qzy7R1lOUtAlxIE1DsyJnBWA==
  • Ironport-sdr: 64666a6a_F38CS3B6KfPwiRE0dSibdjnOC4n+P1VqWKEZ/fRdcJ0t75c Rq3hx5zpGb4ZhcCWJD4FPNTFDzOgfEfZh4mtxBA==

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






Archive powered by MHonArc 2.6.19+.

Top of Page