Add tester for LFSC printer. (#8606)
authorAbdalrhman Mohamed <32971963+abdoo8080@users.noreply.github.com>
Thu, 21 Apr 2022 06:45:04 +0000 (01:45 -0500)
committerGitHub <noreply@github.com>
Thu, 21 Apr 2022 06:45:04 +0000 (06:45 +0000)
This adds an option to check the LFSC proofs generated by `cvc5` for unsat benchmarks. This does not enable the tester in CI as it fails for many benchmarks.

41 files changed:
test/regress/cli/CMakeLists.txt
test/regress/cli/regress0/bv/div_mod.cvc.smt2
test/regress/cli/regress0/bv/fuzz15.delta01.smtv1.smt2
test/regress/cli/regress0/bv/fuzz38.delta01.smtv1.smt2
test/regress/cli/regress0/fp/issue-5524.smt2
test/regress/cli/regress0/fp/rti_3_5_bug.smt2
test/regress/cli/regress0/fp/word-blast.smt2
test/regress/cli/regress0/quantifiers/lra-triv-gn.smt2
test/regress/cli/regress0/seq/seq-types.smt2
test/regress/cli/regress1/aufbv/bug348.smtv1.smt2
test/regress/cli/regress1/auflia/bug330.smt2
test/regress/cli/regress1/bv/divtest.smt2
test/regress/cli/regress1/bv/fuzz38.smtv1.smt2
test/regress/cli/regress1/bv/incorrect1.smtv1.smt2
test/regress/cli/regress1/bv/proj-issue438-prerewrite-fixed-point-original.smt2
test/regress/cli/regress1/bvdiv2.smt2
test/regress/cli/regress1/fp/rti_3_5_bug_report.smt2
test/regress/cli/regress1/issue3970-nl-ext-purify.smt2
test/regress/cli/regress1/quantifiers/NUM878.smt2
test/regress/cli/regress1/quantifiers/inst-max-level-segf.smt2
test/regress/cli/regress1/quantifiers/issue4021-ind-opts.smt2
test/regress/cli/regress1/quantifiers/qbv-test-invert-bvcomp.smt2
test/regress/cli/regress1/quantifiers/seqa-unsat-unknown-110921.smt2
test/regress/cli/regress1/quantifiers/tpp-unit-fail-qbv.smt2
test/regress/cli/regress1/sets/comp-intersect.smt2
test/regress/cli/regress1/sets/comp-odd.smt2
test/regress/cli/regress1/sets/comp-pos-member.smt2
test/regress/cli/regress1/sets/comp-positive.smt2
test/regress/cli/regress1/sygus/issue3201.smt2
test/regress/cli/regress1/sygus/issue3247.smt2
test/regress/cli/regress1/sygus/issue3995-fmf-var-op.smt2
test/regress/cli/regress1/sygus/issue4009-qep.smt2
test/regress/cli/regress1/sygus/issue4083-var-shadow.smt2
test/regress/cli/regress1/sygus/issue4425-sets-sygus-infer.smt2
test/regress/cli/regress1/sygus/proj-issue185.smt2
test/regress/cli/regress2/bug349.smtv1.smt2
test/regress/cli/regress2/fp/issue7056.smt2
test/regress/cli/regress2/instance_1444.smtv1.smt2
test/regress/cli/regress2/nl/ufnia-factor-open-proof.smt2
test/regress/cli/regress2/ooo.tag10.smt2
test/regress/cli/run_regression.py

index ca74fc74f9df08627bcbb7cb3d70be253b41e357..8dcc979d4ab2135876c217af23f508ac9cd3290f 100644 (file)
@@ -3201,7 +3201,10 @@ macro(cvc5_add_regression_test level file)
   add_test(${file}
     ${run_regress_script}
     ${RUN_REGRESSION_ARGS}
-    ${path_to_cvc5}/cvc5 ${CMAKE_CURRENT_LIST_DIR}/${file})
+    --lfsc-binary ${CMAKE_SOURCE_DIR}/deps/bin/lfscc
+    --lfsc-sig-dir ${CMAKE_SOURCE_DIR}/proofs/lfsc/signatures
+    ${path_to_cvc5}/cvc5
+    ${CMAKE_CURRENT_LIST_DIR}/${file})
   set_tests_properties(${file} PROPERTIES LABELS "regress${level}")
 
   # For CMake 3.9.0 and newer, skipped tests do not count as a failure anymore:
index be61e155a582214ace44b1db7ffa76c3b8bed9a4..b35a8b6d67d848e89b7bc7adfe3d6687512f9413 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 ; EXPECT: unsat
 (set-logic ALL)
 (set-option :incremental false)
index f16084981fd3a0d0352be736d0ffb636e1387181..22ca98ba5f17df53b11ce6d422bd5ddba9850b35 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 (set-option :incremental false)
 (set-info :status unsat)
 (set-logic QF_BV)
index cc5d99e188ee821f3d86f12b42a14715c9715732..0c4f1c197916d8d0f70f6e9c5b300d02169a5847 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 (set-option :incremental false)
 (set-info :status unsat)
 (set-logic QF_BV)
index 3e9696871d65f00f0bd90307fc78a793778766ee..f5f2024c0131f15a0611b2d8455df93e6c4175cd 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 ; COMMAND-LINE: --bv-solver=bitblast
 ; EXPECT: unsat
 (set-logic QF_FPLRA)
index 724e08b8c7ef4b3a2cefb1bfced25c8a1fecb874..c2144dfc4d103a1c2ed8317718221e813dd16ce6 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc\r
 ; COMMAND-LINE: --fp-exp\r
 ; EXPECT: unsat\r
 \r
index 65290a3b3b2043f54d10b717b5ae0ff1d6b499e8..1e8ae7320d3935f9ac3928a6be6fa98534ece772 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 ; COMMAND-LINE: --fp-lazy-wb
 ; EXPECT: unsat
 (set-logic QF_BVFP)
index 0d36d2037356adf8d68e5cbef91258702be7c1f6..a6b60b68d6ec20bb582540976c78bdc2e3924b88 100644 (file)
@@ -2,6 +2,7 @@
 ; EXPECT: unsat
 ; DISABLE-TESTER: unsat-core
 ; DISABLE-TESTER: proof
+; DISABLE-TESTER: lfsc
 (set-logic LRA)
 (set-info :status unsat)
 (assert (not (exists ((?X Real)) (>= (/ (- 13) 4) ?X))))
index 3facf688ab91f9c2827ac0d02adb3f565ea6a0e6..f8d8aa8b3a6e977b49c2407c7d2a70e199aa7e13 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 ; COMMAND-LINE: --strings-exp
 ;EXPECT: unsat
 (set-logic ALL)
index a1fc92d771b79f99339464d32f1f284e4230f20b..b5c99bd9f64b62ce01f66d2eded3abcf0fb09bd5 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 ; COMMAND-LINE: --bv-solver=bitblast
 (set-option :incremental false)
 (set-info :status unsat)
index ada1fd8d5a695010c38c01e13c808a71c128fa34..13b0528216418de752a2c088687781966ebd79f2 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 (set-logic QF_AUFLIA)
 (set-info :source |
 Translated from old SVC processor verification benchmarks.  Contact Clark
index fe91cb87b44dabfcc63b376c309b58466430e5b5..c3c3ad7be8460c82011fad1e7dd2500995acb897 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 (set-logic QF_BV)
 (set-info :status unsat)
 (declare-fun x1 () (_ BitVec 12))
index d9f6d46b249e8dbaf21de19ef20158cdedba07d4..68af8acfc2c710cc21285faf81b6edb4b59e6c6d 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 (set-option :incremental false)
 (set-info :status unsat)
 (set-logic QF_BV)
index 8d79f91e2715e8f51ae58fe7a300c76da1d0128a..06ff3aa2723c33087850a806fcf1df4d9cb78369 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 (set-option :incremental false)
 (set-info :status unsat)
 (set-logic QF_BV)
index 62d769bc2685306c37839f29af5564c851dee5a9..f34d0442722c37a1cac4ff79197942562eed3a04 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 (set-logic QF_BV)
 (declare-const T (_ BitVec 1))
 (assert (and (bvsle (_ bv0 32) (bvadd (bvadd (_ bv1 32) (_ bv0 32)) ((_ zero_extend 24) ((_ extract 15 8) (bvshl ((_ zero_extend 24) ((_ extract 15 8) (bvsub (bvxor ((_ zero_extend 24) ((_ extract 15 8) (bvsub ((_ zero_extend 24) ((_ extract 7 0) (bvxor (bvadd ((_ zero_extend 24) ((_ extract 7 0) ((_ extract 7 0) (bvsub (bvadd ((_ zero_extend 24) ((_ extract 7 0) (bvadd (_ bv0 32) ((_ zero_extend 24) ((_ extract 15 8) (bvsub (bvadd ((_ zero_extend 24) ((_ extract 7 0) (bvsub (bvxor (bvadd ((_ zero_extend 24) ((_ extract 7 0) (bvadd (_ bv0 32) ((_ zero_extend 24) (bvxor (bvxor (_ bv0 8) ((_ extract 7 0) ((_ extract 7 0) (bvxor (bvadd (_ bv0 32) ((_ zero_extend 24) ((_ extract 15 8) (bvsub ((_ zero_extend 24) ((_ extract 7 0) (bvsub (bvxor ((_ zero_extend 24) ((_ extract 7 0) (bvadd (_ bv0 32) (bvshl ((_ zero_extend 24) (bvxor (bvxor (_ bv0 8) ((_ extract 7 0) (bvadd (_ bv0 32) ((_ zero_extend 24) (bvxor (_ bv0 8) ((_ extract 7 0) (bvxor (bvadd (_ bv0 32) ((_ zero_extend 24) (bvxor (_ bv0 8) ((_ extract 7 0) (bvsub (_ bv0 32) ((_ zero_extend 24) ((_ zero_extend 7) T))))))) (_ bv0 32)))))))) (_ bv0 8))) (_ bv0 32))))) (_ bv0 32)) (_ bv1 32)))) (_ bv1 32))))) (_ bv0 32))))) (_ bv0 8)))))) (_ bv0 32)) (_ bv0 32)) (_ bv0 32)))) (_ bv0 32)) (_ bv1 32))))))) (_ bv0 32)) (_ bv0 32))))) (_ bv0 32)) (_ bv0 32)))) (_ bv1 32)))) (_ bv0 32)) (_ bv1 32)))) (_ bv1 32)))))) (= (_ bv0 32) (bvxor (_ bv0 32) (bvadd (bvadd (_ bv1 32) (_ bv0 32)) ((_ zero_extend 24) ((_ extract 15 8) (bvshl ((_ zero_extend 24) ((_ extract 15 8) (bvsub (bvxor ((_ zero_extend 24) ((_ extract 15 8) (bvsub ((_ zero_extend 24) ((_ extract 7 0) (bvxor (bvadd ((_ zero_extend 24) ((_ extract 7 0) ((_ extract 7 0) (bvsub (bvadd ((_ zero_extend 24) ((_ extract 7 0) (bvadd (_ bv0 32) ((_ zero_extend 24) ((_ extract 15 8) (bvsub (bvadd ((_ zero_extend 24) ((_ extract 7 0) (bvsub (bvxor (bvadd ((_ zero_extend 24) ((_ extract 7 0) (bvadd (_ bv0 32) ((_ zero_extend 24) (bvxor (bvxor (_ bv0 8) ((_ extract 7 0) ((_ extract 7 0) (bvxor (bvadd (_ bv0 32) ((_ zero_extend 24) ((_ extract 15 8) (bvsub ((_ zero_extend 24) ((_ extract 7 0) (bvsub (bvxor ((_ zero_extend 24) ((_ extract 7 0) (bvadd (_ bv0 32) (bvshl ((_ zero_extend 24) (bvxor (bvxor (_ bv0 8) ((_ extract 7 0) (bvadd (_ bv0 32) ((_ zero_extend 24) (bvxor (_ bv0 8) ((_ extract 7 0) (bvxor (bvadd (_ bv0 32) ((_ zero_extend 24) (bvxor (_ bv0 8) ((_ extract 7 0) (bvsub (_ bv0 32) ((_ zero_extend 24) ((_ zero_extend 7) T))))))) (_ bv0 32)))))))) (_ bv0 8))) (_ bv0 32))))) (_ bv0 32)) (_ bv1 32)))) (_ bv1 32))))) (_ bv0 32))))) (_ bv0 8)))))) (_ bv0 32)) (_ bv0 32)) (_ bv0 32)))) (_ bv0 32)) (_ bv1 32))))))) (_ bv0 32)) (_ bv0 32))))) (_ bv0 32)) (_ bv0 32)))) (_ bv1 32)))) (_ bv0 32)) (_ bv1 32)))) (_ bv1 32)))))))))
index 67d583c763e7b1e48fb170e79f7e997000b5fab0..251b76c0352444a592e65469db6a9fdf9efe45b9 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 (set-logic QF_AUFBVLIA)
 (set-info :smt-lib-version 2.6)
 (set-info :category "crafted")
index 6c0b68c95566649cfcc383a07ab813f0806a60c7..146942cecec700d981b2ce33913a66beacfaf920 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 ; COMMAND-LINE: --fp-exp
 ; EXPECT: unsat
 
index a48660bd8823e18b5205d82a559850c32e47a9e4..ef58b42a2db5bfebbe82a881571a5ce9045b7d85 100644 (file)
@@ -2,6 +2,7 @@
 ; EXPECT: unsat
 ; DISABLE-TESTER: unsat-core
 ; DISABLE-TESTER: proof
+; DISABLE-TESTER: lfsc
 (set-logic QF_UFNRA)
 (set-option :nl-ext-purify true)
 (set-option :sygus-inference true)
index 6f26e7af2dc048ca39e11ecd0248946e18e29938..93261330ef5c42c0c94b18a31394c5071aeb9bf8 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 ; COMMAND-LINE: --cegqi-bv
 ; EXPECT: unsat
 (set-logic BV)
index 47cfae0efa563d7944bb1d5a5ce419e3c6405d23..9bb21cae8e7bc7d6508ade26c4d0a85965f31c11 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 ; COMMAND-LINE: --inst-max-level=0 --simplification=none
 ; EXPECT: unsat
 (set-logic UF)
index f64ea8e723b189f7c2c3fe2d316aa182ddf3f95e..f8ecd754b1dab1adaf5809d39f2812eee660a561 100644 (file)
@@ -1,5 +1,6 @@
 ; DISABLE-TESTER: unsat-core
 ; DISABLE-TESTER: proof
+; DISABLE-TESTER: lfsc
 (set-logic HO_ALL)
 (set-option :miniscope-quant agg)
 (set-option :conjecture-gen true)
index ed9c9880ff019fd89d7078acb01dc45cbcc611d0..f0eab95030eda44d235ed0e599e86c466c46c27f 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 ; COMMAND-LINE: --cegqi-bv --cegqi-bv-ineq=keep --no-cegqi-full
 ; EXPECT: unsat
 (set-logic BV)
index 97af47a37d73c7355e7939c7ac88c6e92777e0f3..eeba7883bf1d19a1e3bd56e9bc0ce0385911801b 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 ; COMMAND-LINE: --strings-exp --seq-array=eager
 ; EXPECT: unsat
 (set-logic ALL)
index 2ef929551b5cbedb20da120e44a92ecc6c9f48f3..0b46717ec5b126ef8add2bd673bfc233beb4c1b1 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 (set-logic BV)
 (set-info :status unsat)
 (declare-fun t () (_ BitVec 4))
index 5f6f7576beab60a18ea611033ae569b85342746e..4f1de2e351e691bddd477eb5d7151a77790e81bf 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 ; COMMAND-LINE: --sets-ext
 ; EXPECT: unsat
 (set-logic ALL)
index 5d2a656196883178a3392c309f6b213392040db6..05450865ae4c2342634b9096ca0cc62b1ac35089 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 ; COMMAND-LINE: --sets-ext
 ; EXPECT: unsat
 (set-logic ALL)
index fdd5926b6826028c1c80e3b2f9dadb0aa2103323..34c4d287051745ac9a6d9ecdc9dedfa652122bef 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 ; COMMAND-LINE: --sets-ext --full-saturate-quant
 ; EXPECT: unsat
 (set-logic ALL)
index 6f8e3e1abaa67bf7c36abdc4e661b3b0b08e7400..be28deda19f0a7176988a8b3ed1b589d82f97726 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 ; COMMAND-LINE: --sets-ext
 ; EXPECT: unsat
 (set-logic ALL)
index 212fca782c45d911922ee57337e09b32a44476ae..831fce6d42c7bb593ce96351151f2c08033464c1 100644 (file)
@@ -2,6 +2,7 @@
 ; COMMAND-LINE: --sygus-inference -q
 ; DISABLE-TESTER: unsat-core
 ; DISABLE-TESTER: proof
+; DISABLE-TESTER: lfsc
 (set-logic ALL)
 (declare-fun v () Bool)
 (assert false)
index 7e2f439ceada3c12e7219995ac61ebceff961265..a6f3f6951b23f478aea0a89d325887aedb0bbadc 100644 (file)
@@ -2,6 +2,7 @@
 ; COMMAND-LINE: --sygus-inference --strings-exp -q
 ; DISABLE-TESTER: unsat-core
 ; DISABLE-TESTER: proof
+; DISABLE-TESTER: lfsc
 (set-logic ALL)
 (declare-fun a () String) 
 (declare-fun b () String) 
index 48b4ab38c59d1ad5e714f66a4c18ce66c7f725ad..6a41fc7a09fef9920f3adffee25ad6b0510b8a39 100644 (file)
@@ -2,6 +2,7 @@
 ; COMMAND-LINE: --sygus-inference --fmf-bound
 ; DISABLE-TESTER: unsat-core
 ; DISABLE-TESTER: proof
+; DISABLE-TESTER: lfsc
 (set-logic HO_ALL)
 (declare-fun a () (_ BitVec 1))
 (assert (bvsgt (bvsmod a a) #b0))
index b27901a1142f5e85d78225bf29594eabed3e3b5d..8f540bf135b67b4dfd71a331b7887c03096e2b48 100644 (file)
@@ -2,6 +2,7 @@
 ; COMMAND-LINE: --sygus-inference --sygus-qe-preproc -q
 ; DISABLE-TESTER: unsat-core
 ; DISABLE-TESTER: proof
+; DISABLE-TESTER: lfsc
 (set-logic ALL)
 (declare-fun a () Real)
 (declare-fun b () Real)
index 4e867e8aaab58dfdab1e789540a4cf66d50defda..17a9dfa3ca4df00e1e7521e4c4f1a037285bb136 100644 (file)
@@ -2,6 +2,7 @@
 ; EXPECT: unsat
 ; DISABLE-TESTER: unsat-core
 ; DISABLE-TESTER: proof
+; DISABLE-TESTER: lfsc
 (set-logic ALL)
 (set-option :miniscope-quant conj-and-fv)
 (set-option :sygus-inference true)
index 466bb73130563590d7485034312ee557302300db..4e35869b6096e1b9c98dd755e171ba2d0562722e 100644 (file)
@@ -2,6 +2,7 @@
 ; EXPECT: unsat
 ; DISABLE-TESTER: unsat-core
 ; DISABLE-TESTER: proof
+; DISABLE-TESTER: lfsc
 (set-logic ALL)
 (declare-fun a () Int)
 (declare-fun d () Int)
index 141ab0ae00f8224b176223ecba791e3f14d6a47c..b6228d453ae621feed2603c11264c82df37a1b2e 100644 (file)
@@ -2,6 +2,7 @@
 ; EXPECT: unsat
 ; DISABLE-TESTER: unsat-core
 ; DISABLE-TESTER: proof
+; DISABLE-TESTER: lfsc
 (set-logic ALL)
 (set-option :sygus-inference true)
 (set-info :status unsat)
index ffbd7f331568cf4840c0e76bf448f0a7984b2630..f8375a3ae3e78b0b9ae0a33155ccd58969bcac33 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 ; COMMAND-LINE: --bv-solver=bitblast
 (set-option :incremental false)
 (set-info :status unsat)
index e419a5a6f086c16f00bc37abbdb52d87bbbb7106..17b439a83f81670585b53343938b301e56569b99 100644 (file)
@@ -1,5 +1,6 @@
-; DISABLE-TESTER: proof
 ; DISABLE-TESTER: unsat-core
+; DISABLE-TESTER: proof
+; DISABLE-TESTER: lfsc
 ; timeout with unsat cores
 (set-logic ALL)
 (set-info :smt-lib-version 2.6)
index 3b25eb26413d27dcce2a8ca6d25e64dc5527939e..fc4cd5802abf56e61da7eea00ad6d50033633afe 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 ; DISABLE-TESTER: proof
 (set-option :incremental false)
 (set-info :status unsat)
index 0f67a5a5db18735893d7f44b0866f8c39da1dc49..720b2e075cb42402a3b9b44fa69237b7f2280170 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 (set-logic QF_UFNIA)
 (set-info :status unsat)
 (declare-fun p2 (Int) Int)
index 2d5cb3b37dd128985c28420f60ffbf1d2166d883..45a1bb08bc6bd692b65e0ecf8f76f275b8fae119 100644 (file)
@@ -1,3 +1,4 @@
+; DISABLE-TESTER: lfsc
 (set-logic QF_UFIDL)
 (set-info :source |
 UCLID benchmark suite.  See UCLID project: http://www.cs.cmu.edu/~uclid
index af46438ec151120b6ccdc1253dba26d4be957892..dca1af1d19fddbe02d4a637a343f6406414e12b1 100755 (executable)
@@ -44,15 +44,26 @@ class Tester:
     def applies(self, benchmark_info):
         return True
 
+    def check_exit_status(self, name, expected_exit_status, exit_status, output, error, flags):
+        if exit_status == STATUS_TIMEOUT:
+            print("Timeout ({}) - Flags: {}".format(name, flags))
+            return EXIT_SKIP if g_args.skip_timeout else EXIT_FAILURE
+        elif exit_status != expected_exit_status:
+            print('not ok ({}) - Expected exit status "{}" but got "{}" - Flags: {}'.format(
+                name, expected_exit_status, exit_status, flags))
+            print()
+            print_outputs(output, error)
+            return EXIT_FAILURE
+        return None
+
     def run(self, benchmark_info):
-        exit_code = EXIT_OK
         output, error, exit_status = run_benchmark(benchmark_info)
-        if exit_status == STATUS_TIMEOUT:
-            exit_code = EXIT_SKIP if g_args.skip_timeout else EXIT_FAILURE
-            print("Timeout - Flags: {}".format(benchmark_info.command_line_args))
-        elif benchmark_info.compare_outputs and output != benchmark_info.expected_output:
-            exit_code = EXIT_FAILURE
-            print("not ok - Flags: {}".format(benchmark_info.command_line_args))
+        exit_code = self.check_exit_status(
+            "cvc5", benchmark_info.expected_exit_status, exit_status, output, error, benchmark_info.command_line_args)
+        if exit_code:
+            return exit_code
+        if benchmark_info.compare_outputs and output != benchmark_info.expected_output:
+            print("not ok (cvc5) - Flags: {}".format(benchmark_info.command_line_args))
             print()
             print("Standard output difference")
             print("=" * 80)
@@ -62,14 +73,11 @@ class Tester:
             print()
             if error:
                 print("Error output")
-                print("=" * 80)
-                print_colored(Color.YELLOW, error)
-                print("=" * 80)
-                print()
-        elif benchmark_info.compare_outputs and error != benchmark_info.expected_error:
-            exit_code = EXIT_FAILURE
+                print_segment(Color.YELLOW, error)
+            return EXIT_FAILURE
+        if benchmark_info.compare_outputs and error != benchmark_info.expected_error:
             print(
-                "not ok - Differences between expected and actual output on stderr - Flags: {}".format(
+                "not ok (cvc5) - Differences between expected and actual output on stderr - Flags: {}".format(
                     benchmark_info.command_line_args
                 )
             )
@@ -79,30 +87,9 @@ class Tester:
             print_diff(error, benchmark_info.expected_error)
             print("=" * 80)
             print()
-        elif exit_status != benchmark_info.expected_exit_status:
-            exit_code = EXIT_FAILURE
-            print(
-                'not ok - Expected exit status "{}" but got "{}" - Flags: {}'.format(
-                    benchmark_info.expected_exit_status,
-                    exit_status,
-                    benchmark_info.command_line_args,
-                )
-            )
-            print()
-            print("Output:")
-            print("=" * 80)
-            print_colored(Color.BLUE, output)
-            print("=" * 80)
-            print()
-            print()
-            print("Error output:")
-            print("=" * 80)
-            print_colored(Color.YELLOW, error)
-            print("=" * 80)
-            print()
-        else:
-            print("ok - Flags: {}".format(benchmark_info.command_line_args))
-        return exit_code
+            return EXIT_FAILURE
+        print("ok - Flags: {}".format(benchmark_info.command_line_args))
+        return EXIT_OK
 
 
 ################################################################################
@@ -165,11 +152,68 @@ class ProofTester(Tester):
     def run(self, benchmark_info):
         return super().run(
             benchmark_info._replace(
-                command_line_args=benchmark_info.command_line_args + ["--check-proofs", "--proof-granularity=theory-rewrite"]
+                command_line_args=benchmark_info.command_line_args +
+                ["--check-proofs", "--proof-granularity=theory-rewrite"]
             )
         )
 
 
+class LfscTester(Tester):
+    def applies(self, benchmark_info):
+        return (
+            benchmark_info.benchmark_ext != ".sy"
+            and benchmark_info.expected_output.strip() == "unsat"
+        )
+
+    def run(self, benchmark_info):
+        with tempfile.NamedTemporaryFile() as tmpf:
+            proof_args = [
+                "--dump-proofs",
+                "--proof-format=lfsc",
+                "--proof-granularity=theory-rewrite",
+            ]
+            output, error, exit_status = run_process(
+                [benchmark_info.cvc5_binary]
+                + benchmark_info.command_line_args
+                + proof_args
+                + [benchmark_info.benchmark_basename],
+                benchmark_info.benchmark_dir,
+                benchmark_info.timeout,
+            )
+            tmpf.write(output.strip("unsat\n".encode()))
+            tmpf.flush()
+            output, error = output.decode(), error.decode()
+            exit_code = self.check_exit_status(
+                "cvc5", EXIT_OK, exit_status, output, error, benchmark_info.command_line_args)
+            if exit_code:
+                return exit_code
+            if "check" not in output:
+                print('not ok (cvc5) - Empty proof - Flags: {}'.format(exit_status,
+                      benchmark_info.command_line_args))
+                print()
+                print_outputs(output, error)
+                return EXIT_FAILURE
+            output, error, exit_status = run_process(
+                [benchmark_info.lfsc_binary] +
+                benchmark_info.lfsc_sigs + [tmpf.name],
+                benchmark_info.benchmark_dir,
+                timeout=benchmark_info.timeout,
+            )
+            output, error = output.decode(), error.decode()
+            exit_code = self.check_exit_status(
+                "lfsc", EXIT_OK, exit_status, output, error, benchmark_info.command_line_args)
+            if exit_code:
+                return exit_code
+            if "success" not in output:
+                print(
+                    "not ok (lfsc) - Unexpected output - Flags: {}".format(benchmark_info.command_line_args))
+                print()
+                print_outputs(output, error)
+                return EXIT_FAILURE
+        print("ok - Flags: {}".format(benchmark_info.command_line_args))
+        return EXIT_OK
+
+
 class ModelTester(Tester):
     def __init__(self):
         pass
@@ -288,6 +332,7 @@ g_testers = {
     "base": BaseTester(),
     "unsat-core": UnsatCoreTester(),
     "proof": ProofTester(),
+    "lfsc": LfscTester(),
     "model": ModelTester(),
     "synth": SynthTester(),
     "abduct": AbductTester(),
@@ -313,6 +358,8 @@ BenchmarkInfo = collections.namedtuple(
         "error_scrubber",
         "timeout",
         "cvc5_binary",
+        "lfsc_binary",
+        "lfsc_sigs",
         "benchmark_dir",
         "benchmark_basename",
         "benchmark_ext",
@@ -347,6 +394,24 @@ def print_colored(color, text):
         print(color + line + Color.ENDC)
 
 
+def print_segment(color, text):
+    """Prints colored `text` inside a border."""
+    print("=" * 80)
+    for line in text.splitlines():
+        print(color + line + Color.ENDC)
+    print("=" * 80)
+    print()
+
+
+def print_outputs(stdout, stderr):
+    """Prints standard output and error."""
+    print("Output:")
+    print_segment(Color.BLUE, stdout)
+    print()
+    print("Error output:")
+    print_segment(Color.YELLOW, stderr)
+
+
 def print_diff(actual, expected):
     """Prints the difference between `actual` and `expected`."""
 
@@ -372,8 +437,8 @@ def run_process(args, cwd, timeout, s_input=None):
 
     cmd = " ".join([shlex.quote(a) for a in args]) if isinstance(args, list) else args
 
-    out = ""
-    err = ""
+    out = bytes()
+    err = bytes()
     exit_status = STATUS_TIMEOUT
     try:
         # Instead of setting shell=True, we explicitly call bash. Using
@@ -471,6 +536,8 @@ def run_regression(
     testers,
     wrapper,
     cvc5_binary,
+    lfsc_binary,
+    lfsc_sigs,
     benchmark_path,
     timeout,
 ):
@@ -611,6 +678,8 @@ def run_regression(
             error_scrubber=error_scrubber,
             timeout=timeout,
             cvc5_binary=cvc5_binary,
+            lfsc_binary=lfsc_binary,
+            lfsc_sigs=lfsc_sigs,
             benchmark_dir=benchmark_dir,
             benchmark_basename=benchmark_basename,
             benchmark_ext=benchmark_ext,
@@ -656,6 +725,8 @@ def main():
     parser.add_argument("--use-skip-return-code", action="store_true")
     parser.add_argument("--skip-timeout", action="store_true")
     parser.add_argument("--tester", choices=g_testers.keys(), action="append")
+    parser.add_argument("--lfsc-binary", default="")
+    parser.add_argument("--lfsc-sig-dir", default="")
     parser.add_argument("wrapper", nargs="*")
     parser.add_argument("cvc5_binary")
     parser.add_argument("benchmark")
@@ -668,6 +739,7 @@ def main():
     g_args = parser.parse_args(argv)
 
     cvc5_binary = os.path.abspath(g_args.cvc5_binary)
+    lfsc_binary = os.path.abspath(g_args.lfsc_binary)
 
     wrapper = g_args.wrapper
     if os.environ.get("VALGRIND") == "1" and not wrapper:
@@ -679,10 +751,24 @@ def main():
     if not testers:
         testers = g_default_testers
 
+    lfsc_sigs = []
+    if not g_args.lfsc_sig_dir == "":
+        lfsc_sig_dir = os.path.abspath(g_args.lfsc_sig_dir)
+        # `os.listdir` would be more appropriate if lfsc did not force us to
+        # list the signatures in order.
+        lfsc_sigs = ["core_defs", "util_defs", "theory_def", "nary_programs",
+                     "boolean_programs", "boolean_rules", "cnf_rules",
+                     "equality_rules", "arith_programs", "arith_rules",
+                     "strings_programs", "strings_rules", "quantifiers_rules"]
+        lfsc_sigs = [os.path.join(lfsc_sig_dir, sig + ".plf")
+                     for sig in lfsc_sigs]
+
     return run_regression(
         testers,
         wrapper,
         cvc5_binary,
+        lfsc_binary,
+        lfsc_sigs,
         g_args.benchmark,
         timeout,
     )