Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import data.finsupp order.complete_lattice algebra.ordered_group data.mv_polynomial
- import algebra.order_functions
- namespace multiset
- variables {α : Type*} [decidable_eq α]
- def to_finsupp (s : multiset α) : α →₀ ℕ :=
- { support := s.to_finset,
- to_fun := λ a, s.count a,
- mem_support_to_fun := λ a,
- begin
- rw mem_to_finset,
- convert not_iff_not_of_iff (count_eq_zero.symm),
- rw not_not
- end }
- @[simp] lemma to_finsupp_support (s : multiset α) :
- s.to_finsupp.support = s.to_finset := rfl
- @[simp] lemma to_finsupp_apply (s : multiset α) (a : α) :
- s.to_finsupp a = s.count a := rfl
- @[simp] lemma to_finsupp_zero :
- to_finsupp (0 : multiset α) = 0 :=
- finsupp.ext $ λ a, count_zero a
- @[simp] lemma to_finsupp_add (s t : multiset α) :
- to_finsupp (s + t) = to_finsupp s + to_finsupp t :=
- finsupp.ext $ λ a, count_add a s t
- namespace to_finsupp
- instance : is_add_monoid_hom (to_finsupp : multiset α → α →₀ ℕ) :=
- { map_zero := to_finsupp_zero,
- map_add := to_finsupp_add }
- end to_finsupp
- @[simp] lemma to_finsupp_to_multiset (s : multiset α) :
- s.to_finsupp.to_multiset = s :=
- ext.2 $ λ a, by rw [finsupp.count_to_multiset, to_finsupp_apply]
- end multiset
- namespace finsupp
- variables {σ : Type*} {α : Type*} [decidable_eq σ]
- instance [preorder α] [has_zero α] : preorder (σ →₀ α) :=
- { le := λ f g, ∀ s, f s ≤ g s,
- le_refl := λ f s, le_refl _,
- le_trans := λ f g h Hfg Hgh s, le_trans (Hfg s) (Hgh s) }
- instance [partial_order α] [has_zero α] : partial_order (σ →₀ α) :=
- { le_antisymm := λ f g hfg hgf, finsupp.ext $ λ s, le_antisymm (hfg s) (hgf s),
- .. finsupp.preorder }
- instance [ordered_cancel_comm_monoid α] [decidable_eq α] :
- add_left_cancel_semigroup (σ →₀ α) :=
- { add_left_cancel := λ a b c h, finsupp.ext $ λ s,
- by { rw finsupp.ext_iff at h, exact add_left_cancel (h s) },
- .. finsupp.add_monoid }
- instance [ordered_cancel_comm_monoid α] [decidable_eq α] :
- add_right_cancel_semigroup (σ →₀ α) :=
- { add_right_cancel := λ a b c h, finsupp.ext $ λ s,
- by { rw finsupp.ext_iff at h, exact add_right_cancel (h s) },
- .. finsupp.add_monoid }
- instance [ordered_cancel_comm_monoid α] [decidable_eq α] :
- ordered_cancel_comm_monoid (σ →₀ α) :=
- { add_le_add_left := λ a b h c s, add_le_add_left (h s) (c s),
- le_of_add_le_add_left := λ a b c h s, le_of_add_le_add_left (h s),
- .. finsupp.add_comm_monoid, .. finsupp.partial_order,
- .. finsupp.add_left_cancel_semigroup, .. finsupp.add_right_cancel_semigroup }
- attribute [simp] to_multiset_zero to_multiset_add
- @[simp] lemma to_multiset_to_finsupp (f : σ →₀ ℕ) :
- f.to_multiset.to_finsupp = f :=
- ext $ λ s, by rw [multiset.to_finsupp_apply, count_to_multiset]
- def diagonal (f : σ →₀ ℕ) : finset ((σ →₀ ℕ) × (σ →₀ ℕ)) :=
- ((multiset.diagonal f.to_multiset).map (prod.map multiset.to_finsupp multiset.to_finsupp)).to_finset
- lemma mem_diagonal {f : σ →₀ ℕ} {p : (σ →₀ ℕ) × (σ →₀ ℕ)} :
- p ∈ diagonal f ↔ p.1 + p.2 = f :=
- begin
- erw [multiset.mem_to_finset, multiset.mem_map],
- split,
- { rintros ⟨⟨a, b⟩, h, rfl⟩,
- rw multiset.mem_diagonal at h,
- simpa using congr_arg multiset.to_finsupp h },
- { intro h,
- refine ⟨⟨p.1.to_multiset, p.2.to_multiset⟩, _, _⟩,
- { simpa using congr_arg to_multiset h },
- { rw [prod.map, to_multiset_to_finsupp, to_multiset_to_finsupp, prod.mk.eta] } }
- end
- lemma swap_mem_diagonal {n : σ →₀ ℕ} {f} (hf : f ∈ diagonal n) : f.swap ∈ diagonal n :=
- by simpa [mem_diagonal, add_comm] using hf
- @[simp] lemma diagonal_zero : diagonal (0 : σ →₀ ℕ) = {(0,0)} := rfl
- lemma to_multiset_strict_mono : strict_mono (@to_multiset σ _) :=
- λ m n h,
- begin
- rw lt_iff_le_and_ne at h ⊢, cases h with h₁ h₂,
- split,
- { rw multiset.le_iff_count, intro s, rw [count_to_multiset, count_to_multiset], exact h₁ s },
- { intro H, apply h₂, replace H := congr_arg multiset.to_finsupp H, simpa using H }
- end
- lemma sum_lt_of_lt (m n : σ →₀ ℕ) (h : m < n) :
- m.sum (λ _, id) < n.sum (λ _, id) :=
- begin
- rw [← card_to_multiset, ← card_to_multiset],
- apply multiset.card_lt_of_lt,
- exact to_multiset_strict_mono _ _ h
- end
- variable (σ)
- def lt_wf : well_founded (@has_lt.lt (σ →₀ ℕ) _) :=
- subrelation.wf (sum_lt_of_lt) $ inv_image.wf _ nat.lt_wf
- -- instance : has_well_founded (σ →₀ ℕ) :=
- -- { r := (<),
- -- wf := lt_wf σ }
- end finsupp
- /-- Multivariate power series, where `σ` is the index set of the variables
- and `α` is the coefficient ring.-/
- def mv_power_series (σ : Type*) (α : Type*) := (σ →₀ ℕ) → α
- namespace mv_power_series
- open finsupp
- variables {σ : Type*} {α : Type*} [decidable_eq σ]
- def coeff (n : σ →₀ ℕ) (φ : mv_power_series σ α) := φ n
- @[extensionality] lemma ext {φ ψ : mv_power_series σ α} (h : ∀ n, coeff n φ = coeff n ψ) : φ = ψ :=
- funext h
- lemma ext_iff {φ ψ : mv_power_series σ α} : φ = ψ ↔ (∀ n, coeff n φ = coeff n ψ) :=
- ⟨λ h n, congr_arg (coeff n) h, ext⟩
- variables [comm_semiring α]
- def monomial (n : σ →₀ ℕ) (a : α) : mv_power_series σ α := λ m, if m = n then a else 0
- lemma coeff_monomial (m n : σ →₀ ℕ) (a : α) :
- coeff m (monomial n a) = if m = n then a else 0 := rfl
- @[simp] lemma coeff_monomial' (n : σ →₀ ℕ) (a : α) :
- coeff n (monomial n a) = a := if_pos rfl
- def C (a : α) : mv_power_series σ α := monomial 0 a
- lemma coeff_C (n : σ →₀ ℕ) (a : α) :
- coeff n (C a : mv_power_series σ α) = if n = 0 then a else 0 := rfl
- @[simp] lemma coeff_C_zero (a : α) : coeff 0 (C a : mv_power_series σ α) = a :=
- coeff_monomial' 0 a
- @[simp] lemma monomial_zero (a : α) : (monomial 0 a : mv_power_series σ α) = C a := rfl
- def X (s : σ) : mv_power_series σ α := monomial (single s 1) 1
- lemma coeff_X (n : σ →₀ ℕ) (s : σ) :
- coeff n (X s : mv_power_series σ α) = if n = (single s 1) then 1 else 0 := rfl
- lemma coeff_X' (s t : σ) :
- coeff (single t 1) (X s : mv_power_series σ α) = if t = s then 1 else 0 :=
- if h : t = s then by simp [h, coeff_X] else
- begin
- rw [coeff_X, if_neg h],
- split_ifs with H,
- { have := @finsupp.single_apply σ ℕ _ _ _ t s 1,
- rw [if_neg h, H, finsupp.single_apply, if_pos rfl] at this,
- exfalso, exact one_ne_zero this, },
- { refl }
- end
- @[simp] lemma coeff_X'' (s : σ) :
- coeff (single s 1) (X s : mv_power_series σ α) = 1 :=
- by rw [coeff_X', if_pos rfl]
- section ring
- variables (σ) (α) (n : σ →₀ ℕ) (φ ψ : mv_power_series σ α)
- def zero : mv_power_series σ α := λ n, 0
- instance : has_zero (mv_power_series σ α) := ⟨zero σ α⟩
- @[simp] lemma coeff_zero : coeff n (0 : mv_power_series σ α) = 0 := rfl
- @[simp] lemma C_zero : (C 0 : mv_power_series σ α) = 0 :=
- ext $ λ n, if h : n = 0 then by simp [h] else by rw [coeff_C, if_neg h, coeff_zero]
- def one : mv_power_series σ α := C 1
- instance : has_one (mv_power_series σ α) := ⟨one σ α⟩
- @[simp] lemma coeff_one :
- coeff n (1 : mv_power_series σ α) = if n = 0 then 1 else 0 := rfl
- @[simp] lemma coeff_one_zero : coeff 0 (1 : mv_power_series σ α) = 1 :=
- coeff_C_zero 1
- @[simp] lemma C_one : (C 1 : mv_power_series σ α) = 1 := rfl
- def add (φ ψ : mv_power_series σ α) : mv_power_series σ α :=
- λ n, coeff n φ + coeff n ψ
- instance : has_add (mv_power_series σ α) := ⟨add σ α⟩
- variables {σ α}
- @[simp] lemma coeff_add : coeff n (φ + ψ) = coeff n φ + coeff n ψ := rfl
- @[simp] lemma zero_add : (0 : mv_power_series σ α) + φ = φ := ext $ λ n, zero_add _
- @[simp] lemma add_zero : φ + 0 = φ := ext $ λ n, add_zero _
- lemma add_comm : φ + ψ = ψ + φ := ext $ λ n, add_comm _ _
- lemma add_assoc (φ₁ φ₂ φ₃ : mv_power_series σ α) :
- (φ₁ + φ₂) + φ₃ = φ₁ + (φ₂ + φ₃) :=
- ext $ λ n, by simp
- @[simp] lemma monomial_add (n : σ →₀ ℕ) (a b : α) :
- (monomial n (a + b) : mv_power_series σ α) = monomial n a + monomial n b :=
- ext $ λ m, if h : m = n then by simp [h] else by simp [coeff_monomial, if_neg h]
- @[simp] lemma C_add (a b : α) : (C (a + b) : mv_power_series σ α) = C a + C b :=
- monomial_add 0 a b
- variables (σ α)
- def mul (φ ψ : mv_power_series σ α) : mv_power_series σ α :=
- λ n, (finsupp.diagonal n).sum (λ p, coeff p.1 φ * coeff p.2 ψ)
- instance : has_mul (mv_power_series σ α) := ⟨mul σ α⟩
- variables {σ α}
- lemma coeff_mul :
- coeff n (φ * ψ) = (finsupp.diagonal n).sum (λ p, coeff p.1 φ * coeff p.2 ψ) := rfl
- @[simp] lemma C_mul (a b : α) : (C (a * b) : mv_power_series σ α) = C a * C b :=
- ext $ λ n,
- begin
- rw [coeff_C, coeff_mul],
- split_ifs,
- { subst n, erw [diagonal_zero, finset.sum_singleton, coeff_C_zero, coeff_C_zero] },
- { rw finset.sum_eq_zero,
- rintros ⟨i,j⟩ hij,
- rw mem_diagonal at hij, rw [coeff_C, coeff_C],
- split_ifs; try {simp * at *; done} }
- end
- @[simp] lemma zero_mul : (0 : mv_power_series σ α) * φ = 0 :=
- ext $ λ n, by simp [coeff_mul]
- @[simp] lemma mul_zero : φ * 0 = 0 :=
- ext $ λ n, by simp [coeff_mul]
- lemma mul_comm : φ * ψ = ψ * φ :=
- ext $ λ n, finset.sum_bij (λ p hp, p.swap)
- (λ p hp, swap_mem_diagonal hp)
- (λ p hp, mul_comm _ _)
- (λ p q hp hq H, by simpa using congr_arg prod.swap H)
- (λ p hp, ⟨p.swap, swap_mem_diagonal hp, p.swap_swap.symm⟩)
- @[simp] lemma one_mul : (1 : mv_power_series σ α) * φ = φ :=
- ext $ λ n,
- begin
- have H : ((0 : σ →₀ ℕ), n) ∈ (diagonal n) := by simp [mem_diagonal],
- rw [coeff_mul, ← finset.insert_erase H, finset.sum_insert (finset.not_mem_erase _ _),
- coeff_one_zero, one_mul, finset.sum_eq_zero, _root_.add_zero],
- rintros ⟨i,j⟩ hij,
- rw [finset.mem_erase, mem_diagonal] at hij,
- rw [coeff_one, if_neg, _root_.zero_mul],
- intro H, apply hij.1, simp * at *
- end
- @[simp] lemma mul_one : φ * 1 = φ :=
- by rw [mul_comm, one_mul]
- lemma mul_add (φ₁ φ₂ φ₃ : mv_power_series σ α) :
- φ₁ * (φ₂ + φ₃) = φ₁ * φ₂ + φ₁ * φ₃ :=
- ext $ λ n, by simp only [coeff_mul, coeff_add, mul_add, finset.sum_add_distrib]
- lemma add_mul (φ₁ φ₂ φ₃ : mv_power_series σ α) :
- (φ₁ + φ₂) * φ₃ = φ₁ * φ₃ + φ₂ * φ₃ :=
- ext $ λ n, by simp only [coeff_mul, coeff_add, add_mul, finset.sum_add_distrib]
- lemma mul_assoc (φ₁ φ₂ φ₃ : mv_power_series σ α) :
- (φ₁ * φ₂) * φ₃ = φ₁ * (φ₂ * φ₃) :=
- ext $ λ n,
- begin
- simp only [coeff_mul],
- have := @finset.sum_sigma ((σ →₀ ℕ) × (σ →₀ ℕ)) α _ _ (diagonal n)
- (λ p, diagonal (p.1)) (λ x, coeff x.2.1 φ₁ * coeff x.2.2 φ₂ * coeff x.1.2 φ₃),
- convert this.symm using 1; clear this,
- { apply finset.sum_congr rfl,
- intros p hp, exact finset.sum_mul },
- have := @finset.sum_sigma ((σ →₀ ℕ) × (σ →₀ ℕ)) α _ _ (diagonal n)
- (λ p, diagonal (p.2)) (λ x, coeff x.1.1 φ₁ * (coeff x.2.1 φ₂ * coeff x.2.2 φ₃)),
- convert this.symm using 1; clear this,
- { apply finset.sum_congr rfl, intros p hp, rw finset.mul_sum },
- apply finset.sum_bij,
- swap 5,
- { rintros ⟨⟨i,j⟩, ⟨k,l⟩⟩ H, exact ⟨(k, l+j), (l, j)⟩ },
- { rintros ⟨⟨i,j⟩, ⟨k,l⟩⟩ H, simp only [finset.mem_sigma, mem_diagonal] at H ⊢, finish },
- { rintros ⟨⟨i,j⟩, ⟨k,l⟩⟩ H, rw mul_assoc },
- { rintros ⟨⟨a,b⟩, ⟨c,d⟩⟩ ⟨⟨i,j⟩, ⟨k,l⟩⟩ H₁ H₂,
- simp only [finset.mem_sigma, mem_diagonal,
- and_imp, prod.mk.inj_iff, add_comm, heq_iff_eq] at H₁ H₂ ⊢,
- finish },
- { rintros ⟨⟨i,j⟩, ⟨k,l⟩⟩ H, refine ⟨⟨(i+k, l), (i, k)⟩, _, _⟩;
- { simp only [finset.mem_sigma, mem_diagonal] at H ⊢, finish } }
- end
- instance : comm_semiring (mv_power_series σ α) :=
- { mul_one := mul_one,
- one_mul := one_mul,
- add_assoc := add_assoc,
- zero_add := zero_add,
- add_zero := add_zero,
- add_comm := add_comm,
- mul_assoc := mul_assoc,
- mul_zero := mul_zero,
- zero_mul := zero_mul,
- mul_comm := mul_comm,
- left_distrib := mul_add,
- right_distrib := add_mul,
- .. mv_power_series.has_zero σ α,
- .. mv_power_series.has_one σ α,
- .. mv_power_series.has_add σ α,
- .. mv_power_series.has_mul σ α }
- instance C.is_semiring_hom : is_semiring_hom (C : α → mv_power_series σ α) :=
- { map_zero := C_zero _ _,
- map_one := C_one _ _,
- map_add := C_add,
- map_mul := C_mul }
- instance coeff.is_add_monoid_hom : is_add_monoid_hom (coeff n : mv_power_series σ α → α) :=
- { map_zero := coeff_zero _ _ _,
- map_add := coeff_add n }
- instance : semimodule α (mv_power_series σ α) :=
- { smul := λ a φ, C a * φ,
- one_smul := λ φ, one_mul _,
- mul_smul := λ a b φ, by simp only [C_mul, mul_assoc],
- smul_add := λ a φ ψ, mul_add _ _ _,
- smul_zero := λ a, mul_zero _,
- add_smul := λ a b φ, by simp only [C_add, add_mul],
- zero_smul := λ φ, by simp only [zero_mul, C_zero] }
- end ring
- -- TODO(jmc): once adic topology lands, show that this is complete
- end mv_power_series
- namespace mv_power_series
- variables {σ : Type*} {α : Type*} [decidable_eq σ] [comm_ring α]
- protected def neg (φ : mv_power_series σ α) : mv_power_series σ α := λ n, - coeff n φ
- instance : has_neg (mv_power_series σ α) := ⟨mv_power_series.neg⟩
- @[simp] lemma coeff_neg (φ : mv_power_series σ α) (n) : coeff n (- φ) = - coeff n φ := rfl
- lemma add_left_neg (φ : mv_power_series σ α) : (-φ) + φ = 0 :=
- ext $ λ n, by rw [coeff_add, coeff_zero, coeff_neg, add_left_neg]
- instance : comm_ring (mv_power_series σ α) :=
- { add_left_neg := add_left_neg,
- .. mv_power_series.has_neg, .. mv_power_series.comm_semiring }
- instance C.is_ring_hom : is_ring_hom (C : α → mv_power_series σ α) :=
- { map_one := C_one _ _,
- map_add := C_add,
- map_mul := C_mul }
- instance coeff.is_add_group_hom (n : σ →₀ ℕ) :
- is_add_group_hom (coeff n : mv_power_series σ α → α) :=
- { map_add := coeff_add n }
- instance : module α (mv_power_series σ α) :=
- { ..mv_power_series.semimodule }
- def inv_of_unit (φ : mv_power_series σ α) (u : units α) (h : coeff 0 φ = u) : mv_power_series σ α
- | n := if n = 0 then ↑u⁻¹ else
- - ↑u⁻¹ * finset.sum (n.diagonal) (λ (x : (σ →₀ ℕ) × (σ →₀ ℕ)),
- if h : x.1 < n then inv_of_unit x.1 * coeff x.2 φ else 0)
- using_well_founded { rel_tac := λ _ _, `[exact ⟨_, finsupp.lt_wf σ⟩] }
- end mv_power_series
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement