Kodkodi User Manual

About Kodkodi 1.1.4

Kodkodi 1.1.4 (March 17, 2009) is a front-end for the Java library Kodkod, a SAT-based solver for first-order logic with relations, transitive closure, and partial instances. Kodkod forms the basis of Alloy Analyzer version 4. The Kodkodi front-end is designed to make the Kodkod library available to other programming languages than Java. Kodkodi is developed and maintained by Jasmin Christian Blanchette at the Technische Universität München.

Requirements

Kodkodi requires the runtimes for ANTLR 3.1.1 and the Nov. 27, 2008 version of Kodkod to be located in the Java classpath. Both are bundled with Kodkodi. In addition, you will need to install a SAT solver. Follow the instructions on Kodkod's home page, or use the platform-independent (but apparently slower) SAT4J solver bundled with Kodkodi. To run the program, you simply need a Java 1.5 virtual machine (normally called java). To recompile it, you need a Java compiler and the ANTLR parser generator tools.

Usage

The kodkodi program takes its input from standard input and writes its output to standard output (on success) or standard error (on failure). Examples are provided in the examples directory.

Usage: kodkodi [options]
options:
  -help               Show usage and exit
  -verbose            Produce more output
  -exit-on-success    Exit on the first successful 'solve' directive
  -clean-up-inst      Remove trivial parts of instance from output
  -max-msecs <num>    Maximum running time in milliseconds
  -max-threads <num>  Maximum number of simultaneous threads

Example:

$ java de.tum.in.isabelle.Kodkodi.Kodkodi < examples/pigeonhole.kki

*** PROBLEM 1 ***

---OUTCOME---
UNSATISFIABLE

---STATS---
p cnf 54 68
primary variables: 6
parsing time: 65 ms
translation time: 92 ms
solving time: 0 ms

Input Format

Kodkodi's input format borrows heavily from the output format of the toString() implementations found in the Kodkod library. The operator that are available in Alloy 4 are given the same precedences as they have there.

The grammar is expressed using a variant of Extended Backus-Naur Form (EBNF). The actual grammar used by Kodkodi is written using ANTLR and can be found in the file Kodkodi.g.

Lexical Issues

The grammar is based on the following lexical units, or tokens:

WHITESPACE    ::= (  | \n | \r | \t | \v)+
COMMENT       ::= // ~(\n)* (\n | EOF)
NUM           ::= [+ | -] (0 | 1 || 9)+
STR_LITERAL   ::= " ~(" | \n)* "

ATOM_NAME     ::= A NAT 
UNIV_NAME     ::= u NAT 
OFF_UNIV_NAME ::= u NAT @ NAT 
TUPLE_NAME    ::= (P | T NAT _) NAT
RELATION_NAME ::= (s | r | m NAT _) NAT
VARIABLE_NAME ::= (S | R | M NAT _) NAT '?
TUPLE_REG     ::= $ (A | P | T NAT _) NAT
TUPLE_SET_REG ::= $ (a | p | t NAT _) NAT
FORMULA_REG   ::= $f NAT 
REL_EXPR_REG  ::= $e NAT 
INT_EXPR_REG  ::= $i NAT 

NAT abbreviates 0 | 1..9 0..9*.

Comments start with // and end with the line. Whitespace is ignored, except as a token separator. In addition to the tokens listed above, various keywords and operators are recognized as tokens. These are shown in bold in the grammar.

The table below describes the lexical conventions adopted for naming atoms, tuples, relations, variables, and registers.

Token NameSyntaxDescription
ATOM_NAMEAjAtom at index j in the universe
UNIV_NAMEunSet of atoms A0 to A(n − 1)
OFF_UNIV_NAMEun@jSet of atoms Aj to A(j + n − 1)
TUPLE_NAMEPjPair at index j in the pair space associated with the universe
Tn_jn-tuple at index j in the n-tuple space associated with the universe (n ≥ 3)
RELATION_NAMEsjSet number j
rjBinary relation number j
mn_jn-ary multirelation number j (n ≥ 3)
VARIABLE_NAMESjUnprimed set variable number j
Sj'Primed set variable number j
RjUnprimed binary relation variable number j
Rj'Primed binary relation variable number j
Mn_jUnprimed n-ary multirelation variable number j (n ≥ 3)
Mn_j'Primed n-ary multirelation variable number j (n ≥ 3)
TUPLE_REG$AjOne-tuple register number j
$PjPair register number j
$Tn_jn-tuple register number j (n ≥ 3)
TUPLE_SET_REG$ajOne-tuple set register number j
$pjPair set register number j
$tn_jn-tuple set register number j (n ≥ 3)
FORMULA_REG$fjFormula register number j
REL_EXPR_REG$ejRelational expression register number j
INT_EXPR_REG$ijInteger expression register number j

Atoms and tuples are defined implicitly in terms of the universe. Relations and variables need no declarations, but relations do need bounds. Variables may be primed—a primed variable is distinct from the corresponding unprimed variant. Registers must be assigned to before they are used in an expression. It is highly recommended to use low indices because Kodkodi stores relations, variables, and registers in 0-based arrays.

Overall Structure

This section presents the overall structure of Kodkod input files.

Problems

problems ::= problem*

Kodkodi takes a list of “problems” as input.

Problem

problem ::= option*
            univ_spec 
            tuple_reg_directive*
            bound_spec*
            int_bound_spec?
            expr_reg_directive*
            solve_directive 

A problem consists of three main parts: a universe specification, a set of bound specifications, and a Kodkod formula to satisfy supplied in a “solve” directive.

Example:

univ: u1
bounds s0: {A0}
solve all [S0 : one s0, S1 : one s0] | S0 = S1;

Kodkod Options

option ::= solver : STR_LITERAL (, STR_LITERAL)* |
           symmetry_breaking : NUM |
           sharing : NUM |
           bit_width : NUM |
           skolem_depth : NUM |
           flatten : (true | false)

Kodkod supports various options, documented in the kodkod.engine.config.Options class. The following solvers are supported:

solver: "DefaultSAT4J"
solver: "LightSAT4J"
solver: "ZChaff"
solver: "zChaff"
solver: "ZChaffMincost"
solver: "zChaffMincost"
solver: "MiniSatProver"
solver: "MiniSat"
solver: "SAT4J" "instance"
solver: "External" "executable" "temp_input" "temp_output" "arg_1" … "arg_n"
solver: "ExternalV2" "executable" "temp_input" "temp_output"
                     "sat_marker" "var_marker" "unsat_marker" "arg_1" … "arg_n"

For "External", the optional arguments "arg_1" … "arg_n are passed before the input file name. For "ExternalV2", they are passed after.

Universe Specification

univ_spec ::= univ : UNIV_NAME

The universe specification fixes the universe's uninterpreted atoms. Kodkodi requires that the atoms are numbered consecutively from A0 to A(n − 1).

Examples:

univ: u2
univ: u100

Relation Bound Specifications

bound_spec ::= bounds RELATION_NAME (, RELATION_NAME) :
               ( tuple_set | [ tuple_set , tuple_set ] )

A relational bound specification gives a lower and an upper bound for the given relations. If only one bound is specified, it is taken as both lower and upper bound. The lower bound must be a subset of the upper bound.

Examples:

bounds s0: {A0}
bounds r2: [{}, {A0 .. A9} -> {A10 .. A19}]

Integer Bound Specification

int_bound_spec ::= int_bounds : int_bound_seq (, int_bound_seq)*
int_bound_seq  ::= [NUM :] [ tuple_set (, tuple_set)* ]

An integer bound specification establishes a correspondence between integers and sets of atoms that represent that integer in relational expressions. The syntax makes it possible to specify the bounds of consecutive integers in sequence.

Example:

int_bounds: [{A0}, {A1}], 10: [{A2}, {A3}, {A4}]

In the above example, 0 is bounded by {A0}, 1 is bounded by {A1}, 10 is bounded by {A2}, 11 is bounded by {A11}, and 12 is bounded by {A4}.

Solve Directive

solve_directive ::= solve formula ;

The “solve” directive tells Kodkod to try to satisfy the given formula.

Example:

solve all [S0 : one s0, S1 : one s0] | !(S0 = S1) => no (S0.r0 & S1.r0)

Register Directives

Registers make it possible to use a complex syntactic construct several times without duplicating it. They also help reduce Kodkod's memory usage and running time.

Tuple Register Directives

tuple_reg_directive ::= TUPLE_REG := tuple |
                        TUPLE_SET_REG := tuple_set 

A tuple register directive assigns a value to a tuple or tuple set register.

Examples:

$P0 := [A0, A0]
$P1 := [A1, A1]
$t4_0 := {$P0, $P1} -> {$P0, $P1}

Expression Register Directives

expr_reg_directive ::= FORMULA_REG := formula |
                       REL_EXPR_REG := rel_expr |
                       INT_EXPR_REG := int_expr 

Formulas, relational expressions, and integer expressions can also be assigned to registers using an expression register directive. An alternative is to use the let binder inside an expression.

Examples:

$f0 := all [S0 : one s0] | s0 in univ
$e5 := (s0 & s1).r1 + (s0 & s2).r2
$i14 := 2 * #($e5) + 1

Tuple Language

Kodkod supports partial solutions in the form of bounds on relations. The bound specifications involve tuples and tuple sets.

Tuples

tuple ::= [ ATOM_NAME (, ATOM_NAME)* ] |
          ATOM_NAME |
          TUPLE_NAME |
          TUPLE_REG 

An n-tuple is normally specified using the syntax [Aj1, …, Ajn]. The brackets are optional when n = 1. Alternatively, tuples can be specified using an index in the n-tuple space. For example, given the universe {A0 .. A9}, the name P27 refers to the pair [A2, A7].

Examples:

[A0, A1, A5, A20]
A0
P5
$P14

Tuple Sets

tuple_set ::= tuple_set (+ | -) tuple_set |
              tuple_set & tuple_set |
              tuple_set -> tuple_set |
              tuple_set [ NUM ] |
              { tuple (, tuple)* } |
              { tuple .. tuple } |
              { tuple # tuple } |
              none |
              all |
              UNIV_NAME |
              OFF_UNIV_NAME |
              TUPLE_SET_REG |
              ( tuple_set ) 

Tuple sets can be constructed in several ways. The +, -, and & operators denote the union, difference, and intersection of two tuple sets, respectively. The -> operator denotes the Cartesian product of two tuple sets. The [] operator projects the tuple set onto the given dimension. Tuple sets can be specified exhaustively by listing all their tuples. If all the tuples have consecutive indices, the range operator .. can be used. Alternatively, if all the tuples occupy a rectangular, cubic, etc., area in the tuple space, they can be specified by passing the lowest and highest corner of the area to the # operator. Finally, none is a synonym for {}, and all denotes the complete tuple set (whose arity is deduced from the context).

Examples:

{A1}
{A1, A2} -> {A3, A4}
{[A1, A2] .. [A3, A4]}
{[A1, A2] # [A3, A4]}
$p14

Tuple Set Operator Precedences and Associativities

The operator precedences and associativities are given in the table below. Fully bracketed operators are not listed.

LevelOperator ClassArityAssociativity
1+   -BinaryLeft-associative
2&BinaryAssociative
3->BinaryAssociative
4[]BinaryLeft-associative

Expression Language

Kodkod supports three types of expression: Boolean expressions (formulas), relational expressions, and integer expressions.

Formulas

formula ::= (all | some) decls | formula |
            let assigns | formula |
            if formula then formula else formula |
            formula || formula |
            formula <=> formula |
            formula => formula |
            formula && formula |
            ! formula |
            ACYCLIC ( RELATION_NAME ) |
            FUNCTION ( RELATION_NAME , rel_expr -> (ONE | LONE) rel_expr ) |
            TOTAL_ORDERING ( RELATION_NAME , (UNIV_NAME | OFF_UNIV_NAME | RELATION_NAME) ,
                             (ATOM_NAME | RELATION_NAME) , (ATOM_NAME | RELATION_NAME) ) |
            rel_expr (in | =) rel_expr |
            int_expr (= | < | <= | > | >=) int_expr |
            (no | lone | one | some) rel_expr |
            false |
            true |
            FORMULA_REG |
            ( formula ) 

A formula, or Boolean expression, specifies a constraint involving relations and integers.

Example:

some [S0 : some s0] | if S0 in s1 then !$f1 else $i0 <= $i1

Relational Expressions

rel_expr ::= let assigns | rel_expr |
             if formula then rel_expr else rel_expr |
             rel_expr (+ | -) rel_expr |
             rel_expr ++ rel_expr |
             rel_expr & rel_expr |
             rel_expr -> rel_expr |
             rel_expr \ rel_expr |
             rel_expr ( rel_expr (, rel_expr)* ) |
             rel_expr [ int_expr (, int_expr)* ] |
             rel_expr . rel_expr |
             (^ | * | ~) rel_expr |
             { decls | formula } |
             (Bits | Int) [ int_expr ] |
             iden |
             ints |
             none |
             univ |
             ATOM_NAME |
             UNIV_NAME |
             OFF_UNIV_NAME |
             RELATION_NAME |
             VARIABLE_NAME |
             REL_EXPR_REG |
             ( rel_expr ) 

A relational expression denotes a relation (set, binary relation, or multirelation). Nearly all operators are identical to those offered by Kodkod, which in turn are modeled after those provided by Alloy. Notable exceptions are the conditional expression if … then … else …; the r\s operator, which is a shorthand for if no r then s else r; and finally r(s1, …, sn), which is equivalent to sn.(…(s1.r)…).

Example:

if #(s0) > 5 then s0.r0 + s1.r1 else none

Integer Expressions

int_expr ::= sum decls | int_expr |
             let assigns | int_expr |
             if formula then int_expr else int_expr |
             int_expr (<< | >> | >>>) int_expr |
             int_expr (+ | -) int_expr |
             int_expr (* | / | %) int_expr |
             (# | sum) ( rel_expr ) |
             int_expr | int_expr |
             int_expr ^ int_expr |
             int_expr & int_expr |
             (~ | - | abs | sgn) int_expr |
             NUM |
             INT_EXPR_REG |
             ( int_expr ) 

An integer expression denotes an integer.

Example:

(sum [S0 : one s0] | #(S0) * (#(S0) + 1) / 2) % 10

Declarations

decls ::= [ decl (, decl)* ]
decl  ::= VARIABLE_NAME : (no | lone | one | some | set) rel_expr

The all, some, and sum quantifiers take a list of variable declarations.

Example:

[S0 : set s0, S1 : one s1]

Assignments

assigns ::= [ assign (, assign)* ]
assign  ::= FORMULA_REG := formula |
            REL_EXP_REG := rel_exp |
            INT_EXP_REG := int_exp  

The let binder takes a list of register assignments.

Example:

[$f0 := all [S0 : one s0] | s0 in univ, $i14 := 2 * #($e5) + 1]

Boolean, Relational, and Integer Operator Precedences and Associativities

The operator precedences and associativities are given in the table below. Fully bracketed operators are not listed.

LevelOperator ClassArityAssociativity
1all |   some |   sum |   let |   if then elseBinary/TernaryRight-associative
2||BinaryAssociative
3<=>BinaryAssociative
4=>BinaryRight-associative
5&&BinaryAssociative
6!UnaryN/A
7in   =   <   <=   >   >=BinaryN/A
8no   lone   one   someUnaryN/A
9<<   >>   >>>BinaryLeft-associative
10+   -  BinaryLeft-associative
11*   /   %BinaryLeft-associative
12++BinaryAssociative
13|   ^   &BinaryAssociative
14->BinaryAssociative
15\BinaryAssociative
16(,)BinaryLeft-associative
17[,]BinaryLeft-associative
18.BinaryLeft-associative
19^   *   ~   -   abs   sgnUnaryN/A

Comments

Comments may be specified as in C++, that is, either as a one line comment starting with // or as a block starting with /* and ending with */.

Examples:

/*
  Copyright 2009 Gnomovision, Inc.
*/

univ: u99999  // Don't panic!