Zulip Chat Archive

Stream: maths

Topic: constructive zerology


Patrick Massot (Jul 17 2018 at 14:59):

@Kenny Lau I have a question for you. Do you have a proof without decidable or classical of:

lemma closure_empty_iff {α : Type*} [topological_space α] [decidable_eq (set α)] (s : set α) :
closure s =   s =  :=
begin
  split ; intro h,
  { by_contradiction h',
    cases set.not_eq_empty_iff_exists.1 h' with _ H,
    simpa [h] using subset_closure H },
  { exact (eq.symm h)  closure_empty },
end

Reid Barton (Jul 17 2018 at 15:06):

Use set.eq_empty_iff_forall_not_mem instead I think

Kenny Lau (Jul 17 2018 at 15:11):

for this case, contradiction is intuitionistically valid

Patrick Massot (Jul 17 2018 at 15:12):

Thanks Reid!

Patrick Massot (Jul 17 2018 at 15:12):

lemma closure_empty_iff {α : Type*} [topological_space α] (s : set α) :
closure s =   s =  :=
begin
  split ; intro h,
  { rw set.eq_empty_iff_forall_not_mem,
    intros x H,
    simpa [h] using subset_closure H },
  { exact (eq.symm h)  closure_empty },
end

Patrick Massot (Jul 17 2018 at 15:14):

I'm very slowly working towards proving that the Hausdorff completion of a uniform space X is nonempty unless X is empty. This is no fun at all.

Patrick Massot (Jul 17 2018 at 15:24):

I can feel the dreaded spiral where I'm upset something is not obvious to Lean and I'm proving more and more stupid lemmas instead of cooling down and figure out what I exactly need

Patrick Massot (Jul 17 2018 at 15:32):

I need a break. If anyone here is bored and loves zerology, I think I may need proofs of:

lemma nonempty_iff_univ {α : Type*} : nonempty α  (univ : set α)   :=
sorry

lemma nonempty_of_nonempty_range {α : Type*} {β : Type*} {f : α  β} (H : ¬range f = ) : nonempty α :=
sorry

Kevin Buzzard (Jul 17 2018 at 15:42):

What am I allowed to use?

Kevin Buzzard (Jul 17 2018 at 15:43):

Excluded middle?

Kevin Buzzard (Jul 17 2018 at 15:43):

Or nothing like this?

Patrick Massot (Jul 17 2018 at 15:45):

Of course I don't care. Again, the goal is to prove the completion is empty only if the original space is empty. And this is only needed to implement Mario's trick allowing to totalize the function "lift to completion" so that any function from a uniform space to a complete Hausdorff space lifts, the lift being garbage is the function is not uniformly continuous.

Patrick Massot (Jul 17 2018 at 15:47):

But at some point we hope to put all this into mathlib, so it would be nicer to avoid unnecessary decidability assumption or classical logic

Kevin Buzzard (Jul 17 2018 at 15:49):

nonempty needs data for its constructor, and (univ : set α) ≠ ∅ is only a proposition

Patrick Massot (Jul 17 2018 at 15:49):

You can have a look at https://github.com/PatrickMassot/lean-perfectoid-spaces/blob/completions/src/for_mathlib/completion.lean to see where I stand

Patrick Massot (Jul 17 2018 at 15:49):

Mario style lifting is defined at https://github.com/PatrickMassot/lean-perfectoid-spaces/blob/completions/src/for_mathlib/completion.lean#L124

Kevin Buzzard (Jul 17 2018 at 15:50):

For the first one you need something like ¬ (∀ a : α, false) → ∃ a : α, true

Patrick Massot (Jul 17 2018 at 15:50):

Maybe I should use inhabited instead of nonempty

Chris Hughes (Jul 17 2018 at 15:51):

Assuming α is nonempty, the assumption decidable_eq (set α) implies decidability of all propositions

Patrick Massot (Jul 17 2018 at 15:51):

Or maybe this is too much trouble, given that I already have a working lift for uniformly continuous functions

Patrick Massot (Jul 17 2018 at 15:52):

I'm upset because none of this has any mathematical content

Kevin Buzzard (Jul 17 2018 at 15:58):

lemma nonempty_iff_univ {α : Type*} : nonempty α  (univ : set α)   :=
begin
  split,
  { intro H,
    cases H with a,
    intro H2,
    show ( : set α) a,
    rw H2,
    trivial
  },
  intro H,
  apply classical.by_contradiction,
  intro H2,
  apply H,
  funext,
  exfalso,
  apply H2,
  exact a
end

Mario Carneiro (Jul 17 2018 at 16:07):

I used many of these same theorems in the proof of dense_embedding.extend

Mario Carneiro (Jul 17 2018 at 16:08):

for the most part I just brute forced through all of it, using exists_mem_of_ne_empty to get elements out of nonempty sets

Mario Carneiro (Jul 17 2018 at 16:08):

and using mem_closure_iff to get a nonempty set from a closure

Kevin Buzzard (Jul 17 2018 at 16:21):

lemma nonempty_of_nonempty_range {α : Type*} {β : Type*} {f : α  β} (H : ¬range f = ) : nonempty α :=
begin
  apply classical.by_contradiction,
  intro H2,
  apply H,
  unfold range,
  funext,
  apply propext,
  show ( y : α, f y = x)  false,
  split,swap,exact false.elim,
  intro H3,cases H3 with a Ha,
  apply H2,
  exact a
end

Kevin Buzzard (Jul 17 2018 at 16:21):

What's the hurry :-)

Mario Carneiro (Jul 17 2018 at 16:22):

not so cleaned up:

lemma nonempty_completion_iff : nonempty (completion α) ↔ nonempty α :=
begin
  split,
  { rintro ⟨c⟩,
    have := eq_univ_iff_forall.1 (to_completion.dense α) c,
    have := mem_closure_iff.1 this _ is_open_univ trivial,
    rcases exists_mem_of_ne_empty this with ⟨_, ⟨_, a, _⟩⟩,
    exact ⟨a⟩ },
  { rintro ⟨a⟩,
    exact ⟨to_completion α a⟩ }
end

Patrick Massot (Jul 17 2018 at 16:22):

Many thanks to both of you!

Patrick Massot (Jul 17 2018 at 16:23):

In the mean time I saw Kevin's first lemma proof and then found some courage to write:

lemma nonempty_of_nonempty_range {α : Type*} {β : Type*} {f : α  β} (H : ¬range f = ) : nonempty α :=
begin
  cases exists_mem_of_ne_empty H with x h,
  cases mem_range.1 h with y _,
  exact y
end

Kevin Buzzard (Jul 17 2018 at 16:24):

I don't know any of these lemmas which people are using :-)

Patrick Massot (Jul 17 2018 at 16:24):

I find them using lots of suffering

Patrick Massot (Jul 17 2018 at 16:24):

But now I need to understand Mario's proof

Kevin Buzzard (Jul 17 2018 at 16:25):

I never quite know whether I should somehow attempt to learn exactly what is in mathlib and where it all is

Kevin Buzzard (Jul 17 2018 at 16:25):

I'm doing a lot of work with multisets at the minute for a student, and now I really know my way around multiset.lean

Kevin Buzzard (Jul 17 2018 at 16:26):

but I don't know my way around data.set.basic in that way

Mario Carneiro (Jul 17 2018 at 16:27):

It's worth a perusal (data.set.lattice is the other important one)

Mario Carneiro (Jul 17 2018 at 16:28):

but ideally you should be able to guess beforehand what is in there

Patrick Massot (Jul 17 2018 at 16:28):

rintro ⟨c⟩ is already a nice trick

Patrick Massot (Jul 17 2018 at 16:29):

But then I'm not sure this isn't too efficient. Don't you think closure_empty_iff should be in mathlib anyway?

Kevin Buzzard (Jul 17 2018 at 16:30):

I hope rintro isn't as slow as rsimp

Patrick Massot (Jul 17 2018 at 16:30):

Never noticed any slowness there

Patrick Massot (Jul 17 2018 at 16:32):

If you don't fear rcases then you don't fear rintro

Patrick Massot (Jul 17 2018 at 16:33):

and, together, they really make a difference in conciseness, without obfuscation (it's all about unpacking stuff that our mind would unpack unconsciously)

Patrick Massot (Jul 17 2018 at 16:41):

Mario, I tried to use your trick in https://github.com/PatrickMassot/lean-perfectoid-spaces/blob/completions/src/for_mathlib/completion.lean#L124 but I needed to assume uniform continuity of f is decidable. Now I want to state lemmas assuming uniform continuity, but Lean asks me for an instance of decidable (uniform_continuous f). Did I do it wrong? What should I do?

Mario Carneiro (Jul 17 2018 at 16:42):

since that proof uses only structural tactics, I would normally compress it into a term proof

Patrick Massot (Jul 17 2018 at 16:43):

which proof?

Mario Carneiro (Jul 17 2018 at 16:44):

the one I gave

Mario Carneiro (Jul 17 2018 at 16:45):

you should have local instance prop_decidable

Patrick Massot (Jul 17 2018 at 16:46):

Oh I will happily add that if you don't tell me this will be an issue when trying to get all this into mathlib

Patrick Massot (Jul 17 2018 at 16:47):

My original version (with unique exists!) had no such assumption, but if course it makes no difference to me

Mario Carneiro (Jul 17 2018 at 16:48):

of course cases on uniform continuity is firmly classical, but we are not working in the constructive fragment here

Patrick Massot (Jul 17 2018 at 16:50):

Nice. I should be able to move on tonight. But right now I'm too hungry, I need diner.

Patrick Massot (Jul 17 2018 at 16:50):

Thanks!

Mario Carneiro (Jul 17 2018 at 16:57):

totalizing functions often requires classical axioms

Patrick Massot (Jul 17 2018 at 20:12):

I'm done totalizing. Now I'm back exactly where I was yesterday except that, in uniform_space.completion_lift f, f is now a function rather than a proof that a function is uniformly continuous. In particular fonctoriality now reads completion_lift (g ∘ f) = (completion_lift g) ∘ completion_lift f, as it should

Patrick Massot (Jul 17 2018 at 20:13):

All this for the cheap price of a few hours and a local attribute [instance] classical.prop_decidable

Patrick Massot (Jul 17 2018 at 20:14):

And I can see wisdom is coming to Kenny. He didn't write anything about that last classical detail.


Last updated: Dec 20 2023 at 11:08 UTC