Architecture of Clafer Tools
Back to Clafer Tools
Module Summary
This page describes a Clafer model of Clafer-related tools.
Module Details
Currently we’ve got three tools clafer compiler, clafer
instance generator, and clafer with multi-objective
optimization. They are all based on a single library
(claferLib) that reads, interprets, and transforms clafer
models.
Clafer library is organized into the several modules:
common provides functions used by all other modules,
front is an implementation of compiler’s front-end,
intermediate performs model analyses and transformations,
optimizer transforms models so that other tools can
efficiently reason on them, generator outputs corresponding
models in other languages.
Before we describe modules of claferLib, let us first
learn about data structures used by the library. text is a
textual input, such as model read from a text file. tokens
is a stream of tokens recognized by lexer. ast is an
in-memory tree representation of parsed Clafer models. ast
is tightly related to the input grammar and provides different
data-types for different elements. ir is another tree
representation that unifies elements of ast to support
better code reuse.
Each module in claferLib transforms data from one
Representation type to another:
in particular, we’ve got transformations of the following types:
The front-end of claferLib is responsible for reading
input files and building their ast representations. The
process starts with tokenizing input text into a stream of tokens
(lexer). Clafer models use indentation to represent
hierarchy of concepts. Such files are not parsable by traditional tools.
We use layoutResolver to transform such input files to the
form that is suitable for traditional parsers. Next, parser
takes the resolved stream of tokens and builds ast out of
them. To support better bug reporting, parser needs to map each
ast node to its position in the input file. This
functionality is supported by mapper.
prettyPrinter transforms ast to text to make
it human-readable.
ast isn’t very convenient to work with. Most of the work
the library does is performed by the Intermediate module.
desugarer converts that representation to ir
(intermediate representation). It also removes syntactic sugar and sets
some predefined default values if they were not specified in the input
model. findDuplicates analyzes the model for name
uniqueness. Next, resolver runs several analyses and
transformations. It starts with generating unique names for each clafer
(setUid). Then, optional inheritanceFlattener
may remove inheritance from models to improve reasoning efficiency over
Clafer models. nameResolution module resolves clafers’
names if they are not unique. It also resolves
(inheritanceresolver) inherited names and other properties
(e.g., group cardinalities). typeResolver finds types of
each element used in constraints. transformer performs
transformations that can be done after the name resolution phase.
stringAnalyzer transforms strings to integers, as not all
reasoners can deal with strings. scopeAnalyzer determines
the minimal scope for each clafer to improve reasoning efficiency. It is
important for reasoners with finite scope, such as the Alloy
Analyzer.
After resolving Clafer models, code generators go through
ir and output corresponding textual representation in other
languages. We typically use alloy output to do analyses.
xml output is preferable for exchange models between
tools.
