Zulip Chat Archive

Stream: new members

Topic: set ℕ and being decidable


Bjørn Kjos-Hanssen (Jan 25 2022 at 04:07):

I want to be able to say "either x is in K or not, so we split up into cases".
Here's a MWE of the obstacle:

axiom mwe (K: set ) : f:  ,  x:, f x =
(em (x  K)).by_cases
(λ h: x  K,  (0:))( λ h: x  K,  (0:))

The error is

failed to synthesize type class instance for K : set , f :   , x : 
 decidable (x  K)

Kyle Miller (Jan 25 2022 at 04:11):

Depending on what you're doing, you can have it take an additional argument [decidable_pred (∈ K)].

Kyle Miller (Jan 25 2022 at 04:12):

If this is inside a proof and you don't care about decidability, you can use tactic#classical to introduce the instances that come from the axiom of choice

Bjørn Kjos-Hanssen (Jan 25 2022 at 04:15):

Thanks @Kyle Miller I got the first suggestion to work. Any more detail on the second suggestion?

Kyle Miller (Jan 25 2022 at 04:18):

If you're in a tactic proof, you can do

begin
  classical,
  -- now every proposition has a `decidable` instance
  rest-of-proof
end

Bjørn Kjos-Hanssen (Jan 25 2022 at 04:20):

Is there a way when I'm not in tactic mode as well? :grinning:

Kyle Miller (Jan 25 2022 at 04:31):

I suppose you can jump in and out of tactic mode with by classical; exact ...expression...

Kyle Miller (Jan 25 2022 at 04:31):

Though there are other things you can do here, too. docs#classical.by_cases might be useful, though written as @classical.by_cases (x \in K) _ (case1) (case2)

Kyle Miller (Jan 25 2022 at 04:32):

You don't need the @ if you give each argument to each case a type, like you do in your MWE

Bjørn Kjos-Hanssen (Jan 25 2022 at 04:32):

Ah... does the @ do something special here?

Kyle Miller (Jan 25 2022 at 04:32):

It causes the two implicit arguments to become explicit

Kyle Miller (Jan 25 2022 at 04:33):

Oh, sorry, I didn't notice classical.by_cases was only for Prop-valued things.

Kyle Miller (Jan 25 2022 at 04:35):

@Bjørn Kjos-Hanssen Maybe this is duplicating something in the library and I didn't need to write it, but here:

noncomputable
def classical.by_cases' (p : Prop) {α : Sort*} (h1 : p  α) (h2 : ¬p  α) : α :=
by classical; exact if h : p then h1 h else h2 h

Kyle Miller (Jan 25 2022 at 04:36):

import tactic

noncomputable
def classical.by_cases' (p : Prop) {α : Sort*} (h1 : p  α) (h2 : ¬p  α) : α :=
by classical; exact if h : p then h1 h else h2 h

axiom mwe (K: set ) : f:  ,  x:, f x =
classical.by_cases' (x  K)
(λ h: x  K,  (0:))( λ h: x  K,  (0:))

Kyle Miller (Jan 25 2022 at 04:39):

And this is what that looks like when p is implicit, too:

import tactic

noncomputable
def classical.by_cases' {p : Prop} {α : Sort*} (h1 : p  α) (h2 : ¬p  α) : α :=
by classical; exact if h : p then h1 h else h2 h

axiom mwe (K: set ) : f:  ,  x:, f x =
classical.by_cases'
(λ h: x  K,  (0:))( λ h: x  K,  (0:))

Patrick Johnson (Jan 25 2022 at 04:49):

You may also want to try open_locale classical

Patrick Johnson (Jan 25 2022 at 05:09):

And you probably want to use if instead of (em (x ∈ K)).by_cases

axiom mwe {K : set } :
 (f :   ),  (x : ), f x = (if x  K then 0 else 0)

Bjørn Kjos-Hanssen (Jan 25 2022 at 05:33):

Thanks both, for the thorough answers :working_on_it:

Bjørn Kjos-Hanssen (Jan 26 2022 at 00:38):

This is probably obvious but if I use exists.elim to get my hands on such an f, how would I now derive f y = 0 if I have a proof of y \in K available?

Yakov Pechersky (Jan 26 2022 at 00:42):

Say "if h : y in K ... then _ else _"

Yakov Pechersky (Jan 26 2022 at 00:42):

Which is nice syntax for the underlying dependent if then else called docs#dite

Yakov Pechersky (Jan 26 2022 at 00:44):

Ah, I misunderstood. exists.elim isn't dependent, you lose that property. You retain it if you use exists.some though, with exists.some_spec holding the property

Bjørn Kjos-Hanssen (Jan 26 2022 at 00:48):

I think I'm just forgetting some basic: if we have (in pseudocode)

def f(x)= if p x then y else z

and we also have a proof h:p a then how do we prove that f a = y?

Yakov Pechersky (Jan 26 2022 at 00:48):

by rw [if_pos h]

Yakov Pechersky (Jan 26 2022 at 00:50):

You're also implying that at some point you got an a. So:

lemma blah (h : p a) : f a = y :=
begin
  rw [f, ite_apply, if_pos h]
end

Yakov Pechersky (Jan 26 2022 at 00:50):

Probably, term mode if_pos h will work, since it will be definitionally true

Bjørn Kjos-Hanssen (Jan 26 2022 at 00:55):

Sorry, actually it's more like I need

def f (x) := if h: p x then y h else z h

in other words the output of f depends on what the proof h is... and then want to use h to prove f a = y h.

Reid Barton (Jan 26 2022 at 00:56):

docs#dif_pos

Bjørn Kjos-Hanssen (Jan 26 2022 at 00:58):

Fantastic... although dif_pos seems like a highly unintuitive name here :yum:

Yakov Pechersky (Jan 26 2022 at 01:06):

ite -> if_pos, dite -> dif_pos

Yakov Pechersky (Jan 26 2022 at 01:07):

where d is for dependent


Last updated: Dec 20 2023 at 11:08 UTC