case forall_ x phi phi_ih | exists_ x phi phi_ih =>
  split_ifs
  case _ c1 =>
    subst c1
    simp only [Holds]
    first | apply forall_congr' | apply exists_congr
    intro d
    congr! 1
    funext x
    simp only [Function.updateITE]
    split_ifs <;> rfl
  case _ c1 =>
    simp only [Holds]
    first | apply forall_congr' | apply exists_congr
    intro d
    cases h1
    case inl h1 =>
      contradiction
    case inr h1 =>
      simp only [Function.updateITE_comm V v x d (V' t) c1]
      apply phi_ih (Function.updateITE V x d) (binders ∪ {x}) h1
      simp only [Function.updateITE]
      simp
      push_neg
      intros v' a1 a2
      simp only [if_neg a2]
      exact h2 v' a1
D : Type
I : Interpretation D
V' : VarAssignment D
v t : VarName
head✝ : Definition
tail✝ : List Definition
tail_ih✝ :
  ∀ (V : VarAssignment D) (binders : Finset VarName) (F : Formula),
    fastAdmitsAux v t binders F →
      (∀ v ∉ binders, V' v = V v) →
        (Holds D I (Function.updateITE V v (V' t)) tail✝ F ↔ Holds D I V tail✝ (fastReplaceFree v t F))
x : VarName
phi : Formula
phi_ih :
  ∀ (V : VarAssignment D) (binders : Finset VarName),
    fastAdmitsAux v t binders phi →
      (∀ v ∉ binders, V' v = V v) →
        (Holds D I (Function.updateITE V v (V' t)) (head✝ :: tail✝) phi ↔
          Holds D I V (head✝ :: tail✝) (fastReplaceFree v t phi))
V : VarAssignment D
binders : Finset VarName
h1 : v = x ∨ fastAdmitsAux v t (binders ∪ {x}) phi
h2 : ∀ v ∉ binders, V' v = V v
⊢ (∃ d, Holds D I (Function.updateITE (Function.updateITE V v (V' t)) x d) (head✝ :: tail✝) phi) ↔
    Holds D I V (head✝ :: tail✝) (if v = x then exists_ x phi else exists_ x (fastReplaceFree v t phi))
no goals