Zulip Chat Archive

Stream: lean4

Topic: Getting values from an existential with a "let"


Mark Wilhelm (Feb 27 2023 at 19:43):

Is this the right syntax for breaking out the sub-parts of the existential?

def fn (h:  n: Nat, n + 1 = 2) : Nat :=
  let a, b := h
  123

it gives an error:

tactic 'cases' failed, nested error:
tactic 'induction' failed, recursor 'Exists.casesOn' can only eliminate into Prop
motive : ( n, n + 1 = 2)  Sort ?u.1347
h_1 : (a : Nat)  a + 1 = 2  motive (_ :  n, n + 1 = 2)
h :  n, n + 1 = 2
 motive h after processing
  _
the dependent pattern matcher can solve the following kinds of equations
- <var> = <term> and <term> = <var>
- <term> = <term> where the terms are definitionally equal
- <constructor> = <constructor>, examples: List.cons x xs = List.cons y ys, and List.cons x xs = List.nil

Ruben Van de Velde (Feb 27 2023 at 19:44):

Not in a def

Ruben Van de Velde (Feb 27 2023 at 19:45):

That would allow you to extract a witness, which would cause trouble

Mark Wilhelm (Feb 27 2023 at 19:46):

hm ok, so you can only do that in tactics then or something?

Ruben Van de Velde (Feb 27 2023 at 19:47):

You could do it in a theorem

Mark Wilhelm (Feb 27 2023 at 19:48):

ah ok that is what i need here, theorem instead of function, thank you

Kevin Buzzard (Feb 27 2023 at 22:44):

You can use classical.some but then your definition would be noncomputable

Eric Wieser (Feb 27 2023 at 22:47):

Note that the error you get is recursor 'Exists.casesOn' can only eliminate into Prop; your syntax is totally fine, but the type theory says "you can't produce data (aka not Prop) by taking apart an Exists".

Locria Cyber (Feb 28 2023 at 03:43):

I think you want Subtype

Jeremy Tan (Aug 24 2023 at 09:17):

@Eric Wieser I'm getting the same error when trying to follow @Oliver Nash's suggestion of moving #6648 to GroupTheory.OrderOfElement. But in defining the inverse I really need the n from the ((isOfFinOrder_iff_pow_eq_one x).1 hx) : ∃ n, 0 < n ∧ x ^ n = 1. Is there a way I can preserve computability?

abbrev IsOfFinOrder.groupPowers (hx : IsOfFinOrder x) : Group (Submonoid.powers x) where
  inv z := by
    obtain n, _ := ((isOfFinOrder_iff_pow_eq_one x).1 hx)
    exact z ^ (n - 1)
  ...

Oliver Nash (Aug 24 2023 at 09:22):

@Jeremy Tan don't worry about computability, we're doing classical maths. E.g., use Classical.choose if you need it.

Jeremy Tan (Aug 24 2023 at 09:39):

But then I'm getting another headache.

open Submonoid in
/-- The submonoid generated by an element is a group if that element has finite order. -/
noncomputable abbrev IsOfFinOrder.groupPowers (hx : IsOfFinOrder x) : Group (powers x) where
  inv z := z ^ (((isOfFinOrder_iff_pow_eq_one x).1 hx).choose - 1)
  mul_left_inv y := Subtype.ext <| by
    obtain _, k, rfl := y
    simp only [coe_one, coe_mul, SubmonoidClass.coe_pow]
    -- here
    rw [ _root_.pow_succ', Nat.sub_add_cancel hpos,  pow_mul, mul_comm, pow_mul, hx, one_pow]

The goal state at the comment is

G: Type u_1
H: Type u_2
A: Type u_3
α: Type u_4
β: Type u_5
inst✝¹: Monoid G
inst: AddMonoid A
xy: G
ab: A
nm: 
hx: IsOfFinOrder x
k: 
 (x ^ k) ^ (Exists.choose (_ :  n, 0 < n  x ^ n = 1) - 1) * x ^ k = 1

I want to ensure that the noncomputably-chosen n in the inv field is the same as the result of the Exists.choose in this goal. How would that go?

Jeremy Tan (Aug 24 2023 at 09:45):

@Oliver Nash I'm really feeling that even with classical logic porting the abbrev to GroupTheory.OrderOfElement is simply impossible

Mario Carneiro (Aug 24 2023 at 09:46):

Don't use obtain, just apply Exists.choose and Exists.choose_spec directly

Mario Carneiro (Aug 24 2023 at 09:48):

actually maybe it's fine, but you are missing ((isOfFinOrder_iff_pow_eq_one x).1 hx).choose_spec in the proof

Mario Carneiro (Aug 24 2023 at 09:50):

I want to ensure that the noncomputably-chosen n in the inv field is the same as the result of the Exists.choose in this goal. How would that go?

This sentence is a bit confusing to me because the noncomputably-chosen n in the inv field is the Exists.choose in that goal

Mario Carneiro (Aug 24 2023 at 09:53):

I would be inclined to revert this definition to the original version, with

abbrev groupOfPowers {x : M} {n : } (hpos : 0 < n) (hx : x ^ n = 1) : Group (powers x) where

and then define

noncomputable abbrev IsOfFinOrder.groupPowers (hx : IsOfFinOrder x) : Group (powers x) where

by using choose to select the n and then call the other function

Mario Carneiro (Aug 24 2023 at 09:54):

because different witnesses yield different groups, at least as defined here

Jeremy Tan (Aug 24 2023 at 10:03):

@Mario Carneiro I managed to complete the move anyway

Jeremy Tan (Aug 24 2023 at 10:04):

It looks a bit uglier with all the choose_specs though

Eric Wieser (Aug 24 2023 at 10:18):

Oliver Nash said:

Jeremy Tan don't worry about computability, we're doing classical maths. E.g., use Classical.choose if you need it.

I don't agree with this. Since it costs almost nothing, I think we should split this into two definitions:

  • A computable one that takes n explicitly
  • A non-computable one that takes IsOfFinOrder x

Eric Wieser (Aug 24 2023 at 10:19):

The former is pretty much just a subexpression of the latter

Oliver Nash (Aug 24 2023 at 10:19):

I have no objection to making this split, though of course I stand by my original remark :-)

Eric Wieser (Aug 24 2023 at 10:22):

Oh, I now see Mario made exactly the same comment as me

Jeremy Tan (Aug 24 2023 at 10:49):

@Eric Wieser I responded to your comment about the abstruseness of the computable abbrev


Last updated: Dec 20 2023 at 11:08 UTC