-- Mathlib/.lake/packages/lean4/src/lean/Std/Tactic/BVDecide/LRAT/Internal/Formula/Lemmas.lean
theorem readyForRupAdd_ofArray {n : Nat} (arr : Array (Option (DefaultClause n))) :
    ReadyForRupAdd (ofArray arr)

Proof state:
n : Nat
arr : Array (Option (DefaultClause n))
hsize✝¹ : (ofArray arr).assignments.size = n
ModifiedAssignmentsInvariant : Array Assignment → Prop :=
  fun assignments =>
    ∃ hsize, ∀ (i : PosFin n) (b : Bool), hasAssignment b assignments[i.val] = true → unit (i, b) ∈ (ofArray arr).toList
hb : ModifiedAssignmentsInvariant (mkArray n unassigned)
acc : Array Assignment
i : PosFin n
b : Bool
cOpt : Option (DefaultClause n)
c : DefaultClause n
cOpt_in_arr : some c ∈ arr.toList
hsize✝ : (ofArray_fold_fn acc (some c)).size = n
l : PosFin n
heq✝ : c.isUnit = some (l, false)
heq : c.clause = [(l, false)]
hsize : acc.size = n
ih : ∀ (i : PosFin n) (b : Bool), hasAssignment b acc[i.val] = true → unit (i, b) ∈ (ofArray arr).toList
i_eq_l : i.val = l.val
h : hasAssignment b acc[l.val].addNegAssignment = true
b_eq_false : ¬b = true
⊢ some (unit (i, b)) ∈ arr.toList

Tactic:
have i_eq_l : i = l := Subtype.ext i_eq_l

Result:
n : Nat
arr : Array (Option (DefaultClause n))
hsize✝¹ : (ofArray arr).assignments.size = n
ModifiedAssignmentsInvariant : Array Assignment → Prop :=
  fun assignments =>
    ∃ hsize, ∀ (i : PosFin n) (b : Bool), hasAssignment b assignments[i.val] = true → unit (i, b) ∈ (ofArray arr).toList
hb : ModifiedAssignmentsInvariant (mkArray n unassigned)
acc : Array Assignment
i : PosFin n
b : Bool
cOpt : Option (DefaultClause n)
c : DefaultClause n
cOpt_in_arr : some c ∈ arr.toList
hsize✝ : (ofArray_fold_fn acc (some c)).size = n
l : PosFin n
heq✝ : c.isUnit = some (l, false)
heq : c.clause = [(l, false)]
hsize : acc.size = n
ih : ∀ (i : PosFin n) (b : Bool), hasAssignment b acc[i.val] = true → unit (i, b) ∈ (ofArray arr).toList
i_eq_l✝ : i.val = l.val
h : hasAssignment b acc[l.val].addNegAssignment = true
b_eq_false : ¬b = true
i_eq_l : i = l
⊢ some (unit (i, b)) ∈ arr.toList

Proof state:
n : Nat
arr : Array (Option (DefaultClause n))
hb : (mkArray n unassigned).size = n
⊢ (List.foldl ofArray_fold_fn (mkArray n unassigned) arr.toList).size = n

Tactic:
have hl (acc : Array Assignment) (ih : acc.size = n) (cOpt : Option (DefaultClause n)) (_cOpt_in_arr : cOpt ∈ arr.toList) :
  (ofArray_fold_fn acc cOpt).size = n := by rw [size_ofArray_fold_fn acc cOpt, ih]

Result:
n : Nat
arr : Array (Option (DefaultClause n))
hb : (mkArray n unassigned).size = n
hl :
  ∀ (acc : Array Assignment),
    acc.size = n → ∀ (cOpt : Option (DefaultClause n)), cOpt ∈ arr.toList → (ofArray_fold_fn acc cOpt).size = n
⊢ (List.foldl ofArray_fold_fn (mkArray n unassigned) arr.toList).size = n

Proof state:
n : Nat
arr : Array (Option (DefaultClause n))
hsize✝¹ : (ofArray arr).assignments.size = n
ModifiedAssignmentsInvariant : Array Assignment → Prop :=
  fun assignments =>
    ∃ hsize, ∀ (i : PosFin n) (b : Bool), hasAssignment b assignments[i.val] = true → unit (i, b) ∈ (ofArray arr).toList
hb : ModifiedAssignmentsInvariant (mkArray n unassigned)
acc : Array Assignment
i : PosFin n
b : Bool
cOpt : Option (DefaultClause n)
c : DefaultClause n
cOpt_in_arr : some c ∈ arr.toList
hsize✝ : (ofArray_fold_fn acc (some c)).size = n
l : PosFin n
heq : c.isUnit = some (l, true)
hsize : acc.size = n
i_eq_l : i.val = l.val
b_eq_false : b = false
h : acc[l.val].hasNegAssignment = true
ih :
  (if false = true then hasPosAssignment else hasNegAssignment) acc[l.val] = true →
    unit (l, false) ∈ (ofArray arr).toList
⊢ unit (l, false) ∈ (ofArray arr).toList

Tactic:
exact ih h

Result:
no goals

Proof state:
n : Nat
arr : Array (Option (DefaultClause n))
hsize✝¹ : (ofArray arr).assignments.size = n
ModifiedAssignmentsInvariant : Array Assignment → Prop :=
  fun assignments =>
    ∃ hsize, ∀ (i : PosFin n) (b : Bool), hasAssignment b assignments[i.val] = true → unit (i, b) ∈ (ofArray arr).toList
hb : ModifiedAssignmentsInvariant (mkArray n unassigned)
acc : Array Assignment
i : PosFin n
b : Bool
cOpt : Option (DefaultClause n)
c : DefaultClause n
cOpt_in_arr : some c ∈ arr.toList
hsize✝ : (ofArray_fold_fn acc (some c)).size = n
l : PosFin n
heq : c.isUnit = some (l, true)
hsize : acc.size = n
ih : ∀ (i : PosFin n) (b : Bool), hasAssignment b acc[i.val] = true → unit (i, b) ∈ (ofArray arr).toList
i_eq_l : i.val = l.val
h : hasAssignment b acc[l.val].addPosAssignment = true
b_eq_true : b = true
⊢ unit (i, b) ∈ (ofArray arr).toList

Tactic:
rw [isUnit_iff, DefaultClause.toList] at heq

Result:
n : Nat
arr : Array (Option (DefaultClause n))
hsize✝¹ : (ofArray arr).assignments.size = n
ModifiedAssignmentsInvariant : Array Assignment → Prop :=
  fun assignments =>
    ∃ hsize, ∀ (i : PosFin n) (b : Bool), hasAssignment b assignments[i.val] = true → unit (i, b) ∈ (ofArray arr).toList
hb : ModifiedAssignmentsInvariant (mkArray n unassigned)
acc : Array Assignment
i : PosFin n
b : Bool
cOpt : Option (DefaultClause n)
c : DefaultClause n
cOpt_in_arr : some c ∈ arr.toList
hsize✝ : (ofArray_fold_fn acc (some c)).size = n
l : PosFin n
heq✝ : c.isUnit = some (l, true)
heq : c.clause = [(l, true)]
hsize : acc.size = n
ih : ∀ (i : PosFin n) (b : Bool), hasAssignment b acc[i.val] = true → unit (i, b) ∈ (ofArray arr).toList
i_eq_l : i.val = l.val
h : hasAssignment b acc[l.val].addPosAssignment = true
b_eq_true : b = true
⊢ unit (i, b) ∈ (ofArray arr).toList

Proof state:
case h_1
n : Nat
arr : Array (Option (DefaultClause n))
hsize✝ : (ofArray arr).assignments.size = n
ModifiedAssignmentsInvariant : Array Assignment → Prop :=
  fun assignments =>
    ∃ hsize, ∀ (i : PosFin n) (b : Bool), hasAssignment b assignments[i.val] = true → unit (i, b) ∈ (ofArray arr).toList
hb : ModifiedAssignmentsInvariant (mkArray n unassigned)
acc : Array Assignment
ih : ModifiedAssignmentsInvariant acc
i : PosFin n
b : Bool
cOpt✝ : Option (DefaultClause n)
cOpt_in_arr : none ∈ arr.toList
hsize : (ofArray_fold_fn acc none).size = n
h : hasAssignment b acc[i.val] = true
⊢ unit (i, b) ∈ (ofArray arr).toList

Tactic:
exact ih.2 i b h

Result:
no goals

Proof state:
n : Nat
arr : Array (Option (DefaultClause n))
hsize✝¹ : (ofArray arr).assignments.size = n
ModifiedAssignmentsInvariant : Array Assignment → Prop :=
  fun assignments =>
    ∃ hsize, ∀ (i : PosFin n) (b : Bool), hasAssignment b assignments[i.val] = true → unit (i, b) ∈ (ofArray arr).toList
hb : ModifiedAssignmentsInvariant (mkArray n unassigned)
acc : Array Assignment
i : PosFin n
b : Bool
cOpt : Option (DefaultClause n)
c : DefaultClause n
cOpt_in_arr : some c ∈ arr.toList
hsize✝ : (ofArray_fold_fn acc (some c)).size = n
l : PosFin n
heq : c.isUnit = some (l, false)
hsize : acc.size = n
i_eq_l : i.val = l.val
b_eq_true : b = true
h : acc[l.val].hasPosAssignment = true
ih : (if True then hasPosAssignment else hasNegAssignment) acc[l.val] = true → unit (l, true) ∈ (ofArray arr).toList
⊢ unit (i, b) ∈ (ofArray arr).toList

Tactic:
rw [b_eq_true, Subtype.ext i_eq_l]

Result:
n : Nat
arr : Array (Option (DefaultClause n))
hsize✝¹ : (ofArray arr).assignments.size = n
ModifiedAssignmentsInvariant : Array Assignment → Prop :=
  fun assignments =>
    ∃ hsize, ∀ (i : PosFin n) (b : Bool), hasAssignment b assignments[i.val] = true → unit (i, b) ∈ (ofArray arr).toList
hb : ModifiedAssignmentsInvariant (mkArray n unassigned)
acc : Array Assignment
i : PosFin n
b : Bool
cOpt : Option (DefaultClause n)
c : DefaultClause n
cOpt_in_arr : some c ∈ arr.toList
hsize✝ : (ofArray_fold_fn acc (some c)).size = n
l : PosFin n
heq : c.isUnit = some (l, false)
hsize : acc.size = n
i_eq_l : i.val = l.val
b_eq_true : b = true
h : acc[l.val].hasPosAssignment = true
ih : (if True then hasPosAssignment else hasNegAssignment) acc[l.val] = true → unit (l, true) ∈ (ofArray arr).toList
⊢ unit (l, true) ∈ (ofArray arr).toList