Zulip Chat Archive

Stream: lean4

Topic: noncomputability across function calls


James Gallicchio (Feb 12 2024 at 18:18):

I am a bit curious how the computability checker works across function call boundaries. Which arguments to a function does the computability checker ensure are computable? Is there a way to mark that an argument should not be used for computation in the body?

James Gallicchio (Feb 12 2024 at 18:26):

as an example, I have a definition

def VEncCNF (L) [LitVar L ν] [Fintype ν] (α : Type u) (P : PropFun ν) :=
  { e : EncCNF L α // e.encodesProp P }

where EncCNF is essentially just a state monad. The Fintype argument and the P argument should both always be treated noncomputably. For example I have a function for constructing these values:

def for_all (arr : Array α) {P : α  PropFun ν} (f : (a : α)  VEncCNF L Unit (P a))
  : VEncCNF L Unit (.all (arr.toList.map P)) :=

and Lean currently seems to be marking that P is used for computation (i.e. I call for_all elsewhere with a noncomputable P and it complains), when in reality it should not be used anywhere.

James Gallicchio (Feb 12 2024 at 18:27):

using mathlib Erased seems like way more effort than it is worth. In the for_all example I would need to use the monad instance on erased, which substantially increases my proof burden

James Gallicchio (Feb 12 2024 at 18:30):

I somewhat successfully used Erased to make an ErasedFintype typeclass to prevent lean from computing that Fintype argument at callsites, but now that the P argument is demanding the same treatment I am getting worn down

Eric Wieser (Feb 12 2024 at 18:31):

I think in Lean 3, using @[inline] allowed Lean to unfold definitions to see that their arguments were not used for computation

James Gallicchio (Feb 12 2024 at 18:32):

I thought there was a discussion a while ago about how computability shouldn't rely on these optimization annotations, but I don't know whether anything came of it.

James Gallicchio (Feb 12 2024 at 18:33):

(also, I have had to mark various definitions noinline and nospecialize at places to prevent Lean's optimizations from taking 30 seconds during compilation for a single def...)

James Gallicchio (Feb 12 2024 at 18:33):

cc @Mario Carneiro

James Gallicchio (Feb 12 2024 at 18:34):

It seems here the suggestion was macro_inline, I'm not sure that is a viable hack in this case

Mario Carneiro (Feb 12 2024 at 18:34):

sorry, the best we have currently is Erased

Mario Carneiro (Feb 12 2024 at 18:35):

this is a known compiler issue but there isn't work on it these days

Mario Carneiro (Feb 12 2024 at 18:37):

using inline should help, assuming you can define the functions in terms of functions which do not take the erased values as arguments

James Gallicchio (Feb 12 2024 at 18:49):

I could also put PropFun in Prop, since it is never intended for computation anyways...

Mario Carneiro (Feb 12 2024 at 18:49):

what is it?

Mario Carneiro (Feb 12 2024 at 18:49):

certainly that will help

James Gallicchio (Feb 12 2024 at 18:51):

It is the inductive propositional formulas quotiented by equivalence

Mario Carneiro (Feb 12 2024 at 18:51):

...

Mario Carneiro (Feb 12 2024 at 18:51):

that's explicitly computational

James Gallicchio (Feb 12 2024 at 18:53):

It's definitely computable, yes, it just shouldn't be used in computation. The reason I am marking things noncomputable here is for performance, because Lean is insisting on building very large lean objects that are never used in the computations.

Mario Carneiro (Feb 12 2024 at 18:53):

have you looked at the IR? I can't see how lean could omit this if it wanted to

James Gallicchio (Feb 12 2024 at 18:54):

Because P is an argument to these functions and Lean doesn't know that it should be erasing P?

James Gallicchio (Feb 12 2024 at 18:55):

I haven't looked at the IR, but I am guessing it is what we expect

Mario Carneiro (Feb 12 2024 at 18:57):

to get erasure, you will have best results if all your erased indices are types and proofs

Mario Carneiro (Feb 12 2024 at 18:59):

And that includes the index of VEncCNF

Mario Carneiro (Feb 12 2024 at 18:59):

The Fintype issue is pretty easy to solve, just use Finite instead

James Gallicchio (Feb 12 2024 at 19:00):

got it :)

Mario Carneiro (Feb 12 2024 at 19:02):

Could PropFun ν be defined as just e.g. (ν -> Prop) -> Prop? I realize that's not necessarily finitely supported but encodesProp should imply that it is

James Gallicchio (Feb 12 2024 at 19:15):

Hm, that’s definitely an idea. Since I have the Fintype argument there anyways. Will try it out


Last updated: May 02 2025 at 03:31 UTC