Twig Documentation


Twig is a theorem proving tool which consists mainly of a decision procedure for deciding properties of equations involing bit-vectors with symbolic lengths.

Table of Contents

1. Introduction
2. Meas: the input language
3. Twig: the command Line tool
4. Gtwig: the graphical user interface
5. Examples

1. Introduction

Twig is a decision procedure for properties bit-vectors of symbolic lengths.  The decsion procedures that it uses have been described in my doctoral thesis: Automated Reasoning about Hardware Data Types Using Bit-vectors of symbolic lengths.  The goal of this research is to provide an invaluable tool for reasoning about parametric hardware descriptions (descriptions in which the width of the bit-vectors and other structures are not fixed integers).  It is hoped that the ability to determine the validity of such properties would help a designer produce a correct product.

In Twig, our goal is to produce a tool with the following top-level features (in order of decreasing importance):
  1. Decision procedures are sound and complete.
  2. Negative decision results are accompanied by a viewable counter-model.
  3. Counter-models are used to interpret (or run) the description. This certifies the counter-model.
  4. Positive decision results are accompanied by a viewable proof.
  5. Proofs are certified in a simple proof system.
  6. Methods for integrating the decision procedures in third party tools are available.
Twig is composed of several components.  The components most visible to the user are
The remainder of this manual will describe how these components work and give some examples which introduce the capabilities of Twig. To read more about the algorithms and methods used in Twig please refer to my doctoral
thesis: Automated Reasoning About Hardware Data Types Using Bit-vectors of Symbolic Length.

2. Meas: the input language

The Meas language is modelled after pure ML with a syntax similar to that of OCaml.   Only the core of the lanugage is available: lambda abstraction, let-bindings, recursive functions, and explicit type restrictions.
A BNF grammar describing Meas syntax is available.  We describe below a much simplified account of the Meas grammar which is more useful for a first glance.

2.1 Types

Types in Meas are partitioned according to characteristic: data, address or function.  Data characteristic is  associated with types that are meant to be data structures in the model.  Address characteristic is associated with vector domains.  Ranges are described by types with data characteristic.  Function charactistic is associated with types for functions (higher-order and otherwise).


address_type_expression ::=

##### length_type_expression

#####| address_type_expression ** address_type_expression

#####| address_type_variable

#####| ( address_type_expression )


length_type_expression ::=

##### NUMBER

#####| length_type_variable

#####| length_type_expression - length_type_expression

#####| length_type_expression + length_type_expression

#####| ( length_type_expression )


address_type_variable ::=

##### IDENTIFIER : address

length_type_variable ::=

##### IDENTIFIER : length


Length expressions are the most basic address types, and the consist of symbolic expressions which represent integer upper bounds for an array domain.  Lengths are constructed using variables, numbers, addition and subtraction.  Address types are formed using variables, length expressions, and cartesian products (**).

data_type_expression ::=

##### bool

#####| data_type_expression ** data_type_expression

#####| address_type_expression ->d data_type_expression

#####| data_type_variable

#####| ( data_type_expression )

data_type_variable ::=

##### IDENTIFIER : data

Types with characteristic data are formed using the boolean constant type (bool), cartesian product (**), array types (->d), and variables.  Since booleans are the underlying constants at the bottom of the syntax of every ground type, we can view types with characteristic data as structures that contain bits.  Vectors are a simple special case of a type with charateristic data (l ->d bool for any length expression l).

functional_type_expression ::=

##### data_type_expression ->f data_type_expression

#####| address_type_expression ->f data_type_expression

#####| functional_type_expression ->f data_type_expression

#####| address_type_expression ->f functional_type_expression

#####| data_type_expression ->f functional_type_expression

#####| functional_type_expression ->f functional_type_expression

#####| functional_type_variable

#####| ( functional_type_expression )

Types with functional characteristic are formed using allowable combinations of the other characteristic and the function arrow (->f).  Types with address characteristic are not allowed to be the range of a type with functional type.  The reason for this is that we do not deal with address types as first class items.  They are only important in so far as they are part of a type with characteristic data.  The denotational semantics of the arrow operators ->d and ->f are the same if we consider only terminating functions.

2.2 Operators and variables

With the rudimentary description of the type system in the  previous section, we are ready to  describe the functions that are available in Twig. The first functions we will describe are familiar the familiar boolean operations and constants.  These are polymorphic, in the sense that they are well defined
for any type of characteristic data (we use a colon ':' as a separator between an expression and its type):

0 : data_type_expression

1 : data_type_expression

For example, 0 : 3 ->d bool is a vector of three boolean values.

not : data_type_expression ->f data_type_expression

Negation is done via the 'not' function which returns the same type as it takes.
For instance, we expect that  the expression 'not  ( 0  :  bool)'  and  '1: bool',
refer to the same thing. For more complicated types, the obvious recursion is done
to negate all the boolean values contained within the data structure.

and : data_type_expression ->f data_type_expression ->f data_type_expression

Conjunction (via the 'and' function)  takes two operands with the same type and returns
the conjunction we expect.  As in the case of negation, types more complicated
than bool are handled by performing elementwise conjunction recursively.

or : data_type_expression ->f data_type_expression ->f data_type_expression

The function 'or' is used for disjunction.

xor : data_type_expression ->f data_type_expression ->f data_type_expression

eq : data_type_expression ->f data_type_expression ->f data_type_expression

Binary functions for equality ('eq') and exclusive-or ('xor') are also available, and they are defined in a similar way to the other boolean operators.

After boolean operations, we have structural operations which enable us to move information around, rather than form relations.  Combining structural operations with boolean operations in an unrestricted fashion allows us to express properties about general Turing machines.  Only for restricted use of structural operations, do we have a decidable fragment which Twig implements.

The first structural operation is concatenation.  It allows two vectors with the same range type to be "stuck together" to form a vector containing both original vectors.

con : (length_type_expression1 ->d data_type_expression) ->f (length_type_expression2 ->d data_type_expression) ->f (length_type_expression1 + length_type_expression2) ->d data_type_expression

The semantics of concatenation are as follows:  'con x y' begins with the 'x' values starting from 0, and past the length of 'x', the 'y' values are found.  So the length of the resulting vector is the sum of the lengths of the argument vectors.

In addition to sticking vectors together with concatenation, we are able to pull them apart with extraction.   Extraction takes a subrange of a vector's domain to form a subvector from the original vector.

extr : (length_type_expression1 ->d data_type_expression) ->f length_type_expression2 ->f length_type_expression3 ->f (length_type_expression3 - length_type_expression1) ->d data_type_expression

To stretch a single bit to a vector by repeating the value, we emply repetition.

rep : (length_type_expression ->f data_type_expression ->f (length_type_expression ->d data_type_expression))

To reduce a vector to a single bit, we use the reduction operations andred and orred.  Andred computes the conjunction of all the bits in its argument vector and is 1 when applied to the empty vector.  Orred computes the disjunction of all the bits in its argument vector and is 0 when applied to the empty vector.

andred : (length_type_expression ->d data_type_expression) ->f data_type_expression

orred : (length_type_expression ->d data_type_expression) ->f data_type_expression

The only other constant other than 0 and 1 is the empty vector:

eps : 0 ->d data_type_expression

Variables can be declared as global unknowns:

unknown variable_identifier

unknown ( variable_identifier : type_expression )

Variables can also be declared as arguments or local variables by referencing
their name and (possibly) their type.

variable_identifier

( variable_identifier : type_expression )


2.3 Properties and expressions

Properties are stated by giving their name and definition.  Free variables and functions must have been previously declared (using a definition or as unknowns).  Forcing this upon the user prevents the introduction of unexpected behaviors due to the fact that some variable was unintentionally misspelled.

property property_identifier : expression

Sensible properties (for the moment) are properties whose types are bits (and therefore definitively of characteristic data.

At this point it is useful to describe expressions.  Expressions are formed by composing the operators and variables in the source to form larger terms:


expression ::=
       fun variable_term -> expression
     |  let variable_term variable_term_list = expression in expression
     |  let rec variable_term variable_term_list = expression in expression
     |  if condition_on_length_type_expression then expression else expression
     |  variable_term_typeless
     |  expression expression
     |  ( expression )
     |  operator

Most of this syntax and its intended semantics is taken from the functional language OCaml.  The names of each of these compositions are as follows (in order): Lambda terms, let-bindings,  recursive let-bindings, conditionals, variables instances, applications, parenthesized expressions and operators (these were described in the previous section).

At the moment,  recursive function descriptions are not yet supported and conditional expressions are only meant to deal with conditions on length variables (used in the types).  The intention is to use conditionals from this built-in syntax to distinguish the base cases of recursively defined functions (once support for these is implemented).  Variable instances are typeless since type constraints can only be placed on them where they are declared (as described in the previous section).

Defined functions and constants can be defined outside of property definitions.  This allows the sharing of these definitions amongst several properties.  We are now ready to describe the  top-level BNF for (?.twig) source files:

 source_file ::=
          epsilon
    | declaration source_file
    | property source_file


3. Twig: command line tool

Usage:

    twig [options] file.twig

General Remarks:
    Twig runs by opening the text file specified, parsing it, and attempting
to prove all properties (unless it otherwise specified in the arguments).  As a side-effect of running twig, a file (file.dat) is written which allows inspection of the results in Gtwig (the GUI part of the Twig project).

Options:

    --single propertyname
       The property specified is the only property that twig will attempt to prove.  Other properties are

    --time
       This option causes Twig to produce a time report which describes the amount of computation time that each part of Twig uses.

    --bdd
       This option chooses the Bdd-based algorithm (replacing the relatively naive tableau algorithm). 

Evironment variables:

You must set the LD_LIBRARY_PATH environment variable to include the path to the shared library (typically /usr/local/lib/dllmuddy.so). 

4. Gtwig: graphical-user interface

The graphical user interface is implemented in GTK+ using the lablgtk libraries for OCaml.  The interface consists of an upper half which displays the source of a file.twig file.  The GUI interface implements all the functionality of the command line command twig.  This functionality is accessed via the menus at the top of the main window.

GTwig Main window

Fig 1. GTwig Main Window

The lower panel consists of several tabs which display information in reaction to user commands.  The three tabs are called Log, Properties and Countermodel.  Below we systematically describe the user commands that are possible from the menus:

File Menu:

File Menu image

New file clears the source text region and loses the source in the text region.  Open file pops up a file chooser dialog which allows the user to specify which new source file will be opened.  Save file saves the file to the filename specified in the window title bar;  if none is yet specified, the user is prompted to supply one using a file chooser dialog.  Save As... functions much the same way except that the file dialog comes up regardless of whether the name of the current source file is known.  Parse File causes the twig parser to analyze the file.  The parser will report syntactic errors in the source file displayed in the source text region.  Type errors are also reported.  The user is notified of this operation's success or failure via the log tab in the lower half of the window.  In the case of an error a link is produced that allows the user to jump to the error location in the source file text region.  A side effect of the parsing operation is the population of the combobox with the names of the properties described in the source file.  Quit causes the GUI to quit.

Edit Menu:

Edit Menu Image

Copy copies the user-highlighted text in the source file text region to the system clipboard.  Cut copies and removes the user-highlighted text in the source file text region (again the copy is kept in the system clipboard).  Paste causes the last clipboard entry to be placed at the user cursor position in the source file text region.

Properties Menu:

Properties menu image

The verify operations in the properties menu are meant to be executed after the source text is parsed.  If the source text has not been parsed, then it is silently parsed before the verify operation is done.  Verify All Properties causes all of the properties in the source file to be verified.  Verify Selected Property causes the verification of the single selected property in the  combobox to occur.  The verification of a property causes a line to be added to the Properties tab below.  Successful verification is signalled with TRUE and failure with FALSE.  When the user highlights a line (property) in the Properties tab that is false, the Countermodel tab is activated and the user can view the associated countermodel.  Clear Results resets the results in the Properties tab below.  Halt does nothing.

5. Examples