Architecture of Clafer Tools

Back to Clafer Tools

Module Summary

This page describes a Clafer model of Clafer-related tools.

c0_claferCompiler claferCompiler : claferLib c0_claferLib abstract claferLib c0_claferCompiler->c0_claferLib c0_Front abstract Front c0_claferLib->c0_Front c0_Intermediate abstract Intermediate c0_claferLib->c0_Intermediate c0_Generator abstract xor Generator : ir2text c0_claferLib->c0_Generator c0_claferIG claferIG : claferLib c0_claferIG->c0_claferLib c0_claferMOO claferMOO : claferLib c0_claferMOO->c0_claferLib c0_text2tokens abstract text2tokens : io c0_Front->c0_text2tokens c0_tokens2tokens abstract tokens2tokens : io c0_Front->c0_tokens2tokens c0_tokens2ast abstract tokens2ast : io c0_Front->c0_tokens2ast c0_ast2ast abstract ast2ast : io c0_Front->c0_ast2ast c0_ast2text abstract ast2text : io c0_Front->c0_ast2text c0_ast2ir abstract ast2ir : io c0_Intermediate->c0_ast2ir c0_ir2ir abstract ir2ir : io c0_Intermediate->c0_ir2ir c0_Intermediate->c0_ir2ir c0_Intermediate->c0_ir2ir c0_Intermediate->c0_ir2ir c0_ir2text abstract ir2text : io c0_Generator->c0_ir2text c0_io abstract io c0_Representation c0_Representation c0_io->c0_Representation input c0_io->c0_Representation output c0_text2tokens->c0_io c0_tokens2tokens->c0_io c0_tokens2ast->c0_io c0_ast2ast->c0_io c0_ast2text->c0_io c0_ast2ir->c0_io c0_ir2ir->c0_io c0_ir2text->c0_io
Module Statistics: | All clafers: 53 | Abstract: 14 | Concrete: 39 | Reference: 2 | Constraints: 11 | Goals: 0 | Global scope: 1..* | Can skip name resolver: no |

Module Downloads: | [.cfr] | [.html] |

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.

claferCompiler : claferLib
claferIG : claferLib
claferMOO : claferLib
moo

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.

abstract claferLib
common
front : Front
intermediate : Intermediate
optimizer
generator : Generator

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.

enum Representation = text | tokens | ast | ir

Each module in claferLib transforms data from one Representation type to another:

abstract io
input -> Representation
output -> Representation

in particular, we’ve got transformations of the following types:

abstract text2tokens : io
[ input = text && output = tokens ]
abstract tokens2tokens : io
abstract tokens2ast : io
[ input = tokens && output = ast ]
abstract ast2ast : io
[ input = ast && output = ast ]
abstract ast2text : io
[ input = ast && output = text ]
abstract ast2ir : io
[ input = ast && output = ir ]
abstract ir2ir : io
[ input = ir && output = ir ]
abstract ir2text : io
[ input = ir && output = text ]

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.

abstract Front
lexer : text2tokens
xor layoutResolver : tokens2tokens ?
stable
experimental
parser : tokens2ast
mapper : ast2ast
prettyPrinter : ast2text ?

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.

abstract Intermediate
desugarer : ast2ir
findDuplicates ?
resolver : ir2ir ?
setUid
inheritanceFlattener ?
nameResolution
nameResolver ?
inheritanceResolver
typeResolver
transformer : ir2ir
stringAnalyzer : ir2ir ?
scopeAnalysis : ir2ir ?

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.

abstract xor Generator : ir2text
stats
xml
desClafer
xsdSchema