/-- Equivalence between `∀ i : Fin m, Fin (n i)` and `Fin (∏ i : Fin m, n i)`. -/
def finPiFinEquiv {m : ℕ} {n : Fin m → ℕ} : (∀ i : Fin m, Fin (n i)) ≃ Fin (∏ i : Fin m, n i) :=
  Equiv.ofRightInverseOfCardLE (le_of_eq <| by simp_rw [Fintype.card_pi, Fintype.card_fin])
    (fun f => ⟨∑ i, f i * ∏ j, n (Fin.castLE i.is_lt.le j), by
      induction' m with m ih
      · simp
      rw [Fin.prod_univ_castSucc, Fin.sum_univ_castSucc]
      suffices
        ∀ (n : Fin m → ℕ) (nn : ℕ) (f : ∀ i : Fin m, Fin (n i)) (fn : Fin nn),
          ((∑ i : Fin m, ↑(f i) * ∏ j : Fin i, n (Fin.castLE i.prop.le j)) + ↑fn * ∏ j, n j) <
            (∏ i : Fin m, n i) * nn by
        replace := this (Fin.init n) (n (Fin.last _)) (Fin.init f) (f (Fin.last _))
        rw [← Fin.snoc_init_self f]
        simp (config := { singlePass := true }) only [← Fin.snoc_init_self n]
        simp_rw [Fin.snoc_castSucc, Fin.snoc_last, Fin.snoc_init_self n]
        exact this
      intro n nn f fn
      cases nn
      · dsimp only [Nat.zero_eq] at fn -- porting note: added, wrong zero
        exact isEmptyElim fn
      refine' (add_lt_add_of_lt_of_le (ih _) <| mul_le_mul_right' (Fin.is_le _) _).trans_eq _
      rw [← one_add_mul (_ : ℕ), mul_comm, add_comm]
      -- porting note: added, wrong `succ`
      rfl⟩)
    (fun a b => ⟨(a / ∏ j : Fin b, n (Fin.castLE b.is_lt.le j)) % n b, by
      cases m
      · exact b.elim0
      cases' h : n b with nb
      · rw [prod_eq_zero (Finset.mem_univ _) h] at a
        exact isEmptyElim a
      exact Nat.mod_lt _ nb.succ_pos⟩)
    (by
      intro a; revert a; dsimp only [Fin.val_mk]
      refine' Fin.consInduction _ _ n
      · intro a
        haveI : Subsingleton (Fin (∏ i : Fin 0, i.elim0)) :=
          (Fin.castIso <| prod_empty).toEquiv.subsingleton
        exact Subsingleton.elim _ _
      · intro n x xs ih a
        

Proof state:
case refine'_2
α : Type u_1
β : Type u_2
m : ℕ
n✝ : Fin m → ℕ
n x : ℕ
xs : Fin n → ℕ
ih :
  ∀ (a : Fin (∏ i : Fin n, xs i)),
    {
        val :=
          ∑ i : Fin n,
            (↑a / ∏ j : Fin ↑i, xs (Fin.castLE (_ : ↑i ≤ n) j)) % xs i * ∏ j : Fin ↑i, xs (Fin.castLE (_ : ↑i ≤ n) j),
        isLt :=
          (_ :
            ∑ i : Fin n,
                ↑{ val := (↑a / ∏ j : Fin ↑i, xs (Fin.castLE (_ : ↑i ≤ n) j)) % xs i,
                      isLt := (_ : (↑a / ∏ j : Fin ↑i, xs (Fin.castLE (_ : ↑i ≤ n) j)) % xs i < xs i) } *
                  ∏ j : Fin ↑i, xs (Fin.castLE (_ : ↑i ≤ n) j) <
              ∏ i : Fin n, xs i) } =
      a
a : Fin (∏ i : Fin (n + 1), Fin.cons x xs i)
⊢ {
      val :=
        ∑ i : Fin (n + 1),
          (↑a / ∏ j : Fin ↑i, Fin.cons x xs (Fin.castLE (_ : ↑i ≤ n + 1) j)) % Fin.cons x xs i *
            ∏ j : Fin ↑i, Fin.cons x xs (Fin.castLE (_ : ↑i ≤ n + 1) j),
      isLt :=
        (_ :
          ∑ i : Fin (n + 1),
              ↑{ val := (↑a / ∏ j : Fin ↑i, Fin.cons x xs (Fin.castLE (_ : ↑i ≤ n + 1) j)) % Fin.cons x xs i,
                    isLt :=
                      (_ :
                        (↑a / ∏ j : Fin ↑i, Fin.cons x xs (Fin.castLE (_ : ↑i ≤ n + 1) j)) % Fin.cons x xs i <
                          Fin.cons x xs i) } *
                ∏ j : Fin ↑i, Fin.cons x xs (Fin.castLE (_ : ↑i ≤ n + 1) j) <
            ∏ i : Fin (n + 1), Fin.cons x xs i) } =
    a

Next tactic:
simp_rw [Fin.forall_iff, Fin.ext_iff] at ih