Zulip Chat Archive

Stream: general

Topic: golf challenge


Kenny Lau (Jan 29 2019 at 09:15):

import data.equiv.basic data.polynomial linear_algebra.multivariate_polynomial

universes u v w

namespace mv_polynomial

variables (α : Type u) (β : Type v) [comm_ring α] [decidable_eq α] [decidable_eq β]

def option_ring_equiv_aux11 : α  polynomial (mv_polynomial β α) :=
polynomial.C  C

instance option_ring_equiv_aux12 : ring (polynomial (mv_polynomial β α)) :=
@comm_ring.to_ring _ $ polynomial.comm_ring

instance option_ring_equiv_aux13 : is_ring_hom (polynomial.C : mv_polynomial β α  polynomial (mv_polynomial β α)) :=
by apply polynomial.C.is_ring_hom

instance option_ring_equiv_aux14 : is_ring_hom (option_ring_equiv_aux11 α β) :=
is_ring_hom.comp _ _

instance option_ring_equiv_aux15 : is_semiring_hom (option_ring_equiv_aux11 α β) :=
is_ring_hom.is_semiring_hom _

def option_ring_equiv_aux1 : mv_polynomial (option β) α  polynomial (mv_polynomial β α) :=
eval₂ (option_ring_equiv_aux11 α β) (λ x, option.rec_on x polynomial.X (polynomial.C  X))

def option_ring_equiv_aux21 : mv_polynomial β α  mv_polynomial (option β) α :=
eval₂ C (X  some)

instance option_ring_equiv_aux22 : is_ring_hom (option_ring_equiv_aux21 α β) :=
by convert eval₂.is_ring_hom _ _; apply_instance

instance option_ring_equiv_aux23 : is_semiring_hom (option_ring_equiv_aux21 α β) :=
is_ring_hom.is_semiring_hom _

def option_ring_equiv_aux2 : polynomial (mv_polynomial β α)  mv_polynomial (option β) α :=
polynomial.eval₂ (option_ring_equiv_aux21 α β) (X none)

variables {α β}
set_option class.instance_max_depth 5
theorem option_ring_equiv_aux3 (f : mv_polynomial (option β) α) : option_ring_equiv_aux2 α β (option_ring_equiv_aux1 α β f) = f :=
induction_on f
  (λ r, calc option_ring_equiv_aux2 α β (option_ring_equiv_aux1 α β (C r))
           = option_ring_equiv_aux2 α β (option_ring_equiv_aux11 α β r) : by congr' 1; convert eval₂_C _ _ _; convert mv_polynomial.option_ring_equiv_aux15 α β
       ... = option_ring_equiv_aux21 α β (C r) : by convert polynomial.eval₂_C _ _; apply_instance
       ... = C r : by convert eval₂_C _ _ _; apply_instance)
  sorry
  sorry

end mv_polynomial

Kenny Lau (Jan 29 2019 at 09:15):

challenge: shorten this code, but keep the compiling time low

Kenny Lau (Jan 29 2019 at 09:16):

(yes, the set_option class.instance_max_depth 5 line is there to keep the compiling time low)

Kenny Lau (Jan 29 2019 at 09:16):

@Johannes Hölzl

Kenny Lau (Jan 29 2019 at 12:31):

@Chris Hughes

Johannes Hölzl (Jan 30 2019 at 15:18):

@Kenny Lau I think we have a problem either with the ring homomorphisms, or some of the mv_polynomial instances... I changed the proof to mv_polynomial (β ⊕ γ) α ≃r mv_polynomial β (mv_polynomial γ α), allowing also the symmetric variant.

Kenny Lau (Jan 30 2019 at 15:19):

are you planning to put this into mathlib? I'm about to prove the same theorem

Johannes Hölzl (Jan 30 2019 at 15:20):

its already in master

Johannes Hölzl (Jan 30 2019 at 15:20):

https://github.com/leanprover/mathlib/commit/f7b9d6b43e478661eb87fef36c75e8e4ffc08499

Kenny Lau (Jan 30 2019 at 15:20):

oh nice!

Johan Commelin (Jan 30 2019 at 15:23):

Aah, using rename we might be able to slightly cleanup the mv_polynomial adjunction that I PR'd a while ago.

Kenny Lau (Jul 02 2020 at 08:59):

import data.polynomial

universes u

open polynomial
open_locale classical

lemma nat_degree_le_nat_degree {R : Type u} [semiring R] {f g : polynomial R}
  (hfg : f.degree  g.degree) : f.nat_degree  g.nat_degree :=
begin
  by_cases hf : f = 0, { rw [hf, nat_degree_zero], exact zero_le _ },
  by_cases hg : g = 0, { rw [hg, degree_zero, le_bot_iff, degree_eq_bot] at hfg, cc },
  rwa [degree_eq_nat_degree hf, degree_eq_nat_degree hg, with_bot.coe_le_coe] at hfg
end

theorem nat_degree_div_by_monic {R : Type u} [comm_ring R] (f : polynomial R) {g : polynomial R}
  (hg : g.monic) : nat_degree (f / g) = nat_degree f - nat_degree g :=
begin
  by_cases h01 : (0 : R) = 1,
  { haveI := subsingleton_of_zero_eq_one h01,
    rw [subsingleton.elim (f / g) 0, subsingleton.elim f 0, subsingleton.elim g 0,
        nat_degree_zero] },
  haveI : nonzero R := h01,
  by_cases hfg : f / g = 0,
  { rw [hfg, nat_degree_zero], rw div_by_monic_eq_zero_iff hg hg.ne_zero at hfg,
    rw nat.sub_eq_zero_of_le (nat_degree_le_nat_degree $ le_of_lt hfg) },
  have hgf := hfg, rw div_by_monic_eq_zero_iff hg hg.ne_zero at hgf, push_neg at hgf,
  have := degree_add_div_by_monic hg hgf,
  have hf : f  0, { intro hf, apply hfg, rw [hf, zero_div_by_monic] },
  rw [degree_eq_nat_degree hf, degree_eq_nat_degree hg.ne_zero, degree_eq_nat_degree hfg,
       with_bot.coe_add, with_bot.coe_eq_coe] at this,
  rw [ this, nat.add_sub_cancel_left]
end

Kenny Lau (Jul 10 2020 at 11:39):

import data.mv_polynomial
import linear_algebra.determinant

universes u v

variables (n : Type u) [fintype n] [decidable_eq n]

noncomputable def det_poly : mv_polynomial (n × n)  :=
matrix.det $ λ i j : n, mv_polynomial.X (i, j)

variables {n} {R : Type v} [comm_ring R] (M : matrix n n R)

theorem eval_det_poly : (det_poly n).eval₂ coe (λ p, M p.1 p.2) = M.det :=
sorry

Kenny Lau (Jul 10 2020 at 11:40):

golf challenge

Reid Barton (Jul 10 2020 at 11:41):

https://github.com/rwbarton/swan/blob/lean-3.4.2/src/for_mathlib/determinant.lean

Kenny Lau (Jul 10 2020 at 11:41):

lol

Reid Barton (Jul 10 2020 at 11:43):

It might use simp lemmas that weren't in mathlib at the time

Kenny Lau (Jul 10 2020 at 12:01):

my solution:

import data.mv_polynomial
import linear_algebra.determinant

universes u v

variables (n : Type u) [fintype n] [decidable_eq n]

noncomputable def det_poly : mv_polynomial (n × n)  :=
matrix.det $ λ i j : n, mv_polynomial.X (i, j)

variables {n} {R : Type v} [comm_ring R] (M : matrix n n R)

namespace mv_polynomial

theorem eval₂_int_cast {α β σ : Type*} [comm_ring α] [comm_ring β]
  (f : α  β) (g : σ  β) [is_ring_hom f] (n : ) :
  (n : mv_polynomial σ α).eval₂ f g = n :=
int.induction_on n (eval₂_zero f g)
  (λ i ih, by rw [int.cast_add, int.cast_add, int.cast_one, int.cast_one, eval₂_add, ih, eval₂_one])
  (λ i ih, by rw [int.cast_sub, int.cast_sub, int.cast_one, int.cast_one, eval₂_sub, ih, eval₂_one])

end mv_polynomial

open mv_polynomial

theorem eval_det_poly : (det_poly n).eval₂ coe (λ p, M p.1 p.2) = M.det :=
begin
  unfold det_poly matrix.det,
  haveI : is_semiring_hom (coe :   R) := int.cast_zero, int.cast_one, int.cast_add, int.cast_mul,
  haveI : is_ring_hom (coe :   R) := is_ring_hom.of_semiring _,
  simp_rw [eval₂_sum, eval₂_mul, eval₂_int_cast, eval₂_prod, eval₂_X]
end

Johan Commelin (Jul 10 2020 at 12:02):

Dont we know that eval2 is a ring hom?

Johan Commelin (Jul 10 2020 at 12:06):

I would expect something like (eval2_hom f g).map_int_cast n as proof term.

Reid Barton (Jul 10 2020 at 12:06):

like this? https://github.com/rwbarton/swan/blob/lean-3.4.2/src/for_mathlib/ring_hom_coe.lean

Reid Barton (Jul 10 2020 at 12:06):

but this is from ye olden days of 2019

Johan Commelin (Jul 10 2020 at 12:13):

Is it planned to get this stuff into mathlib?

Johan Commelin (Jul 10 2020 at 12:13):

Zulip lacks :swan:...

Reid Barton (Jul 10 2020 at 12:14):

this is about all the stuff there is here

Kenny Lau (Jul 10 2020 at 13:33):

if only mv_polynomial were computable

Kenny Lau (Jul 10 2020 at 13:33):

then we can have explicit formulas of determinants easily

Johan Commelin (Jul 10 2020 at 13:33):

simp should be able to make it easy nonetheless.


Last updated: Dec 20 2023 at 11:08 UTC