Zulip Chat Archive

Stream: new members

Topic: How prove things about Exists.choose terms?


Scott Carnahan (Aug 22 2023 at 15:38):

I am stuck on the following theorem:

import Mathlib.Data.Nat.Factorial.Basic
import Mathlib.Data.Polynomial.Eval
import Mathlib.RingTheory.Polynomial.Pochhammer

class BinomialSemiring (R: Type _) extends Semiring R where
  /-- Multiplication by factorials is injective -/
  inj_smul_factorial :  (n:) (r s: R), n.factorial * r = n.factorial * s  r = s
  /-- All Pochhammer evaluations are divisible by the suitable factorials -/
  exist_binomial_coeffs :  (r:R) (n:),  (x:R), n.factorial * x = Polynomial.eval r (pochhammer R n)

open Classical

noncomputable def multichoose {R:Type _} [BinomialSemiring R] (r:R) :   R :=
  λ n  (BinomialSemiring.exist_binomial_coeffs r n).choose

theorem factorial_mul_multichoose_eq_pochhammer [BinomialSemiring R] (r:R) (n:) : n.factorial * multichoose r n = Polynomial.eval r (pochhammer R n) := by
    sorry

If I use unfold multichoose I get the goal ↑(Nat.factorial n) * Exists.choose (_ : ∃ x, ↑(Nat.factorial n) * x = Polynomial.eval r (pochhammer R n)) = Polynomial.eval r (pochhammer R n) and I don't know how to collapse the left side.

Ruben Van de Velde (Aug 22 2023 at 15:41):

Does docs#Exists.choose_spec help?

Kevin Buzzard (Aug 22 2023 at 15:43):

theorem factorial_mul_multichoose_eq_pochhammer {R:Type _} [BinomialSemiring R]
    (r:R) (n:) : n.factorial * multichoose r n = Polynomial.eval r (pochhammer R n) :=
  (BinomialSemiring.exist_binomial_coeffs r n).choose_spec

Kevin Buzzard (Aug 22 2023 at 15:44):

The only thing you know about the output of Exists.choose is Exists.choose_spec. Even if you proved the exists statement with "let x=37 and now show that this works" Lean forgets that x=37 (because this showed up in a proof).

Scott Carnahan (Aug 22 2023 at 15:48):

It worked! Thank you very much.

Junyan Xu (Aug 23 2023 at 22:23):

In mathlib the usual practice would be defining this class with fields

multichoose : R    R
factorial_mul_multichoose :  n : ,  r, n.factorial * multichoose r n = (pochhammer R n).eval r

Scott Carnahan (Aug 24 2023 at 01:38):

@Junyan Xu Should that code go in the part with class BinomialSemiring ?

Scott Carnahan (Aug 24 2023 at 01:51):

Okay, I see now. That is quite nice, since it gets rid of the non-computable part.

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

Junyan Xu said:

In mathlib the usual practice would be defining this class with fields

To elaborate a little more: if there's a _unique_ choice of multichoose, then you'd use the above. If there's no unique choice, then the noncomputable version might still be preferred


Last updated: Dec 20 2023 at 11:08 UTC