Theorem: FOL.NV.Sub.Pred.One.Ind.substitution_is_valid (FOL/NV/Sub/Pred/One/Ind/Sub.lean)

State before:
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : F.IsValid
⊢ F'.IsValid
Tactic:
simp only [IsValid] at h2
State after:
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
⊢ F'.IsValid

State before:
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
⊢ F'.IsValid
Tactic:
simp only [IsValid]
State after:
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
⊢ ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F'

State before:
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
⊢ ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F'
Tactic:
intro D I V E
State after:
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
⊢ Holds D I V E F'

State before:
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
⊢ Holds D I V E F'
Tactic:
let J : Interpretation D :=
  { nonempty := I.nonempty
    pred_const_ := I.pred_const_
    pred_var_ := fun (Q : PredName) (ds : List D) =>
      if (Q = P ∧ ds.length = zs.length)
      then Holds D I (Function.updateListITE V zs ds) E H
      else I.pred_var_ Q ds }
State after:
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
⊢ Holds D I V E F'

State before:
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
⊢ Holds D I V E F'
Tactic:
obtain s1 := substitution_theorem D I J V E F P zs H F' h1
State after:
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length → (Holds D I (Function.updateListITE V zs ds) E H ↔ J.pred_var_ P ds)) →
    I.pred_const_ = J.pred_const_ →
      (∀ (Q : PredName) (ds : List D), ¬(Q = P ∧ ds.length = zs.length) → (I.pred_var_ Q ds ↔ J.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
⊢ Holds D I V E F'

State before:
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length → (Holds D I (Function.updateListITE V zs ds) E H ↔ J.pred_var_ P ds)) →
    I.pred_const_ = J.pred_const_ →
      (∀ (Q : PredName) (ds : List D), ¬(Q = P ∧ ds.length = zs.length) → (I.pred_var_ Q ds ↔ J.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
⊢ Holds D I V E F'
Tactic:
simp only [Interpretation.pred_var_] at s1
State after:
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length →
        (Holds D I (Function.updateListITE V zs ds) E H ↔
          if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)) →
    True →
      (∀ (Q : PredName) (ds : List D),
          ¬(Q = P ∧ ds.length = zs.length) →
            (I.pred_var_ Q ds ↔
              if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H
              else I.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
⊢ Holds D I V E F'

State before:
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length →
        (Holds D I (Function.updateListITE V zs ds) E H ↔
          if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)) →
    True →
      (∀ (Q : PredName) (ds : List D),
          ¬(Q = P ∧ ds.length = zs.length) →
            (I.pred_var_ Q ds ↔
              if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H
              else I.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
s2 : Holds D I V E F' ↔ Holds D J V E F
⊢ Holds D I V E F'
Tactic:
simp only [s2]
State after:
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length →
        (Holds D I (Function.updateListITE V zs ds) E H ↔
          if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)) →
    True →
      (∀ (Q : PredName) (ds : List D),
          ¬(Q = P ∧ ds.length = zs.length) →
            (I.pred_var_ Q ds ↔
              if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H
              else I.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
s2 : Holds D I V E F' ↔ Holds D J V E F
⊢ Holds D J V E F

State before:
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length →
        (Holds D I (Function.updateListITE V zs ds) E H ↔
          if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)) →
    True →
      (∀ (Q : PredName) (ds : List D),
          ¬(Q = P ∧ ds.length = zs.length) →
            (I.pred_var_ Q ds ↔
              if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H
              else I.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
s2 : Holds D I V E F' ↔ Holds D J V E F
⊢ Holds D J V E F
Tactic:
apply h2
State after:
no goals

State before:
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length →
        (Holds D I (Function.updateListITE V zs ds) E H ↔
          if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)) →
    True →
      (∀ (Q : PredName) (ds : List D),
          ¬(Q = P ∧ ds.length = zs.length) →
            (I.pred_var_ Q ds ↔
              if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H
              else I.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
⊢ Holds D I V E F' ↔ Holds D J V E F
Tactic:
apply s1
State after:
case h2
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length →
        (Holds D I (Function.updateListITE V zs ds) E H ↔
          if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)) →
    True →
      (∀ (Q : PredName) (ds : List D),
          ¬(Q = P ∧ ds.length = zs.length) →
            (I.pred_var_ Q ds ↔
              if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H
              else I.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
⊢ ∀ (Q : PredName) (ds : List D),
    Q = P ∧ ds.length = zs.length →
      (Holds D I (Function.updateListITE V zs ds) E H ↔
        if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)

case h3_const
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length →
        (Holds D I (Function.updateListITE V zs ds) E H ↔
          if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)) →
    True →
      (∀ (Q : PredName) (ds : List D),
          ¬(Q = P ∧ ds.length = zs.length) →
            (I.pred_var_ Q ds ↔
              if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H
              else I.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
⊢ True

case h3_var
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length →
        (Holds D I (Function.updateListITE V zs ds) E H ↔
          if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)) →
    True →
      (∀ (Q : PredName) (ds : List D),
          ¬(Q = P ∧ ds.length = zs.length) →
            (I.pred_var_ Q ds ↔
              if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H
              else I.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
⊢ ∀ (Q : PredName) (ds : List D),
    ¬(Q = P ∧ ds.length = zs.length) →
      (I.pred_var_ Q ds ↔
        if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds)

State before:
case h2
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length →
        (Holds D I (Function.updateListITE V zs ds) E H ↔
          if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)) →
    True →
      (∀ (Q : PredName) (ds : List D),
          ¬(Q = P ∧ ds.length = zs.length) →
            (I.pred_var_ Q ds ↔
              if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H
              else I.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
⊢ ∀ (Q : PredName) (ds : List D),
    Q = P ∧ ds.length = zs.length →
      (Holds D I (Function.updateListITE V zs ds) E H ↔
        if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)
Tactic:
intro Q ds a1
State after:
case h2
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length →
        (Holds D I (Function.updateListITE V zs ds) E H ↔
          if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)) →
    True →
      (∀ (Q : PredName) (ds : List D),
          ¬(Q = P ∧ ds.length = zs.length) →
            (I.pred_var_ Q ds ↔
              if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H
              else I.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
Q : PredName
ds : List D
a1 : Q = P ∧ ds.length = zs.length
⊢ Holds D I (Function.updateListITE V zs ds) E H ↔
    if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds

State before:
case h2
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length →
        (Holds D I (Function.updateListITE V zs ds) E H ↔
          if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)) →
    True →
      (∀ (Q : PredName) (ds : List D),
          ¬(Q = P ∧ ds.length = zs.length) →
            (I.pred_var_ Q ds ↔
              if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H
              else I.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
Q : PredName
ds : List D
a1 : Q = P ∧ ds.length = zs.length
⊢ Holds D I (Function.updateListITE V zs ds) E H ↔
    if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds
Tactic:
cases a1
State after:
case h2.intro
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length →
        (Holds D I (Function.updateListITE V zs ds) E H ↔
          if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)) →
    True →
      (∀ (Q : PredName) (ds : List D),
          ¬(Q = P ∧ ds.length = zs.length) →
            (I.pred_var_ Q ds ↔
              if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H
              else I.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
Q : PredName
ds : List D
left✝ : Q = P
right✝ : ds.length = zs.length
⊢ Holds D I (Function.updateListITE V zs ds) E H ↔
    if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds

State before:
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length →
        (Holds D I (Function.updateListITE V zs ds) E H ↔
          if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)) →
    True →
      (∀ (Q : PredName) (ds : List D),
          ¬(Q = P ∧ ds.length = zs.length) →
            (I.pred_var_ Q ds ↔
              if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H
              else I.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
Q : PredName
ds : List D
a1_left : Q = P
a1_right : ds.length = zs.length
⊢ Holds D I (Function.updateListITE V zs ds) E H ↔
    if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds
Tactic:
case h2.intro a1_left a1_right =>
simp
simp only [if_pos a1_right]
State after:
no goals

State before:
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length →
        (Holds D I (Function.updateListITE V zs ds) E H ↔
          if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)) →
    True →
      (∀ (Q : PredName) (ds : List D),
          ¬(Q = P ∧ ds.length = zs.length) →
            (I.pred_var_ Q ds ↔
              if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H
              else I.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
Q : PredName
ds : List D
a1_left : Q = P
a1_right : ds.length = zs.length
⊢ Holds D I (Function.updateListITE V zs ds) E H ↔
    if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds
Tactic:
simp
State after:
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length →
        (Holds D I (Function.updateListITE V zs ds) E H ↔
          if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)) →
    True →
      (∀ (Q : PredName) (ds : List D),
          ¬(Q = P ∧ ds.length = zs.length) →
            (I.pred_var_ Q ds ↔
              if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H
              else I.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
Q : PredName
ds : List D
a1_left : Q = P
a1_right : ds.length = zs.length
⊢ Holds D I (Function.updateListITE V zs ds) E H ↔
    if ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds

State before:
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length →
        (Holds D I (Function.updateListITE V zs ds) E H ↔
          if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)) →
    True →
      (∀ (Q : PredName) (ds : List D),
          ¬(Q = P ∧ ds.length = zs.length) →
            (I.pred_var_ Q ds ↔
              if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H
              else I.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
Q : PredName
ds : List D
a1_left : Q = P
a1_right : ds.length = zs.length
⊢ Holds D I (Function.updateListITE V zs ds) E H ↔
    if ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds
Tactic:
simp only [if_pos a1_right]
State after:
no goals

State before:
case h3_const
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length →
        (Holds D I (Function.updateListITE V zs ds) E H ↔
          if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)) →
    True →
      (∀ (Q : PredName) (ds : List D),
          ¬(Q = P ∧ ds.length = zs.length) →
            (I.pred_var_ Q ds ↔
              if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H
              else I.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
⊢ True
Tactic:
simp
State after:
no goals

State before:
case h3_var
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length →
        (Holds D I (Function.updateListITE V zs ds) E H ↔
          if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)) →
    True →
      (∀ (Q : PredName) (ds : List D),
          ¬(Q = P ∧ ds.length = zs.length) →
            (I.pred_var_ Q ds ↔
              if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H
              else I.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
⊢ ∀ (Q : PredName) (ds : List D),
    ¬(Q = P ∧ ds.length = zs.length) →
      (I.pred_var_ Q ds ↔
        if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds)
Tactic:
intro Q ds a1
State after:
case h3_var
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length →
        (Holds D I (Function.updateListITE V zs ds) E H ↔
          if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)) →
    True →
      (∀ (Q : PredName) (ds : List D),
          ¬(Q = P ∧ ds.length = zs.length) →
            (I.pred_var_ Q ds ↔
              if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H
              else I.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
Q : PredName
ds : List D
a1 : ¬(Q = P ∧ ds.length = zs.length)
⊢ I.pred_var_ Q ds ↔
    if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds

State before:
case h3_var
F F' : Formula
P : PredName
zs : List VarName
H : Formula
h1 : IsSub P zs H F F'
h2 : ∀ (D : Type) (I : Interpretation D) (V : VarAssignment D) (E : Env), Holds D I V E F
D : Type
I : Interpretation D
V : VarAssignment D
E : Env
J : Interpretation D :=
  { nonempty := ⋯, pred_const_ := I.pred_const_,
    pred_var_ := fun Q ds =>
      if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds }
s1 :
  (∀ (Q : PredName) (ds : List D),
      Q = P ∧ ds.length = zs.length →
        (Holds D I (Function.updateListITE V zs ds) E H ↔
          if True ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ P ds)) →
    True →
      (∀ (Q : PredName) (ds : List D),
          ¬(Q = P ∧ ds.length = zs.length) →
            (I.pred_var_ Q ds ↔
              if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H
              else I.pred_var_ Q ds)) →
        (Holds D I V E F' ↔ Holds D J V E F)
Q : PredName
ds : List D
a1 : ¬(Q = P ∧ ds.length = zs.length)
⊢ I.pred_var_ Q ds ↔
    if Q = P ∧ ds.length = zs.length then Holds D I (Function.updateListITE V zs ds) E H else I.pred_var_ Q ds
Tactic:
simp only [if_neg a1]
State after:
no goals