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 theinv
field is the same as the result of theExists.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_spec
s 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