Zulip Chat Archive

Stream: mathlib4

Topic: avoid expansion of class fields


Filippo A. E. Nuccio (Nov 02 2023 at 09:46):

What is the lean4 equivalent of the .. when defining a term of a certain class? Consider the following

import Mathlib.RingTheory.DiscreteValuationRing.Basic

example (A : Type) [CommRing A] [IsDomain A] [IsPrincipalIdealRing A] [LocalRing A]
  (h : LocalRing.maximalIdeal A  ) : DiscreteValuationRing A :=

If I put a _ and hover on the bulb and ask to generate skeleton for the structure under construction I get

example (A : Type) [CommRing A] [IsDomain A] [IsPrincipalIdealRing A] [LocalRing A]
  (h : LocalRing.maximalIdeal A  ) : DiscreteValuationRing A where
    principal := _
    exists_pair_ne := _
    isUnit_or_isUnit_of_add_one := _
    not_a_field' := _

Now, DiscreteValuationRing is defined as

class DiscreteValuationRing (R : Type u) [CommRing R] [IsDomain R]
    extends IsPrincipalIdealRing R, LocalRing R : Prop where
  not_a_field' : maximalIdeal R  

and principal is the name of the constructor for IsPrincipalIdealRing, hence the first field. Now, LocalRing in itself extends Nontrivial (whose constructor is exists_pair_ne) and has isUnit_or_isUnit_of_add_one as the other constructor: of course I can find them by destructuring my term LocalRing A, but I would like to be able to remove the two constructors

    exists_pair_ne := _
    isUnit_or_isUnit_of_add_one := _

and simply pass a term of type LocalRing A (found by infer_instance). What is the syntax?

Eric Wieser (Nov 02 2023 at 09:50):

Are you asking what the equivalent of Lean 3's {foo := _, ..bar} is? It's { bar with foo := _ }, or if using where, __ := bar

Filippo A. E. Nuccio (Nov 02 2023 at 09:52):

So this should be like this?

example (A : Type) [CommRing A] [IsDomain A] [IsPrincipalIdealRing A] [LocalRing A]
  (h : LocalRing.maximalIdeal A  ) : DiscreteValuationRing A where
    principal := sorry
    not_a_field' := sorry
   _ _ := by infer_instance

Floris van Doorn (Nov 02 2023 at 09:53):

I expect you want to remove the space between the two _

Filippo A. E. Nuccio (Nov 02 2023 at 09:53):

Ah! Let me try.

Filippo A. E. Nuccio (Nov 02 2023 at 10:01):

Ok, thanks @Eric Wieser and @Floris van Doorn ! It basically works, in the sense (but this was probably the same in Lean3) that it cannot really guess what __ is (and understandably so), so

example (A : Type) [CommRing A] [IsDomain A] [IsPrincipalIdealRing A] [LocalRing A]
  (h : LocalRing.maximalIdeal A  ) : DiscreteValuationRing A where
    principal := by infer_instance
    not_a_field' := h
    __  := by infer_instance

gives a problem in the last line (it has no clue of what to look for), but

example (A : Type) [CommRing A] [IsDomain A] [IsPrincipalIdealRing A] [LocalRing A]
  (h : LocalRing.maximalIdeal A  ) : DiscreteValuationRing A where
    principal := by infer_instance
    not_a_field' := h
    __ : LocalRing A := by infer_instance

is OK. The other option is to explicitly name the term LocalRing A:

example (A : Type) [CommRing A] [IsDomain A] [IsPrincipalIdealRing A] [hA : LocalRing A]
  (h : LocalRing.maximalIdeal A  ) : DiscreteValuationRing A where
    principal := by infer_instance
    not_a_field' := h
    __ := hA

Is there a mathlib preference between the previous two solutions?

Eric Wieser (Nov 02 2023 at 10:02):

Huh, I didn't even know that __ : LocalRing A := by infer_instance was legal!

Eric Wieser (Nov 02 2023 at 10:03):

I'm used to seeing __ := inferInstanceAs <| LocalRing A, but I think __ : LocalRing A := inferInstance is probably best

Eric Wieser (Nov 02 2023 at 10:04):

__ : LocalRing A := ‹_› would also work here, but that doesn't work in general

Filippo A. E. Nuccio (Nov 02 2023 at 10:04):

Right! But at any rate you discourage naming the term LocalRing A to call it explicitely, right?


Last updated: Dec 20 2023 at 11:08 UTC