regress0/fmf/sc_bad_model_1221.smt2 \
regress0/fmf/syn002-si-real-int.smt2 \
regress0/fmf/tail_rec.smt2 \
+ regress0/fp/simple.smt2 \
regress0/fuzz_1.smt \
regress0/fuzz_3.smt \
regress0/get-value-incremental.smt2 \
regress0/quantifiers/is-int.smt2 \
regress0/quantifiers/issue2031-bv-var-elim.smt2 \
regress0/quantifiers/issue1805.smt2 \
+ regress0/quantifiers/issue2033-macro-arith.smt2 \
regress0/quantifiers/lra-triv-gn.smt2 \
regress0/quantifiers/macros-int-real.smt2 \
regress0/quantifiers/macros-real-arg.smt2 \
- regress0/quantifiers/issue2033-macro-arith.smt2 \
regress0/quantifiers/matching-lia-1arg.smt2 \
regress0/quantifiers/mix-complete-strat.smt2 \
regress0/quantifiers/mix-match.smt2 \
(e.g. there could be multiple non-linear facts and it is ok if any of them is
printed).
+Sometimes, certain benchmarks only apply to certain CVC4
+configurations. The `REQUIRES` directive can be used to only run
+a given benchmark when a feature is supported. For example:
+
+```
+; REQUIRES: symfpu
+```
+
+This benchmark is only run when symfpu has been configured.
+Multiple `REQUIRES` directives are supported. For a list of
+features that can be listed as a requirement, refer to CVC4's
+`--show-config` output.
+
Sometimes it is useful to keep the directives separate. You can separate the
benchmark from the output expectations by putting the benchmark in `<benchmark
file>.smt` and the directives in `<benchmark file>.smt.expect`, which is looked
EXPECT_ERROR = 'EXPECT-ERROR: '
EXIT = 'EXIT: '
COMMAND_LINE = 'COMMAND-LINE: '
+REQUIRES = 'REQUIRES: '
def run_process(args, cwd, timeout, s_input=None):
out = ''
err = ''
exit_status = 124
- timer = threading.Timer(timeout, lambda p: p.kill(), [proc])
try:
- timer.start()
+ if timeout:
+ timer = threading.Timer(timeout, lambda p: p.kill(), [proc])
+ timer.start()
out, err = proc.communicate(input=s_input)
exit_status = proc.returncode
finally:
- timer.cancel()
+ if timeout:
+ timer.cancel()
return out, err, exit_status
+def get_cvc4_features(cvc4_binary):
+ """Returns a list of features supported by the CVC4 binary `cvc4_binary`."""
+
+ output, _, _ = run_process([cvc4_binary, '--show-config'], None, None)
+ if isinstance(output, bytes):
+ output = output.decode()
+
+ features = []
+ for line in output.split('\n'):
+ tokens = [t.strip() for t in line.split(':')]
+ if len(tokens) == 2:
+ key, value = tokens
+ if value == 'yes':
+ features.append(key)
+
+ return features
+
+
def run_benchmark(dump, wrapper, scrubber, error_scrubber, cvc4_binary,
command_line, benchmark_dir, benchmark_filename, timeout):
"""Runs CVC4 on the file `benchmark_filename` in the directory
if not os.path.isfile(benchmark_path):
sys.exit('"{}" does not exist or is not a file'.format(benchmark_path))
+ cvc4_features = get_cvc4_features(cvc4_binary)
+
basic_command_line_args = []
benchmark_basename = os.path.basename(benchmark_path)
expected_error = ''
expected_exit_status = None
command_lines = []
+ requires = []
for line in metadata_lines:
# Skip lines that do not start with a comment character.
if line[0] != comment_char:
expected_exit_status = int(line[len(EXIT):])
elif line.startswith(COMMAND_LINE):
command_lines.append(line[len(COMMAND_LINE):])
+ elif line.startswith(REQUIRES):
+ requires.append(line[len(REQUIRES):].strip())
expected_output = expected_output.strip()
expected_error = expected_error.strip()
)
return
+ for req_feature in requires:
+ if req_feature not in cvc4_features:
+ print('1..0 # Skipped regression: {} not supported'.format(
+ req_feature))
+ return
+
if not command_lines:
command_lines.append('')
not cvc4_binary.endswith('pcvc4'):
extra_command_line_args += ['--check-unsat-cores']
if extra_command_line_args:
- command_line_args_configs.append(
- all_args + extra_command_line_args)
+ command_line_args_configs.append(all_args +
+ extra_command_line_args)
# Run CVC4 on the benchmark with the different option sets and check
# whether the exit status, stdout output, stderr output are as expected.