Zulip Chat Archive
Stream: new members
Topic: noncomputable
Paul van Wamelen (Feb 17 2020 at 16:08):
I'm trying
def to_complex (x : ℤ[ω]) : ℂ := x.re + x.im * (1 + I * real.sqrt 3) / 2
but getting definition 'to_complex' is noncomputable, it depends on 'complex.discrete_field'
.
Is there some import
or open
that will "deal" with this? What are the consequences of ignoring the noncomputability of sqrt?
It looks like an interesting exercise to make real.sqrt
computable (looks like there is a proof sketch in the comments of real.sqrt
's definition). Is that worth trying? Is it just a matter of constructing the Cauchy sequence that converges to sqrt(n)?
Reid Barton (Feb 17 2020 at 16:12):
The real numbers as implemented in mathlib have no useful computational structure anyways (they are Cauchy sequences without any explicit rate of convergence). You should just put noncomputable theory
at the top of your file if you are going to use the reals a lot.
Paul van Wamelen (Feb 17 2020 at 16:29):
Thanks!
Are you saying that even if we complete the proof of sqrt_aux_converges
sqrt would still be "uncomputable"?
Chris Hughes (Feb 17 2020 at 16:31):
It would be computable in the sense that Lean wouldn't have the noncomputable
tag, but it would not be computable in any practical sense. There is no computable function real -> bool
for example, so there's basically nothing you can do with a "computable" function on the current implementation of the reals.
Paul van Wamelen (Feb 17 2020 at 16:37):
I think I see :)
Thanks again! (I must say I'm blown away by the support here...)
Kevin Buzzard (Feb 17 2020 at 17:16):
I tend to not put noncomputable theory
at the top of my files, and then every time Lean complains something is noncomputable I just write noncomputable
in front of it, so e.g. noncomputable def to_complex ...
would also remove the error.
Alexandre Rademaker (May 07 2020 at 01:42):
Why for such simple theorems I need the noncomputable
in front of the theorems?
constant Class : Type
-- SUMO immediateSubclass
constant subClass : Class → Class → Type
-- SUMO subclass
constant Inherits : Class → Class → Type
constant inhz (c : Class) : Inherits c c
constant inhs (c1 c2 c3 : Class) : subClass c1 c2 → Inherits c2 c3 → Inherits c1 c3
constants Human Hominid Entity : Class
constant human_hominid : subClass Human Hominid
constant hominid_entity : subClass Hominid Entity
noncomputable theorem test1 : Inherits Human Hominid :=
inhs Human Hominid Hominid human_hominid (inhz Hominid)
noncomputable theorem test2 : Inherits Human Entity :=
inhs Human Hominid Entity human_hominid (inhs Hominid Entity Entity hominid_entity (inhz Entity))
Is it possible, using some tactics, to let Lean come up of the proof terms automatically? That is, to synthesize the proof term?
Mario Carneiro (May 07 2020 at 01:43):
noncomputable
has nothing to do with computation in this sense
Mario Carneiro (May 07 2020 at 01:44):
it's noncomputable
because you can't directly execute the proofs because they use undefined constants
Alexandre Rademaker (May 07 2020 at 01:45):
undefined constants? but in my example, they are all defined.
Mario Carneiro (May 07 2020 at 01:45):
noncomputable theorem
is an indication that you have incorrectly marked a def
as a theorem, or you have a type where you wanted a prop. Are subClass
and Inherits
supposed to be propositions? They are named like such
Mario Carneiro (May 07 2020 at 01:45):
constant
is the same as axiom
Alexandre Rademaker (May 07 2020 at 01:46):
No, subClass is supposed to be a dependent type and Inherits a function.
Mario Carneiro (May 07 2020 at 01:47):
You may want to consider using variable
or parameter
here
Alexandre Rademaker (May 07 2020 at 01:47):
actually, I would like to be able to have a term like inhs Human Hominid Hominid human_hominid (inhz Hominid)
produced automatically for a type Inherits Human Hominid
Mario Carneiro (May 07 2020 at 01:48):
you can probably do that using typeclass inference
Alexandre Rademaker (May 07 2020 at 01:50):
Wow! Thank you Mario. Can you give me any reference to understand it better? Probably I have to read https://leanprover.github.io/theorem_proving_in_lean/type_classes.html, right?
Alexandre Rademaker (May 07 2020 at 01:51):
BTW, nice, I don't need the noncomputable with variables
constant Class : Type
-- SUMO immediateSubclass
constant subClass : Class → Class → Type
-- SUMO subclass
constant Inherits : Class → Class → Type
variable inhz (c : Class) : Inherits c c
variable inhs (c1 c2 c3 : Class) : subClass c1 c2 → Inherits c2 c3 → Inherits c1 c3
variables Human Hominid Entity : Class
variable human_hominid : subClass Human Hominid
variable hominid_entity : subClass Hominid Entity
theorem test1 : Inherits Human Hominid :=
inhs Human Hominid Hominid human_hominid (inhz Hominid)
theorem test2 : Inherits Human Entity :=
inhs Human Hominid Entity human_hominid (inhs Hominid Entity Entity hominid_entity (inhz Entity))
Mario Carneiro (May 07 2020 at 01:53):
constant Class : Type
-- SUMO immediateSubclass
@[class] constant subClass : Class → Class → Type
-- SUMO subclass
@[class] constant Inherits : Class → Class → Type
@[instance] constant inhz (c : Class) : Inherits c c
@[instance] constant inhs (c1 c2 c3 : Class) [Inherits c2 c3] [subClass c1 c2] : Inherits c1 c3
constants Human Hominid Entity : Class
@[instance] constant human_hominid : subClass Human Hominid
@[instance] constant hominid_entity : subClass Hominid Entity
noncomputable def test1 : Inherits Human Hominid := by apply_instance
noncomputable def test2 : Inherits Human Entity := by apply_instance
Alexandre Rademaker (May 07 2020 at 01:57):
thank you. I am getting two errors
.… 19 19 warning definition 'test1' was incorrectly marked as noncomputable (lean-checker)
.… 19 27 error maximum class-instance resolution depth has been reached (the limit can be increased by setting option 'class.instance_max_depth') (the class-instance resolution trace can be visualized by setting option 'trace.class_instances')
state:
⊢ Inherits Human Hominid (lean-checker)
Mario Carneiro (May 07 2020 at 02:05):
You won't be able to use a variable for typeclass inference here. Instances have to be def
s or constant
s
Mario Carneiro (May 07 2020 at 02:06):
The error is because you missed that I swapped the arguments to inhs
Mario Carneiro (May 07 2020 at 02:07):
I make no guarantees about the behavior of this typeclass search, and there are issues with infinite searches if it follows the wrong path
Mario Carneiro (May 07 2020 at 02:07):
but it works in a pinch
Alexandre Rademaker (May 07 2020 at 02:08):
I see. But I copied and pasted your code. So I didn't understand your point about the swapping of the arguments of inhs...
Mario Carneiro (May 07 2020 at 02:09):
Are you sure? What version of lean are you running
Mario Carneiro (May 07 2020 at 02:09):
I guessed that you modified your code to look like mine
Alexandre Rademaker (May 07 2020 at 02:10):
Oh, I got. Now I have just green marks
Mario Carneiro (May 07 2020 at 02:10):
but I don't know any version of lean where the noncomputable
mark on the def is unnecessary
Alexandre Rademaker (May 07 2020 at 02:12):
Hum, I see. So I guess that I can't expect too much from Lean to synthesize proof terms as I was expecting with this approach I was investigating.
Mario Carneiro (May 07 2020 at 02:13):
there are other ways to do it but they are more complicated
Mario Carneiro (May 07 2020 at 02:16):
constant Class : Type
-- SUMO immediateSubclass
constant subClass : Class → Class → Type
-- SUMO subclass
constant Inherits : Class → Class → Type
constant inhz (c : Class) : Inherits c c
constant inhs (c1 c2 c3 : Class) : subClass c1 c2 → Inherits c2 c3 → Inherits c1 c3
constants Human Hominid Entity : Class
constant human_hominid : subClass Human Hominid
constant hominid_entity : subClass Hominid Entity
meta def prove_subclass : tactic unit :=
`[apply human_hominid] <|> `[apply hominid_entity]
meta def prove_inherits : tactic unit :=
`[apply inhz] <|> (`[apply inhs] >> prove_subclass >> prove_inherits)
noncomputable def test1 : Inherits Human Hominid := by prove_inherits
noncomputable def test2 : Inherits Human Entity := by prove_inherits
Alexandre Rademaker (May 07 2020 at 02:22):
In this article, https://www.molto-project.eu/sites/default/files/FinalSUMOCNL.pdf, the authors have an interesting idea of mapping a KIF ontology (a knowledge representation language) to dependent type. They used https://www.grammaticalframework.org that implements dependent types too. I am trying to adapt their solution to Lean. The idea is to model the taxonomy of classes. Later, I would expect Lean to automatically construct terms that proof a chain of subclasses like Human < Hominid < CognitiveAgent < Agent < ... < Entity.
Alexandre Rademaker (May 07 2020 at 02:24):
What impressed me was that I was expecting Lean to have a much more powerful type system. But in GF they were able to easily generate a term for a given type. Page 6 of the article. The command mean: give me a term for the type Inherits Human Hominid
.
> gt -cat="Inherits Human Hominid"
(inhs Human Hominid Hominid Human_Class (inhz Hominid))
Alexandre Rademaker (May 07 2020 at 02:26):
Oh, sorry I was answering a question that you made in another thread! ;-)
Mario Carneiro (May 07 2020 at 02:27):
Reading the paper, I'm pretty sure you want subClass
and Inherits
to be props. The reason they use a dependent type is because that's the nearest equivalent to a proposition in a haskell-esque type theory
Mario Carneiro (May 07 2020 at 02:28):
I think gt -cat
is doing something similar to lean's typeclass inference
Mario Carneiro (May 07 2020 at 02:33):
pages 5-6 read very much like a description of typeclass inference. I'm pretty sure that gt -cat
is a prolog-like search
However, there are some types of axioms which could not be ported to SUMOGF, such as the ones that use quantification over classes, negative type declarations and axioms which use the predicates subclass, range or domain.
...which also predicts that negations in theorems would be problematic to represent this way, because instance search only works with horn clauses (from A , B, ... Y infer Z)
Alexandre Rademaker (May 07 2020 at 02:39):
Thank you, I will think more about the implications of moving to propositions. In the previous example of trying to prove a simple SUMO axiom in Lean, I used untyped FOL mapping to Lean - https://github.com/own-pt/common-sense-lean/blob/master/misc/bs.lean. This makes the simple proof very verbose. I had a single type https://github.com/own-pt/common-sense-lean/blob/master/misc/bs.lean#L21 and guards in the axioms https://github.com/own-pt/common-sense-lean/blob/master/misc/bs.lean#L96. I am trying to better use types and have a way to move from the class hierarchy to types.
Anyway, the use of tactics was interesting, thank you for sharing. Unfortunately, we needed to go back to constants and noncomputable...
Mario Carneiro (May 07 2020 at 02:41):
The reason lean gets lost with the initial version of inhs
is because it builds up a stack subclass Human ?a /\ subclass ?a ?b /\ subclass ?b ?c /\ Inherits ?c Hominid -> Inherits Human Hominid
that doesn't resolve because it keeps applying inhs
to the last Inherits
subgoal. It's similar to the left recursion problem in context free grammars
Mario Carneiro (May 07 2020 at 02:42):
I am curious if GF has the same problem if you stated inhs
as Inherits c1 c2 → subClass c2 c3 → Inherits c1 c3
instead
Alexandre Rademaker (May 07 2020 at 02:44):
This is interesting. I moved subclass back to the original position and it is working for me
constant Class : Type
-- SUMO immediateSubclass
@[class] constant subClass : Class → Class → Type
-- SUMO subclass
@[class] constant Inherits : Class → Class → Type
@[instance] constant inhz (c : Class) : Inherits c c
@[instance] constant inhs (c1 c2 c3 : Class) [subClass c1 c2] [Inherits c2 c3] : Inherits c1 c3
constants Human Hominid Entity : Class
@[instance] constant human_hominid : subClass Human Hominid
@[instance] constant hominid_entity : subClass Hominid Entity
set_option class.instance_max_depth 100
set_option trace.class_instances true
noncomputable def test1 : Inherits Human Hominid := by apply_instance
noncomputable def test2 : Inherits Human Entity := by apply_instance
Alexandre Rademaker (May 07 2020 at 02:50):
Unfortunately, I can't test the change in GF, the code in https://github.com/GrammaticalFramework/gf-contrib/tree/master/SUMO is incomplete.
Alexandre Rademaker (May 07 2020 at 02:53):
Mario Carneiro said:
Are you sure? What version of lean are you running
% lean -v
Lean (version 3.4.2, Release)
Mario Carneiro (May 07 2020 at 04:09):
@Alexandre Rademaker So I had a go at simplifying your bs.lean, see https://gist.github.com/digama0/16c62d1af34212de2e3fba380d87c043 . You can't quite take care of everything with typeclass inference but almost all the proofs that look like typeclass inference can be done using it
Alexandre Rademaker (May 07 2020 at 12:53):
I see, thank you so much for your attention. I will read it carefully to understand the details. The main issue, I believe, is to understand the limitations of that approach. The comments not provable
in the end means not probable with typeclass inference or not provable at all with this way to model classes and instances?
Still, I think the predicates and functions are not really typed, right? I can't say that partition : Class → Class → Class → Prop
and 'using it' like:
axiom a67131 {c row0 row1 : Class} :
(partition3 c row0 row1 ↔ (exhaustiveDecomposition3 c row0 row1 ∧ disjointDecomposition3 c row0 row1))
That is, I can't really internalize the class hierarchy in the types.
In Lean 3.4.2 almost all proofs reached the maximum class-instance resolution depth, and I set it to 1000.
Mario Carneiro (May 09 2020 at 05:44):
Alexandre Rademaker said:
I see, thank you so much for your attention. I will read it carefully to understand the details. The main issue, I believe, is to understand the limitations of that approach. The comments
not provable
in the end means not probable with typeclass inference or not provable at all with this way to model classes and instances?
Not provable from the axioms that were provided. Presumably you have omitted some axioms that are needed to prove these.
Mario Carneiro (May 09 2020 at 05:47):
Indeed, these predicates and functions are essentially untyped, and typeclass inference is having to solve a harder problem than it normally would because there are so few classes and so many instances. One simple way to improve this is to have one typeclass per property and try to minimize the number of two-argument typeclasses. And things like ins x Class
are really calling out for a Class
type as you indicate, which would eliminate the need to do any type class search, although you still have to do something about subtyping.
Alex Zhang (Jun 26 2021 at 08:01):
What is the function of putting noncomputable
before instance
?
noncomputable instance : inner_product_space ℝ (n → ℝ) :=
inner_product_space.of_core
sorry
Eric Wieser (Jun 26 2021 at 08:23):
Perhaps it helps to realize that instance
is just short for @[instance] def
, so this is just like putting noncomputable
before a def.
Alex Zhang (Jun 26 2021 at 08:39):
What will be the difference in practice if I don't put the noncomputable
?
Kevin Buzzard (Jun 26 2021 at 10:40):
It's not you who chooses -- Lean will tell you what's computable and what isn't, and you tag appropriately. Noncomputability is irrelevant if you just want to prove theorems, it just stops you doing things like #eval and #reduce, but there are plenty of other ways to evaluate things eg use theorems
Eric Wieser (Jun 26 2021 at 10:44):
Lean will give an error if you put noncomputable
on something that is computable, or don't put it on something that isn't. Lean is trying to make you tell the human reader what is and is not computable, even though lean itself knows without you telling it
Eric Wieser (Jun 26 2021 at 10:44):
If you think your readers don't care, you can start your file with noncomputable theory
and lean will stop complaining.
Alex Zhang (Jul 19 2021 at 20:09):
Why is this def noncomputable?
noncomputable def of_bijective {α β} (f : α → β) (hf : bijective f) : α ≃ β :=
(of_injective f hf.1).trans $ (set_congr hf.2.range_eq).trans $ equiv.set.univ β
Yakov Pechersky (Jul 19 2021 at 20:10):
Because it does not actually provide an explicit inverse function to f
Alex Zhang (Jul 19 2021 at 20:12):
Is it possible to make this computable by another proof?
def of_bijective {α β} (f : α → β) (hf : bijective f) : α ≃ β := sorry
Kevin Buzzard (Jul 19 2021 at 20:13):
No.
Alex Zhang (Jul 19 2021 at 20:13):
Oh, I see
Alex Zhang (Jul 19 2021 at 20:13):
I depends on axiom of choice.
Kevin Buzzard (Jul 19 2021 at 20:13):
https://xenaproject.wordpress.com/2019/06/11/the-inverse-of-a-bijection/
Yakov Pechersky (Jul 19 2021 at 20:14):
If you see the other thread, you'll see that you don't actually care about the computability of that iso, because you need it solely in the context of a proof.
Alex Zhang (Jul 19 2021 at 20:15):
Currently, for the purpose of my work, I actually don't need to care about the computability of anything at all :)
Alex Zhang (Jul 20 2021 at 14:39):
Is it possible to make a computable instance? F
is a finite field.
import field_theory.finite.basic
variables {F : Type*} [field F] [fintype F] [decidable_eq F] {p : ℕ} [char_p F p]
def is_quad_residue (a : F) : Prop := ∃ b, a = b^2
noncomputable
instance (a : F) : decidable (is_quad_residue a) := by {simp[is_quad_residue], exact classical.dec (∃ (b : F), a = _)}
Adam Topaz (Jul 20 2021 at 14:42):
import field_theory.finite.basic
variables {F : Type*} [field F] [fintype F] [decidable_eq F] {p : ℕ} [char_p F p]
@[derive decidable]
def is_quad_residue (a : F) : Prop := ∃ b, a = b^2
example (a : F) : decidable (is_quad_residue a) := by apply_instance
Anne Baanen (Jul 20 2021 at 14:43):
Similarly:
import field_theory.finite.basic
variables {F : Type*} [field F] [fintype F] [decidable_eq F] {p : ℕ} [char_p F p]
def is_quad_residue (a : F) : Prop := ∃ b, a = b^2
instance (a : F) : decidable (is_quad_residue a) := by { unfold is_quad_residue, apply_instance }
Yakov Pechersky (Jul 20 2021 at 14:52):
Just know that the decidable instance it generates is a brute force search over the entirety of F.
Adam Topaz (Jul 20 2021 at 14:54):
Yakov Pechersky said:
Just know that the decidable instance it generates is a brute force search over the entirety of F.
As it should be!
Adam Topaz (Jul 20 2021 at 14:58):
It would be fun to make a decidable instance based on quadratic reciprocity :wink:
David Wärn (Jul 20 2021 at 15:20):
Euler's criterion and exponentiation by squaring might be easier
Kevin Buzzard (Jul 20 2021 at 15:21):
My instinct is that the QR proof is faster?
Kevin Buzzard (Jul 20 2021 at 15:21):
Am I wrong?
Yakov Pechersky (Jul 20 2021 at 15:25):
One would have to be careful to use a binary_rec pow definition and not the unary one.
Kevin Buzzard (Jul 20 2021 at 15:28):
I guess the repeated squaring would work for finite fields other than Z/p
David Wärn (Jul 20 2021 at 16:52):
Euler's criterion is easier to prove correct, but mathlib probably has all the theory needed to prove correctness of the QR algorithm. Both algorithms are very fast (polynomial in number of digits), but I would also guess that QR is faster by some constant factor
Kevin Buzzard (Jul 20 2021 at 17:35):
One reason for doing this would be that there are fast primality tests which use this stuff -- they fail quickly for non-primes.
Bjørn Kjos-Hanssen (Apr 22 2022 at 01:16):
What exactly is the meaning of noncomputable
in Lean?
Mario Carneiro (Apr 22 2022 at 01:50):
not executable by the lean VM
Bjørn Kjos-Hanssen (Apr 22 2022 at 02:06):
That makes it sound like one day it may become executable...
Bjørn Kjos-Hanssen (Apr 22 2022 at 02:10):
And therefore become computable
Mario Carneiro (Apr 22 2022 at 03:04):
well sure, depending on what kind of evolution you have in mind
Mario Carneiro (Apr 22 2022 at 03:04):
you can rewrite a function to become computable
Mario Carneiro (Apr 22 2022 at 03:05):
#12301 is a recent example of exactly that
Mario Carneiro (Apr 22 2022 at 03:09):
in particular, just because a function is marked noncomputable
does not mean there is not an equal function which is computable
Mario Carneiro (Apr 22 2022 at 03:11):
noncomputable def foo : nat := classical.some (⟨37, rfl⟩ : ∃ x : nat, x = 37)
def bar : nat := 37
example : foo = bar := classical.some_spec (⟨37, rfl⟩ : ∃ x : nat, x = 37)
Mario Carneiro (Apr 22 2022 at 03:13):
Using noncomputable!
you can even force a computable definition to be noncomputable
def bar : nat := 37
noncomputable! def baz : nat := 37
example : bar = baz := rfl
Bjørn Kjos-Hanssen (Apr 22 2022 at 05:55):
Hmm so in particular, noncomputable means "Lean, don't try to compute a representation for this, just check whether it's logically correct"?
Eric Wieser (Apr 22 2022 at 06:00):
Usually it means "lean has told me it is unable to compute this"
Reid Barton (Apr 22 2022 at 11:37):
In practice it means that your function can't be run from a tactic
Last updated: Dec 20 2023 at 11:08 UTC