The Kettle Manual

Version 1.10.6 of Tue Oct 19 18:05:38 PST 2004

1  Introduction

Kettle is a theorem prover using the cooperating-decision procedures model due to Shostak and Nelson. It was originally designed as the theorem proving engine for constructing proof-carrying code. As such, Kettle can produce concrete representations of proofs for all facts that it proves.

This documentation is very incomplete at the moment.

A PDF version and a PS version of this document.

online API documentation

2  Installation

Kettle should run on any architecture that has an Ocaml compiler. We use it all the time on Linux and on Windows/cygwin.

If you are using Windows, get the cygwin distribution and make sure to get all Development tools (Dev), the XFree86-bin, XFree86-lib and XFree86-prog packages (XFree86) as well as TclTk package (lib). (you need the latter to use the the GUI). You should get also the ocaml package.

Next you need to tell Ocaml where Tcl is located: add an environment variable
export TCL_LIBRARY=/usr/share/tcl8.4
On cygwin, you can alternatively set in the Control Panel/System/Advanced TCL_LIBRARY to c:\cygwin\usr\share\tcl8.4.

Now you can configure and build Ocaml (if not on cygwin):
./configure
# Make sure the last step has configured Labltk 
make world
make opt
make install
Now you are ready to build Kettle:
  1. Download the Kettle distribution.
  2. Unzip and untar the source distribution. This will create a directory called kettle whose structure is explained below.
    tar xvfz kettle-1.10.6.tar.gz
  3. Enter the kettle directory and run the configure script and then GNU make to build the distribution. If you are on Windows, at least the configure step must be run from within bash.
          cd kettle
          ./configure
          make
          make RELEASE=1
          cd test
          make quicktest
          
This should leave the executable file obj/x86_WIN32/kettle.asm.exe (or x86_LINUX as might be the case). If you skip the ``make RELEASE=1'' you will only obtain the bytecode version (kettle.byte.exe), which is somewhat slower but faster to build.

To test that you have Kettle working you can run:
cd test
make quicktest
To test if the (experimental) GUI works, do
cd test
make prove/equality/uninterpreted GUI=1
The above command will run the prover on the file equality/uninterpreted.cvc and will leave a proof in the file equality/uninterpreted.prf.

3  The Kettle Theorem Prover

3.1  The Input Language

Kettle supports goals written either in the CVS syntax, or in the LF syntax. In lieu of a documentation, you can start by looking at examples in the test/uninterpreted directory. You can find examples of LF inputs in the files with extension .p, and examples of CVC input are in files with the extension .cvc.

3.2  Command Line Options

Kettle must be invoked with the names of the files containg goals to prove. Additionally, Kettle supports the following command line options:

4  The Graphical User Interface

If you invoke Kettle with the -gui argument, it will invoke the GUI after proving a fact. The purpose of the GUI is to show what goals were successful (and to show a proof for them) and which were not. The GUI is only useful if the input to Kettle contains annotations naming the various parts of the predicate to be proved. We discuss below an example of an input file containing GUI annotations, but if you are anxious you can find this example in the test/arith/gui.p file and you can play with it by running:
> cd test
> make prove/arith/gui GUI=1

4.1  The GUI Annotations

For the GUI to work the input file must contain annotations in the form of a new predicate constructor. For example, if p is a predicate then the following is an annotated version of p, saying that the name of the predicate is "this is p" and that it corresponds to line 9 in the file named foo.java:
(block [file:"foo.java",line:9,name:"this is p"]  p)
This section is written using the LF input language. For the CVC input language the same is true except that the syntax for the above example is
BLOCK [file:"foo.java",line:9,name:"this is p"]
p
ENDBLOCK
There must be a block annotation surrounding each top-level predicate to be proved. This will give the name that the GUI will show for the top-level predicate.

Each assumption and each goal that is encountered in the predicate are associated with the innermost block that contains them. If you want the maximum amount of information in the GUI you must have a block annotation for each assumption and for each goal. For example, the following input describes a predicate with two parts, the first part having an assumption and two goals.
Sat_p1 : pf
  (block [file:"foo.java",line:9,name:"this is p"]
    (block [file:"foo.java",line:9,name:"Part1"]
       (=> (x < 0) 
           (block [file:"foo.java",line:10,name:"Part1-Goal1"]
              (<= (+ x 1) 0)
           )
           (block [file:"foo.java",line:11,name:"Part1-Goal2"]
              (<= (+ x 1) 0)
           ))
    )
    (block [file:"foo.java",line:29,name:"Part2"]
           (block [file:"foo.java",line:11,name:"Part2-Goal1"]
              (= 0 0)
           )
    )
  )
The nested structure of the blocks gives the hierarchy.

4.2  The GUI panes

The GUI has four panes: Position, Source, Goals and Assumptions. The Position pane shows a hierarchical view of the verification steps. There is a root node, whose children are the individual predicates to be proved. Nodes with a little triangle handle are internal nodes in the hierarchy. If you click on the handle you can collapse or expand the hierarchy under that node. If you click on the label for a node, then the source pane shows the line to which it corresponds.

The Assumptions pane shows the assumptions that are in scope at the start of a block (not including the assumptions in the block itself). Typically, as you go does in the hierarchy, you will have more assumptions. Assumptions have names (e.g. H_1), which are refered from the proofs.

The Goal pane shows different things for different kinds of nodes. If you are on a goal node (typically a leaf) then you will see the goals for that node, along with their proofs. If you are on an assumption node, you will see in the Goals pane the assumption(s) that the node is adding.

In both the Assumptions and the Goals panes you can double click on a line and you get a pretty-printed version of the line in a separate window.

If all goals are successful then the GUI will start with all nodes collapsed. If there are failed goals then the tree is expanded to show all the failures. Also, the failed goals and all the parent nodes are collored red.

The GUI will try to find the files to show in the Source pane based on the information contained in the predicate annotations, along with a set of search directories (semicolon separated path names). The search directories, along with all configuration elements of the GUI are saved in a file called kettle_gui.cfg in the current directory and are restored automatically at the next invocation.

5  The Kettle Architecture

Kettle can parse input files in the LF or CVC format.

The code for the main proving engine is in Engine. The engine is given a thunk that when invoked will return the next input fragment. Input fragments are things like a literal to prove in the current context, an assumption to add to the current context, an indication to pop the last assumption, etc. The data type for the input language is described in the Input file. This architecture was essential for proving very large sequences of literals, what would not all fit in memory at once.

The actual inputs are written in terms of logical expressions and formulas, defined in Logic. Proofs of formulas can be written using the language defined in Proof. The same module also defines a proof checker that is enabled when you pass the --checkproofs argument on the command line.

The Engine module is initialized with a list of satisfiability procedures to use, and a proof generator. A satisfiability procedure consists of one or more ML modules, one of which exports a structure of type Satproc.entries. That structure contains entry points to the main operations that a satisfiability procedure supports.

In order to add a satisfiability procedure you can take the following steps: Also, before starting the engine, you must set the current UI to use. If you pass the --gui argument to Kettle, you will use the GUI, otherwise you use a text user interface.

6  Annotation Language

The following is the grammar for annotations:
Annotation A ::= ANN(AName, AA1,AA2, ...)
Annotation name AName ::= Predident   |  Ident
Annotation argument AA ::= E   |  P   |  "..."   |  { Reg1,Reg2, ...}
Predicate start startpred ::= 'A' - 'Z'   |  '<'   |  '>'   |  '='
Expression start startident ::= 'a' - 'z'   |  '_'   |  '%'   |  '$'   |  '!'   |  ''   |  '&'   |  '*'
        |  '+'   |  '-'   |  '\'   |  '?'   |  '|'   |  '/'   |  ' '
Predicate constructor Predident ::= Startpred (Startpred   |  Startident   |  ['0' - '9']) *
Expression constructor Ident ::= Startident (Startpred   |  Startident   |  ['0' - '9']) *
Number Num ::= ['0' - '9'] +
Register Reg ::= Architecture dependent gcc notation
Predicate P ::= TRUE   |  FALSE
        |  (AND P1 P2 ...)   |  (OR P1 P2 ...)
        |  (=> P1 P2)   |  (ALL [Ident] P)   |  (EXISTS [Ident] P)
        |  (Predident E1 E2 ...)
Expression E ::= Num   |  Reg   |  Ident
        |  (+ E1 E2)   |  (- E1 E2)   |  (* E1 E2)   |  Num( E )   |  (Ident E1 E2 ...)

Important syntactic notes:

7  Regression Testing

Kettle comes with a number of tests and a regression testing engine. You can start it in the test directory by running testkettle --run. The tests are defined in testkettle.pl.

8  Changes


This document was translated from LATEX by HEVEA.