Zulip Chat Archive

Stream: lean4

Topic: How to know if a function is recursive?


Abdalrhman M Mohamed (Jun 23 2022 at 17:27):

Is there a utility in Lean that tells if a function is recursive, mutually recursive, or not recursive?

-- recursive
def Nat.add' : Nat  Nat  Nat
  | 0     , b => b
  | succ a, b => succ (add' a b)

-- not recursive
def Nat.double x := Nat.add' x x

mutual
-- mutually recursive
def Nat.odd : Nat  Bool
  | 0     => false
  | n + 1 => ¬(even n)

-- mutually recursive
def Nat.even : Nat  Bool
  | 0     => true
  | n + 1 => ¬(odd n)
end

Leonardo de Moura (Jun 23 2022 at 20:51):

We currently don't have an API for directly answering this question, but we can add it.
How are you planning to use it? I am assuming this is for the CVC 5 <-> Lean interface :)
So, I am assuming you also want to know whether a function is tagged as partial or not.
If it is mutually recursive, I am assuming you also want to retrieve all functions in the mutual block, correct?
We have all this information internally, but we need to figure out how to provide it in a convenient way.

Arthur Paulino (Jun 23 2022 at 21:07):

Leonardo de Moura said:

all functions in the mutual block

Is this currently available? I know we have it for inductives. But for definitions we're computing it in a more involved way. If we have it as an attribute of DefinitionVal that would be great :pray:
CC: @Hanting Zhang @John Burnham

Leonardo de Moura (Jun 23 2022 at 21:10):

@Arthur Paulino I will add an API for retrieving this information.

Wojciech Nawrocki (Jun 23 2022 at 21:29):

Fwiw, the two places I went looking for this were FunInfo and DefinitionVal. Either one seems fairly natural/convenient.

Arthur Paulino (Jun 23 2022 at 22:04):

For us, having it available in DefinitionVal would be ideal because we're building on top of Lean.Environment. I don't recall seeing FunInfo :thinking:

Abdalrhman M Mohamed (Jun 23 2022 at 23:33):

How are you planning to use it? I am assuming this is for the CVC 5 <-> Lean interface :)

Yes. You're right!

If it is mutually recursive, I am assuming you also want to retrieve all functions in the mutual block, correct?

That would be awesome!!! It would be nice to have something similar for mutual datatypes

Leonardo de Moura (Jun 23 2022 at 23:47):

We now have

def ConstantInfo.all : ConstantInfo  List Name

The name is not great, but it is consistent with InductiveVal.all.
The test suite has an example: https://github.com/leanprover/lean4/blob/98c775da3472401c03f7688b4292e6ee3a25bba3/tests/lean/allFieldForConstants.lean
Recall that Lean breaks a mutual block into strongly connected components. Example:

mutual
  partial def f (x : Nat) : Nat :=
    if x < 10 then g x + 1 else 0
  partial def g (x : Nat) : Nat :=
    f (x * 3 / 2)
  partial def h (x : Nat) : Nat :=
    f x
end

#eval printMutualBlock ``f -- [f, g]
#eval printMutualBlock ``g -- [f, g]
-- Recall that Lean breaks a mutual block into strongly connected components
#eval printMutualBlock ``h -- [h]

Leonardo de Moura (Jun 23 2022 at 23:48):

The new data is ignored by the Lean kernel.

Arthur Paulino (Jun 23 2022 at 23:52):

Thanks!!

Guilherme Reis (Jun 24 2022 at 00:34):

Hey guys, how can I do this VClosure type?

inductive Value where
  | VInt (value : Int)
  | VClosure (context : Std.HashMap String Value)

the error that I'm getting: (kernel) arg #1 of 'Value.VClosure' contains a non-valid occurrence of the datatypes being declared

Arthur Paulino (Jun 24 2022 at 15:39):

@Guilherme Reis I'd recommend asking this question in a dedicated thread :+1:

Mario Carneiro (Jun 24 2022 at 21:07):

One interesting consequence of the SCC algorithm used in mutual compilation is that you can use mutual definitions to declare non-mutual definitions out of order:

mutual
  def f (x : Nat) : Nat := g x
  def g (x : Nat) : Nat := x
end

As far as I can tell there is no difference between these functions and:

def g (x : Nat) : Nat := x
def f (x : Nat) : Nat := g x

So this might be useful for writing functions out of order for presentation purposes or something.


Last updated: Dec 20 2023 at 11:08 UTC