Zulip Chat Archive

Stream: general

Topic: characteristic of fields


Kenny Lau (Oct 16 2018 at 18:54):

@Mario Carneiro @Johan Commelin @Kevin Buzzard how should we define the char of a field?

Mario Carneiro (Oct 16 2018 at 18:55):

I think your definition should be on semirings instead of zero/one/mul classes

Mario Carneiro (Oct 16 2018 at 18:57):

I guess it could be on rings, since a nonzero characteristic semiring is a ring

Chris Hughes (Oct 16 2018 at 18:57):

Should it be a class or just a Prop?

Mario Carneiro (Oct 16 2018 at 18:57):

a prop, it is a prop

Mario Carneiro (Oct 16 2018 at 18:57):

oh wait you aren't asking about char_p

Kenny Lau (Oct 16 2018 at 18:58):

both

Chris Hughes (Oct 16 2018 at 18:58):

I'm asking about char.

Kenny Lau (Oct 16 2018 at 18:58):

I'm asking about this thing in general

Kenny Lau (Oct 16 2018 at 18:58):

how did metamath / other languages deal with this?

Kenny Lau (Oct 16 2018 at 18:58):

and is char(Q) 0 or 1?

Mario Carneiro (Oct 16 2018 at 18:59):

char(Q) is 0

Kenny Lau (Oct 16 2018 at 18:59):

in where?

Mario Carneiro (Oct 16 2018 at 18:59):

in metamath

Mario Carneiro (Oct 16 2018 at 18:59):

and in math

Kenny Lau (Oct 16 2018 at 18:59):

but how is char defined?

Kenny Lau (Oct 16 2018 at 18:59):

I feel like there's 1,000,000 subtleties

Mario Carneiro (Oct 16 2018 at 19:00):

the order of 1

Kenny Lau (Oct 16 2018 at 19:00):

how is order defined?

Chris Hughes (Oct 16 2018 at 19:00):

We don't have order_of on non finite groups

Mario Carneiro (Oct 16 2018 at 19:00):

and the order of a group element is the smallest nonzero power of the element that is 1

Mario Carneiro (Oct 16 2018 at 19:01):

or 0 if it doesn't exist

Kenny Lau (Oct 16 2018 at 19:01):

so that's a def not a prop?

Kenny Lau (Oct 16 2018 at 19:01):

ok I don't like this

Mario Carneiro (Oct 16 2018 at 19:01):

metamath doesn't care about computability tho

Kenny Lau (Oct 16 2018 at 19:01):

do we have another approach?

Mario Carneiro (Oct 16 2018 at 19:01):

there is a computable definition yielding a roption nat

Mario Carneiro (Oct 16 2018 at 19:02):

and if we define get_or_else for roption then we can make it 0 otherwise

Kenny Lau (Oct 16 2018 at 19:03):

would it be usable?

Mario Carneiro (Oct 16 2018 at 19:04):

I am a fan of roption definitions; it would give you a relational interface

Mario Carneiro (Oct 16 2018 at 19:04):

p \in char R

Kevin Buzzard (Oct 16 2018 at 19:05):

The characteristic of a ring is the kernel of the canonical ring homomorphism from the integers to the ring.

Mario Carneiro (Oct 16 2018 at 19:05):

there is also the ideal option

Kenny Lau (Oct 16 2018 at 19:05):

The characteristic of a ring is the kernel of the canonical ring homomorphism from the integers to the ring.

next

Kevin Buzzard (Oct 16 2018 at 19:05):

That's the best definition.

Mario Carneiro (Oct 16 2018 at 19:05):

that's just restating x^n = 0 though

Mario Carneiro (Oct 16 2018 at 19:06):

maybe a better question is not what is the characteristic but what is it for

Mario Carneiro (Oct 16 2018 at 19:07):

We have PID defined, right? Is it constructive exists?

Kenny Lau (Oct 16 2018 at 19:07):

class is_principal_ideal (S : set α) : Prop :=
(principal :  a : α, S = {x | a  x})

class principal_ideal_domain (α : Type*) extends integral_domain α :=
(principal :  (S : set α) [is_ideal S], is_principal_ideal S)

Kenny Lau (Oct 16 2018 at 19:07):

yes

Mario Carneiro (Oct 16 2018 at 19:07):

well no

Kevin Buzzard (Oct 16 2018 at 19:07):

That looks right to me. Is Mario asking about whether there's a function from ideals to generators though?

Mario Carneiro (Oct 16 2018 at 19:08):

yeah

Kevin Buzzard (Oct 16 2018 at 19:08):

A maths PID is what Kenny just quoted.

Mario Carneiro (Oct 16 2018 at 19:08):

I guess there is no constructive proof that Z is a PID then?

Kevin Buzzard (Oct 16 2018 at 19:08):

Of course the notion of PID was not invented by constructivists.

Kenny Lau (Oct 16 2018 at 19:08):

nothing involving arbitrary sets can be constructive

Kevin Buzzard (Oct 16 2018 at 19:08):

History is written by the victors

Mario Carneiro (Oct 16 2018 at 19:09):

that's not exactly true kenny, it's possible that the ideal structure can be leveraged to give a generator

Kevin Buzzard (Oct 16 2018 at 19:09):

I guess there is no constructive proof that Z is a PID then?

The standard proof in textbooks ("if the ideal is zero then done, if not then choose the smallest positive integer") is constructive.

Mario Carneiro (Oct 16 2018 at 19:10):

well, constructive with LEM

Kenny Lau (Oct 16 2018 at 19:10):

you can't decide if the ideal is zero

Mario Carneiro (Oct 16 2018 at 19:10):

you can't determine if an arbitrary ideal is zero

Kevin Buzzard (Oct 16 2018 at 19:10):

In Z??

Mario Carneiro (Oct 16 2018 at 19:10):

that's exactly the problem with defining characteristic

Kenny Lau (Oct 16 2018 at 19:10):

give me an algorithm

Mario Carneiro (Oct 16 2018 at 19:11):

the set of periods of an element is an ideal of Z

Mario Carneiro (Oct 16 2018 at 19:11):

but you can't tell if it is zero

Kevin Buzzard (Oct 16 2018 at 19:11):

I'm not going to talk about this any more. It's silly.

Mario Carneiro (Oct 16 2018 at 19:11):

I think we have our answer Kenny

Kevin Buzzard (Oct 16 2018 at 19:11):

:-)

Mario Carneiro (Oct 16 2018 at 19:11):

totalize it

Kenny Lau (Oct 16 2018 at 19:12):

could you summarize the answer?

Kevin Buzzard (Oct 16 2018 at 19:12):

Are you going to assume LEM?

Mario Carneiro (Oct 16 2018 at 19:12):

char Q = 0

Mario Carneiro (Oct 16 2018 at 19:12):

noncomputable

Mario Carneiro (Oct 16 2018 at 19:12):

live with it

Kenny Lau (Oct 16 2018 at 19:12):

no roption?

Mario Carneiro (Oct 16 2018 at 19:12):

if you insist, you can define char' A : roption nat

Mario Carneiro (Oct 16 2018 at 19:13):

and define char in terms of it

Mario Carneiro (Oct 16 2018 at 19:13):

but most of the theory will be about char

Kenny Lau (Oct 16 2018 at 19:13):

it won't be a class then

Patrick Massot (Oct 16 2018 at 19:13):

kenny_char : roption Prop (because who knows?)

Mario Carneiro (Oct 16 2018 at 19:13):

also, char is a type

Kenny Lau (Oct 16 2018 at 19:13):

but every ring has a unique char

Mario Carneiro (Oct 16 2018 at 19:13):

characters

Mario Carneiro (Oct 16 2018 at 19:14):

there is also the ideal definition, dunno how useful it is but that's constructive too

Patrick Massot (Oct 16 2018 at 19:14):

Let's write it in French then! car

Kenny Lau (Oct 16 2018 at 19:14):

I mean, it's useful to make "char A = p" into a class

Mario Carneiro (Oct 16 2018 at 19:14):

I agree on that

Mario Carneiro (Oct 16 2018 at 19:14):

char_p is fine and unproblematic

Kenny Lau (Oct 16 2018 at 19:14):

oh ok

Reid Barton (Oct 16 2018 at 19:14):

but every ring has a unique char

isn't this not true constructively? or am I really confused

Mario Carneiro (Oct 16 2018 at 19:15):

no, that's true

Kenny Lau (Oct 16 2018 at 19:15):

I'm talking about the reason to make it into a typeclass

Mario Carneiro (Oct 16 2018 at 19:15):

if a ring has two characteristics then they are equal

Kenny Lau (Oct 16 2018 at 19:15):

class char_p (α : Type u) [has_zero α] [has_one α] [has_add α] (p : ) : Prop :=
(cast_eq_zero : (p:α) = 0)

Do we all agree that this definition is deficit?

Reid Barton (Oct 16 2018 at 19:15):

It's the "has" part I am worried about

Reid Barton (Oct 16 2018 at 19:16):

I agree "unique" is okay.

Mario Carneiro (Oct 16 2018 at 19:16):

no you can't prove existence of a characteristic (number) in general without LEM

Mario Carneiro (Oct 16 2018 at 19:16):

the ideal is fine of course

Reid Barton (Oct 16 2018 at 19:16):

right, okay

Reid Barton (Oct 16 2018 at 19:25):

I guess there is no constructive proof that Z is a PID then?

I think you can even prove constructively that "Z is a PID" => LEM

Reid Barton (Oct 16 2018 at 19:26):

by taking a proposition P and defining the ideal I = {x | x = 0 \/ P}

Reid Barton (Oct 16 2018 at 19:26):

and then looking at whether its generator is zero or not

Kenny Lau (Oct 16 2018 at 19:29):

class char_p (α : Type u) [semiring α] (p : ) : Prop :=
(cast_eq_zero_iff :  x:, (x:α) = 0  p  x)

Kenny Lau (Oct 16 2018 at 19:29):

how about this

Kenny Lau (Oct 16 2018 at 19:31):

class char_p (α : Type u) [semiring α] (p : ) : Prop :=
(cast_eq_zero_iff :  x:, (x:α) = 0  p  x)

theorem char_p.cast_eq_zero {α : Type u} [semiring α] {p : } [char_p α p] : (p:α) = 0 :=
(char_p.cast_eq_zero_iff α p p).2 (dvd_refl p)

theorem char_p.eq (α : Type u) [semiring α] (p q : ) [char_p α p] [char_p α q] : p = q :=
nat.dvd_antisymm
  ((char_p.cast_eq_zero_iff α p q).1 char_p.cast_eq_zero)
  ((char_p.cast_eq_zero_iff α q p).1 char_p.cast_eq_zero)

Kenny Lau (Oct 16 2018 at 19:33):

I think your definition should be on semirings instead of zero/one/mul classes

but char_zero is defined on [add_monoid \a] [has_one \a]?

Mario Carneiro (Oct 16 2018 at 19:43):

or that

Kenny Lau (Oct 16 2018 at 19:45):

existe uma diferencia?

Kenny Lau (Oct 16 2018 at 20:06):

class char_p (α : Type u) [semiring α] (p : ) : Prop :=
(cast_eq_zero_iff :  x:, (x:α) = 0  p  x)

theorem char_p.cast_eq_zero (α : Type u) [semiring α] (p : ) [char_p α p] : (p:α) = 0 :=
(char_p.cast_eq_zero_iff α p p).2 (dvd_refl p)

theorem char_p.eq (α : Type u) [semiring α] (p q : ) [char_p α p] [char_p α q] : p = q :=
nat.dvd_antisymm
  ((char_p.cast_eq_zero_iff α p q).1 (char_p.cast_eq_zero _ _))
  ((char_p.cast_eq_zero_iff α q p).1 (char_p.cast_eq_zero _ _))

instance char_p.of_char_zero (α : Type u) [semiring α] [char_zero α] : char_p α 0 :=
⟨λ x, by rw [zero_dvd_iff,  nat.cast_zero, nat.cast_inj]

theorem char_p.exists (α : Type u) [semiring α] :  p, char_p α p :=
by letI := classical.dec_eq α; exact
classical.by_cases
  (assume H :  p:, (p:α) = 0  p = 0, 0,
    ⟨λ x, by rw [zero_dvd_iff]; exact H x, by rintro rfl; refl⟩⟩⟩)
  (λ H, nat.find (classical.not_forall.1 H), ⟨λ x,
    ⟨λ H1, nat.dvd_of_mod_eq_zero (by_contradiction $ λ H2,
      nat.find_min (classical.not_forall.1 H)
        (nat.mod_lt x $ nat.pos_of_ne_zero $ not_of_not_imp $
          nat.find_spec (classical.not_forall.1 H))
        (not_imp_of_and_not by rwa [ nat.mod_add_div x (nat.find (classical.not_forall.1 H)),
          nat.cast_add, nat.cast_mul, of_not_not (not_not_of_not_imp $ nat.find_spec (classical.not_forall.1 H)),
          zero_mul, add_zero] at H1, H2)),
    λ H1, by rw [ nat.mul_div_cancel' H1, nat.cast_mul,
      of_not_not (not_not_of_not_imp $ nat.find_spec (classical.not_forall.1 H)), zero_mul]⟩⟩⟩)

theorem char_p.exists_unique (α : Type u) [semiring α] : ∃! p, char_p α p :=
let c, H := char_p.exists α in
c, H, λ y H2, by resetI; apply char_p.eq α

Kenny Lau (Oct 16 2018 at 20:06):

How does this look? @Mario Carneiro @Patrick Massot

Kenny Lau (Oct 16 2018 at 20:06):

@Kevin Buzzard

Kevin Buzzard (Oct 16 2018 at 20:08):

class char_p (α : Type u) [semiring α] (p : ) : Prop :=
(cast_eq_zero_iff :  x:, (x:α) = 0  p  x)

I see you went for the ideal idea after all ;-)

Mario Carneiro (Oct 16 2018 at 20:08):

char_p.eq should definitely not have square brackets

Kevin Buzzard (Oct 16 2018 at 20:09):

is_char_p?

Mario Carneiro (Oct 16 2018 at 20:10):

Maybe it should be a property of Z, then you can literally say is_ideal (char_p A)

Kenny Lau (Oct 16 2018 at 20:16):

wait I'm confused

Kenny Lau (Oct 16 2018 at 20:16):

theorem char_p.eq (α : Type u) [semiring α] (p q : ) (c1 : char_p α p) (c2 : char_p α q) : p = q :=
nat.dvd_antisymm
  ((char_p.cast_eq_zero_iff α p q).1 (char_p.cast_eq_zero _ _))
  ((char_p.cast_eq_zero_iff α q p).1 (char_p.cast_eq_zero _ _))

Kenny Lau (Oct 16 2018 at 20:16):

how can the proof still work now that I turned [] to ()?

Mario Carneiro (Oct 16 2018 at 20:17):

maybe kevin knows... I told him the solution to this puzzle a few weeks ago

Kenny Lau (Oct 16 2018 at 20:17):

anyway how is this now?

class char_p (α : Type u) [semiring α] (p : ) : Prop :=
(cast_eq_zero_iff :  x:, (x:α) = 0  p  x)

theorem char_p.cast_eq_zero (α : Type u) [semiring α] (p : ) [char_p α p] : (p:α) = 0 :=
(char_p.cast_eq_zero_iff α p p).2 (dvd_refl p)

theorem char_p.eq (α : Type u) [semiring α] {p q : } (c1 : char_p α p) (c2 : char_p α q) : p = q :=
nat.dvd_antisymm
  ((char_p.cast_eq_zero_iff α p q).1 (char_p.cast_eq_zero _ _))
  ((char_p.cast_eq_zero_iff α q p).1 (char_p.cast_eq_zero _ _))

instance char_p.of_char_zero (α : Type u) [semiring α] [char_zero α] : char_p α 0 :=
⟨λ x, by rw [zero_dvd_iff,  nat.cast_zero, nat.cast_inj]

theorem char_p.exists (α : Type u) [semiring α] :  p, char_p α p :=
by letI := classical.dec_eq α; exact
classical.by_cases
  (assume H :  p:, (p:α) = 0  p = 0, 0,
    ⟨λ x, by rw [zero_dvd_iff]; exact H x, by rintro rfl; refl⟩⟩⟩)
  (λ H, nat.find (classical.not_forall.1 H), ⟨λ x,
    ⟨λ H1, nat.dvd_of_mod_eq_zero (by_contradiction $ λ H2,
      nat.find_min (classical.not_forall.1 H)
        (nat.mod_lt x $ nat.pos_of_ne_zero $ not_of_not_imp $
          nat.find_spec (classical.not_forall.1 H))
        (not_imp_of_and_not by rwa [ nat.mod_add_div x (nat.find (classical.not_forall.1 H)),
          nat.cast_add, nat.cast_mul, of_not_not (not_not_of_not_imp $ nat.find_spec (classical.not_forall.1 H)),
          zero_mul, add_zero] at H1, H2)),
    λ H1, by rw [ nat.mul_div_cancel' H1, nat.cast_mul,
      of_not_not (not_not_of_not_imp $ nat.find_spec (classical.not_forall.1 H)), zero_mul]⟩⟩⟩)

theorem char_p.exists_unique (α : Type u) [semiring α] : ∃! p, char_p α p :=
let c, H := char_p.exists α in
c, H, λ y H2, char_p.eq α H2 H

Mario Carneiro (Oct 16 2018 at 20:18):

char_p.exists should be defining a function... called char

Kenny Lau (Oct 16 2018 at 20:18):

we can functionize that

Kevin Buzzard (Oct 16 2018 at 20:19):

He told Johannes too.

Kenny Lau (Oct 16 2018 at 20:19):

invalid definition, a declaration named 'char' has already been declared

Kenny Lau (Oct 16 2018 at 20:19):

hard luck

Kenny Lau (Oct 16 2018 at 20:24):

noncomputable def ring_char (α : Type u) [semiring α] :  :=
classical.some (char_p.exists_unique α)

theorem ring_char.spec (α : Type u) [semiring α] :  x:, (x:α) = 0  ring_char α  x :=
by letI := (classical.some_spec (char_p.exists_unique α)).1;
unfold ring_char; exact char_p.cast_eq_zero_iff α (ring_char α)

theorem ring_char.eq (α : Type u) [semiring α] {p : } (C : char_p α p) : p = ring_char α :=
(classical.some_spec (char_p.exists_unique α)).2 p C

Kenny Lau (Oct 16 2018 at 20:24):

how is this?

Kevin Buzzard (Oct 16 2018 at 20:34):

how can the proof still work now that I turned [] to ()?

Type class inference just grabs anything it can find to the left of the colon. The round and square brackets are just for the signature of the theorem, they don't affect how type class inference works in the proof. This is not so well-known because it's not common to put a typeclass left of the colon and not in a square bracket.

Kevin Buzzard (Oct 16 2018 at 20:34):

I discovered it a few weeks ago when I was trying to understand Patrick's type class hell with his completions and had exactly the same reaction.

Kevin Buzzard (Oct 16 2018 at 20:35):

I've had to construct that argument from memory because my search for the conversation failed. Hopefully it's some sort of approximation to the truth.

Bryan Gin-ge Chen (Oct 16 2018 at 20:40):

I guess it's this conversation? I found it by searching for "left of colon".

Kenny Lau (Oct 16 2018 at 20:42):

@Mario Carneiro Could you help me with some typeclass problems? It's in L324 here: https://github.com/kckennylau/Lean/blob/master/perfect_closure.lean#L324

Kenny Lau (Oct 16 2018 at 20:42):

Lean can't figure out the coercion in (↑x : perfect_closure α p)

Kevin Buzzard (Oct 16 2018 at 20:43):

https://leanprover.zulipchat.com/#narrow/stream/116395-maths/subject/Separation.20stuff/near/134261591

Kevin Buzzard (Oct 16 2018 at 20:43):

You owe Mario a light bulb

Kenny Lau (Oct 16 2018 at 20:44):

done

Kevin Buzzard (Oct 16 2018 at 20:44):

(thanks Bryan)

Kenny Lau (Oct 16 2018 at 20:53):

@Mario Carneiro never mind it's stupid


Last updated: Dec 20 2023 at 11:08 UTC