Proof format: LFSC

Using the flag proof-format-mode=lfsc , cvc5 outputs proofs in the LFSC proof format.

The LFSC proof format is based on the LF logical framework extended with computational side conditions, as described in [ SOR+13 ] . A high performance C++ proof checker for LFSC is available here .

For a quick start, the cvc5 repository contains a script which will download and install the LFSC proof checker, and create scripts for generating proofs with cvc5 and checking them with the LFSC proof checker.

LFSC is a meta-framework, meaning that the proof rules used by cvc5 are defined in signature files, also contained within the cvc5 repository in this directory . Based on these signatures, cvc5 provides basic support for LFSC proofs over all theories that it supports.

Note that several proof rules in the internal calculus are not yet supported in LFSC signatures, and are instead printed as trust steps in the LFSC proof. A trust step proves an arbitrary formula with no provided justification. The LFSC proof contains warnings for which proof rules from the internal calculus were recorded as trust steps in the LFSC proof.

For more fine-grained proofs, the additional option proof-granularity=theory-rewrite should be passed to cvc5. This often will result in LFSC proofs with more detail, and whose trust steps correspond only to equalities corresponding to theory rewrites.

A simple example of cvc5 producing a proof in LFSC proof format:

$ bin/cvc5 --dump-proofs --proof-format-mode=lfsc --proof-granularity=theory-rewrite ../test/regress/cli/regress0/proofs/qgu-fuzz-1-bool-sat.smt2
unsat
; WARNING: adding trust step for THEORY_REWRITE
(define cvc.c (var 0 Bool))
(define cvc.b (var 1 Bool))
(define cvc.d (var 2 Bool))
(check
(@ t1 (= cvc.b cvc.d)
(@ t2 (or cvc.b (or cvc.d false))
(@ t3 (= t2 t1)
(@ t4 (and t3 true)
(@ t5 (ite cvc.d cvc.c false)
(@ t6 (= cvc.c cvc.d)
(@ t7 (or cvc.d (or cvc.b false))
(@ t8 (and t7 (and t6 (and (not t5) t4)))
(@ t9 (= f_and f_and)
(@ t10 (and cvc.d (and cvc.c true))
(@ t11 (= cvc.d cvc.d)
(@ t12 (not cvc.d)
(@ t13 (and t12 t4)
(@ t14 (and t7 t13)
(# a0 (holds t8)
(: (holds false)

(plet _  _ 

(refl t3)
(\ p1

(plet _  _ 

(refl f_and)
(\ p2

(plet _  _ 

(refl t7)
(\ p3

(plet _  _ 

(refl f_and)
(\ p4

(plet _  _ 

(refl f_and)
(\ p5

(plet _  _ 

(cong _  _  _  _ 
(cong _  _  _  _  p5 p3)
(cong _  _  _  _ 
(cong _  _  _  _  p5
(refl t6))
(cong _  _  _  _ 
(cong _  _  _  _  p5
(cong _  _  _  _ 
(refl f_not)
(trust (= t5 t10)) ; from THEORY_REWRITE
))
(cong _  _  _  _ 
(cong _  _  _  _  p5 p1)
(refl true)))))
(\ p6

(plet _  _ 

(and_elim _  _  1
(eq_resolve _  _  a0 p6))
(\ p7

(plet _  _ 

(refl f_and)
(\ p8

(plet _  _ 

(refl cvc.d)
(\ p9

(plet _  _ 

(eq_resolve _  _  a0
(trans _  _  _  p6
(trans _  _  _ 
(cong _  _  _  _ 
(cong _  _  _  _  p4
(refl t7))
(cong _  _  _  _ 
(cong _  _  _  _  p4
(cong _  _  _  _ 
(cong _  _  _  _ 
(refl f_=) p7) p9))
(cong _  _  _  _ 
(cong _  _  _  _  p4
(cong _  _  _  _ 
(refl f_not)
(cong _  _  _  _ 
(cong _  _  _  _  p8 p9)
(cong _  _  _  _ 
(cong _  _  _  _  p8 p7)
(refl true)))))
(cong _  _  _  _ 
(cong _  _  _  _  p4
(refl t3))
(refl true)))))
(trans _  _  _ 
(cong _  _  _  _ 
(cong _  _  _  _  p2 p3)
(cong _  _  _  _ 
(cong _  _  _  _  p2
(trust (= t11 true)) ; from THEORY_REWRITE
)
(cong _  _  _  _ 
(cong _  _  _  _  p2
(cong _  _  _  _ 
(refl f_not)
(trust (= (and cvc.d (and cvc.d true)) cvc.d)) ; from THEORY_REWRITE
))
(cong _  _  _  _ 
(cong _  _  _  _  p2 p1)
(refl true)))))
(trust (= (and t7 (and true t13)) t14)) ; from THEORY_REWRITE
))))
(\ p10

(plet _  _ 

(reordering _  t2
(and_elim _  _  0 p10))
(\ p11

(plet _  _ 

(and_elim _  _  1 p10)
(\ p12


(resolution _  _  _ 
(resolution _  _  _ 
(reordering _  (or t1 (or (not t2) false))
(equiv_elim1 _  _ 
(and_elim _  _  2 p10)))
(resolution _  _  _ 
(resolution _  _  _ 
(reordering _  (or cvc.d (or (not cvc.b) (or (not t1) false)))
(cnf_equiv_pos1 cvc.b cvc.d)) p12 tt cvc.d)
(resolution _  _  _  p11 p12 tt cvc.d) ff cvc.b) tt t1) p11 ff t2))))))))))))))))))))))))))))))))))))))))))