l3lab/ntp-mathlib huggingface dataset:
/-- Map each element of a `Multiset` to an action, evaluate these actions in order,
    and collect the results.
-/
def traverse : Multiset α' → F (Multiset β') := by
  refine' Quotient.lift (Functor.map Coe.coe ∘ Traversable.traverse f) _
  introv p; unfold Function.comp
  induction p
  case nil => rfl
  case cons x l₁ l₂ _ h =>
    have :
      Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₁ =
        Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₂ := by 

Proof state:
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
a b : List α'
x : α'
l₁ l₂ : List α'
a✝ : l₁ ~ l₂
h : Coe.coe <$> Traversable.traverse f l₁ = Coe.coe <$> Traversable.traverse f l₂
⊢ (Seq.seq (cons <$> f x) fun x => Coe.coe <$> Traversable.traverse f l₁) =
    Seq.seq (cons <$> f x) fun x => Coe.coe <$> Traversable.traverse f l₂

Next tactic:
rw [h]
/-- Map each element of a `Multiset` to an action, evaluate these actions in order,
    and collect the results.
-/
def traverse : Multiset α' → F (Multiset β') := by
  refine' Quotient.lift (Functor.map Coe.coe ∘ Traversable.traverse f) _
  introv p; unfold Function.comp
  induction p
  case nil => rfl
  case cons x l₁ l₂ _ h =>
    have :
      Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₁ =
        Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₂ := by rw [h]
    

Proof state:
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
a b : List α'
x : α'
l₁ l₂ : List α'
a✝ : l₁ ~ l₂
h : Coe.coe <$> Traversable.traverse f l₁ = Coe.coe <$> Traversable.traverse f l₂
this :
  (Seq.seq (cons <$> f x) fun x => Coe.coe <$> Traversable.traverse f l₁) =
    Seq.seq (cons <$> f x) fun x => Coe.coe <$> Traversable.traverse f l₂
⊢ Coe.coe <$> Traversable.traverse f (x :: l₁) = Coe.coe <$> Traversable.traverse f (x :: l₂)

Next tactic:
simpa [functor_norm] using this
/-- Map each element of a `Multiset` to an action, evaluate these actions in order,
    and collect the results.
-/
def traverse : Multiset α' → F (Multiset β') := by
  refine' Quotient.lift (Functor.map Coe.coe ∘ Traversable.traverse f) _
  introv p; unfold Function.comp
  induction p
  case nil => rfl
  case cons x l₁ l₂ _ h =>
    have :
      Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₁ =
        Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₂ := by rw [h]
    simpa [functor_norm] using this
  

Proof state:
case swap
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
a b : List α'
x✝ y✝ : α'
l✝ : List α'
⊢ Coe.coe <$> Traversable.traverse f (y✝ :: x✝ :: l✝) = Coe.coe <$> Traversable.traverse f (x✝ :: y✝ :: l✝)
case trans
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
a b l₁✝ l₂✝ l₃✝ : List α'
a✝¹ : l₁✝ ~ l₂✝
a✝ : l₂✝ ~ l₃✝
a_ih✝¹ : Coe.coe <$> Traversable.traverse f l₁✝ = Coe.coe <$> Traversable.traverse f l₂✝
a_ih✝ : Coe.coe <$> Traversable.traverse f l₂✝ = Coe.coe <$> Traversable.traverse f l₃✝
⊢ Coe.coe <$> Traversable.traverse f l₁✝ = Coe.coe <$> Traversable.traverse f l₃✝

Next tactic:
case swap x y l =>
    have :
      (fun a b (l : List β') ↦ (↑(a :: b :: l) : Multiset β')) <$> f y <*> f x =
        (fun a b l ↦ ↑(a :: b :: l)) <$> f x <*> f y := by
      rw [CommApplicative.commutative_map]
      congr
      funext a b l
      simpa [flip] using Perm.swap a b l
    simp [(· ∘ ·), this, functor_norm, Coe.coe]
/-- Map each element of a `Multiset` to an action, evaluate these actions in order,
    and collect the results.
-/
def traverse : Multiset α' → F (Multiset β') := by
  refine' Quotient.lift (Functor.map Coe.coe ∘ Traversable.traverse f) _
  introv p; unfold Function.comp
  induction p
  case nil => rfl
  case cons x l₁ l₂ _ h =>
    have :
      Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₁ =
        Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₂ := by rw [h]
    simpa [functor_norm] using this
  

Proof state:
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
a b : List α'
x y : α'
l : List α'
⊢ Coe.coe <$> Traversable.traverse f (y :: x :: l) = Coe.coe <$> Traversable.traverse f (x :: y :: l)

Next tactic:
case swap x y l =>
    have :
      (fun a b (l : List β') ↦ (↑(a :: b :: l) : Multiset β')) <$> f y <*> f x =
        (fun a b l ↦ ↑(a :: b :: l)) <$> f x <*> f y := by
      rw [CommApplicative.commutative_map]
      congr
      funext a b l
      simpa [flip] using Perm.swap a b l
    simp [(· ∘ ·), this, functor_norm, Coe.coe]
/-- Map each element of a `Multiset` to an action, evaluate these actions in order,
    and collect the results.
-/
def traverse : Multiset α' → F (Multiset β') := by
  refine' Quotient.lift (Functor.map Coe.coe ∘ Traversable.traverse f) _
  introv p; unfold Function.comp
  induction p
  case nil => rfl
  case cons x l₁ l₂ _ h =>
    have :
      Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₁ =
        Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₂ := by rw [h]
    simpa [functor_norm] using this
  case swap x y l =>
    

Proof state:
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
a b : List α'
x y : α'
l : List α'
⊢ Coe.coe <$> Traversable.traverse f (y :: x :: l) = Coe.coe <$> Traversable.traverse f (x :: y :: l)

Next tactic:
have :
      (fun a b (l : List β') ↦ (↑(a :: b :: l) : Multiset β')) <$> f y <*> f x =
        (fun a b l ↦ ↑(a :: b :: l)) <$> f x <*> f y := by
      rw [CommApplicative.commutative_map]
      congr
      funext a b l
      simpa [flip] using Perm.swap a b l
/-- Map each element of a `Multiset` to an action, evaluate these actions in order,
    and collect the results.
-/
def traverse : Multiset α' → F (Multiset β') := by
  refine' Quotient.lift (Functor.map Coe.coe ∘ Traversable.traverse f) _
  introv p; unfold Function.comp
  induction p
  case nil => rfl
  case cons x l₁ l₂ _ h =>
    have :
      Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₁ =
        Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₂ := by rw [h]
    simpa [functor_norm] using this
  case swap x y l =>
    have :
      (fun a b (l : List β') ↦ (↑(a :: b :: l) : Multiset β')) <$> f y <*> f x =
        (fun a b l ↦ ↑(a :: b :: l)) <$> f x <*> f y := by
      

Proof state:
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
a b : List α'
x y : α'
l : List α'
⊢ (Seq.seq ((fun a b l => ↑(a :: b :: l)) <$> f y) fun x_1 => f x) =
    Seq.seq ((fun a b l => ↑(a :: b :: l)) <$> f x) fun x => f y

Next tactic:
rw [CommApplicative.commutative_map]
/-- Map each element of a `Multiset` to an action, evaluate these actions in order,
    and collect the results.
-/
def traverse : Multiset α' → F (Multiset β') := by
  refine' Quotient.lift (Functor.map Coe.coe ∘ Traversable.traverse f) _
  introv p; unfold Function.comp
  induction p
  case nil => rfl
  case cons x l₁ l₂ _ h =>
    have :
      Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₁ =
        Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₂ := by rw [h]
    simpa [functor_norm] using this
  case swap x y l =>
    have :
      (fun a b (l : List β') ↦ (↑(a :: b :: l) : Multiset β')) <$> f y <*> f x =
        (fun a b l ↦ ↑(a :: b :: l)) <$> f x <*> f y := by
      rw [CommApplicative.commutative_map]
      

Proof state:
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
a b : List α'
x y : α'
l : List α'
⊢ (Seq.seq ((flip fun a b l => ↑(a :: b :: l)) <$> f x) fun x => f y) =
    Seq.seq ((fun a b l => ↑(a :: b :: l)) <$> f x) fun x => f y

Next tactic:
congr
/-- Map each element of a `Multiset` to an action, evaluate these actions in order,
    and collect the results.
-/
def traverse : Multiset α' → F (Multiset β') := by
  refine' Quotient.lift (Functor.map Coe.coe ∘ Traversable.traverse f) _
  introv p; unfold Function.comp
  induction p
  case nil => rfl
  case cons x l₁ l₂ _ h =>
    have :
      Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₁ =
        Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₂ := by rw [h]
    simpa [functor_norm] using this
  case swap x y l =>
    have :
      (fun a b (l : List β') ↦ (↑(a :: b :: l) : Multiset β')) <$> f y <*> f x =
        (fun a b l ↦ ↑(a :: b :: l)) <$> f x <*> f y := by
      rw [CommApplicative.commutative_map]
      congr
      

Proof state:
case e_a.e_a
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
a b : List α'
x y : α'
l : List α'
⊢ (flip fun a b l => ↑(a :: b :: l)) = fun a b l => ↑(a :: b :: l)

Next tactic:
funext a b l
/-- Map each element of a `Multiset` to an action, evaluate these actions in order,
    and collect the results.
-/
def traverse : Multiset α' → F (Multiset β') := by
  refine' Quotient.lift (Functor.map Coe.coe ∘ Traversable.traverse f) _
  introv p; unfold Function.comp
  induction p
  case nil => rfl
  case cons x l₁ l₂ _ h =>
    have :
      Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₁ =
        Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₂ := by rw [h]
    simpa [functor_norm] using this
  case swap x y l =>
    have :
      (fun a b (l : List β') ↦ (↑(a :: b :: l) : Multiset β')) <$> f y <*> f x =
        (fun a b l ↦ ↑(a :: b :: l)) <$> f x <*> f y := by
      rw [CommApplicative.commutative_map]
      congr
      funext a b l
      

Proof state:
case e_a.e_a.h.h.h
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
a✝ b✝ : List α'
x y : α'
l✝ : List α'
a b : β'
l : List β'
⊢ flip (fun a b l => ↑(a :: b :: l)) a b l = ↑(a :: b :: l)

Next tactic:
simpa [flip] using Perm.swap a b l
/-- Map each element of a `Multiset` to an action, evaluate these actions in order,
    and collect the results.
-/
def traverse : Multiset α' → F (Multiset β') := by
  refine' Quotient.lift (Functor.map Coe.coe ∘ Traversable.traverse f) _
  introv p; unfold Function.comp
  induction p
  case nil => rfl
  case cons x l₁ l₂ _ h =>
    have :
      Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₁ =
        Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₂ := by rw [h]
    simpa [functor_norm] using this
  case swap x y l =>
    have :
      (fun a b (l : List β') ↦ (↑(a :: b :: l) : Multiset β')) <$> f y <*> f x =
        (fun a b l ↦ ↑(a :: b :: l)) <$> f x <*> f y := by
      rw [CommApplicative.commutative_map]
      congr
      funext a b l
      simpa [flip] using Perm.swap a b l
    

Proof state:
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
a b : List α'
x y : α'
l : List α'
this :
  (Seq.seq ((fun a b l => ↑(a :: b :: l)) <$> f y) fun x_1 => f x) =
    Seq.seq ((fun a b l => ↑(a :: b :: l)) <$> f x) fun x => f y
⊢ Coe.coe <$> Traversable.traverse f (y :: x :: l) = Coe.coe <$> Traversable.traverse f (x :: y :: l)

Next tactic:
simp [(· ∘ ·), this, functor_norm, Coe.coe]
/-- Map each element of a `Multiset` to an action, evaluate these actions in order,
    and collect the results.
-/
def traverse : Multiset α' → F (Multiset β') := by
  refine' Quotient.lift (Functor.map Coe.coe ∘ Traversable.traverse f) _
  introv p; unfold Function.comp
  induction p
  case nil => rfl
  case cons x l₁ l₂ _ h =>
    have :
      Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₁ =
        Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₂ := by rw [h]
    simpa [functor_norm] using this
  case swap x y l =>
    have :
      (fun a b (l : List β') ↦ (↑(a :: b :: l) : Multiset β')) <$> f y <*> f x =
        (fun a b l ↦ ↑(a :: b :: l)) <$> f x <*> f y := by
      rw [CommApplicative.commutative_map]
      congr
      funext a b l
      simpa [flip] using Perm.swap a b l
    simp [(· ∘ ·), this, functor_norm, Coe.coe]
  

Proof state:
case trans
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
a b l₁✝ l₂✝ l₃✝ : List α'
a✝¹ : l₁✝ ~ l₂✝
a✝ : l₂✝ ~ l₃✝
a_ih✝¹ : Coe.coe <$> Traversable.traverse f l₁✝ = Coe.coe <$> Traversable.traverse f l₂✝
a_ih✝ : Coe.coe <$> Traversable.traverse f l₂✝ = Coe.coe <$> Traversable.traverse f l₃✝
⊢ Coe.coe <$> Traversable.traverse f l₁✝ = Coe.coe <$> Traversable.traverse f l₃✝

Next tactic:
case trans => simp [*]
/-- Map each element of a `Multiset` to an action, evaluate these actions in order,
    and collect the results.
-/
def traverse : Multiset α' → F (Multiset β') := by
  refine' Quotient.lift (Functor.map Coe.coe ∘ Traversable.traverse f) _
  introv p; unfold Function.comp
  induction p
  case nil => rfl
  case cons x l₁ l₂ _ h =>
    have :
      Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₁ =
        Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₂ := by rw [h]
    simpa [functor_norm] using this
  case swap x y l =>
    have :
      (fun a b (l : List β') ↦ (↑(a :: b :: l) : Multiset β')) <$> f y <*> f x =
        (fun a b l ↦ ↑(a :: b :: l)) <$> f x <*> f y := by
      rw [CommApplicative.commutative_map]
      congr
      funext a b l
      simpa [flip] using Perm.swap a b l
    simp [(· ∘ ·), this, functor_norm, Coe.coe]
  

Proof state:
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
a b l₁✝ l₂✝ l₃✝ : List α'
a✝¹ : l₁✝ ~ l₂✝
a✝ : l₂✝ ~ l₃✝
a_ih✝¹ : Coe.coe <$> Traversable.traverse f l₁✝ = Coe.coe <$> Traversable.traverse f l₂✝
a_ih✝ : Coe.coe <$> Traversable.traverse f l₂✝ = Coe.coe <$> Traversable.traverse f l₃✝
⊢ Coe.coe <$> Traversable.traverse f l₁✝ = Coe.coe <$> Traversable.traverse f l₃✝

Next tactic:
case trans => simp [*]
/-- Map each element of a `Multiset` to an action, evaluate these actions in order,
    and collect the results.
-/
def traverse : Multiset α' → F (Multiset β') := by
  refine' Quotient.lift (Functor.map Coe.coe ∘ Traversable.traverse f) _
  introv p; unfold Function.comp
  induction p
  case nil => rfl
  case cons x l₁ l₂ _ h =>
    have :
      Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₁ =
        Multiset.cons <$> f x <*> Coe.coe <$> Traversable.traverse f l₂ := by rw [h]
    simpa [functor_norm] using this
  case swap x y l =>
    have :
      (fun a b (l : List β') ↦ (↑(a :: b :: l) : Multiset β')) <$> f y <*> f x =
        (fun a b l ↦ ↑(a :: b :: l)) <$> f x <*> f y := by
      rw [CommApplicative.commutative_map]
      congr
      funext a b l
      simpa [flip] using Perm.swap a b l
    simp [(· ∘ ·), this, functor_norm, Coe.coe]
  case trans => 

Proof state:
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
a b l₁✝ l₂✝ l₃✝ : List α'
a✝¹ : l₁✝ ~ l₂✝
a✝ : l₂✝ ~ l₃✝
a_ih✝¹ : Coe.coe <$> Traversable.traverse f l₁✝ = Coe.coe <$> Traversable.traverse f l₂✝
a_ih✝ : Coe.coe <$> Traversable.traverse f l₂✝ = Coe.coe <$> Traversable.traverse f l₃✝
⊢ Coe.coe <$> Traversable.traverse f l₁✝ = Coe.coe <$> Traversable.traverse f l₃✝

Next tactic:
simp [*]
instance : LawfulMonad Multiset := LawfulMonad.mk'
  (bind_pure_comp := fun _ _ ↦ by simp only [pure_def, bind_def, bind_singleton, fmap_def])
  (id_map := fun _ ↦ by 

Proof state:
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
α✝ : Type ?u.28443
x✝ : Multiset α✝
⊢ id <$> x✝ = x✝

Next tactic:
simp only [fmap_def, id_eq, map_id']
instance : LawfulMonad Multiset := LawfulMonad.mk'
  (bind_pure_comp := fun _ _ ↦ by simp only [pure_def, bind_def, bind_singleton, fmap_def])
  (id_map := fun _ ↦ by simp only [fmap_def, id_eq, map_id'])
  (pure_bind := fun _ _ ↦ by 

Proof state:
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
α✝ β✝ : Type ?u.28443
x✝¹ : α✝
x✝ : α✝ → Multiset β✝
⊢ pure x✝¹ >>= x✝ = x✝ x✝¹

Next tactic:
simp only [pure_def, bind_def, singleton_bind]
instance : LawfulMonad Multiset := LawfulMonad.mk'
  (bind_pure_comp := fun _ _ ↦ by 

Proof state:
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
α✝ β✝ : Type ?u.28443
x✝¹ : α✝ → β✝
x✝ : Multiset α✝
⊢ (do
      let y ← x✝
      pure (x✝¹ y)) =
    x✝¹ <$> x✝

Next tactic:
simp only [pure_def, bind_def, bind_singleton, fmap_def]
@[simp]
theorem map_comp_coe {α β} (h : α → β) :
    Functor.map h ∘ Coe.coe = (Coe.coe ∘ Functor.map h : List α → Multiset β) := by
  

Proof state:
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
α β : Type u_1
h : α → β
⊢ Functor.map h ∘ Coe.coe = Coe.coe ∘ Functor.map h

Next tactic:
funext
@[simp]
theorem map_comp_coe {α β} (h : α → β) :
    Functor.map h ∘ Coe.coe = (Coe.coe ∘ Functor.map h : List α → Multiset β) := by
  funext; 

Proof state:
case h
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
α β : Type u_1
h : α → β
x✝ : List α
⊢ (Functor.map h ∘ Coe.coe) x✝ = (Coe.coe ∘ Functor.map h) x✝

Next tactic:
simp only [Function.comp_apply, Coe.coe, fmap_def, coe_map, List.map_eq_map]
theorem id_traverse {α : Type*} (x : Multiset α) : traverse (pure : α → Id α) x = x := by
  

Proof state:
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
α : Type u_1
x : Multiset α
⊢ traverse pure x = x

Next tactic:
refine' Quotient.inductionOn x _
theorem id_traverse {α : Type*} (x : Multiset α) : traverse (pure : α → Id α) x = x := by
  refine' Quotient.inductionOn x _
  

Proof state:
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
α : Type u_1
x : Multiset α
⊢ ∀ (a : List α), traverse pure ⟦a⟧ = ⟦a⟧

Next tactic:
intro
theorem id_traverse {α : Type*} (x : Multiset α) : traverse (pure : α → Id α) x = x := by
  refine' Quotient.inductionOn x _
  intro
  

Proof state:
F : Type u → Type u
inst✝¹ : Applicative F
inst✝ : CommApplicative F
α' β' : Type u
f : α' → F β'
α : Type u_1
x : Multiset α
a✝ : List α
⊢ traverse pure ⟦a✝⟧ = ⟦a✝⟧

Next tactic:
simp [traverse, Coe.coe]
theorem comp_traverse {G H : Type _ → Type _} [Applicative G] [Applicative H] [CommApplicative G]
    [CommApplicative H] {α β γ : Type _} (g : α → G β) (h : β → H γ) (x : Multiset α) :
    traverse (Comp.mk ∘ Functor.map h ∘ g) x =
    Comp.mk (Functor.map (traverse h) (traverse g x)) := by
  

Proof state:
F : Type u → Type u
inst✝⁵ : Applicative F
inst✝⁴ : CommApplicative F
α' β' : Type u
f : α' → F β'
G H : Type u_1 → Type u_1
inst✝³ : Applicative G
inst✝² : Applicative H
inst✝¹ : CommApplicative G
inst✝ : CommApplicative H
α β γ : Type u_1
g : α → G β
h : β → H γ
x : Multiset α
⊢ traverse (Comp.mk ∘ Functor.map h ∘ g) x = Comp.mk (traverse h <$> traverse g x)

Next tactic:
refine' Quotient.inductionOn x _
theorem comp_traverse {G H : Type _ → Type _} [Applicative G] [Applicative H] [CommApplicative G]
    [CommApplicative H] {α β γ : Type _} (g : α → G β) (h : β → H γ) (x : Multiset α) :
    traverse (Comp.mk ∘ Functor.map h ∘ g) x =
    Comp.mk (Functor.map (traverse h) (traverse g x)) := by
  refine' Quotient.inductionOn x _
  

Proof state:
F : Type u → Type u
inst✝⁵ : Applicative F
inst✝⁴ : CommApplicative F
α' β' : Type u
f : α' → F β'
G H : Type u_1 → Type u_1
inst✝³ : Applicative G
inst✝² : Applicative H
inst✝¹ : CommApplicative G
inst✝ : CommApplicative H
α β γ : Type u_1
g : α → G β
h : β → H γ
x : Multiset α
⊢ ∀ (a : List α), traverse (Comp.mk ∘ Functor.map h ∘ g) ⟦a⟧ = Comp.mk (traverse h <$> traverse g ⟦a⟧)

Next tactic:
intro
theorem comp_traverse {G H : Type _ → Type _} [Applicative G] [Applicative H] [CommApplicative G]
    [CommApplicative H] {α β γ : Type _} (g : α → G β) (h : β → H γ) (x : Multiset α) :
    traverse (Comp.mk ∘ Functor.map h ∘ g) x =
    Comp.mk (Functor.map (traverse h) (traverse g x)) := by
  refine' Quotient.inductionOn x _
  intro
  

Proof state:
F : Type u → Type u
inst✝⁵ : Applicative F
inst✝⁴ : CommApplicative F
α' β' : Type u
f : α' → F β'
G H : Type u_1 → Type u_1
inst✝³ : Applicative G
inst✝² : Applicative H
inst✝¹ : CommApplicative G
inst✝ : CommApplicative H
α β γ : Type u_1
g : α → G β
h : β → H γ
x : Multiset α
a✝ : List α
⊢ traverse (Comp.mk ∘ Functor.map h ∘ g) ⟦a✝⟧ = Comp.mk (traverse h <$> traverse g ⟦a✝⟧)

Next tactic:
simp only [traverse, quot_mk_to_coe, lift_coe, Coe.coe, Function.comp_apply, Functor.map_map,
    functor_norm]
theorem comp_traverse {G H : Type _ → Type _} [Applicative G] [Applicative H] [CommApplicative G]
    [CommApplicative H] {α β γ : Type _} (g : α → G β) (h : β → H γ) (x : Multiset α) :
    traverse (Comp.mk ∘ Functor.map h ∘ g) x =
    Comp.mk (Functor.map (traverse h) (traverse g x)) := by
  refine' Quotient.inductionOn x _
  intro
  simp only [traverse, quot_mk_to_coe, lift_coe, Coe.coe, Function.comp_apply, Functor.map_map,
    functor_norm]
  

Proof state:
F : Type u → Type u
inst✝⁵ : Applicative F
inst✝⁴ : CommApplicative F
α' β' : Type u
f : α' → F β'
G H : Type u_1 → Type u_1
inst✝³ : Applicative G
inst✝² : Applicative H
inst✝¹ : CommApplicative G
inst✝ : CommApplicative H
α β γ : Type u_1
g : α → G β
h : β → H γ
x : Multiset α
a✝ : List α
⊢ Comp.mk (((fun x => ofList <$> x) ∘ Traversable.traverse h) <$> Traversable.traverse g a✝) =
    Comp.mk
      ((Quotient.lift (Functor.map ofList ∘ Traversable.traverse h)
            (_ :
              ∀ (a b : List β),
                a ≈ b →
                  (Functor.map Coe.coe ∘ Traversable.traverse h) a = (Functor.map Coe.coe ∘ Traversable.traverse h) b) ∘
          ofList) <$>
        Traversable.traverse g a✝)

Next tactic:
simp only [Function.comp, lift_coe]
theorem map_traverse {G : Type* → Type _} [Applicative G] [CommApplicative G] {α β γ : Type _}
    (g : α → G β) (h : β → γ) (x : Multiset α) :
    Functor.map (Functor.map h) (traverse g x) = traverse (Functor.map h ∘ g) x := by
  

Proof state:
F : Type u → Type u
inst✝³ : Applicative F
inst✝² : CommApplicative F
α' β' : Type u
f : α' → F β'
G : Type u_1 → Type u_1
inst✝¹ : Applicative G
inst✝ : CommApplicative G
α β γ : Type u_1
g : α → G β
h : β → γ
x : Multiset α
⊢ Functor.map h <$> traverse g x = traverse (Functor.map h ∘ g) x

Next tactic:
refine' Quotient.inductionOn x _
theorem map_traverse {G : Type* → Type _} [Applicative G] [CommApplicative G] {α β γ : Type _}
    (g : α → G β) (h : β → γ) (x : Multiset α) :
    Functor.map (Functor.map h) (traverse g x) = traverse (Functor.map h ∘ g) x := by
  refine' Quotient.inductionOn x _
  

Proof state:
F : Type u → Type u
inst✝³ : Applicative F
inst✝² : CommApplicative F
α' β' : Type u
f : α' → F β'
G : Type u_1 → Type u_1
inst✝¹ : Applicative G
inst✝ : CommApplicative G
α β γ : Type u_1
g : α → G β
h : β → γ
x : Multiset α
⊢ ∀ (a : List α), Functor.map h <$> traverse g ⟦a⟧ = traverse (Functor.map h ∘ g) ⟦a⟧

Next tactic:
intro
theorem map_traverse {G : Type* → Type _} [Applicative G] [CommApplicative G] {α β γ : Type _}
    (g : α → G β) (h : β → γ) (x : Multiset α) :
    Functor.map (Functor.map h) (traverse g x) = traverse (Functor.map h ∘ g) x := by
  refine' Quotient.inductionOn x _
  intro
  

Proof state:
F : Type u → Type u
inst✝³ : Applicative F
inst✝² : CommApplicative F
α' β' : Type u
f : α' → F β'
G : Type u_1 → Type u_1
inst✝¹ : Applicative G
inst✝ : CommApplicative G
α β γ : Type u_1
g : α → G β
h : β → γ
x : Multiset α
a✝ : List α
⊢ Functor.map h <$> traverse g ⟦a✝⟧ = traverse (Functor.map h ∘ g) ⟦a✝⟧

Next tactic:
simp only [traverse, quot_mk_to_coe, lift_coe, Function.comp_apply, Functor.map_map, map_comp_coe]