Skip to content

Commit d69367f

Browse files
authored
fix: don't filter clauses when converting CNF for LRAT checker (#13944)
This PR changes a `filterMap` to a `map` in `CNF.convertLRAT'` so that tautological clauses become `none` in the array rather then being deleted. Without this, deleting clauses causes the clause indices of the remaining clauses to change, so an LRAT proof generated on the original CNF is not valid on the converted CNF. This was not caught before as an AIG constructed with `mkGateCached` will not produce tautological clauses in its CNF, but with `mkGate` it is possible - e.g. `mkGate lhs lhs.invert` produces the tautological clause `[out, !lhs, lhs]`.
1 parent 9820f61 commit d69367f

1 file changed

Lines changed: 6 additions & 20 deletions

File tree

src/Std/Tactic/BVDecide/LRAT/Internal/Convert.lean

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,7 @@ def CNF.Clause.convertLRAT' (clause : CNF.Clause (PosFin n)) : Option (DefaultCl
5252
Turn a `CNF PosFin` into the representation used by the LRAT checker.
5353
-/
5454
def CNF.convertLRAT' (clauses : CNF (PosFin n)) : Array (Option (DefaultClause n)) :=
55-
clauses.clauses.filterMap (fun clause =>
56-
match CNF.Clause.convertLRAT' clause with
57-
| some clause => some (some clause)
58-
-- This might look stupid but we are in an Option (Option x) here so explicitly returning none
59-
-- is different from not doing this pattern match.
60-
| none => none
61-
)
55+
clauses.clauses.map CNF.Clause.convertLRAT'
6256

6357
theorem CNF.Clause.mem_lrat_of_mem (clause : CNF.Clause (PosFin n)) (h1 : l ∈ clause)
6458
(h2 : DefaultClause.ofArray clause.toArray = some lratClause) : l ∈ lratClause.clause := by
@@ -133,21 +127,13 @@ theorem CNF.unsat_of_convertLRAT_unsat (cnf : CNF Nat) :
133127
simp only [Formula.formulaEntails_def, List.all_eq_true, decide_eq_true_eq]
134128
intro lratClause hlclause
135129
simp only [Formula.toList, DefaultFormula.toList, DefaultFormula.ofArray, convertLRAT',
136-
Array.size_append, List.size_toArray, List.length_cons, List.length_nil, Nat.zero_add,
137-
Array.foldl_append', List.foldl_toArray', List.foldl_cons,
138-
List.foldl_nil, Array.toList_append, Array.toList_filterMap', List.cons_append, List.nil_append,
139-
List.toList_toArray, id_eq, List.filterMap_cons_none, List.map_nil, List.append_nil,
140-
List.mem_filterMap, Array.mem_toList_iff, exists_eq_right] at hlclause
130+
Array.toList_append, Array.toList_map, List.cons_append, List.nil_append, id_eq,
131+
List.filterMap_cons_none, List.filterMap_map, List.map_nil, List.append_nil,
132+
List.mem_filterMap, Array.mem_toList_iff, Array.mem_iff_getElem] at hlclause
141133
rcases hlclause with ⟨reflectClause, ⟨hrclause1, hrclause2⟩⟩
142134
simp only [CNF.eval, Array.all_eq_true] at h2
143-
split at hrclause2
144-
· next heq =>
145-
rw [← heq] at hrclause2
146-
simp only [Option.some.injEq] at hrclause2
147-
rw [Array.mem_iff_getElem] at hrclause1
148-
rcases hrclause1 with ⟨i, h, rfl⟩
149-
simp [CNF.Clause.convertLRAT_sat_of_sat _ hrclause2, h2 i h]
150-
· contradiction
135+
rcases hrclause1 with ⟨i, h, rfl⟩
136+
simp [CNF.Clause.convertLRAT_sat_of_sat _ hrclause2, h2 i h]
151137

152138
end Internal
153139
end LRAT

0 commit comments

Comments
 (0)