A tool to generate runnable specification models for business IT systems in TLA+ language
Ruby Gherkin HTML TLA Shell
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


[Readme](README.md) [Releases](RELEASES.md)

Sbuilder - A Specification Builder for TLA+ Tools - $Release:0.3.9$

A tool to generate runnable formal models in TLA+ language for target systems. Formal model can be verified using TLA+ Tools, and parts of it can be presented as implementation blueprints to developers.


  • documentation for background information, User's Guide and Developer's Guide

  • on-line documentation (including Cucumber tests) for more details on configuring Sbuilder, and on features implemented by Sbuilder

Target Systems

Sbuilder supports modeling business IT systems, where system architecture identifies

  • interfaces: entry point providing access to services within the system. Application interface is the public entry point, and infrastructure interface is the internal entry point allowing aggregation of (application) services from smaller units.

  • services: unit of functionality accessible over interfaces. Infrastructure service is not directly accessible over application interface, as opposed to application services

  • database: persistent data store, which services may access, and modify.

Runnable Specification Code

Sbuilder combines three main elements to create runnable TLA+ formal model:

  1. API interfaces: Natively Sbuilder accepts RESTfull interface api specification expressed in Swagger v2.0 format. API Loader Extension Point allows importing API confiugration also from external systems, e.g. from salesforce

  2. TLA Snippets: Sbuilder tangles either manually crafted TLA snippets from Sbuilder code repository, or snippets loaded using Snippet Loader Extension Point, with code created for API interfaces. TLA -snippets are also used to specify correctness criteria for the system. Examples of TLA Snippets are:

    • state: TLA+ variables modeling database

    • operator: TLA+ language constructs, which enable "to define all the data structures and operations that occur in the specification"

    • procedures: implementation of target system application services as TLA PlusCal procedures in TLA+ language

    • macros: TLA PlusCal implementation of common behavior, for example to modify system state

    • invariant: operator definitions, and INVARIANT directives in TLA+ language specifying properties, which must be not violated in specification executions

    • possibility: optional operator definitions to increase confidence in correctness invariants

    • assumption: operator definitions, in TLA+ language specifying properties on specification model constants, which must be not violated.

  3. Setups: To complete the runnable formal model Sbuilder uses setups. A setup is a sequence of interface operations, and their input parameters. Setup also define domain cardinalities, or domain values. The tools allows defining multiple setups, each setup resulting to a complete, runnable TLA+ code, allowing application model to be run in various environment context

Sbuilder can generate implementation blueprints as depicted in section modeling pipeline below. Implementation blueprints are html-pages including code snippets from Sbuilder code repository, or code generated based on interface specifications.

Two Operating Modes

Sbuilder supports two operating modes:

  • Modeling Pipeline
  • Embedded Mode

Modeling Pipeline

Sbuilder can be embedded into "mainstream" software development process to support specification and design up-front, before actually starting the implementation.

In Modeling Pipeline mode, Sbuilder is used to create formal specification model of the application with the objectives 1) to get better understanding, 2) to get the design right, 3) and to write better code for the system being built. more details

See sbuilder-example for a toy example of using sbuilder in Modeling Pipeline mode.

Embedded Mode

Adding a separate task to create a formal specification model calls for commitment, which may be hard to achieve in contemporary software development practices. In order to hide the complexities in creating a formal model, Sbuilder can be embedded into a framework, and to use implementation code in creating formal model of the application.

An example of embedded sbuilder is in sbuilder-ethereum.



Sbuilder -tool requires Ruby 2.1

To run the specification model created by Sbuilder -tool, you must have Java and TLA+ Tools installed.

TLA+ Tools jar can be obtained from download page, see TLA+ Tools for more instructions on installation.


To install Sbuilder Gem, create a Gemfile -file with the content

source "https://rubygems.org"
gem 'tla-sbuilder'

and run

bundle install

To Use Pet Store Example Application

Create default directories used by sbuilder in current working directory

bundle exec sbuilder.rb init

Create example configuration

bundle exec sbuilder.rb example pet

To list configuration files created for pet store example

ls cnf

To list specification extensions in TLA-sbuilder code repository

ls src/pet

To generate all setups in petstore example

bundle exec sbuilder.rb generate -t src/pet/

To run model checking for setup pet1 using TLA+tools jar in ~/java/tla/tla2tools.jar

export CP=~/java/tla/tla2tools.jar
(cd gen/pet1/tla; java -cp $CP pcal.trans model)
(cd gen/pet1/tla; java -cp  $CP tlc2.TLC setup)

and observe Model checking completed. No error has been found. to conclude that correctness invariants for the model are not violated.

In setup pet1, it is NOT possible to reach a state where predicate

at_least_two_tags == Cardinality( v_tags ) > 1

holds. This is because setup steps in cnf/extend_petstore_run1.yaml do not call interface operation /tags(post).

To show that it is NOT possible to reach a state, where at_least_two_tags holds, run

(cd gen/pet1/tla; java -cp  $CP tlc2.TLC possible_tag_with_invalid_address)

and observe Model checking completed. No error has been found..

However, steps for setup pet3, defined in cnf/extend_petstore_run3.yaml, do call /tags(post) twice, making it possible to reach a state where predicate at_least_two_tags holds.

The possibility to reach this state can be demonstrated running

(cd gen/pet3/tla; java -cp $CP pcal.trans model)
(cd gen/pet3/tla; java -cp  $CP tlc2.TLC possible_tag_with_invalid_address)	

and observing Error: Evaluating invariant possible_tag_with_invalid_address failed.

Create Own Model

See on-line documentation for more details.

Create default directories used by sbuilder in current working directory

bundle exec sbuilder.rb init

Create extension templates for including specification extensions in default in TLA-sbuilder code repository into specification model.

bundle exec sbuilder.rb extend

Remove .example from all files in cnf directory

Generate example setups:

bundle exec sbuilder.rb generate

To run the model checking for setup default using TLA+tools jar in ~/java/tla/tla2tools.jar

export CP=~/java/tla/tla2tools.jar
(cd gen/default/tla; java -cp $CP pcal.trans model)
(cd gen/default/tla; java -cp  $CP tlc2.TLC setup)

Create TLA snippets in directory src, and include template snippets into Sbuilder context using Snippet Loader plugin Sbuilder::SnippetLoaderSimple.

For example, put the following code into file src/operator_at_least_two_tags.tla

at_least_two_tags == Cardinality( v_tags ) > 1

and add configuration in snippets section in cnf/sbuilder.yaml, which gives the class name of the plugin to use (Sbuilder::SnippetLoaderSimple), defines metatype (framework-svc), application name (at_least_two_tags), and filename of the snippet in default src -directory (operator_at_least_two_tags.tla). The use of metatype allows single appName to mapped to several unique specNames by adding a metatype specific prefix to the appName. In this example, framework-svc metatype adds empty prefix to appName.

  - className: Sbuilder::SnippetLoaderSimple 
      - metatype: framework-svc
        appName: at_least_two_tags
        file: operator_at_least_two_tags.tla

Run bundle exec sbuilder.rb generate, and observe that at_least_two_tags operator, indeed, is included into generated formal model e.g. in file gen/customer1/tla/model.tla:

(* SNIPPET: framework-svc/at_least_two_tags --> at_least_two_tags *)
at_least_two_tags == Cardinality( v_tags ) > 1
(* --END OF SNIPPET-- *)

Manage State Space Explosion, and Allow Scaling

State space explosion is inherent problem in model checking, the theory behind TLA+ tool.

Sbuilder tries to avoid problems due to state space explosion by controlling, how environment invokes interface operations, and in effect, by throttling number of states generated during model checking.

In order to avoid enumerating too large sets Sbuilder allows

  • fixing input parameter bindings in an interface operation. In cases, where domain sizes are not a problem, SBuilder allows TLA+ tool to use non-deterministic choice for input parameter values.

  • using reduced domain ranges, when checking assumptions on resolved domains.

In TLA+tools, number of states/sec decreases as specification code volume increases (see a benchmark results for more details).

SBuilder tries to avoid problems due to increase in specification code by offering run time option --filter-src, which parses TLA+ snippets and runs static call flow analysis to prune off unused snippets from specification model. Parser is in alpha phase, in case of error, use option --filter-list to continue after parser error, and to configure manually modules call flow analyzer would otherwise omit from the specification code.


Main configuration file sbuilder.yaml


Setups modeling environment


Extending Sbuilder

API Loader Extension Point

Sbuilder defines an API Loader Extension Point to load API interfaces, and data type definitions into Sbuilder context. An API loader is a Ruby class

For a plugin implementation example, see an Swagger API loader in Sbuilder:

For example, to activate Sbuilder API loader plugin Sbuilder::Interfaces::Salesforce::SalesforceLoader implemented in tla-sbuilder-salesforce GEM using configuration hash shown below, add the following YAML snippet into sbuilder.yaml configuration file extend.loaders -section:

          - gem: tla-sbuilder-salesforce
            className: Sbuilder::Interfaces::Salesforce::SalesforceLoader
                  client_id: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxdaYTBJBssnuS0bvkraFcSSlC9EQZngf97yspdbh8iV_EV
                  client_secret: xxxxxxxxxx476009913
                  username: xxxxxxxev@gmail.com
                  password: 'xxxxxxxx'
                  security_token:  'xxxxxxxxxxVnEZjYP9cUZix9'

API instances are configured using entries referring plugin className in sbuilder.yaml interfaces array. For example, the entry for an Salesforce API instance entry.

    -  className: Sbuilder::Interfaces::Salesforce::SalesforceLoader
       file: salesforce-api.yaml
	   cache: sf

In the example, file -property points to a plugin configuration file, and cache property gives name prefix for files, which the plugin may use to cache API content to speed up generation phase.

Snippet Loader Extension Point

Sbuilder defines an Snippet Loader Extension Point to load TLA snippets into Sbuilder context. An Snippet loader is a Ruby class

For a plugin implementation, see an SnippetLoaderSimple example

Snippet loader plugins are activated in the same way as API loader plugins using a configuration in extend.loaders -section in cnf/sbuilder.yaml

An example of using Snippet Loader Plugin was presented earlier in this README.