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