Theorem: FOL.NV.Sub.Pred.All.Rec.Option.Fresh.substitution_theorem_aux (FOL/NV/Sub/Pred/All/Rec/Option/Fresh/Sub.lean)

State before:
D : Type
I : Interpretation D
V V' V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
σ : VarName → VarName
F : Formula
h1 : ∀ (x : VarName), isFreeIn x F → V' x = V (σ x)
h2 : ∀ x ∈ F.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E F ↔ Holds D I V E (subAux c τ σ F)
Tactic:
induction F generalizing V V' σ
State after:
case pred_const_
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
a✝¹ : PredName
a✝ : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x (pred_const_ a✝¹ a✝) → V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ a✝¹ a✝).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (pred_const_ a✝¹ a✝) ↔ Holds D I V E (subAux c τ σ (pred_const_ a✝¹ a✝))

case pred_var_
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
a✝¹ : PredName
a✝ : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x (pred_var_ a✝¹ a✝) → V' x = V (σ x)
h2 : ∀ x ∈ (pred_var_ a✝¹ a✝).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (pred_var_ a✝¹ a✝) ↔ Holds D I V E (subAux c τ σ (pred_var_ a✝¹ a✝))

case eq_
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
a✝¹ a✝ : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x (eq_ a✝¹ a✝) → V' x = V (σ x)
h2 : ∀ x ∈ (eq_ a✝¹ a✝).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (eq_ a✝¹ a✝) ↔ Holds D I V E (subAux c τ σ (eq_ a✝¹ a✝))

case true_
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x true_ → V' x = V (σ x)
h2 : ∀ x ∈ true_.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E true_ ↔ Holds D I V E (subAux c τ σ true_)

case false_
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x false_ → V' x = V (σ x)
h2 : ∀ x ∈ false_.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E false_ ↔ Holds D I V E (subAux c τ σ false_)

case not_
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
a✝ : Formula
a_ih✝ :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x a✝ → V' x = V (σ x)) →
      (∀ x ∈ a✝.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E a✝ ↔ Holds D I V E (subAux c τ σ a✝))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x a✝.not_ → V' x = V (σ x)
h2 : ∀ x ∈ a✝.not_.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E a✝.not_ ↔ Holds D I V E (subAux c τ σ a✝.not_)

case imp_
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
a✝¹ a✝ : Formula
a_ih✝¹ :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x a✝¹ → V' x = V (σ x)) →
      (∀ x ∈ a✝¹.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E a✝¹ ↔ Holds D I V E (subAux c τ σ a✝¹))
a_ih✝ :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x a✝ → V' x = V (σ x)) →
      (∀ x ∈ a✝.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E a✝ ↔ Holds D I V E (subAux c τ σ a✝))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x (a✝¹.imp_ a✝) → V' x = V (σ x)
h2 : ∀ x ∈ (a✝¹.imp_ a✝).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (a✝¹.imp_ a✝) ↔ Holds D I V E (subAux c τ σ (a✝¹.imp_ a✝))

case and_
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
a✝¹ a✝ : Formula
a_ih✝¹ :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x a✝¹ → V' x = V (σ x)) →
      (∀ x ∈ a✝¹.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E a✝¹ ↔ Holds D I V E (subAux c τ σ a✝¹))
a_ih✝ :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x a✝ → V' x = V (σ x)) →
      (∀ x ∈ a✝.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E a✝ ↔ Holds D I V E (subAux c τ σ a✝))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x (a✝¹.and_ a✝) → V' x = V (σ x)
h2 : ∀ x ∈ (a✝¹.and_ a✝).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (a✝¹.and_ a✝) ↔ Holds D I V E (subAux c τ σ (a✝¹.and_ a✝))

case or_
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
a✝¹ a✝ : Formula
a_ih✝¹ :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x a✝¹ → V' x = V (σ x)) →
      (∀ x ∈ a✝¹.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E a✝¹ ↔ Holds D I V E (subAux c τ σ a✝¹))
a_ih✝ :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x a✝ → V' x = V (σ x)) →
      (∀ x ∈ a✝.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E a✝ ↔ Holds D I V E (subAux c τ σ a✝))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x (a✝¹.or_ a✝) → V' x = V (σ x)
h2 : ∀ x ∈ (a✝¹.or_ a✝).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (a✝¹.or_ a✝) ↔ Holds D I V E (subAux c τ σ (a✝¹.or_ a✝))

case iff_
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
a✝¹ a✝ : Formula
a_ih✝¹ :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x a✝¹ → V' x = V (σ x)) →
      (∀ x ∈ a✝¹.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E a✝¹ ↔ Holds D I V E (subAux c τ σ a✝¹))
a_ih✝ :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x a✝ → V' x = V (σ x)) →
      (∀ x ∈ a✝.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E a✝ ↔ Holds D I V E (subAux c τ σ a✝))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x (a✝¹.iff_ a✝) → V' x = V (σ x)
h2 : ∀ x ∈ (a✝¹.iff_ a✝).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (a✝¹.iff_ a✝) ↔ Holds D I V E (subAux c τ σ (a✝¹.iff_ a✝))

case forall_
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
a✝¹ : VarName
a✝ : Formula
a_ih✝ :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x a✝ → V' x = V (σ x)) →
      (∀ x ∈ a✝.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E a✝ ↔ Holds D I V E (subAux c τ σ a✝))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x (forall_ a✝¹ a✝) → V' x = V (σ x)
h2 : ∀ x ∈ (forall_ a✝¹ a✝).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (forall_ a✝¹ a✝) ↔ Holds D I V E (subAux c τ σ (forall_ a✝¹ a✝))

case exists_
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
a✝¹ : VarName
a✝ : Formula
a_ih✝ :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x a✝ → V' x = V (σ x)) →
      (∀ x ∈ a✝.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E a✝ ↔ Holds D I V E (subAux c τ σ a✝))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x (exists_ a✝¹ a✝) → V' x = V (σ x)
h2 : ∀ x ∈ (exists_ a✝¹ a✝).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (exists_ a✝¹ a✝) ↔ Holds D I V E (subAux c τ σ (exists_ a✝¹ a✝))

case def_
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
a✝¹ : DefName
a✝ : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x (def_ a✝¹ a✝) → V' x = V (σ x)
h2 : ∀ x ∈ (def_ a✝¹ a✝).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (def_ a✝¹ a✝) ↔ Holds D I V E (subAux c τ σ (def_ a✝¹ a✝))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x (pred_const_ X xs) → V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (pred_const_ X xs) ↔ Holds D I V E (subAux c τ σ (pred_const_ X xs))
Tactic:
case pred_const_ X xs =>
  simp only [isFreeIn] at h1
  simp only [subAux]
  simp only [Holds]
  simp only [I']
  simp only [Interpretation.usingPred]
  simp
  congr! 1
  simp only [List.map_eq_map_iff]
  intro x a1
  simp
  exact h1 x a1
State after:
no goals

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), isFreeIn x_1 (eq_ x y) → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
⊢ Holds D (I' D I V'' E τ) V' E (eq_ x y) ↔ Holds D I V E (subAux c τ σ (eq_ x y))
Tactic:
case eq_ x y =>
  simp only [isFreeIn] at h1
  simp only [subAux]
  simp only [Holds]
  have s1 : V' x = V (σ x)
  apply h1
  simp
  simp only [s1]
  have s2 : V' y = V (σ y)
  apply h1
  simp
  simp only [s2]
State after:
no goals

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x false_ → V' x = V (σ x)
h2 : ∀ x ∈ false_.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E false_ ↔ Holds D I V E (subAux c τ σ false_)
Tactic:
case true_ | false_ =>
  simp only [subAux]
  simp only [Holds]
State after:
no goals

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi.not_ → V' x = V (σ x)
h2 : ∀ x ∈ phi.not_.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E phi.not_ ↔ Holds D I V E (subAux c τ σ phi.not_)
Tactic:
case not_ phi phi_ih =>
  simp only [isFreeIn] at h1
  simp only [predVarSet] at h2
  simp only [subAux]
  simp only [Holds]
  congr! 1
  exact phi_ih V V' σ h1 h2
State after:
no goals

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x (pred_const_ X xs) → V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (pred_const_ X xs) ↔ Holds D I V E (subAux c τ σ (pred_const_ X xs))
Tactic:
simp only [isFreeIn] at h1
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (pred_const_ X xs) ↔ Holds D I V E (subAux c τ σ (pred_const_ X xs))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (pred_const_ X xs) ↔ Holds D I V E (subAux c τ σ (pred_const_ X xs))
Tactic:
simp only [subAux]
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (pred_const_ X xs) ↔ Holds D I V E (pred_const_ X (List.map σ xs))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (pred_const_ X xs) ↔ Holds D I V E (pred_const_ X (List.map σ xs))
Tactic:
simp only [Holds]
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ (I' D I V'' E τ).pred_const_ X (List.map V' xs) ↔ I.pred_const_ X (List.map V (List.map σ xs))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ (I' D I V'' E τ).pred_const_ X (List.map V' xs) ↔ I.pred_const_ X (List.map V (List.map σ xs))
Tactic:
simp only [I']
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ (Interpretation.usingPred D I fun X ds =>
          if h : (τ X ds.length).isSome = true then
            if ds.length = ((τ X ds.length).get ⋯).1.length then
              Holds D I (Function.updateListITE V'' ((τ X ds.length).get ⋯).1 ds) E ((τ X ds.length).get ⋯).2
            else I.pred_var_ X ds
          else I.pred_var_ X ds).pred_const_
      X (List.map V' xs) ↔
    I.pred_const_ X (List.map V (List.map σ xs))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ (Interpretation.usingPred D I fun X ds =>
          if h : (τ X ds.length).isSome = true then
            if ds.length = ((τ X ds.length).get ⋯).1.length then
              Holds D I (Function.updateListITE V'' ((τ X ds.length).get ⋯).1 ds) E ((τ X ds.length).get ⋯).2
            else I.pred_var_ X ds
          else I.pred_var_ X ds).pred_const_
      X (List.map V' xs) ↔
    I.pred_const_ X (List.map V (List.map σ xs))
Tactic:
simp only [Interpretation.usingPred]
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ I.pred_const_ X (List.map V' xs) ↔ I.pred_const_ X (List.map V (List.map σ xs))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ I.pred_const_ X (List.map V' xs) ↔ I.pred_const_ X (List.map V (List.map σ xs))
Tactic:
simp
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ I.pred_const_ X (List.map V' xs) ↔ I.pred_const_ X (List.map (V ∘ σ) xs)

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ I.pred_const_ X (List.map V' xs) ↔ I.pred_const_ X (List.map (V ∘ σ) xs)
Tactic:
congr! 1
State after:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ List.map V' xs = List.map (V ∘ σ) xs

State before:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ List.map V' xs = List.map (V ∘ σ) xs
Tactic:
simp only [List.map_eq_map_iff]
State after:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ ∀ x ∈ xs, V' x = (V ∘ σ) x

State before:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ ∀ x ∈ xs, V' x = (V ∘ σ) x
Tactic:
intro x a1
State after:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : x ∈ xs
⊢ V' x = (V ∘ σ) x

State before:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : x ∈ xs
⊢ V' x = (V ∘ σ) x
Tactic:
simp
State after:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : x ∈ xs
⊢ V' x = V (σ x)

State before:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_const_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : x ∈ xs
⊢ V' x = V (σ x)
Tactic:
exact h1 x a1
State after:
no goals

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x (pred_var_ X xs) → V' x = V (σ x)
h2 : ∀ x ∈ (pred_var_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (pred_var_ X xs) ↔ Holds D I V E (subAux c τ σ (pred_var_ X xs))
Tactic:
simp only [isFreeIn] at h1
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_var_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (pred_var_ X xs) ↔ Holds D I V E (subAux c τ σ (pred_var_ X xs))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ (pred_var_ X xs).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (pred_var_ X xs) ↔ Holds D I V E (subAux c τ σ (pred_var_ X xs))
Tactic:
simp only [predVarSet] at h2
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ {(X, xs.length)}.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (pred_var_ X xs) ↔ Holds D I V E (subAux c τ σ (pred_var_ X xs))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ {(X, xs.length)}.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (pred_var_ X xs) ↔ Holds D I V E (subAux c τ σ (pred_var_ X xs))
Tactic:
simp at h2
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ predVarFreeVarSet τ (X, xs.length), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (pred_var_ X xs) ↔ Holds D I V E (subAux c τ σ (pred_var_ X xs))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 : ∀ x ∈ predVarFreeVarSet τ (X, xs.length), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (pred_var_ X xs) ↔ Holds D I V E (subAux c τ σ (pred_var_ X xs))
Tactic:
simp only [predVarFreeVarSet] at h2
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (pred_var_ X xs) ↔ Holds D I V E (subAux c τ σ (pred_var_ X xs))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (pred_var_ X xs) ↔ Holds D I V E (subAux c τ σ (pred_var_ X xs))
Tactic:
simp only [subAux]
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (pred_var_ X xs) ↔
    Holds D I V E
      (if h : (τ X xs.length).isSome = true then
        if xs.length = ((τ X xs.length).get ⋯).1.length then
          Var.All.Rec.Fresh.sub (Function.updateListITE id ((τ X xs.length).get ⋯).1 (List.map σ xs)) c
            ((τ X xs.length).get ⋯).2
        else pred_var_ X (List.map σ xs)
      else pred_var_ X (List.map σ xs))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (pred_var_ X xs) ↔
    Holds D I V E
      (if h : (τ X xs.length).isSome = true then
        if xs.length = ((τ X xs.length).get ⋯).1.length then
          Var.All.Rec.Fresh.sub (Function.updateListITE id ((τ X xs.length).get ⋯).1 (List.map σ xs)) c
            ((τ X xs.length).get ⋯).2
        else pred_var_ X (List.map σ xs)
      else pred_var_ X (List.map σ xs))
Tactic:
simp only [Holds]
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
⊢ (I' D I V'' E τ).pred_var_ X (List.map V' xs) ↔
    Holds D I V E
      (if h : (τ X xs.length).isSome = true then
        if xs.length = ((τ X xs.length).get ⋯).1.length then
          Var.All.Rec.Fresh.sub (Function.updateListITE id ((τ X xs.length).get ⋯).1 (List.map σ xs)) c
            ((τ X xs.length).get ⋯).2
        else pred_var_ X (List.map σ xs)
      else pred_var_ X (List.map σ xs))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
⊢ (I' D I V'' E τ).pred_var_ X (List.map V' xs) ↔
    Holds D I V E
      (if h : (τ X xs.length).isSome = true then
        if xs.length = ((τ X xs.length).get ⋯).1.length then
          Var.All.Rec.Fresh.sub (Function.updateListITE id ((τ X xs.length).get ⋯).1 (List.map σ xs)) c
            ((τ X xs.length).get ⋯).2
        else pred_var_ X (List.map σ xs)
      else pred_var_ X (List.map σ xs))
Tactic:
simp only [I']
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
⊢ (Interpretation.usingPred D I fun X ds =>
          if h : (τ X ds.length).isSome = true then
            if ds.length = ((τ X ds.length).get ⋯).1.length then
              Holds D I (Function.updateListITE V'' ((τ X ds.length).get ⋯).1 ds) E ((τ X ds.length).get ⋯).2
            else I.pred_var_ X ds
          else I.pred_var_ X ds).pred_var_
      X (List.map V' xs) ↔
    Holds D I V E
      (if h : (τ X xs.length).isSome = true then
        if xs.length = ((τ X xs.length).get ⋯).1.length then
          Var.All.Rec.Fresh.sub (Function.updateListITE id ((τ X xs.length).get ⋯).1 (List.map σ xs)) c
            ((τ X xs.length).get ⋯).2
        else pred_var_ X (List.map σ xs)
      else pred_var_ X (List.map σ xs))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
⊢ (Interpretation.usingPred D I fun X ds =>
          if h : (τ X ds.length).isSome = true then
            if ds.length = ((τ X ds.length).get ⋯).1.length then
              Holds D I (Function.updateListITE V'' ((τ X ds.length).get ⋯).1 ds) E ((τ X ds.length).get ⋯).2
            else I.pred_var_ X ds
          else I.pred_var_ X ds).pred_var_
      X (List.map V' xs) ↔
    Holds D I V E
      (if h : (τ X xs.length).isSome = true then
        if xs.length = ((τ X xs.length).get ⋯).1.length then
          Var.All.Rec.Fresh.sub (Function.updateListITE id ((τ X xs.length).get ⋯).1 (List.map σ xs)) c
            ((τ X xs.length).get ⋯).2
        else pred_var_ X (List.map σ xs)
      else pred_var_ X (List.map σ xs))
Tactic:
simp only [Interpretation.usingPred]
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
⊢ (if h : (τ X (List.map V' xs).length).isSome = true then
      if (List.map V' xs).length = ((τ X (List.map V' xs).length).get ⋯).1.length then
        Holds D I (Function.updateListITE V'' ((τ X (List.map V' xs).length).get ⋯).1 (List.map V' xs)) E
          ((τ X (List.map V' xs).length).get ⋯).2
      else I.pred_var_ X (List.map V' xs)
    else I.pred_var_ X (List.map V' xs)) ↔
    Holds D I V E
      (if h : (τ X xs.length).isSome = true then
        if xs.length = ((τ X xs.length).get ⋯).1.length then
          Var.All.Rec.Fresh.sub (Function.updateListITE id ((τ X xs.length).get ⋯).1 (List.map σ xs)) c
            ((τ X xs.length).get ⋯).2
        else pred_var_ X (List.map σ xs)
      else pred_var_ X (List.map σ xs))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
⊢ (if h : (τ X (List.map V' xs).length).isSome = true then
      if (List.map V' xs).length = ((τ X (List.map V' xs).length).get ⋯).1.length then
        Holds D I (Function.updateListITE V'' ((τ X (List.map V' xs).length).get ⋯).1 (List.map V' xs)) E
          ((τ X (List.map V' xs).length).get ⋯).2
      else I.pred_var_ X (List.map V' xs)
    else I.pred_var_ X (List.map V' xs)) ↔
    Holds D I V E
      (if h : (τ X xs.length).isSome = true then
        if xs.length = ((τ X xs.length).get ⋯).1.length then
          Var.All.Rec.Fresh.sub (Function.updateListITE id ((τ X xs.length).get ⋯).1 (List.map σ xs)) c
            ((τ X xs.length).get ⋯).2
        else pred_var_ X (List.map σ xs)
      else pred_var_ X (List.map σ xs))
Tactic:
simp
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
⊢ (if h : (τ X xs.length).isSome = true then
      if xs.length = ((τ X xs.length).get ⋯).1.length then
        Holds D I (Function.updateListITE V'' ((τ X xs.length).get ⋯).1 (List.map V' xs)) E ((τ X xs.length).get ⋯).2
      else I.pred_var_ X (List.map V' xs)
    else I.pred_var_ X (List.map V' xs)) ↔
    Holds D I V E
      (if h : (τ X xs.length).isSome = true then
        if xs.length = ((τ X xs.length).get ⋯).1.length then
          Var.All.Rec.Fresh.sub (Function.updateListITE id ((τ X xs.length).get ⋯).1 (List.map σ xs)) c
            ((τ X xs.length).get ⋯).2
        else pred_var_ X (List.map σ xs)
      else pred_var_ X (List.map σ xs))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
⊢ (if h : (τ X xs.length).isSome = true then
      if xs.length = ((τ X xs.length).get ⋯).1.length then
        Holds D I (Function.updateListITE V'' ((τ X xs.length).get ⋯).1 (List.map V' xs)) E ((τ X xs.length).get ⋯).2
      else I.pred_var_ X (List.map V' xs)
    else I.pred_var_ X (List.map V' xs)) ↔
    Holds D I V E
      (if h : (τ X xs.length).isSome = true then
        if xs.length = ((τ X xs.length).get ⋯).1.length then
          Var.All.Rec.Fresh.sub (Function.updateListITE id ((τ X xs.length).get ⋯).1 (List.map σ xs)) c
            ((τ X xs.length).get ⋯).2
        else pred_var_ X (List.map σ xs)
      else pred_var_ X (List.map σ xs))
Tactic:
split_ifs
State after:
case pos
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
h✝¹ : (τ X xs.length).isSome = true
h✝ : xs.length = ((τ X xs.length).get ⋯).1.length
⊢ Holds D I (Function.updateListITE V'' ((τ X xs.length).get ⋯).1 (List.map V' xs)) E ((τ X xs.length).get ⋯).2 ↔
    Holds D I V E
      (Var.All.Rec.Fresh.sub (Function.updateListITE id ((τ X xs.length).get ⋯).1 (List.map σ xs)) c
        ((τ X xs.length).get ⋯).2)

case neg
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
h✝¹ : (τ X xs.length).isSome = true
h✝ : ¬xs.length = ((τ X xs.length).get ⋯).1.length
⊢ I.pred_var_ X (List.map V' xs) ↔ Holds D I V E (pred_var_ X (List.map σ xs))

case neg
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
h✝ : ¬(τ X xs.length).isSome = true
⊢ I.pred_var_ X (List.map V' xs) ↔ Holds D I V E (pred_var_ X (List.map σ xs))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : (τ X xs.length).isSome = true
c2 : ¬xs.length = ((τ X xs.length).get ⋯).1.length
⊢ I.pred_var_ X (List.map V' xs) ↔ Holds D I V E (pred_var_ X (List.map σ xs))
Tactic:
case _ c1 c2 =>
  simp only [Holds]
  simp
  congr! 1
  simp only [List.map_eq_map_iff]
  intro x a1
  simp
  exact h1 x a1
State after:
no goals

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : ¬(τ X xs.length).isSome = true
⊢ I.pred_var_ X (List.map V' xs) ↔ Holds D I V E (pred_var_ X (List.map σ xs))
Tactic:
case _ c1 =>
  simp only [Holds]
  simp
  congr! 1
  simp only [List.map_eq_map_iff]
  intro x a1
  simp
  exact h1 x a1
State after:
no goals

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : (τ X xs.length).isSome = true
c2 : xs.length = ((τ X xs.length).get ⋯).1.length
⊢ Holds D I (Function.updateListITE V'' ((τ X xs.length).get ⋯).1 (List.map V' xs)) E ((τ X xs.length).get ⋯).2 ↔
    Holds D I V E
      (Var.All.Rec.Fresh.sub (Function.updateListITE id ((τ X xs.length).get ⋯).1 (List.map σ xs)) c
        ((τ X xs.length).get ⋯).2)
Tactic:
simp only [c1] at h2
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
c2 : xs.length = ((τ X xs.length).get ⋯).1.length
h2 :
  ∀ x ∈ if h : True then ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset else ∅, V'' x = V x
⊢ Holds D I (Function.updateListITE V'' ((τ X xs.length).get ⋯).1 (List.map V' xs)) E ((τ X xs.length).get ⋯).2 ↔
    Holds D I V E
      (Var.All.Rec.Fresh.sub (Function.updateListITE id ((τ X xs.length).get ⋯).1 (List.map σ xs)) c
        ((τ X xs.length).get ⋯).2)

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
c2 : xs.length = ((τ X xs.length).get ⋯).1.length
h2 :
  ∀ x ∈ if h : True then ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset else ∅, V'' x = V x
⊢ Holds D I (Function.updateListITE V'' ((τ X xs.length).get ⋯).1 (List.map V' xs)) E ((τ X xs.length).get ⋯).2 ↔
    Holds D I V E
      (Var.All.Rec.Fresh.sub (Function.updateListITE id ((τ X xs.length).get ⋯).1 (List.map σ xs)) c
        ((τ X xs.length).get ⋯).2)
Tactic:
simp at h2
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
c2 : xs.length = ((τ X xs.length).get ⋯).1.length
h2 : ∀ x ∈ ((τ X xs.length).get ⋯).2.freeVarSet, x ∉ ((τ X xs.length).get ⋯).1 → V'' x = V x
⊢ Holds D I (Function.updateListITE V'' ((τ X xs.length).get ⋯).1 (List.map V' xs)) E ((τ X xs.length).get ⋯).2 ↔
    Holds D I V E
      (Var.All.Rec.Fresh.sub (Function.updateListITE id ((τ X xs.length).get ⋯).1 (List.map σ xs)) c
        ((τ X xs.length).get ⋯).2)

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
c2 : xs.length = ((τ X xs.length).get ⋯).1.length
h2 : ∀ x ∈ ((τ X xs.length).get ⋯).2.freeVarSet, x ∉ ((τ X xs.length).get ⋯).1 → V'' x = V x
⊢ Holds D I (Function.updateListITE V'' ((τ X xs.length).get ⋯).1 (List.map V' xs)) E ((τ X xs.length).get ⋯).2 ↔
    Holds D I V E
      (Var.All.Rec.Fresh.sub (Function.updateListITE id ((τ X xs.length).get ⋯).1 (List.map σ xs)) c
        ((τ X xs.length).get ⋯).2)
Tactic:
set zs := (Option.get (τ X (List.length xs)) (_ : Option.isSome (τ X (List.length xs)) = true)).1
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
h2 : ∀ x ∈ ((τ X xs.length).get ⋯).2.freeVarSet, x ∉ zs → V'' x = V x
⊢ Holds D I (Function.updateListITE V'' zs (List.map V' xs)) E ((τ X xs.length).get ⋯).2 ↔
    Holds D I V E (Var.All.Rec.Fresh.sub (Function.updateListITE id zs (List.map σ xs)) c ((τ X xs.length).get ⋯).2)

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
h2 : ∀ x ∈ ((τ X xs.length).get ⋯).2.freeVarSet, x ∉ zs → V'' x = V x
⊢ Holds D I (Function.updateListITE V'' zs (List.map V' xs)) E ((τ X xs.length).get ⋯).2 ↔
    Holds D I V E (Var.All.Rec.Fresh.sub (Function.updateListITE id zs (List.map σ xs)) c ((τ X xs.length).get ⋯).2)
Tactic:
set H := (Option.get (τ X (List.length xs)) (_ : Option.isSome (τ X (List.length xs)) = true)).2
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
⊢ Holds D I (Function.updateListITE V'' zs (List.map V' xs)) E H ↔
    Holds D I V E (Var.All.Rec.Fresh.sub (Function.updateListITE id zs (List.map σ xs)) c H)

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
⊢ Holds D I (Function.updateListITE V'' zs (List.map V' xs)) E H ↔
    Holds D I V E (Var.All.Rec.Fresh.sub (Function.updateListITE id zs (List.map σ xs)) c H)
Tactic:
obtain s1 := Sub.Var.All.Rec.Fresh.substitution_theorem D I V E (Function.updateListITE id zs (xs.map σ)) c H
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
s1 :
  Holds D I V E (Var.All.Rec.Fresh.sub (Function.updateListITE id zs (List.map σ xs)) c H) ↔
    Holds D I (V ∘ Function.updateListITE id zs (List.map σ xs)) E H
⊢ Holds D I (Function.updateListITE V'' zs (List.map V' xs)) E H ↔
    Holds D I V E (Var.All.Rec.Fresh.sub (Function.updateListITE id zs (List.map σ xs)) c H)

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
s1 :
  Holds D I V E (Var.All.Rec.Fresh.sub (Function.updateListITE id zs (List.map σ xs)) c H) ↔
    Holds D I (V ∘ Function.updateListITE id zs (List.map σ xs)) E H
⊢ Holds D I (Function.updateListITE V'' zs (List.map V' xs)) E H ↔
    Holds D I V E (Var.All.Rec.Fresh.sub (Function.updateListITE id zs (List.map σ xs)) c H)
Tactic:
simp only [Function.updateListITE_comp] at s1
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
s1 :
  Holds D I V E (Var.All.Rec.Fresh.sub (Function.updateListITE id zs (List.map σ xs)) c H) ↔
    Holds D I (Function.updateListITE (V ∘ id) zs (List.map V (List.map σ xs))) E H
⊢ Holds D I (Function.updateListITE V'' zs (List.map V' xs)) E H ↔
    Holds D I V E (Var.All.Rec.Fresh.sub (Function.updateListITE id zs (List.map σ xs)) c H)

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
s1 :
  Holds D I V E (Var.All.Rec.Fresh.sub (Function.updateListITE id zs (List.map σ xs)) c H) ↔
    Holds D I (Function.updateListITE (V ∘ id) zs (List.map V (List.map σ xs))) E H
⊢ Holds D I (Function.updateListITE V'' zs (List.map V' xs)) E H ↔
    Holds D I V E (Var.All.Rec.Fresh.sub (Function.updateListITE id zs (List.map σ xs)) c H)
Tactic:
simp at s1
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
s1 :
  Holds D I V E (Var.All.Rec.Fresh.sub (Function.updateListITE id zs (List.map σ xs)) c H) ↔
    Holds D I (Function.updateListITE V zs (List.map (V ∘ σ) xs)) E H
⊢ Holds D I (Function.updateListITE V'' zs (List.map V' xs)) E H ↔
    Holds D I V E (Var.All.Rec.Fresh.sub (Function.updateListITE id zs (List.map σ xs)) c H)

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
s1 :
  Holds D I V E (Var.All.Rec.Fresh.sub (Function.updateListITE id zs (List.map σ xs)) c H) ↔
    Holds D I (Function.updateListITE V zs (List.map (V ∘ σ) xs)) E H
⊢ Holds D I (Function.updateListITE V'' zs (List.map V' xs)) E H ↔
    Holds D I V E (Var.All.Rec.Fresh.sub (Function.updateListITE id zs (List.map σ xs)) c H)
Tactic:
simp only [s1]
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
s1 :
  Holds D I V E (Var.All.Rec.Fresh.sub (Function.updateListITE id zs (List.map σ xs)) c H) ↔
    Holds D I (Function.updateListITE V zs (List.map (V ∘ σ) xs)) E H
⊢ Holds D I (Function.updateListITE V'' zs (List.map V' xs)) E H ↔
    Holds D I (Function.updateListITE V zs (List.map (V ∘ σ) xs)) E H

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
s1 :
  Holds D I V E (Var.All.Rec.Fresh.sub (Function.updateListITE id zs (List.map σ xs)) c H) ↔
    Holds D I (Function.updateListITE V zs (List.map (V ∘ σ) xs)) E H
⊢ Holds D I (Function.updateListITE V'' zs (List.map V' xs)) E H ↔
    Holds D I (Function.updateListITE V zs (List.map (V ∘ σ) xs)) E H
Tactic:
clear s1
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
⊢ Holds D I (Function.updateListITE V'' zs (List.map V' xs)) E H ↔
    Holds D I (Function.updateListITE V zs (List.map (V ∘ σ) xs)) E H

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
⊢ Holds D I (Function.updateListITE V'' zs (List.map V' xs)) E H ↔
    Holds D I (Function.updateListITE V zs (List.map (V ∘ σ) xs)) E H
Tactic:
apply Holds_coincide_Var
State after:
case h1
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
⊢ ∀ (v : VarName),
    isFreeIn v H →
      Function.updateListITE V'' zs (List.map V' xs) v = Function.updateListITE V zs (List.map (V ∘ σ) xs) v

State before:
case h1
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
⊢ ∀ (v : VarName),
    isFreeIn v H →
      Function.updateListITE V'' zs (List.map V' xs) v = Function.updateListITE V zs (List.map (V ∘ σ) xs) v
Tactic:
intro x a1
State after:
case h1
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
⊢ Function.updateListITE V'' zs (List.map V' xs) x = Function.updateListITE V zs (List.map (V ∘ σ) xs) x

State before:
case h1
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
⊢ Function.updateListITE V'' zs (List.map V' xs) x = Function.updateListITE V zs (List.map (V ∘ σ) xs) x
Tactic:
by_cases c3 : x ∈ zs
State after:
case pos
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
c3 : x ∈ zs
⊢ Function.updateListITE V'' zs (List.map V' xs) x = Function.updateListITE V zs (List.map (V ∘ σ) xs) x

case neg
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
c3 : x ∉ zs
⊢ Function.updateListITE V'' zs (List.map V' xs) x = Function.updateListITE V zs (List.map (V ∘ σ) xs) x

State before:
case pos
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
c3 : x ∈ zs
⊢ Function.updateListITE V'' zs (List.map V' xs) x = Function.updateListITE V zs (List.map (V ∘ σ) xs) x
Tactic:
apply Function.updateListITE_map_mem_ext
State after:
case pos.h1
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
c3 : x ∈ zs
⊢ ∀ y ∈ xs, V' y = (V ∘ σ) y

case pos.h2
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
c3 : x ∈ zs
⊢ zs.length = xs.length

case pos.h3
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
c3 : x ∈ zs
⊢ x ∈ zs

State before:
case pos.h1
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
c3 : x ∈ zs
⊢ ∀ y ∈ xs, V' y = (V ∘ σ) y
Tactic:
simp
State after:
case pos.h1
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
c3 : x ∈ zs
⊢ ∀ y ∈ xs, V' y = V (σ y)

State before:
case pos.h1
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
c3 : x ∈ zs
⊢ ∀ y ∈ xs, V' y = V (σ y)
Tactic:
exact h1
State after:
no goals

State before:
case pos.h2
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
c3 : x ∈ zs
⊢ zs.length = xs.length
Tactic:
simp only [← c2]
State after:
no goals

State before:
case pos.h3
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
c3 : x ∈ zs
⊢ x ∈ zs
Tactic:
exact c3
State after:
no goals

State before:
case neg
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
c3 : x ∉ zs
⊢ Function.updateListITE V'' zs (List.map V' xs) x = Function.updateListITE V zs (List.map (V ∘ σ) xs) x
Tactic:
simp only [Function.updateListITE_not_mem V'' x zs (List.map V' xs) c3]
State after:
case neg
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
c3 : x ∉ zs
⊢ V'' x = Function.updateListITE V zs (List.map (V ∘ σ) xs) x

State before:
case neg
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
c3 : x ∉ zs
⊢ V'' x = Function.updateListITE V zs (List.map (V ∘ σ) xs) x
Tactic:
simp only [Function.updateListITE_not_mem V x zs (List.map (V ∘ σ ) xs) c3]
State after:
case neg
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
c3 : x ∉ zs
⊢ V'' x = V x

State before:
case neg
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
c3 : x ∉ zs
⊢ V'' x = V x
Tactic:
apply h2
State after:
case neg.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
c3 : x ∉ zs
⊢ x ∈ H.freeVarSet

case neg.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
c3 : x ∉ zs
⊢ x ∉ zs

State before:
case neg.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
c3 : x ∉ zs
⊢ x ∈ H.freeVarSet
Tactic:
simp only [isFreeIn_iff_mem_freeVarSet] at a1
State after:
case neg.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
c3 : x ∉ zs
a1 : x ∈ H.freeVarSet
⊢ x ∈ H.freeVarSet

State before:
case neg.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
c3 : x ∉ zs
a1 : x ∈ H.freeVarSet
⊢ x ∈ H.freeVarSet
Tactic:
exact a1
State after:
no goals

State before:
case neg.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
c1 : (τ X xs.length).isSome = true
zs : List VarName := ((τ X xs.length).get ⋯).1
c2 : xs.length = zs.length
H : Formula := ((τ X xs.length).get ⋯).2
h2 : ∀ x ∈ H.freeVarSet, x ∉ zs → V'' x = V x
x : VarName
a1 : isFreeIn x H
c3 : x ∉ zs
⊢ x ∉ zs
Tactic:
exact c3
State after:
no goals

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : (τ X xs.length).isSome = true
c2 : ¬xs.length = ((τ X xs.length).get ⋯).1.length
⊢ I.pred_var_ X (List.map V' xs) ↔ Holds D I V E (pred_var_ X (List.map σ xs))
Tactic:
simp only [Holds]
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : (τ X xs.length).isSome = true
c2 : ¬xs.length = ((τ X xs.length).get ⋯).1.length
⊢ I.pred_var_ X (List.map V' xs) ↔ I.pred_var_ X (List.map V (List.map σ xs))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : (τ X xs.length).isSome = true
c2 : ¬xs.length = ((τ X xs.length).get ⋯).1.length
⊢ I.pred_var_ X (List.map V' xs) ↔ I.pred_var_ X (List.map V (List.map σ xs))
Tactic:
simp
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : (τ X xs.length).isSome = true
c2 : ¬xs.length = ((τ X xs.length).get ⋯).1.length
⊢ I.pred_var_ X (List.map V' xs) ↔ I.pred_var_ X (List.map (V ∘ σ) xs)

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : (τ X xs.length).isSome = true
c2 : ¬xs.length = ((τ X xs.length).get ⋯).1.length
⊢ I.pred_var_ X (List.map V' xs) ↔ I.pred_var_ X (List.map (V ∘ σ) xs)
Tactic:
congr! 1
State after:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : (τ X xs.length).isSome = true
c2 : ¬xs.length = ((τ X xs.length).get ⋯).1.length
⊢ List.map V' xs = List.map (V ∘ σ) xs

State before:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : (τ X xs.length).isSome = true
c2 : ¬xs.length = ((τ X xs.length).get ⋯).1.length
⊢ List.map V' xs = List.map (V ∘ σ) xs
Tactic:
simp only [List.map_eq_map_iff]
State after:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : (τ X xs.length).isSome = true
c2 : ¬xs.length = ((τ X xs.length).get ⋯).1.length
⊢ ∀ x ∈ xs, V' x = (V ∘ σ) x

State before:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : (τ X xs.length).isSome = true
c2 : ¬xs.length = ((τ X xs.length).get ⋯).1.length
⊢ ∀ x ∈ xs, V' x = (V ∘ σ) x
Tactic:
intro x a1
State after:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : (τ X xs.length).isSome = true
c2 : ¬xs.length = ((τ X xs.length).get ⋯).1.length
x : VarName
a1 : x ∈ xs
⊢ V' x = (V ∘ σ) x

State before:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : (τ X xs.length).isSome = true
c2 : ¬xs.length = ((τ X xs.length).get ⋯).1.length
x : VarName
a1 : x ∈ xs
⊢ V' x = (V ∘ σ) x
Tactic:
simp
State after:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : (τ X xs.length).isSome = true
c2 : ¬xs.length = ((τ X xs.length).get ⋯).1.length
x : VarName
a1 : x ∈ xs
⊢ V' x = V (σ x)

State before:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : (τ X xs.length).isSome = true
c2 : ¬xs.length = ((τ X xs.length).get ⋯).1.length
x : VarName
a1 : x ∈ xs
⊢ V' x = V (σ x)
Tactic:
exact h1 x a1
State after:
no goals

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : ¬(τ X xs.length).isSome = true
⊢ I.pred_var_ X (List.map V' xs) ↔ Holds D I V E (pred_var_ X (List.map σ xs))
Tactic:
simp only [Holds]
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : ¬(τ X xs.length).isSome = true
⊢ I.pred_var_ X (List.map V' xs) ↔ I.pred_var_ X (List.map V (List.map σ xs))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : ¬(τ X xs.length).isSome = true
⊢ I.pred_var_ X (List.map V' xs) ↔ I.pred_var_ X (List.map V (List.map σ xs))
Tactic:
simp
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : ¬(τ X xs.length).isSome = true
⊢ I.pred_var_ X (List.map V' xs) ↔ I.pred_var_ X (List.map (V ∘ σ) xs)

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : ¬(τ X xs.length).isSome = true
⊢ I.pred_var_ X (List.map V' xs) ↔ I.pred_var_ X (List.map (V ∘ σ) xs)
Tactic:
congr! 1
State after:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : ¬(τ X xs.length).isSome = true
⊢ List.map V' xs = List.map (V ∘ σ) xs

State before:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : ¬(τ X xs.length).isSome = true
⊢ List.map V' xs = List.map (V ∘ σ) xs
Tactic:
simp only [List.map_eq_map_iff]
State after:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : ¬(τ X xs.length).isSome = true
⊢ ∀ x ∈ xs, V' x = (V ∘ σ) x

State before:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : ¬(τ X xs.length).isSome = true
⊢ ∀ x ∈ xs, V' x = (V ∘ σ) x
Tactic:
intro x a1
State after:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : ¬(τ X xs.length).isSome = true
x : VarName
a1 : x ∈ xs
⊢ V' x = (V ∘ σ) x

State before:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : ¬(τ X xs.length).isSome = true
x : VarName
a1 : x ∈ xs
⊢ V' x = (V ∘ σ) x
Tactic:
simp
State after:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : ¬(τ X xs.length).isSome = true
x : VarName
a1 : x ∈ xs
⊢ V' x = V (σ x)

State before:
case a.h.e'_4
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
X : PredName
xs : List VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ x ∈ xs, V' x = V (σ x)
h2 :
  ∀
    x ∈
      if h : (τ X xs.length).isSome = true then
        ((τ X xs.length).get ⋯).2.freeVarSet \ ((τ X xs.length).get ⋯).1.toFinset
      else ∅,
    V'' x = V x
c1 : ¬(τ X xs.length).isSome = true
x : VarName
a1 : x ∈ xs
⊢ V' x = V (σ x)
Tactic:
exact h1 x a1
State after:
no goals

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), isFreeIn x_1 (eq_ x y) → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
⊢ Holds D (I' D I V'' E τ) V' E (eq_ x y) ↔ Holds D I V E (subAux c τ σ (eq_ x y))
Tactic:
simp only [isFreeIn] at h1
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
⊢ Holds D (I' D I V'' E τ) V' E (eq_ x y) ↔ Holds D I V E (subAux c τ σ (eq_ x y))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
⊢ Holds D (I' D I V'' E τ) V' E (eq_ x y) ↔ Holds D I V E (subAux c τ σ (eq_ x y))
Tactic:
simp only [subAux]
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
⊢ Holds D (I' D I V'' E τ) V' E (eq_ x y) ↔ Holds D I V E (eq_ (σ x) (σ y))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
⊢ Holds D (I' D I V'' E τ) V' E (eq_ x y) ↔ Holds D I V E (eq_ (σ x) (σ y))
Tactic:
simp only [Holds]
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
⊢ V' x = V' y ↔ V (σ x) = V (σ y)

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
⊢ V' x = V' y ↔ V (σ x) = V (σ y)
Tactic:
have s1 : V' x = V (σ x)
State after:
case s1
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
⊢ V' x = V (σ x)

D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
s1 : V' x = V (σ x)
⊢ V' x = V' y ↔ V (σ x) = V (σ y)

State before:
case s1
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
⊢ V' x = V (σ x)

D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
s1 : V' x = V (σ x)
⊢ V' x = V' y ↔ V (σ x) = V (σ y)
Tactic:
apply h1
State after:
case s1.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
⊢ x = x ∨ x = y

D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
s1 : V' x = V (σ x)
⊢ V' x = V' y ↔ V (σ x) = V (σ y)

State before:
case s1.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
⊢ x = x ∨ x = y

D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
s1 : V' x = V (σ x)
⊢ V' x = V' y ↔ V (σ x) = V (σ y)
Tactic:
simp
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
s1 : V' x = V (σ x)
⊢ V' x = V' y ↔ V (σ x) = V (σ y)

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
s1 : V' x = V (σ x)
⊢ V' x = V' y ↔ V (σ x) = V (σ y)
Tactic:
simp only [s1]
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
s1 : V' x = V (σ x)
⊢ V (σ x) = V' y ↔ V (σ x) = V (σ y)

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
s1 : V' x = V (σ x)
⊢ V (σ x) = V' y ↔ V (σ x) = V (σ y)
Tactic:
have s2 : V' y = V (σ y)
State after:
case s2
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
s1 : V' x = V (σ x)
⊢ V' y = V (σ y)

D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
s1 : V' x = V (σ x)
s2 : V' y = V (σ y)
⊢ V (σ x) = V' y ↔ V (σ x) = V (σ y)

State before:
case s2
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
s1 : V' x = V (σ x)
⊢ V' y = V (σ y)

D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
s1 : V' x = V (σ x)
s2 : V' y = V (σ y)
⊢ V (σ x) = V' y ↔ V (σ x) = V (σ y)
Tactic:
apply h1
State after:
case s2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
s1 : V' x = V (σ x)
⊢ y = x ∨ y = y

D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
s1 : V' x = V (σ x)
s2 : V' y = V (σ y)
⊢ V (σ x) = V' y ↔ V (σ x) = V (σ y)

State before:
case s2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
s1 : V' x = V (σ x)
⊢ y = x ∨ y = y

D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
s1 : V' x = V (σ x)
s2 : V' y = V (σ y)
⊢ V (σ x) = V' y ↔ V (σ x) = V (σ y)
Tactic:
simp
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
s1 : V' x = V (σ x)
s2 : V' y = V (σ y)
⊢ V (σ x) = V' y ↔ V (σ x) = V (σ y)

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x y : VarName
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), x_1 = x ∨ x_1 = y → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (eq_ x y).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
s1 : V' x = V (σ x)
s2 : V' y = V (σ y)
⊢ V (σ x) = V' y ↔ V (σ x) = V (σ y)
Tactic:
simp only [s2]
State after:
no goals

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x false_ → V' x = V (σ x)
h2 : ∀ x ∈ false_.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E false_ ↔ Holds D I V E (subAux c τ σ false_)
Tactic:
simp only [subAux]
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x false_ → V' x = V (σ x)
h2 : ∀ x ∈ false_.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E false_ ↔ Holds D I V E false_

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x false_ → V' x = V (σ x)
h2 : ∀ x ∈ false_.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E false_ ↔ Holds D I V E false_
Tactic:
simp only [Holds]
State after:
no goals

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi.not_ → V' x = V (σ x)
h2 : ∀ x ∈ phi.not_.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E phi.not_ ↔ Holds D I V E (subAux c τ σ phi.not_)
Tactic:
simp only [isFreeIn] at h1
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)
h2 : ∀ x ∈ phi.not_.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E phi.not_ ↔ Holds D I V E (subAux c τ σ phi.not_)

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)
h2 : ∀ x ∈ phi.not_.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E phi.not_ ↔ Holds D I V E (subAux c τ σ phi.not_)
Tactic:
simp only [predVarSet] at h2
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E phi.not_ ↔ Holds D I V E (subAux c τ σ phi.not_)

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E phi.not_ ↔ Holds D I V E (subAux c τ σ phi.not_)
Tactic:
simp only [subAux]
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E phi.not_ ↔ Holds D I V E (subAux c τ σ phi).not_

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E phi.not_ ↔ Holds D I V E (subAux c τ σ phi).not_
Tactic:
simp only [Holds]
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ ¬Holds D (I' D I V'' E τ) V' E phi ↔ ¬Holds D I V E (subAux c τ σ phi)

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ ¬Holds D (I' D I V'' E τ) V' E phi ↔ ¬Holds D I V E (subAux c τ σ phi)
Tactic:
congr! 1
State after:
case a.h.e'_1.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi)

State before:
case a.h.e'_1.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi)
Tactic:
exact phi_ih V V' σ h1 h2
State after:
no goals

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x (phi.iff_ psi) → V' x = V (σ x)
h2 : ∀ x ∈ (phi.iff_ psi).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (phi.iff_ psi) ↔ Holds D I V E (subAux c τ σ (phi.iff_ psi))
Tactic:
simp only [isFreeIn] at h1
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.iff_ psi).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (phi.iff_ psi) ↔ Holds D I V E (subAux c τ σ (phi.iff_ psi))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.iff_ psi).predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (phi.iff_ psi) ↔ Holds D I V E (subAux c τ σ (phi.iff_ psi))
Tactic:
simp only [predVarSet] at h2
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (phi.iff_ psi) ↔ Holds D I V E (subAux c τ σ (phi.iff_ psi))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (phi.iff_ psi) ↔ Holds D I V E (subAux c τ σ (phi.iff_ psi))
Tactic:
simp only [subAux]
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (phi.iff_ psi) ↔ Holds D I V E ((subAux c τ σ phi).iff_ (subAux c τ σ psi))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (phi.iff_ psi) ↔ Holds D I V E ((subAux c τ σ phi).iff_ (subAux c τ σ psi))
Tactic:
simp only [Holds]
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D (I' D I V'' E τ) V' E psi) ↔
    (Holds D I V E (subAux c τ σ phi) ↔ Holds D I V E (subAux c τ σ psi))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D (I' D I V'' E τ) V' E psi) ↔
    (Holds D I V E (subAux c τ σ phi) ↔ Holds D I V E (subAux c τ σ psi))
Tactic:
congr! 1
State after:
case a.h.e'_1.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi)

case a.h.e'_2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi)

State before:
case a.h.e'_1.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi)
Tactic:
apply phi_ih V V' σ
State after:
case a.h.e'_1.a.h1
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ ∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)

case a.h.e'_1.a.h2
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x

State before:
case a.h.e'_1.a.h1
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ ∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)
Tactic:
intro x a1
State after:
case a.h.e'_1.a.h1
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : isFreeIn x phi
⊢ V' x = V (σ x)

State before:
case a.h.e'_1.a.h1
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : isFreeIn x phi
⊢ V' x = V (σ x)
Tactic:
apply h1
State after:
case a.h.e'_1.a.h1.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : isFreeIn x phi
⊢ isFreeIn x phi ∨ isFreeIn x psi

State before:
case a.h.e'_1.a.h1.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : isFreeIn x phi
⊢ isFreeIn x phi ∨ isFreeIn x psi
Tactic:
left
State after:
case a.h.e'_1.a.h1.a.h
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : isFreeIn x phi
⊢ isFreeIn x phi

State before:
case a.h.e'_1.a.h1.a.h
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : isFreeIn x phi
⊢ isFreeIn x phi
Tactic:
exact a1
State after:
no goals

State before:
case a.h.e'_1.a.h2
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
Tactic:
intro x a1
State after:
case a.h.e'_1.a.h2
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ)
⊢ V'' x = V x

State before:
case a.h.e'_1.a.h2
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ)
⊢ V'' x = V x
Tactic:
apply h2
State after:
case a.h.e'_1.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ)
⊢ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ)

State before:
case a.h.e'_1.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ)
⊢ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ)
Tactic:
simp only [Finset.mem_biUnion, Finset.mem_union] at a1
State after:
case a.h.e'_1.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : ∃ a ∈ phi.predVarSet, x ∈ predVarFreeVarSet τ a
⊢ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ)

State before:
case a.h.e'_1.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : ∃ a ∈ phi.predVarSet, x ∈ predVarFreeVarSet τ a
⊢ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ)
Tactic:
apply Exists.elim a1
State after:
case a.h.e'_1.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : ∃ a ∈ phi.predVarSet, x ∈ predVarFreeVarSet τ a
⊢ ∀ (a : PredName × ℕ),
    a ∈ phi.predVarSet ∧ x ∈ predVarFreeVarSet τ a → x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ)

State before:
case a.h.e'_1.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : ∃ a ∈ phi.predVarSet, x ∈ predVarFreeVarSet τ a
⊢ ∀ (a : PredName × ℕ),
    a ∈ phi.predVarSet ∧ x ∈ predVarFreeVarSet τ a → x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ)
Tactic:
intro a a2
State after:
case a.h.e'_1.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : ∃ a ∈ phi.predVarSet, x ∈ predVarFreeVarSet τ a
a : PredName × ℕ
a2 : a ∈ phi.predVarSet ∧ x ∈ predVarFreeVarSet τ a
⊢ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ)

State before:
case a.h.e'_1.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : ∃ a ∈ phi.predVarSet, x ∈ predVarFreeVarSet τ a
a : PredName × ℕ
a2 : a ∈ phi.predVarSet ∧ x ∈ predVarFreeVarSet τ a
⊢ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ)
Tactic:
simp only [Finset.mem_biUnion, Finset.mem_union]
State after:
case a.h.e'_1.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : ∃ a ∈ phi.predVarSet, x ∈ predVarFreeVarSet τ a
a : PredName × ℕ
a2 : a ∈ phi.predVarSet ∧ x ∈ predVarFreeVarSet τ a
⊢ ∃ a, (a ∈ phi.predVarSet ∨ a ∈ psi.predVarSet) ∧ x ∈ predVarFreeVarSet τ a

State before:
case a.h.e'_1.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : ∃ a ∈ phi.predVarSet, x ∈ predVarFreeVarSet τ a
a : PredName × ℕ
a2 : a ∈ phi.predVarSet ∧ x ∈ predVarFreeVarSet τ a
⊢ ∃ a, (a ∈ phi.predVarSet ∨ a ∈ psi.predVarSet) ∧ x ∈ predVarFreeVarSet τ a
Tactic:
apply Exists.intro a
State after:
case a.h.e'_1.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : ∃ a ∈ phi.predVarSet, x ∈ predVarFreeVarSet τ a
a : PredName × ℕ
a2 : a ∈ phi.predVarSet ∧ x ∈ predVarFreeVarSet τ a
⊢ (a ∈ phi.predVarSet ∨ a ∈ psi.predVarSet) ∧ x ∈ predVarFreeVarSet τ a

State before:
case a.h.e'_1.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : ∃ a ∈ phi.predVarSet, x ∈ predVarFreeVarSet τ a
a : PredName × ℕ
a2 : a ∈ phi.predVarSet ∧ x ∈ predVarFreeVarSet τ a
⊢ (a ∈ phi.predVarSet ∨ a ∈ psi.predVarSet) ∧ x ∈ predVarFreeVarSet τ a
Tactic:
tauto
State after:
no goals

State before:
case a.h.e'_2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi)
Tactic:
apply psi_ih V V' σ
State after:
case a.h.e'_2.a.h1
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ ∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)

case a.h.e'_2.a.h2
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ ∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x

State before:
case a.h.e'_2.a.h1
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ ∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)
Tactic:
intro x a1
State after:
case a.h.e'_2.a.h1
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : isFreeIn x psi
⊢ V' x = V (σ x)

State before:
case a.h.e'_2.a.h1
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : isFreeIn x psi
⊢ V' x = V (σ x)
Tactic:
apply h1
State after:
case a.h.e'_2.a.h1.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : isFreeIn x psi
⊢ isFreeIn x phi ∨ isFreeIn x psi

State before:
case a.h.e'_2.a.h1.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : isFreeIn x psi
⊢ isFreeIn x phi ∨ isFreeIn x psi
Tactic:
right
State after:
case a.h.e'_2.a.h1.a.h
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : isFreeIn x psi
⊢ isFreeIn x psi

State before:
case a.h.e'_2.a.h1.a.h
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : isFreeIn x psi
⊢ isFreeIn x psi
Tactic:
exact a1
State after:
no goals

State before:
case a.h.e'_2.a.h2
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ ∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
Tactic:
intro x a1
State after:
case a.h.e'_2.a.h2
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ)
⊢ V'' x = V x

State before:
case a.h.e'_2.a.h2
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ)
⊢ V'' x = V x
Tactic:
apply h2
State after:
case a.h.e'_2.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ)
⊢ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ)

State before:
case a.h.e'_2.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ)
⊢ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ)
Tactic:
simp only [Finset.mem_biUnion, Finset.mem_union] at a1
State after:
case a.h.e'_2.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : ∃ a ∈ psi.predVarSet, x ∈ predVarFreeVarSet τ a
⊢ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ)

State before:
case a.h.e'_2.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : ∃ a ∈ psi.predVarSet, x ∈ predVarFreeVarSet τ a
⊢ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ)
Tactic:
apply Exists.elim a1
State after:
case a.h.e'_2.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : ∃ a ∈ psi.predVarSet, x ∈ predVarFreeVarSet τ a
⊢ ∀ (a : PredName × ℕ),
    a ∈ psi.predVarSet ∧ x ∈ predVarFreeVarSet τ a → x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ)

State before:
case a.h.e'_2.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : ∃ a ∈ psi.predVarSet, x ∈ predVarFreeVarSet τ a
⊢ ∀ (a : PredName × ℕ),
    a ∈ psi.predVarSet ∧ x ∈ predVarFreeVarSet τ a → x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ)
Tactic:
intro a a2
State after:
case a.h.e'_2.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : ∃ a ∈ psi.predVarSet, x ∈ predVarFreeVarSet τ a
a : PredName × ℕ
a2 : a ∈ psi.predVarSet ∧ x ∈ predVarFreeVarSet τ a
⊢ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ)

State before:
case a.h.e'_2.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : ∃ a ∈ psi.predVarSet, x ∈ predVarFreeVarSet τ a
a : PredName × ℕ
a2 : a ∈ psi.predVarSet ∧ x ∈ predVarFreeVarSet τ a
⊢ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ)
Tactic:
simp only [Finset.mem_biUnion, Finset.mem_union]
State after:
case a.h.e'_2.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : ∃ a ∈ psi.predVarSet, x ∈ predVarFreeVarSet τ a
a : PredName × ℕ
a2 : a ∈ psi.predVarSet ∧ x ∈ predVarFreeVarSet τ a
⊢ ∃ a, (a ∈ phi.predVarSet ∨ a ∈ psi.predVarSet) ∧ x ∈ predVarFreeVarSet τ a

State before:
case a.h.e'_2.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : ∃ a ∈ psi.predVarSet, x ∈ predVarFreeVarSet τ a
a : PredName × ℕ
a2 : a ∈ psi.predVarSet ∧ x ∈ predVarFreeVarSet τ a
⊢ ∃ a, (a ∈ phi.predVarSet ∨ a ∈ psi.predVarSet) ∧ x ∈ predVarFreeVarSet τ a
Tactic:
apply Exists.intro a
State after:
case a.h.e'_2.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : ∃ a ∈ psi.predVarSet, x ∈ predVarFreeVarSet τ a
a : PredName × ℕ
a2 : a ∈ psi.predVarSet ∧ x ∈ predVarFreeVarSet τ a
⊢ (a ∈ phi.predVarSet ∨ a ∈ psi.predVarSet) ∧ x ∈ predVarFreeVarSet τ a

State before:
case a.h.e'_2.a.h2.a
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
phi psi : Formula
phi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
psi_ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x psi → V' x = V (σ x)) →
      (∀ x ∈ psi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E psi ↔ Holds D I V E (subAux c τ σ psi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x : VarName), isFreeIn x phi ∨ isFreeIn x psi → V' x = V (σ x)
h2 : ∀ x ∈ (phi.predVarSet ∪ psi.predVarSet).biUnion (predVarFreeVarSet τ), V'' x = V x
x : VarName
a1 : ∃ a ∈ psi.predVarSet, x ∈ predVarFreeVarSet τ a
a : PredName × ℕ
a2 : a ∈ psi.predVarSet ∧ x ∈ predVarFreeVarSet τ a
⊢ (a ∈ phi.predVarSet ∨ a ∈ psi.predVarSet) ∧ x ∈ predVarFreeVarSet τ a
Tactic:
tauto
State after:
no goals

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x : VarName
phi : Formula
ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), isFreeIn x_1 (exists_ x phi) → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (exists_ x phi).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
⊢ Holds D (I' D I V'' E τ) V' E (exists_ x phi) ↔ Holds D I V E (subAux c τ σ (exists_ x phi))
Tactic:
simp only [isFreeIn] at h1
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x : VarName
phi : Formula
ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), ¬x_1 = x ∧ isFreeIn x_1 phi → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (exists_ x phi).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
⊢ Holds D (I' D I V'' E τ) V' E (exists_ x phi) ↔ Holds D I V E (subAux c τ σ (exists_ x phi))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x : VarName
phi : Formula
ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), ¬x_1 = x ∧ isFreeIn x_1 phi → V' x_1 = V (σ x_1)
h2 : ∀ x_1 ∈ (exists_ x phi).predVarSet.biUnion (predVarFreeVarSet τ), V'' x_1 = V x_1
⊢ Holds D (I' D I V'' E τ) V' E (exists_ x phi) ↔ Holds D I V E (subAux c τ σ (exists_ x phi))
Tactic:
simp only [predVarSet] at h2
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x : VarName
phi : Formula
ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), ¬x_1 = x ∧ isFreeIn x_1 phi → V' x_1 = V (σ x_1)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (exists_ x phi) ↔ Holds D I V E (subAux c τ σ (exists_ x phi))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x : VarName
phi : Formula
ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), ¬x_1 = x ∧ isFreeIn x_1 phi → V' x_1 = V (σ x_1)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (exists_ x phi) ↔ Holds D I V E (subAux c τ σ (exists_ x phi))
Tactic:
simp only [subAux]
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x : VarName
phi : Formula
ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), ¬x_1 = x ∧ isFreeIn x_1 phi → V' x_1 = V (σ x_1)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (exists_ x phi) ↔
    Holds D I V E
      (exists_
        (if
            x ∈
              Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ) then
          fresh x c
            (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
        else x)
        (subAux c τ
          (Function.updateITE σ x
            (if
                x ∈
                  Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                    phi.predVarSet.biUnion (predVarFreeVarSet τ) then
              fresh x c
                (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
            else x))
          phi))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x : VarName
phi : Formula
ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), ¬x_1 = x ∧ isFreeIn x_1 phi → V' x_1 = V (σ x_1)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D (I' D I V'' E τ) V' E (exists_ x phi) ↔
    Holds D I V E
      (exists_
        (if
            x ∈
              Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ) then
          fresh x c
            (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
        else x)
        (subAux c τ
          (Function.updateITE σ x
            (if
                x ∈
                  Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                    phi.predVarSet.biUnion (predVarFreeVarSet τ) then
              fresh x c
                (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
            else x))
          phi))
Tactic:
simp only [I']
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x : VarName
phi : Formula
ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), ¬x_1 = x ∧ isFreeIn x_1 phi → V' x_1 = V (σ x_1)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D
      (Interpretation.usingPred D I fun X ds =>
        if h : (τ X ds.length).isSome = true then
          if ds.length = ((τ X ds.length).get ⋯).1.length then
            Holds D I (Function.updateListITE V'' ((τ X ds.length).get ⋯).1 ds) E ((τ X ds.length).get ⋯).2
          else I.pred_var_ X ds
        else I.pred_var_ X ds)
      V' E (exists_ x phi) ↔
    Holds D I V E
      (exists_
        (if
            x ∈
              Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ) then
          fresh x c
            (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
        else x)
        (subAux c τ
          (Function.updateITE σ x
            (if
                x ∈
                  Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                    phi.predVarSet.biUnion (predVarFreeVarSet τ) then
              fresh x c
                (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
            else x))
          phi))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x : VarName
phi : Formula
ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), ¬x_1 = x ∧ isFreeIn x_1 phi → V' x_1 = V (σ x_1)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D
      (Interpretation.usingPred D I fun X ds =>
        if h : (τ X ds.length).isSome = true then
          if ds.length = ((τ X ds.length).get ⋯).1.length then
            Holds D I (Function.updateListITE V'' ((τ X ds.length).get ⋯).1 ds) E ((τ X ds.length).get ⋯).2
          else I.pred_var_ X ds
        else I.pred_var_ X ds)
      V' E (exists_ x phi) ↔
    Holds D I V E
      (exists_
        (if
            x ∈
              Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ) then
          fresh x c
            (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
        else x)
        (subAux c τ
          (Function.updateITE σ x
            (if
                x ∈
                  Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                    phi.predVarSet.biUnion (predVarFreeVarSet τ) then
              fresh x c
                (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
            else x))
          phi))
Tactic:
simp only [Interpretation.usingPred]
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x : VarName
phi : Formula
ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), ¬x_1 = x ∧ isFreeIn x_1 phi → V' x_1 = V (σ x_1)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D
      { nonempty := ⋯, pred_const_ := I.pred_const_,
        pred_var_ := fun X ds =>
          if h : (τ X ds.length).isSome = true then
            if ds.length = ((τ X ds.length).get ⋯).1.length then
              Holds D I (Function.updateListITE V'' ((τ X ds.length).get ⋯).1 ds) E ((τ X ds.length).get ⋯).2
            else I.pred_var_ X ds
          else I.pred_var_ X ds }
      V' E (exists_ x phi) ↔
    Holds D I V E
      (exists_
        (if
            x ∈
              Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ) then
          fresh x c
            (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
        else x)
        (subAux c τ
          (Function.updateITE σ x
            (if
                x ∈
                  Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                    phi.predVarSet.biUnion (predVarFreeVarSet τ) then
              fresh x c
                (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
            else x))
          phi))

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x : VarName
phi : Formula
ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), ¬x_1 = x ∧ isFreeIn x_1 phi → V' x_1 = V (σ x_1)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ Holds D
      { nonempty := ⋯, pred_const_ := I.pred_const_,
        pred_var_ := fun X ds =>
          if h : (τ X ds.length).isSome = true then
            if ds.length = ((τ X ds.length).get ⋯).1.length then
              Holds D I (Function.updateListITE V'' ((τ X ds.length).get ⋯).1 ds) E ((τ X ds.length).get ⋯).2
            else I.pred_var_ X ds
          else I.pred_var_ X ds }
      V' E (exists_ x phi) ↔
    Holds D I V E
      (exists_
        (if
            x ∈
              Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ) then
          fresh x c
            (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
        else x)
        (subAux c τ
          (Function.updateITE σ x
            (if
                x ∈
                  Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                    phi.predVarSet.biUnion (predVarFreeVarSet τ) then
              fresh x c
                (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
            else x))
          phi))
Tactic:
simp only [Holds]
State after:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x : VarName
phi : Formula
ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), ¬x_1 = x ∧ isFreeIn x_1 phi → V' x_1 = V (σ x_1)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ (∃ d,
      Holds D
        { nonempty := ⋯, pred_const_ := I.pred_const_,
          pred_var_ := fun X ds =>
            if h : (τ X ds.length).isSome = true then
              if ds.length = ((τ X ds.length).get ⋯).1.length then
                Holds D I (Function.updateListITE V'' ((τ X ds.length).get ⋯).1 ds) E ((τ X ds.length).get ⋯).2
              else I.pred_var_ X ds
            else I.pred_var_ X ds }
        (Function.updateITE V' x d) E phi) ↔
    ∃ d,
      Holds D I
        (Function.updateITE V
          (if
              x ∈
                Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                  phi.predVarSet.biUnion (predVarFreeVarSet τ) then
            fresh x c
              (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
          else x)
          d)
        E
        (subAux c τ
          (Function.updateITE σ x
            (if
                x ∈
                  Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                    phi.predVarSet.biUnion (predVarFreeVarSet τ) then
              fresh x c
                (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
            else x))
          phi)

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x : VarName
phi : Formula
ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), ¬x_1 = x ∧ isFreeIn x_1 phi → V' x_1 = V (σ x_1)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ (∃ d,
      Holds D
        { nonempty := ⋯, pred_const_ := I.pred_const_,
          pred_var_ := fun X ds =>
            if h : (τ X ds.length).isSome = true then
              if ds.length = ((τ X ds.length).get ⋯).1.length then
                Holds D I (Function.updateListITE V'' ((τ X ds.length).get ⋯).1 ds) E ((τ X ds.length).get ⋯).2
              else I.pred_var_ X ds
            else I.pred_var_ X ds }
        (Function.updateITE V' x d) E phi) ↔
    ∃ d,
      Holds D I
        (Function.updateITE V
          (if
              x ∈
                Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                  phi.predVarSet.biUnion (predVarFreeVarSet τ) then
            fresh x c
              (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
          else x)
          d)
        E
        (subAux c τ
          (Function.updateITE σ x
            (if
                x ∈
                  Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                    phi.predVarSet.biUnion (predVarFreeVarSet τ) then
              fresh x c
                (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
            else x))
          phi)
Tactic:
first | apply forall_congr' | apply exists_congr
State after:
case h
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x : VarName
phi : Formula
ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), ¬x_1 = x ∧ isFreeIn x_1 phi → V' x_1 = V (σ x_1)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ ∀ (a : D),
    Holds D
        { nonempty := ⋯, pred_const_ := I.pred_const_,
          pred_var_ := fun X ds =>
            if h : (τ X ds.length).isSome = true then
              if ds.length = ((τ X ds.length).get ⋯).1.length then
                Holds D I (Function.updateListITE V'' ((τ X ds.length).get ⋯).1 ds) E ((τ X ds.length).get ⋯).2
              else I.pred_var_ X ds
            else I.pred_var_ X ds }
        (Function.updateITE V' x a) E phi ↔
      Holds D I
        (Function.updateITE V
          (if
              x ∈
                Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                  phi.predVarSet.biUnion (predVarFreeVarSet τ) then
            fresh x c
              (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
          else x)
          a)
        E
        (subAux c τ
          (Function.updateITE σ x
            (if
                x ∈
                  Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                    phi.predVarSet.biUnion (predVarFreeVarSet τ) then
              fresh x c
                (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
            else x))
          phi)

State before:
case h
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x : VarName
phi : Formula
ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), ¬x_1 = x ∧ isFreeIn x_1 phi → V' x_1 = V (σ x_1)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ ∀ (a : D),
    Holds D
        { nonempty := ⋯, pred_const_ := I.pred_const_,
          pred_var_ := fun X ds =>
            if h : (τ X ds.length).isSome = true then
              if ds.length = ((τ X ds.length).get ⋯).1.length then
                Holds D I (Function.updateListITE V'' ((τ X ds.length).get ⋯).1 ds) E ((τ X ds.length).get ⋯).2
              else I.pred_var_ X ds
            else I.pred_var_ X ds }
        (Function.updateITE V' x a) E phi ↔
      Holds D I
        (Function.updateITE V
          (if
              x ∈
                Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                  phi.predVarSet.biUnion (predVarFreeVarSet τ) then
            fresh x c
              (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
          else x)
          a)
        E
        (subAux c τ
          (Function.updateITE σ x
            (if
                x ∈
                  Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                    phi.predVarSet.biUnion (predVarFreeVarSet τ) then
              fresh x c
                (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
            else x))
          phi)
Tactic:
intro d
State after:
case h
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x : VarName
phi : Formula
ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), ¬x_1 = x ∧ isFreeIn x_1 phi → V' x_1 = V (σ x_1)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
d : D
⊢ Holds D
      { nonempty := ⋯, pred_const_ := I.pred_const_,
        pred_var_ := fun X ds =>
          if h : (τ X ds.length).isSome = true then
            if ds.length = ((τ X ds.length).get ⋯).1.length then
              Holds D I (Function.updateListITE V'' ((τ X ds.length).get ⋯).1 ds) E ((τ X ds.length).get ⋯).2
            else I.pred_var_ X ds
          else I.pred_var_ X ds }
      (Function.updateITE V' x d) E phi ↔
    Holds D I
      (Function.updateITE V
        (if
            x ∈
              Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ) then
          fresh x c
            (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
        else x)
        d)
      E
      (subAux c τ
        (Function.updateITE σ x
          (if
              x ∈
                Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                  phi.predVarSet.biUnion (predVarFreeVarSet τ) then
            fresh x c
              (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
          else x))
        phi)

State before:
case h
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x : VarName
phi : Formula
ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), ¬x_1 = x ∧ isFreeIn x_1 phi → V' x_1 = V (σ x_1)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
d : D
⊢ Holds D
      { nonempty := ⋯, pred_const_ := I.pred_const_,
        pred_var_ := fun X ds =>
          if h : (τ X ds.length).isSome = true then
            if ds.length = ((τ X ds.length).get ⋯).1.length then
              Holds D I (Function.updateListITE V'' ((τ X ds.length).get ⋯).1 ds) E ((τ X ds.length).get ⋯).2
            else I.pred_var_ X ds
          else I.pred_var_ X ds }
      (Function.updateITE V' x d) E phi ↔
    Holds D I
      (Function.updateITE V
        (if
            x ∈
              Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ) then
          fresh x c
            (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
        else x)
        d)
      E
      (subAux c τ
        (Function.updateITE σ x
          (if
              x ∈
                Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                  phi.predVarSet.biUnion (predVarFreeVarSet τ) then
            fresh x c
              (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
          else x))
        phi)
Tactic:
apply ih
State after:
case h.h1
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x : VarName
phi : Formula
ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), ¬x_1 = x ∧ isFreeIn x_1 phi → V' x_1 = V (σ x_1)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
d : D
⊢ ∀ (x_1 : VarName),
    isFreeIn x_1 phi →
      Function.updateITE V' x d x_1 =
        Function.updateITE V
          (if
              x ∈
                Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                  phi.predVarSet.biUnion (predVarFreeVarSet τ) then
            fresh x c
              (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
          else x)
          d
          (Function.updateITE σ x
            (if
                x ∈
                  Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                    phi.predVarSet.biUnion (predVarFreeVarSet τ) then
              fresh x c
                (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
            else x)
            x_1)

case h.h2
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x : VarName
phi : Formula
ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), ¬x_1 = x ∧ isFreeIn x_1 phi → V' x_1 = V (σ x_1)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
d : D
⊢ ∀ x_1 ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ),
    V'' x_1 =
      Function.updateITE V
        (if
            x ∈
              Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ) then
          fresh x c
            (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
        else x)
        d x_1

State before:
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x : VarName
phi : Formula
ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), ¬x_1 = x ∧ isFreeIn x_1 phi → V' x_1 = V (σ x_1)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ (∀ (d : D),
      Holds D
        { nonempty := ⋯, pred_const_ := I.pred_const_,
          pred_var_ := fun X ds =>
            if h : (τ X ds.length).isSome = true then
              if ds.length = ((τ X ds.length).get ⋯).1.length then
                Holds D I (Function.updateListITE V'' ((τ X ds.length).get ⋯).1 ds) E ((τ X ds.length).get ⋯).2
              else I.pred_var_ X ds
            else I.pred_var_ X ds }
        (Function.updateITE V' x d) E phi) ↔
    ∀ (d : D),
      Holds D I
        (Function.updateITE V
          (if
              x ∈
                Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                  phi.predVarSet.biUnion (predVarFreeVarSet τ) then
            fresh x c
              (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
          else x)
          d)
        E
        (subAux c τ
          (Function.updateITE σ x
            (if
                x ∈
                  Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                    phi.predVarSet.biUnion (predVarFreeVarSet τ) then
              fresh x c
                (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
            else x))
          phi)
Tactic:
apply forall_congr'
State after:
case h
D : Type
I : Interpretation D
V'' : VarAssignment D
E : Env
c : Char
τ : PredName → ℕ → Option (List VarName × Formula)
x : VarName
phi : Formula
ih :
  ∀ (V V' : VarAssignment D) (σ : VarName → VarName),
    (∀ (x : VarName), isFreeIn x phi → V' x = V (σ x)) →
      (∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x) →
        (Holds D (I' D I V'' E τ) V' E phi ↔ Holds D I V E (subAux c τ σ phi))
V V' : VarAssignment D
σ : VarName → VarName
h1 : ∀ (x_1 : VarName), ¬x_1 = x ∧ isFreeIn x_1 phi → V' x_1 = V (σ x_1)
h2 : ∀ x ∈ phi.predVarSet.biUnion (predVarFreeVarSet τ), V'' x = V x
⊢ ∀ (a : D),
    Holds D
        { nonempty := ⋯, pred_const_ := I.pred_const_,
          pred_var_ := fun X ds =>
            if h : (τ X ds.length).isSome = true then
              if ds.length = ((τ X ds.length).get ⋯).1.length then
                Holds D I (Function.updateListITE V'' ((τ X ds.length).get ⋯).1 ds) E ((τ X ds.length).get ⋯).2
              else I.pred_var_ X ds
            else I.pred_var_ X ds }
        (Function.updateITE V' x a) E phi ↔
      Holds D I
        (Function.updateITE V
          (if
              x ∈
                Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                  phi.predVarSet.biUnion (predVarFreeVarSet τ) then
            fresh x c
              (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
          else x)
          a)
        E
        (subAux c τ
          (Function.updateITE σ x
            (if
                x ∈
                  Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪
                    phi.predVarSet.biUnion (predVarFreeVarSet τ) then
              fresh x c
                (Finset.image (Function.updateITE σ x x) phi.freeVarSet ∪ phi.predVarSet.biUnion (predVarFreeVarSet τ))
            else x))
          phi)