/-
Copyright (c) 2022 Eric Wieser. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Eric Wieser

! This file was ported from Lean 3 source module data.multiset.interval
! leanprover-community/mathlib commit 23aa88e32dcc9d2a24cca7bc23268567ed4cd7d6
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathbin.Data.Finset.LocallyFinite
import Mathbin.Data.Dfinsupp.Interval
import Mathbin.Data.Dfinsupp.Multiset
import Mathbin.Data.Nat.Interval

/-!
# Finite intervals of multisets

> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
> Any changes to this file require a corresponding PR to mathlib4.

This file provides the `locally_finite_order` instance for `multiset α` and calculates the
cardinality of its finite intervals.

## Implementation notes

We implement the intervals via the intervals on `dfinsupp`, rather than via filtering
`multiset.powerset`; this is because `(multiset.replicate n x).powerset` has `2^n` entries not `n+1`
entries as it contains duplicates. We do not go via `finsupp` as this would be noncomputable, and
multisets are typically used computationally.

-/

open Finset Dfinsupp Function

open BigOperators Pointwise

variable {α : Type _} {β : α → Type _}

namespace Multiset

variable [DecidableEq α] (f g : Multiset α)

instance : LocallyFiniteOrder (Multiset α) :=
  LocallyFiniteOrder.ofIcc (Multiset α)
    (fun f g =>
      (Finset.Icc f.toDfinsupp g.toDfinsupp).map Multiset.equivDfinsupp.toEquiv.symm.toEmbedding)
    fun f g x => by simp

/- warning: multiset.Icc_eq -> Multiset.Icc_eq is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (f : Multiset.{u1} α) (g : Multiset.{u1} α), Eq.{succ u1} (Finset.{u1} (Multiset.{u1} α)) (Finset.Icc.{u1} (Multiset.{u1} α) (PartialOrder.toPreorder.{u1} (Multiset.{u1} α) (Multiset.partialOrder.{u1} α)) (Multiset.locallyFiniteOrder.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) f g) (Finset.map.{u1, u1} (Dfinsupp.{u1, 0} α (fun (a : α) => Nat) (fun (i : α) => Nat.hasZero)) (Multiset.{u1} α) (Equiv.toEmbedding.{succ u1, succ u1} (Dfinsupp.{u1, 0} α (fun (a : α) => Nat) (fun (i : α) => Nat.hasZero)) (Multiset.{u1} α) (Equiv.symm.{succ u1, succ u1} (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (a : α) => Nat) (fun (i : α) => Nat.hasZero)) (AddEquiv.toEquiv.{u1, u1} (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (a : α) => Nat) (fun (i : α) => Nat.hasZero)) (Multiset.hasAdd.{u1} α) (AddZeroClass.toHasAdd.{u1} (Dfinsupp.{u1, 0} α (fun (a : α) => Nat) (fun (i : α) => Nat.hasZero)) (Dfinsupp.addZeroClass'.{u1, 0} α Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid))) (Multiset.equivDfinsupp.{u1} α (fun (a : α) (b : α) => _inst_1 a b))))) (Finset.Icc.{u1} (Dfinsupp.{u1, 0} α (fun (a : α) => Nat) (fun (i : α) => Nat.hasZero)) (Dfinsupp.preorder.{u1, 0} α (fun (a : α) => Nat) (fun (i : α) => Nat.hasZero) (fun (i : α) => PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring)))) (Dfinsupp.locallyFiniteOrder.{u1, 0} α (fun (a : α) => Nat) (fun (a : α) (b : α) => _inst_1 a b) (fun (i : α) (a : Nat) (b : Nat) => Nat.decidableEq a b) (fun (i : α) => OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring)) (fun (i : α) => Nat.hasZero) (fun (i : α) => Nat.locallyFiniteOrder)) (coeFn.{succ u1, succ u1} (AddMonoidHom.{u1, u1} (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (a : α) => Nat) (fun (i : α) => Nat.hasZero)) (AddMonoid.toAddZeroClass.{u1} (Multiset.{u1} α) (AddRightCancelMonoid.toAddMonoid.{u1} (Multiset.{u1} α) (AddCancelMonoid.toAddRightCancelMonoid.{u1} (Multiset.{u1} α) (AddCancelCommMonoid.toAddCancelMonoid.{u1} (Multiset.{u1} α) (OrderedCancelAddCommMonoid.toCancelAddCommMonoid.{u1} (Multiset.{u1} α) (Multiset.orderedCancelAddCommMonoid.{u1} α)))))) (Dfinsupp.addZeroClass'.{u1, 0} α Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid))) (fun (_x : AddMonoidHom.{u1, u1} (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (a : α) => Nat) (fun (i : α) => Nat.hasZero)) (AddMonoid.toAddZeroClass.{u1} (Multiset.{u1} α) (AddRightCancelMonoid.toAddMonoid.{u1} (Multiset.{u1} α) (AddCancelMonoid.toAddRightCancelMonoid.{u1} (Multiset.{u1} α) (AddCancelCommMonoid.toAddCancelMonoid.{u1} (Multiset.{u1} α) (OrderedCancelAddCommMonoid.toCancelAddCommMonoid.{u1} (Multiset.{u1} α) (Multiset.orderedCancelAddCommMonoid.{u1} α)))))) (Dfinsupp.addZeroClass'.{u1, 0} α Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid))) => (Multiset.{u1} α) -> (Dfinsupp.{u1, 0} α (fun (a : α) => Nat) (fun (i : α) => Nat.hasZero))) (AddMonoidHom.hasCoeToFun.{u1, u1} (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (a : α) => Nat) (fun (i : α) => Nat.hasZero)) (AddMonoid.toAddZeroClass.{u1} (Multiset.{u1} α) (AddRightCancelMonoid.toAddMonoid.{u1} (Multiset.{u1} α) (AddCancelMonoid.toAddRightCancelMonoid.{u1} (Multiset.{u1} α) (AddCancelCommMonoid.toAddCancelMonoid.{u1} (Multiset.{u1} α) (OrderedCancelAddCommMonoid.toCancelAddCommMonoid.{u1} (Multiset.{u1} α) (Multiset.orderedCancelAddCommMonoid.{u1} α)))))) (Dfinsupp.addZeroClass'.{u1, 0} α Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid))) (Multiset.toDfinsupp.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) f) (coeFn.{succ u1, succ u1} (AddMonoidHom.{u1, u1} (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (a : α) => Nat) (fun (i : α) => Nat.hasZero)) (AddMonoid.toAddZeroClass.{u1} (Multiset.{u1} α) (AddRightCancelMonoid.toAddMonoid.{u1} (Multiset.{u1} α) (AddCancelMonoid.toAddRightCancelMonoid.{u1} (Multiset.{u1} α) (AddCancelCommMonoid.toAddCancelMonoid.{u1} (Multiset.{u1} α) (OrderedCancelAddCommMonoid.toCancelAddCommMonoid.{u1} (Multiset.{u1} α) (Multiset.orderedCancelAddCommMonoid.{u1} α)))))) (Dfinsupp.addZeroClass'.{u1, 0} α Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid))) (fun (_x : AddMonoidHom.{u1, u1} (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (a : α) => Nat) (fun (i : α) => Nat.hasZero)) (AddMonoid.toAddZeroClass.{u1} (Multiset.{u1} α) (AddRightCancelMonoid.toAddMonoid.{u1} (Multiset.{u1} α) (AddCancelMonoid.toAddRightCancelMonoid.{u1} (Multiset.{u1} α) (AddCancelCommMonoid.toAddCancelMonoid.{u1} (Multiset.{u1} α) (OrderedCancelAddCommMonoid.toCancelAddCommMonoid.{u1} (Multiset.{u1} α) (Multiset.orderedCancelAddCommMonoid.{u1} α)))))) (Dfinsupp.addZeroClass'.{u1, 0} α Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid))) => (Multiset.{u1} α) -> (Dfinsupp.{u1, 0} α (fun (a : α) => Nat) (fun (i : α) => Nat.hasZero))) (AddMonoidHom.hasCoeToFun.{u1, u1} (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (a : α) => Nat) (fun (i : α) => Nat.hasZero)) (AddMonoid.toAddZeroClass.{u1} (Multiset.{u1} α) (AddRightCancelMonoid.toAddMonoid.{u1} (Multiset.{u1} α) (AddCancelMonoid.toAddRightCancelMonoid.{u1} (Multiset.{u1} α) (AddCancelCommMonoid.toAddCancelMonoid.{u1} (Multiset.{u1} α) (OrderedCancelAddCommMonoid.toCancelAddCommMonoid.{u1} (Multiset.{u1} α) (Multiset.orderedCancelAddCommMonoid.{u1} α)))))) (Dfinsupp.addZeroClass'.{u1, 0} α Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid))) (Multiset.toDfinsupp.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) g)))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (f : Multiset.{u1} α) (g : Multiset.{u1} α), Eq.{succ u1} (Finset.{u1} (Multiset.{u1} α)) (Finset.Icc.{u1} (Multiset.{u1} α) (PartialOrder.toPreorder.{u1} (Multiset.{u1} α) (Multiset.instPartialOrderMultiset.{u1} α)) (Multiset.instLocallyFiniteOrderMultisetToPreorderInstPartialOrderMultiset.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) f g) (Finset.map.{u1, u1} (Dfinsupp.{u1, 0} α (fun (a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero)) (Multiset.{u1} α) (Equiv.toEmbedding.{succ u1, succ u1} (Dfinsupp.{u1, 0} α (fun (a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero)) (Multiset.{u1} α) (Equiv.symm.{succ u1, succ u1} (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero)) (AddEquiv.toEquiv.{u1, u1} (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero)) (Multiset.instAddMultiset.{u1} α) (Dfinsupp.instAddDfinsuppToZero.{u1, 0} α (fun (_a : α) => Nat) (fun (i : α) => AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid)) (Multiset.equivDfinsupp.{u1} α (fun (a : α) (b : α) => _inst_1 a b))))) (Finset.Icc.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.403 : Multiset.{u1} α) => Dfinsupp.{u1, 0} α (fun (_a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero)) f) (Dfinsupp.instPreorderDfinsupp.{u1, 0} α (fun (a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero) (fun (i : α) => PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring))) (Dfinsupp.instLocallyFiniteOrderDfinsuppInstPreorderDfinsuppToPreorder.{u1, 0} α (fun (a : α) => Nat) (fun (a : α) (b : α) => _inst_1 a b) (fun (i : α) (a : Nat) (b : Nat) => instDecidableEqNat a b) (fun (i : α) => StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero) (fun (i : α) => instLocallyFiniteOrderNatToPreorderToPartialOrderStrictOrderedSemiring)) (FunLike.coe.{succ u1, succ u1, succ u1} (AddMonoidHom.{u1, u1} (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (_a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero)) (AddMonoid.toAddZeroClass.{u1} (Multiset.{u1} α) (AddRightCancelMonoid.toAddMonoid.{u1} (Multiset.{u1} α) (AddCancelMonoid.toAddRightCancelMonoid.{u1} (Multiset.{u1} α) (AddCancelCommMonoid.toAddCancelMonoid.{u1} (Multiset.{u1} α) (OrderedCancelAddCommMonoid.toCancelAddCommMonoid.{u1} (Multiset.{u1} α) (Multiset.instOrderedCancelAddCommMonoidMultiset.{u1} α)))))) (Dfinsupp.addZeroClass'.{u1, 0} α Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid))) (Multiset.{u1} α) (fun (_x : Multiset.{u1} α) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.403 : Multiset.{u1} α) => Dfinsupp.{u1, 0} α (fun (_a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero)) _x) (AddHomClass.toFunLike.{u1, u1, u1} (AddMonoidHom.{u1, u1} (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (_a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero)) (AddMonoid.toAddZeroClass.{u1} (Multiset.{u1} α) (AddRightCancelMonoid.toAddMonoid.{u1} (Multiset.{u1} α) (AddCancelMonoid.toAddRightCancelMonoid.{u1} (Multiset.{u1} α) (AddCancelCommMonoid.toAddCancelMonoid.{u1} (Multiset.{u1} α) (OrderedCancelAddCommMonoid.toCancelAddCommMonoid.{u1} (Multiset.{u1} α) (Multiset.instOrderedCancelAddCommMonoidMultiset.{u1} α)))))) (Dfinsupp.addZeroClass'.{u1, 0} α Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid))) (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (_a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero)) (AddZeroClass.toAdd.{u1} (Multiset.{u1} α) (AddMonoid.toAddZeroClass.{u1} (Multiset.{u1} α) (AddRightCancelMonoid.toAddMonoid.{u1} (Multiset.{u1} α) (AddCancelMonoid.toAddRightCancelMonoid.{u1} (Multiset.{u1} α) (AddCancelCommMonoid.toAddCancelMonoid.{u1} (Multiset.{u1} α) (OrderedCancelAddCommMonoid.toCancelAddCommMonoid.{u1} (Multiset.{u1} α) (Multiset.instOrderedCancelAddCommMonoidMultiset.{u1} α))))))) (AddZeroClass.toAdd.{u1} (Dfinsupp.{u1, 0} α (fun (_a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero)) (Dfinsupp.addZeroClass'.{u1, 0} α Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid))) (AddMonoidHomClass.toAddHomClass.{u1, u1, u1} (AddMonoidHom.{u1, u1} (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (_a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero)) (AddMonoid.toAddZeroClass.{u1} (Multiset.{u1} α) (AddRightCancelMonoid.toAddMonoid.{u1} (Multiset.{u1} α) (AddCancelMonoid.toAddRightCancelMonoid.{u1} (Multiset.{u1} α) (AddCancelCommMonoid.toAddCancelMonoid.{u1} (Multiset.{u1} α) (OrderedCancelAddCommMonoid.toCancelAddCommMonoid.{u1} (Multiset.{u1} α) (Multiset.instOrderedCancelAddCommMonoidMultiset.{u1} α)))))) (Dfinsupp.addZeroClass'.{u1, 0} α Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid))) (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (_a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero)) (AddMonoid.toAddZeroClass.{u1} (Multiset.{u1} α) (AddRightCancelMonoid.toAddMonoid.{u1} (Multiset.{u1} α) (AddCancelMonoid.toAddRightCancelMonoid.{u1} (Multiset.{u1} α) (AddCancelCommMonoid.toAddCancelMonoid.{u1} (Multiset.{u1} α) (OrderedCancelAddCommMonoid.toCancelAddCommMonoid.{u1} (Multiset.{u1} α) (Multiset.instOrderedCancelAddCommMonoidMultiset.{u1} α)))))) (Dfinsupp.addZeroClass'.{u1, 0} α Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid)) (AddMonoidHom.addMonoidHomClass.{u1, u1} (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (_a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero)) (AddMonoid.toAddZeroClass.{u1} (Multiset.{u1} α) (AddRightCancelMonoid.toAddMonoid.{u1} (Multiset.{u1} α) (AddCancelMonoid.toAddRightCancelMonoid.{u1} (Multiset.{u1} α) (AddCancelCommMonoid.toAddCancelMonoid.{u1} (Multiset.{u1} α) (OrderedCancelAddCommMonoid.toCancelAddCommMonoid.{u1} (Multiset.{u1} α) (Multiset.instOrderedCancelAddCommMonoidMultiset.{u1} α)))))) (Dfinsupp.addZeroClass'.{u1, 0} α Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid))))) (Multiset.toDfinsupp.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) f) (FunLike.coe.{succ u1, succ u1, succ u1} (AddMonoidHom.{u1, u1} (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (_a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero)) (AddMonoid.toAddZeroClass.{u1} (Multiset.{u1} α) (AddRightCancelMonoid.toAddMonoid.{u1} (Multiset.{u1} α) (AddCancelMonoid.toAddRightCancelMonoid.{u1} (Multiset.{u1} α) (AddCancelCommMonoid.toAddCancelMonoid.{u1} (Multiset.{u1} α) (OrderedCancelAddCommMonoid.toCancelAddCommMonoid.{u1} (Multiset.{u1} α) (Multiset.instOrderedCancelAddCommMonoidMultiset.{u1} α)))))) (Dfinsupp.addZeroClass'.{u1, 0} α Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid))) (Multiset.{u1} α) (fun (_x : Multiset.{u1} α) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.403 : Multiset.{u1} α) => Dfinsupp.{u1, 0} α (fun (_a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero)) _x) (AddHomClass.toFunLike.{u1, u1, u1} (AddMonoidHom.{u1, u1} (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (_a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero)) (AddMonoid.toAddZeroClass.{u1} (Multiset.{u1} α) (AddRightCancelMonoid.toAddMonoid.{u1} (Multiset.{u1} α) (AddCancelMonoid.toAddRightCancelMonoid.{u1} (Multiset.{u1} α) (AddCancelCommMonoid.toAddCancelMonoid.{u1} (Multiset.{u1} α) (OrderedCancelAddCommMonoid.toCancelAddCommMonoid.{u1} (Multiset.{u1} α) (Multiset.instOrderedCancelAddCommMonoidMultiset.{u1} α)))))) (Dfinsupp.addZeroClass'.{u1, 0} α Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid))) (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (_a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero)) (AddZeroClass.toAdd.{u1} (Multiset.{u1} α) (AddMonoid.toAddZeroClass.{u1} (Multiset.{u1} α) (AddRightCancelMonoid.toAddMonoid.{u1} (Multiset.{u1} α) (AddCancelMonoid.toAddRightCancelMonoid.{u1} (Multiset.{u1} α) (AddCancelCommMonoid.toAddCancelMonoid.{u1} (Multiset.{u1} α) (OrderedCancelAddCommMonoid.toCancelAddCommMonoid.{u1} (Multiset.{u1} α) (Multiset.instOrderedCancelAddCommMonoidMultiset.{u1} α))))))) (AddZeroClass.toAdd.{u1} (Dfinsupp.{u1, 0} α (fun (_a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero)) (Dfinsupp.addZeroClass'.{u1, 0} α Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid))) (AddMonoidHomClass.toAddHomClass.{u1, u1, u1} (AddMonoidHom.{u1, u1} (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (_a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero)) (AddMonoid.toAddZeroClass.{u1} (Multiset.{u1} α) (AddRightCancelMonoid.toAddMonoid.{u1} (Multiset.{u1} α) (AddCancelMonoid.toAddRightCancelMonoid.{u1} (Multiset.{u1} α) (AddCancelCommMonoid.toAddCancelMonoid.{u1} (Multiset.{u1} α) (OrderedCancelAddCommMonoid.toCancelAddCommMonoid.{u1} (Multiset.{u1} α) (Multiset.instOrderedCancelAddCommMonoidMultiset.{u1} α)))))) (Dfinsupp.addZeroClass'.{u1, 0} α Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid))) (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (_a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero)) (AddMonoid.toAddZeroClass.{u1} (Multiset.{u1} α) (AddRightCancelMonoid.toAddMonoid.{u1} (Multiset.{u1} α) (AddCancelMonoid.toAddRightCancelMonoid.{u1} (Multiset.{u1} α) (AddCancelCommMonoid.toAddCancelMonoid.{u1} (Multiset.{u1} α) (OrderedCancelAddCommMonoid.toCancelAddCommMonoid.{u1} (Multiset.{u1} α) (Multiset.instOrderedCancelAddCommMonoidMultiset.{u1} α)))))) (Dfinsupp.addZeroClass'.{u1, 0} α Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid)) (AddMonoidHom.addMonoidHomClass.{u1, u1} (Multiset.{u1} α) (Dfinsupp.{u1, 0} α (fun (_a : α) => Nat) (fun (i : α) => LinearOrderedCommMonoidWithZero.toZero.{0} ((fun (_a : α) => Nat) i) Nat.linearOrderedCommMonoidWithZero)) (AddMonoid.toAddZeroClass.{u1} (Multiset.{u1} α) (AddRightCancelMonoid.toAddMonoid.{u1} (Multiset.{u1} α) (AddCancelMonoid.toAddRightCancelMonoid.{u1} (Multiset.{u1} α) (AddCancelCommMonoid.toAddCancelMonoid.{u1} (Multiset.{u1} α) (OrderedCancelAddCommMonoid.toCancelAddCommMonoid.{u1} (Multiset.{u1} α) (Multiset.instOrderedCancelAddCommMonoidMultiset.{u1} α)))))) (Dfinsupp.addZeroClass'.{u1, 0} α Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid))))) (Multiset.toDfinsupp.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) g)))
Case conversion may be inaccurate. Consider using '#align multiset.Icc_eq Multiset.Icc_eqₓ'. -/
theorem Icc_eq :
    Finset.Icc f g =
      (Finset.Icc f.toDfinsupp g.toDfinsupp).map Multiset.equivDfinsupp.toEquiv.symm.toEmbedding :=
  rfl
#align multiset.Icc_eq Multiset.Icc_eq

/- warning: multiset.card_Icc -> Multiset.card_Icc is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (f : Multiset.{u1} α) (g : Multiset.{u1} α), Eq.{1} Nat (Finset.card.{u1} (Multiset.{u1} α) (Finset.Icc.{u1} (Multiset.{u1} α) (PartialOrder.toPreorder.{u1} (Multiset.{u1} α) (Multiset.partialOrder.{u1} α)) (Multiset.locallyFiniteOrder.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) f g)) (Finset.prod.{0, u1} Nat α Nat.commMonoid (Union.union.{u1} (Finset.{u1} α) (Finset.hasUnion.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) (Multiset.toFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b) f) (Multiset.toFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b) g)) (fun (i : α) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (Multiset.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) i g) (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))) (Multiset.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) i f)))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (f : Multiset.{u1} α) (g : Multiset.{u1} α), Eq.{1} Nat (Finset.card.{u1} (Multiset.{u1} α) (Finset.Icc.{u1} (Multiset.{u1} α) (PartialOrder.toPreorder.{u1} (Multiset.{u1} α) (Multiset.instPartialOrderMultiset.{u1} α)) (Multiset.instLocallyFiniteOrderMultisetToPreorderInstPartialOrderMultiset.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) f g)) (Finset.prod.{0, u1} Nat α Nat.commMonoid (Union.union.{u1} (Finset.{u1} α) (Finset.instUnionFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) (Multiset.toFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b) f) (Multiset.toFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b) g)) (fun (i : α) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (Multiset.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) i g) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (Multiset.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) i f)))
Case conversion may be inaccurate. Consider using '#align multiset.card_Icc Multiset.card_Iccₓ'. -/
theorem card_Icc :
    (Finset.Icc f g).card = ∏ i in f.toFinset ∪ g.toFinset, g.count i + 1 - f.count i := by
  simp_rw [Icc_eq, Finset.card_map, Dfinsupp.card_Icc, Nat.card_Icc, Multiset.toDfinsupp_apply,
    toDfinsupp_support]
#align multiset.card_Icc Multiset.card_Icc

/- warning: multiset.card_Ico -> Multiset.card_Ico is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (f : Multiset.{u1} α) (g : Multiset.{u1} α), Eq.{1} Nat (Finset.card.{u1} (Multiset.{u1} α) (Finset.Ico.{u1} (Multiset.{u1} α) (PartialOrder.toPreorder.{u1} (Multiset.{u1} α) (Multiset.partialOrder.{u1} α)) (Multiset.locallyFiniteOrder.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) f g)) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (Finset.prod.{0, u1} Nat α Nat.commMonoid (Union.union.{u1} (Finset.{u1} α) (Finset.hasUnion.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) (Multiset.toFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b) f) (Multiset.toFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b) g)) (fun (i : α) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (Multiset.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) i g) (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))) (Multiset.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) i f))) (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (f : Multiset.{u1} α) (g : Multiset.{u1} α), Eq.{1} Nat (Finset.card.{u1} (Multiset.{u1} α) (Finset.Ico.{u1} (Multiset.{u1} α) (PartialOrder.toPreorder.{u1} (Multiset.{u1} α) (Multiset.instPartialOrderMultiset.{u1} α)) (Multiset.instLocallyFiniteOrderMultisetToPreorderInstPartialOrderMultiset.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) f g)) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (Finset.prod.{0, u1} Nat α Nat.commMonoid (Union.union.{u1} (Finset.{u1} α) (Finset.instUnionFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) (Multiset.toFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b) f) (Multiset.toFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b) g)) (fun (i : α) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (Multiset.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) i g) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (Multiset.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) i f))) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))
Case conversion may be inaccurate. Consider using '#align multiset.card_Ico Multiset.card_Icoₓ'. -/
theorem card_Ico :
    (Finset.Ico f g).card = (∏ i in f.toFinset ∪ g.toFinset, g.count i + 1 - f.count i) - 1 := by
  rw [card_Ico_eq_card_Icc_sub_one, card_Icc]
#align multiset.card_Ico Multiset.card_Ico

/- warning: multiset.card_Ioc -> Multiset.card_Ioc is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (f : Multiset.{u1} α) (g : Multiset.{u1} α), Eq.{1} Nat (Finset.card.{u1} (Multiset.{u1} α) (Finset.Ioc.{u1} (Multiset.{u1} α) (PartialOrder.toPreorder.{u1} (Multiset.{u1} α) (Multiset.partialOrder.{u1} α)) (Multiset.locallyFiniteOrder.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) f g)) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (Finset.prod.{0, u1} Nat α Nat.commMonoid (Union.union.{u1} (Finset.{u1} α) (Finset.hasUnion.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) (Multiset.toFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b) f) (Multiset.toFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b) g)) (fun (i : α) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (Multiset.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) i g) (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))) (Multiset.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) i f))) (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (f : Multiset.{u1} α) (g : Multiset.{u1} α), Eq.{1} Nat (Finset.card.{u1} (Multiset.{u1} α) (Finset.Ioc.{u1} (Multiset.{u1} α) (PartialOrder.toPreorder.{u1} (Multiset.{u1} α) (Multiset.instPartialOrderMultiset.{u1} α)) (Multiset.instLocallyFiniteOrderMultisetToPreorderInstPartialOrderMultiset.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) f g)) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (Finset.prod.{0, u1} Nat α Nat.commMonoid (Union.union.{u1} (Finset.{u1} α) (Finset.instUnionFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) (Multiset.toFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b) f) (Multiset.toFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b) g)) (fun (i : α) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (Multiset.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) i g) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (Multiset.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) i f))) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))
Case conversion may be inaccurate. Consider using '#align multiset.card_Ioc Multiset.card_Iocₓ'. -/
theorem card_Ioc :
    (Finset.Ioc f g).card = (∏ i in f.toFinset ∪ g.toFinset, g.count i + 1 - f.count i) - 1 := by
  rw [card_Ioc_eq_card_Icc_sub_one, card_Icc]
#align multiset.card_Ioc Multiset.card_Ioc

/- warning: multiset.card_Ioo -> Multiset.card_Ioo is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (f : Multiset.{u1} α) (g : Multiset.{u1} α), Eq.{1} Nat (Finset.card.{u1} (Multiset.{u1} α) (Finset.Ioo.{u1} (Multiset.{u1} α) (PartialOrder.toPreorder.{u1} (Multiset.{u1} α) (Multiset.partialOrder.{u1} α)) (Multiset.locallyFiniteOrder.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) f g)) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (Finset.prod.{0, u1} Nat α Nat.commMonoid (Union.union.{u1} (Finset.{u1} α) (Finset.hasUnion.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) (Multiset.toFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b) f) (Multiset.toFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b) g)) (fun (i : α) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (Multiset.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) i g) (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))) (Multiset.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) i f))) (OfNat.ofNat.{0} Nat 2 (OfNat.mk.{0} Nat 2 (bit0.{0} Nat Nat.hasAdd (One.one.{0} Nat Nat.hasOne)))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (f : Multiset.{u1} α) (g : Multiset.{u1} α), Eq.{1} Nat (Finset.card.{u1} (Multiset.{u1} α) (Finset.Ioo.{u1} (Multiset.{u1} α) (PartialOrder.toPreorder.{u1} (Multiset.{u1} α) (Multiset.instPartialOrderMultiset.{u1} α)) (Multiset.instLocallyFiniteOrderMultisetToPreorderInstPartialOrderMultiset.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) f g)) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (Finset.prod.{0, u1} Nat α Nat.commMonoid (Union.union.{u1} (Finset.{u1} α) (Finset.instUnionFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) (Multiset.toFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b) f) (Multiset.toFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b) g)) (fun (i : α) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (Multiset.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) i g) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (Multiset.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) i f))) (OfNat.ofNat.{0} Nat 2 (instOfNatNat 2)))
Case conversion may be inaccurate. Consider using '#align multiset.card_Ioo Multiset.card_Iooₓ'. -/
theorem card_Ioo :
    (Finset.Ioo f g).card = (∏ i in f.toFinset ∪ g.toFinset, g.count i + 1 - f.count i) - 2 := by
  rw [card_Ioo_eq_card_Icc_sub_two, card_Icc]
#align multiset.card_Ioo Multiset.card_Ioo

/- warning: multiset.card_Iic -> Multiset.card_Iic is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (f : Multiset.{u1} α), Eq.{1} Nat (Finset.card.{u1} (Multiset.{u1} α) (Finset.Iic.{u1} (Multiset.{u1} α) (PartialOrder.toPreorder.{u1} (Multiset.{u1} α) (Multiset.partialOrder.{u1} α)) (Finset.LocallyFiniteOrder.toLocallyFiniteOrderBot.{u1} (Multiset.{u1} α) (PartialOrder.toPreorder.{u1} (Multiset.{u1} α) (Multiset.partialOrder.{u1} α)) (Multiset.orderBot.{u1} α) (Multiset.locallyFiniteOrder.{u1} α (fun (a : α) (b : α) => _inst_1 a b))) f)) (Finset.prod.{0, u1} Nat α Nat.commMonoid (Multiset.toFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b) f) (fun (i : α) => HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (Multiset.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) i f) (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (f : Multiset.{u1} α), Eq.{1} Nat (Finset.card.{u1} (Multiset.{u1} α) (Finset.Iic.{u1} (Multiset.{u1} α) (PartialOrder.toPreorder.{u1} (Multiset.{u1} α) (Multiset.instPartialOrderMultiset.{u1} α)) (Finset.LocallyFiniteOrder.toLocallyFiniteOrderBot.{u1} (Multiset.{u1} α) (PartialOrder.toPreorder.{u1} (Multiset.{u1} α) (Multiset.instPartialOrderMultiset.{u1} α)) (Multiset.instOrderBotMultisetToLEToPreorderInstPartialOrderMultiset.{u1} α) (Multiset.instLocallyFiniteOrderMultisetToPreorderInstPartialOrderMultiset.{u1} α (fun (a : α) (b : α) => _inst_1 a b))) f)) (Finset.prod.{0, u1} Nat α Nat.commMonoid (Multiset.toFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b) f) (fun (i : α) => HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (Multiset.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) i f) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))))
Case conversion may be inaccurate. Consider using '#align multiset.card_Iic Multiset.card_Iicₓ'. -/
theorem card_Iic : (Finset.Iic f).card = ∏ i in f.toFinset, f.count i + 1 := by
  simp_rw [Iic_eq_Icc, card_Icc, bot_eq_zero, to_finset_zero, empty_union, count_zero, tsub_zero]
#align multiset.card_Iic Multiset.card_Iic

end Multiset