Jun 1, 2001
This document describes HolSatLib as distributed with the Kananaskis release of Hol98. Section 2 describes how to install it with Taupo releases.
HolSatLib provides a very simple harness in Hol98 for invoking SAT solvers on HOL terms. Currently the following solvers are supported
| Solver | Home Page |
| SATO | http://www.cs.uiowa.edu/~hzhang/sato.html |
| GRASP | http://sat.inesc.pt/~jpms/grasp |
| ZCHAFF | http://www.ee.princeton.edu/~chaff/zchaff.html |
These solvers all require input in the standard
DIMACS format
for conjunctive normal form (CNF). It is intended to be straightforward to add other
DIMACS compatible SAT solvers.
The purpose of HolSatLib is to provide a platform for experimenting with combinations of theorem proving and SAT. Hol98 can be used to deductively manipulate terms into CNF as required for SAT analysis, and then the results of the analysis can be reimported into HOL and either checked or just trusted.
Currently HolSatLib has only been tested under Linux, though it should be possible to run it under Windows.
The following examples illustrates HolSatLib in action.
Setting show_tags to true makes the Hol98 top level print theorem tags.
The function satOracle takes a SAT solver (currently either sato, grasp or zchaff, but more could be added) and a term t and
The function satProve performs steps 1-3 above, but then uses Hol98 to check that the model is really a model and then returns an untagged theorem. Note that checking a model is generally much quicker than finding it (one just `evaluates' the term with the values supplied by the model).
Thus if one is prepared to trust the solver then use satOracle, but if one wants to verify the results (which could be time-consuming) use satProve.
The next example illustrates what happens on unsatisfiable terms.
If a term t is unsatisfiable then satOracle will return |- ~t, tagged with the name of the SAT solver used. However, satProve will raise an exception, since there is no efficient way to check for unsatisfiability using pure Hol98 theorem proving.
A tautology checker that uses SAT can be easily programmed using CNF_CONV, which is supplied in the structure canonTools that comes with HolSatLib. To check the validity of a term t
Example Hol98 code to mechanise these steps is as follows:
- [th1]
- use CNF_CONV to prove |- ~t = t', where t¢ is in CNF;
- [th2]
- use SAT to prove |- ~t';
- [th3]
- by negating both sides of th1, prove |- ~~t = ~t';
- [th4]
- hence by combining th2 and th3 derive |- ~~t.
- [th5]
- hence by the law of double negation conclude |- t.
gunzip HolSatLib.tar.gz; tar -xf HolSatLib.tar
this should result in a directory dir/HolSatLib containing
Cnf.sml HolSatLib.sig HolSatLib.sml SatSolvers.sml doc sat_solvers
Holmake cleanAll; Holmake
you should see
Analysing HolSatLib.sml
Trying to create directory .HOLMK for dependency files
Analysing HolSatLib.sig
Compiling HolSatLib.sig
Analysing SatSolvers.sml
Compiling SatSolvers.sml
Compiling HolSatLib.sml
Analysing Cnf.sml
Compiling Cnf.sml
loadPath := "dir/HolSatLib" :: !loadPath;
load "HolSatLib"; open HolSatLib;
HolSatLib currently comes with three modules
| Module | Description |
| HolSatLib | functions for invoking SAT solvers |
| SatSolvers | specifications of sato, grasp and zchaff |
| Cnf | tool for converting HOL terms to CNF (from Joe Hurd) |
The signature of HolSatLib is shown below, followed by a description of the components.
signature HolSatLib = sig
datatype sat_solver =
SatSolver of {name : string,
URL : string,
executable : string,
notime_run : string -> string * string -> string,
time_run : string -> (string * string) * int -> string,
only_true : bool,
failure_string : string,
start_string : string,
end_string : string}
val sato : sat_solver
val grasp : sat_solver
val zchaff : sat_solver
val tmp_name : string ref
val sat_command : string ref
val prefix : string ref
val showSatVarMap : unit -> int * (string * int) list
val satOracle : sat_solver -> Term.term -> Thm.th
val satProve : sat_solver -> Term.term -> Thm.thm
val readDimacs : string -> Term.term
The datatype sat_solver is defined in the module SatSolvers. The data in the record argument to the constructor SatSolver is an ad-hoc list of what is needed to invoke a SAT program and parse the results. One only needs to know what the fields contain if one is adding another SAT prover. See the source code SatSolvers.sml for some information in the comments.
The ML identifiers sato, grasp and zchaff are bound by module SatSolvers to descriptions of the corresponding SAT solvers. These descriptions are passed to satOracle and satProve to select which SAT solver to invoke.
The reference tmp_name contains the temporary file name used in the last invokation of a SAT solver by satOracle or satProve. This name was generated using FileSys.tmpName.
The reference sat_command contains the actual command executed (using Process.system) for the last invokation of a SAT solver. This command reads from an input file and writes to an output file. The file names are generated by extending tmp_name (the input file name extension is cnf and the out extension is the name of the SAT solver used).
The reference prefix contains the string that is concatenated to numbers to get the HOL variables used when reading a separately generated DIMACS file with readDimacs. Default value is "v".
The function showSatVarMap returns a pair consisting of the one plus the number of variables used (i.e. the first number not currently used as a variable) and the mapping from variable names to numbers for encoding a term in DIMACS format by satOracle or satProve.
satOracle solver term
satProve solver term goes through the same steps 1,2 and 3 as satOracle, but instead of step 4
readDimacs file reads a DIMACS format file and returns an CNF HOL term corresponding the the SAT problem in the file names file. The integers in the file are prefixed with the string in the reference prefix (the default is "v").
readDimacs is mainly intended as a tool for getting
CNF examples by reading in examples from the DIMACS problem set,
which is distributed with HolSatLib in the directory
HolSatLib/doc/DIMACS or is available from
ftp://dimacs.rutgers.edu/pub/challenge/satisfiability/benchmarks/cnf/.
SatSolvers contains the definition of the datatype sat_solver for specifying SAT solvers.
The record that is supplied as an argument to the constructor SatSolver has the following fields.
| name | name of the SAT solver |
| URL | URL of the SAT executable for downloading |
| executable | name of the SAT solver command |
| notime_run | evaluating notime_run ex (infile,outfile) returns a string |
| giving a command to execute to run the SAT solver from input | |
| infile and produce output outfile; the paramenter | |
| ex should be the full path name of the SAT solver command | |
| all command options are the defaults (see solver documentation) | |
| time_run | evaluating time_run ex ((infile,outfile),time) returns a string |
| giving a command to execute to run the SAT solver for time units | |
| of time (the units are specified in the SAT solver's documentation) | |
| from input infile and produce output outfile; the paramenter | |
| ex should be the full path name of the SAT solver command; | |
| all command options, besides the time, are the defaults | |
| (currently time_run is not used) | |
| failure_string | string whose presence in the solver output indicated unsatisfiability |
| start_string | string indicating start of model |
| end_string | string indicating end of model |
Note that if a model is found, it is assumed to be bracketed
by start_string and end_string. SAT solvers
(like satz)
for which models are not bracketed by a fixed pair of strings cannot currently
be specified for use with HolSatLib. If access to such solvers is needed, then
it will be necessary to extend the datatype sat_solver to contain
additional parsing data (e.g. regular expressions).
The module canonTools contains a simple conversion CNF_CONV : term -> thm, from Joe Hurd, to convert HOL terms to a form suitable for inputting to satOracle or satProve.
CNF_CONV t returns a theorem |- t = t¢, where t¢ is in CNF.
There are other tools for converting to various canonical forms. See the source code canonTools.sml for details.