See ../README for information about this project for checking lrat proofs. OVERALL STRUCTURE of cube-and-conquer proof effort, where a cube is a conjunction of literals: (1) Transform (with a given proof file) input formula F0 to a "transformed" formula F1 (by adding clauses each verified by RAT). Run proof to check that if F0 is SAT, then F1 is SAT. See theorem TRANSFORM-PRESERVES-SAT in file transform.lisp. + Optionally write F0 and F1 to files, to diff against the files that allegedly contain these formulas. See clean-formula.lisp for a discussion of writing out F1. (2) For a collection of cubes Gi, show that for each i, F1 tautologically implies ~Gi: if a |= F1 then a |= ~Gi. See theorem VERIFY-FOR-CUBE-SOUNDNESS in file verify-for-cube-soundness.lisp. Optionally: write F1 and, more importantly, write ~Gi as a one-line file as so (see verify-for-cube-print in file top.lisp): -lit_1 ... -lit_k 0 (3) Run the usual incremental checker to prove that the conjunction of clauses ~Gi is UNSAT. Notice that from (2) and (3) we know that F1 is UNSAT; hence from (1), F0 is UNSAT. (We could even weaken (3) by conjoining F1 before proving UNSAT, though we do not do so.) (We could produce a single theorem by having a single function that takes all relevant input files and checks all of the above and returns all relevant formulas for diffing. The theorem would state that if this process runs without error, then F0 is unsatisfiable. But we don't do this, since we prefer to have theorems about (1) through (3) that make it really clear that F0 is UNSAT. Suppose the proofs in (2) and (3) succeed.) .................... IMPLEMENTATION REQUIREMENTS FOR (1): Trivially modify the function proved-formula so that it returns not only the input formula but also the produced formula, and prove the a theorem such as the following. (let* ((results (run-checker cnf-file clrat-file chunk-size debug ctx state)) (error? (get-error? results)) (input-formula (get-input-formula results)) (produced-formula (get-produced-formula results))) (implies (and (not error?) (satisfiable input-formula)) (satisfiable produced-formula))) .................... IMPLEMENTATION REQUIREMENTS FOR (2): We write a new function: verify-for-cube(cnf-file, proof-file, cube-file, chunk-size, debug, state) Cnf-file contains a formula in the usual format. Proof-file is in clrat format. Cube-file has a single line: a lit_1 lit_2 ... lit_k 0 A very simple function, extend-with-cube, produces the formula to be proved UNSAT using proof-file. That function appends, to the end of the formula read from cnf-file, the sequence of unit clauses obtained from cube-file: {{lit_1}, {lit_2}, ..., {lit_k}} Verify-for-cube is similar to the existing function, proved-formula, in that it returns the formula parsed from the cnf-file. But verify-for-cube also returns the clause obtained by negating the input cube, i.e., the clause: {-lit_1, -lit_2, ..., -lit_k} The theorem to prove has essentially the following form. LET results = verify-for-cube(cnf-file,clrat-file,cube-file,...) IN LET error? = get-error?(results) IN LET formula = get-formula(results) IN LET clause = get-clause(results) IN (NOT error?) & (assignment |= formula) ==> evaluate-clause(clause,assignment) = TRUE A new function, print-clause, will print a clause on a single line terminated by 0. In our specific case where the clause is ~Gi, that line will be: -lit_1 -lit_2 ..., -lit_k 0 .................... I'll tackle (2) first, then (1).