File: Mathlib/Data/Multiset/Pi.lean

full_name: Multiset.Pi.empty
code: /-- Given `δ : α → Sort*`, `Pi.empty δ` is the trivial dependent function out of the empty
multiset. -/
def empty (δ : α → Sort*) : ∀ a ∈ (0 : Multiset α), δ a 
goal: a ∈ 0 → δ a

full_name: Multiset.Pi.cons
code: /-- Given `δ : α → Sort*`, a multiset `m` and a term `a`, as well as a term `b : δ a` and a
function `f` such that `f a' : δ a'` for all `a'` in `m`, `Pi.cons m a b f` is a function `g` such
that `g a'' : δ a''` for all `a''` in `a ::ₘ m`. -/
def cons (b : δ a) (f : ∀ a ∈ m, δ a) : ∀ a' ∈ a ::ₘ m, δ a' 
goal: a' ∈ a ::ₘ m → δ a'

full_name: Multiset.Pi.cons_same
code: theorem cons_same {b : δ a} {f : ∀ a ∈ m, δ a} (h : a ∈ a ::ₘ m) :
    cons m a b f a h = b 
goal: Multiset.Pi.cons m a b f a h = b

full_name: Multiset.Pi.cons_ne
code: theorem cons_ne {a a' : α} {b : δ a} {f : ∀ a ∈ m, δ a} (h' : a' ∈ a ::ₘ m)
    (h : a' ≠ a) : Pi.cons m a b f a' h' = f a' ((mem_cons.1 h').resolve_left h) 
goal: Multiset.Pi.cons m a b f a' h' = f a' ⋯

full_name: Multiset.Pi.cons_swap
code: theorem cons_swap {a a' : α} {b : δ a} {b' : δ a'} {m : Multiset α} {f : ∀ a ∈ m, δ a}
    (h : a ≠ a') : HEq (Pi.cons (a' ::ₘ m) a b (Pi.cons m a' b' f))
      (Pi.cons (a ::ₘ m) a' b' (Pi.cons m a b f)) 
goal: HEq (Multiset.Pi.cons (a' ::ₘ m) a b (Multiset.Pi.cons m a' b' f))
  (Multiset.Pi.cons (a ::ₘ m) a' b' (Multiset.Pi.cons m a b f))

full_name: Multiset.Pi.cons_eta
code: @[simp, nolint simpNF] -- Porting note: false positive, this lemma can prove itself
theorem cons_eta {m : Multiset α} {a : α} (f : ∀ a' ∈ a ::ₘ m, δ a') :
    (cons m a (f _ (mem_cons_self _ _)) fun a' ha' => f a' (mem_cons_of_mem ha')) = f 
goal: (Multiset.Pi.cons m a (f a ⋯) fun a' ha' => f a' ⋯) = f

full_name: Multiset.Pi.cons_map
code: theorem cons_map (b : δ a) (f : ∀ a' ∈ m, δ a')
    {δ' : α → Sort*} (φ : ∀ ⦃a'⦄, δ a' → δ' a') :
    Pi.cons _ _ (φ b) (fun a' ha' ↦ φ (f a' ha')) = (fun a' ha' ↦ φ ((cons _ _ b f) a' ha')) 
goal: (Multiset.Pi.cons m a (φ b) fun a' ha' => φ (f a' ha')) = fun a' ha' => φ (Multiset.Pi.cons m a b f a' ha')

full_name: Multiset.Pi.forall_rel_cons_ext
code: theorem forall_rel_cons_ext {r : ∀ ⦃a⦄, δ a → δ a → Prop} {b₁ b₂ : δ a} {f₁ f₂ : ∀ a' ∈ m, δ a'}
    (hb : r b₁ b₂) (hf : ∀ (a : α) (ha : a ∈ m), r (f₁ a ha) (f₂ a ha)) :
    ∀ a ha, r (cons _ _ b₁ f₁ a ha) (cons _ _ b₂ f₂ a ha) 
goal: ∀ (a_1 : α) (ha : a_1 ∈ a ::ₘ m), r (Multiset.Pi.cons m a b₁ f₁ a_1 ha) (Multiset.Pi.cons m a b₂ f₂ a_1 ha)

full_name: Multiset.Pi.cons_injective
code: theorem cons_injective {a : α} {b : δ a} {s : Multiset α} (hs : a ∉ s) :
    Function.Injective (Pi.cons s a b) 
goal: Function.Injective (Multiset.Pi.cons s a b)

full_name: Multiset.pi
code: /-- `pi m t` constructs the Cartesian product over `t` indexed by `m`. -/
def pi (m : Multiset α) (t : ∀ a, Multiset (β a)) : Multiset (∀ a ∈ m, β a) 
goal: Multiset ((a : α) → a ∈ m → β a)

full_name: Multiset.pi_zero
code: @[simp]
theorem pi_zero (t : ∀ a, Multiset (β a)) : pi 0 t = {Pi.empty β} 
goal: Multiset.pi 0 t = {Multiset.Pi.empty β}

full_name: Multiset.pi_cons
code: @[simp]
theorem pi_cons (m : Multiset α) (t : ∀ a, Multiset (β a)) (a : α) :
    pi (a ::ₘ m) t = (t a).bind fun b => (pi m t).map <| Pi.cons m a b 
goal: (a ::ₘ m).pi t = (t a).bind fun b => Multiset.map (Multiset.Pi.cons m a b) (m.pi t)

full_name: Multiset.card_pi
code: theorem card_pi (m : Multiset α) (t : ∀ a, Multiset (β a)) :
    card (pi m t) = prod (m.map fun a => card (t a)) 
goal: Multiset.card (m.pi t) = (Multiset.map (fun a => Multiset.card (t a)) m).prod

full_name: Multiset.Nodup.pi
code: protected theorem Nodup.pi {s : Multiset α} {t : ∀ a, Multiset (β a)} :
    Nodup s → (∀ a ∈ s, Nodup (t a)) → Nodup (pi s t) 
goal: s.Nodup → (∀ a ∈ s, (t a).Nodup) → (s.pi t).Nodup

full_name: Multiset.mem_pi
code: theorem mem_pi (m : Multiset α) (t : ∀ a, Multiset (β a)) :
    ∀ f : ∀ a ∈ m, β a, f ∈ pi m t ↔ ∀ (a) (h : a ∈ m), f a h ∈ t a 
goal: f ∈ m.pi t ↔ ∀ (a : α) (h : a ∈ m), f a h ∈ t a