Skip to content
 
 

Latest commit

 

History

17 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

 ******************************************************************************
 *                           FuzzSMT                                          *
 ******************************************************************************

  This is a release of FuzzSMT which is a fuzzing tool for SMT formulas. See
  www.smtlib.org for more details about SMT. For more info about fuzz
  testing SMT solvers see our paper: 'Robert Brummayer and Armin Biere. 
  Fuzzing and Delta-Debugging SMT Solvers', presented at SMT'09. FuzzSMT is
  released under GPL. A copy of the license can be found in the file COPYING. 

  The fuzzer is written in Java 5. I assume that you work on a UNIX/LINUX
  system with Sun's JDK 5 or higher installed.  However, it should be easy
  to follow the introductions and to use FuzzSMT on any other operating
  system that supports Java. Note that if you do not want to compile the
  fuzzer yourself, you just need a compatible Java runtime environment
  (supporting Java 5 or higher) in order to run the fuzzer.

  To build the fuzzer, go to the working directory of FuzzSMT and run
  './build.sh'. It compiles the sources with javac and packages them into
  'fuzzsmt.jar', so a JDK is all you need. The jar is not kept in the
  repository, so this is the first thing to do after cloning. Anyone who
  would rather use Apache Ant can still type 'ant' instead; the build-file
  'build.xml' does the same thing. For UNIX/LINUX system I provide a simple
  wrapper shell script 'fuzzsmt' which is convenient to use.

  If you want to enable the debugging code of the fuzzer, then compile with
  debugging info: add '-g' to the javac line in 'build.sh', or with Ant set
  it in the build file 'build.xml':

  <javac debug="yes" srcdir="${src}" destdir="${build}"/>

  The code of the fuzzer contains assertions. If you want to enable these
  assertions at run time, you have to call the java interpreter with the
  option '-ea'. Simply add this option to the script 'fuzzsmt'. If you just
  want to run the fuzzer, skip the two steps above.

  In contrast to my previous fuzzing tool called FuzzSMTBV, FuzzSMT is not
  limited to bit-vector theories. Call 'fuzzsmt -h' to get an overview of the
  supported theories. I tried to support all theories that are supported
  by the current version of the SMT-LIB. As you can imagine it was a lot of
  work. I still have some ideas and improvements that I want to implement,
  maybe in future releases.

  The fuzzer has been designed to be highly customizable. Therefore, there
  are many commandline options available. You should experiment with them
  in order to adjust the fuzzer to your needs. Call the fuzzer with '-h' in
  order to get an overview of the available options. As the usage message is
  quite large, it is a good idea to pipe it to a pager such as less. Do not
  worry, each option has a default value, so you do not have to adjust them
  if you do not want to. I tried to configure the fuzzer with reasonable
  default values. So, if you do not want to change the default values,
  just call the fuzzer with the specified logic, e.g. 'fuzzsmt QF_IDL'.

  The fuzzer has been designed to randomize itself. Typically, for each
  option, e.g. the number of variables in the input layer, you can specify
  a minimum and a maximum value. The fuzzer randomly chooses a value within
  this domain.  This takes the load off the user, i.e. the user does not have
  to write a script that randomizes the fuzzer options. If you do not want
  this behavior, e.g. you are interested in random formulas that have exactly
  'n' variables, then simply set the minimum and the maximum value to 'n'.

  If you have comments, questions, improvements or bug reports, then just
  send them to my mail address: robert.brummayer@gmail.com 
  I will try to answer your mails as soon as possible.

  Robert


 ******************************************************************************
 *                              FuzzSMT 0.33                                  *
 ******************************************************************************
Changes in 0.3
--------------
* By default, FuzzSMT now outputs SMT-LIB2 format. To output SMT-LIB1 format put
  the -smtlib1 command line argument after the name of the logic.
* The -bulk-export option creates instances in the current directory.
  Files are named f_[0..n).smt or f_[0..n).smt2. This feature was added because the
  JVM is slow to load, the JVM takes perhaps 100ms to load, but it only takes around
  1ms to generate each instance. Using this feature means that 100 instances can be
  generated in around 200ms instead of 10s. i.e. FuzzSMT is asymptotically 100 times
  faster.
* The QF_AUFBV logic now has a default maximum number of uninterpreted predicates
  and uninterpreted functions of 2. Previously it had a maximum of zero, so no
  uninterpreted functions would be output by default.
* The LRA & QF_ABV logics have been added. No old logics have been removed, for
  instance QF_A remains even though it is not an SMT-LIB2 logic.
* The amount to rotate left and rotate right are now taken from
  [0,2 + bitwidth), previously it was in [0, bitwidth). This generates instances
  that rely on the modulo-bitwidth behaviour of rotate left/right.

Changes in 0.31
---------------
* The version number has been changed.
* QF_RDL no longer outputs single arity pluses, e.g. (+ v12). The specification of QF_RDL was changed in December 2010.
* It's possible to specify a prefix now when outputing bulk files. This is to help when multiple threads are operating in the same directory.
* The default file prefix when bulk exporting is now _file_

Changes in 0.32
---------------
* The SMT-LIB 2 bit-vector overflow-detection predicates are now generated for
  the bit-vector logics (QF_BV, QF_ABV, QF_AUFBV, QF_UFBV):
  bvnego, bvuaddo, bvsaddo, bvusubo, bvssubo, bvumulo, bvsmulo, bvsdivo.
  These are SMT-LIB 2 only, so they are never emitted in -smtlib1 mode.
  Use -no-overflow to suppress them (e.g. when targeting a solver that does
  not yet support them).
* Operators that SMT-LIB 2 declares left-associative or variadic are now
  emitted with a random number of arguments between 2 and the -nary limit,
  rather than always exactly two. This applies to the bit-vector operators
  bvand, bvor, bvadd, bvmul and bvxor, and to the core Boolean operators
  and, or, xor, =>, = and distinct. It exercises solver parser paths that
  binary-only output never reaches.
  NOTE: the default limit is 3, so the default output of 0.32 differs from
  0.31 even with no new options given. Pass -nary 2 to restore the previous
  binary-only behaviour. Like the overflow predicates, this is SMT-LIB 2
  only and never affects -smtlib1 output.
* The Boolean layer now seeds its operand pool with the constants true and
  false, so they appear in generated instances instead of never being used.
* Distinct with more than two operands is now generated, lifting a 0.31
  limitation. Because distinct over three or more Booleans is trivially false
  by pigeonhole, the n-ary form is deliberately made very rare (well under one
  occurrence in ten thousand generated instances): it stays reachable, so a
  long fuzzing run still covers the n-ary parser path, but in practice
  distinct is binary.

Changes in 0.33
---------------
* The SMT-LIB 2 FloatingPoint theory is now supported, adding the logics
  QF_FP, QF_FPLRA, QF_BVFP, QF_BVFPLRA, QF_ABVFP, QF_ABVFPLRA and
  QF_AUFBVFP. The theory was added to SMT-LIB after 0.31 was written, which
  is why it was missing.
* Generated floating point terms cover fp.abs, fp.neg, fp.sqrt,
  fp.roundToIntegral, fp.add, fp.sub, fp.mul, fp.div, fp.rem, fp.min,
  fp.max, fp.fma and ite. Generated predicates cover fp.leq, fp.lt, fp.geq,
  fp.gt, fp.eq, the seven classification predicates (fp.isNormal,
  fp.isSubnormal, fp.isZero, fp.isInfinite, fp.isNaN, fp.isNegative,
  fp.isPositive) and core = and distinct.
* All the literal forms are generated: the (fp sign exponent significand)
  triple, +oo, -oo, +zero, -zero, NaN, and the conversions from a bit
  pattern and from signed and unsigned machine integers.
* Rounding modes are drawn from the five constants, in both their short and
  their long spelling, and from declared RoundingMode variables. Use
  -mvrm/-Mvrm to control how many such variables are declared.
* Operands of an fp operator have to agree on both the exponent and the
  significand width. Where they do not, the operand is converted with the
  theory's own to_fp rather than with the extract/extend that the
  bit-vector layers use, so conversions appear throughout the output.
* Sorts are drawn from Float16, Float32, Float64 and Float128, and the
  abbreviated names are emitted about half the time. -fp-any instead draws
  arbitrary (eb,sb) pairs, bounded by -Mfpeb and -Mfpsb.
* In the mixed logics the theory boundary is crossed in both directions:
  to_fp and to_fp_unsigned build floating point terms out of bit-vectors
  and reals, and fp.to_ubv, fp.to_sbv and fp.to_real go the other way. The
  partial conversions are deliberately left unguarded, so NaN, the
  infinities and out-of-range values do reach them. -mconv/-Mconv set how
  many conversions are generated per direction.
* fp.div, fp.rem, fp.fma and fp.sqrt are not generated for sorts wider than
  Float64, i.e. for Float128 and for anything at least as wide drawn by
  -fp-any. On those sorts they bit-blast into circuits that solvers do not
  get through, and a timed out instance tells a fuzzing run nothing.
  Measured over 50 QF_FP instances with z3 5.0.0 and a ten second limit,
  leaving them out takes the timeouts from 10 to 6, the median solving time
  from 520ms to 103ms and the third quartile from 6.1s to 1.1s. Pass
  -fp-wide-ops to generate them anyway. All the other operators are
  generated on every sort, and all four are still generated on Float16,
  Float32 and Float64.
* Floating point exists only in SMT-LIB 2, so -smtlib1 together with any of
  the floating point logics is rejected rather than silently ignored.

* distinct is now generated wherever = between terms of the same sort is,
  and with 2 to -nary operands rather than always two. It reaches arrays,
  which it did not before: QF_ABV and QF_AUFBV only ever compared arrays
  with =, and QF_A and QF_AX only ever compared them two at a time. An
  n-ary distinct over arrays makes a solver reason about how many distinct
  arrays a sort can hold, e.g. five pairwise distinct
  (Array (_ BitVec 1) (_ BitVec 1)) terms are unsatisfiable by pigeonhole.
  Operands are sampled without repetition, since a distinct naming the same
  term twice is false whatever else it lists.
* Array distinct needs extensionality just as array = does, so it is
  generated only when -mxn/-Mxn ask for array comparisons. Those still
  default to 0, which keeps the output usable by solvers without
  extensionality.
* A parenthesis was missing from the bit-vector array extensionality layer,
  so every instance generated with -mxn/-Mxn above 0 was unbalanced and no
  parser would take it. The layer had never run before, since the options
  default to 0.

Limitations
-----------
* No QF_UFFPDTNIRA: it needs algebraic datatypes, which are not generated
  for any logic.
* A binary distinct may name the same term twice, i.e. be trivially false.
  Only the n-ary form samples without repetition.
* The arrays in QF_ABVFP, QF_ABVFPLRA and QF_AUFBVFP are bit-vector indexed
  arrays of bit-vectors. Arrays with floating point elements are not
  generated.
* The LRA output is the same as QF_LRA, i.e. no variables are quantified over.
* No UFLRA & UFNIA logics. Both logics have benchmarks, but aren't currently listed on:
	http://goedel.cs.uiowa.edu/smtlib/logics.html
* Sometimes QF_UFBV outputs divisions where the denominator isn't constrained to be non-zero.

Testing of 0.31
---------------
Example validation. The below script was run for a while; Z3 2.16 & "CVC3 2010-09-25" were able to parse most of the generated instances.

while [ 1 -eq 1 ]; do
	for t in  'QF_ABV' 'QF_AUFBV' 'QF_AUFLIA' 'QF_AX' 'QF_BV' 'QF_IDL' 'QF_L
IA' 'QF_LRA'  'QF_NIA' 'QF_NRA'  'QF_RDL' 'QF_UF' 'QF_UFBV' 'QF_UFIDL' 'QF_UFLIA
' 'QF_UFLRA' 'QF_UFNRA'   'AUFLIA' 'AUFLIRA' 'AUFNIRA' 'LRA' ; do
		java FuzzSMT  $t -bulk-export 100 
		for f in `ls -1 _file_*.smt2` ; do
			cvc3=`(ulimit -t 25; cat $f | ~/tools/cvc3_ex -lang smt2)`
			z3=`(ulimit -t 25;z3 MBQI=true ELIM_QUANTIFIERS=true $f)
`			z3=`echo $z3 | rev | cut -d " " -f1 | rev`
			echo $cvc3 $z3
			if [ "$cvc3" = "sat" -a "$z3" = "unsat" ]; then
				mv $f `tempfile --directory=cvc3`
			fi
			if [  "$cvc3" = "unsat" -a "$z3" = "sat"  ]; then
				mv $f `tempfile --directory=cvc3`
			fi
		done
	done
done



About

SMT fuzzer by Robert Brummayer, with other edits

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages