\documentclass[a4paper,12pt]{article}

\usepackage[english]{babel}
\usepackage[T1]{fontenc}
\usepackage[latin1]{inputenc}
\usepackage{graphicx}   % for figures
\usepackage{pslatex}
\usepackage{alltt}
\usepackage{moreverb}

\usefont{T1}{cmr}{m}{sl}
\selectfont

\linespread{1.3} 
\parindent=0.5in

\topmargin=-2cm
\oddsidemargin=0.0cm
\evensidemargin=0.0cm
\textwidth=16cm
\textheight=24.5cm

%\bibliographystyle{amsalpha}

\begin{document}

% 1 Title
\title{Constraint Checking - User Manual}
\author{Dan Forss \\Mattias Hästbacka \\Tomas Lillqvist \\Matias Nyman}

\date{\today}
\maketitle

\tableofcontents

\section{Getting started}
This section will quickly go through the constraint creating process
and how to activate checking for a model.

Constraints are contained in a package of type
coral.lang.CONSTRAINT10.Package. Create this package by selecting
``New Model'' in the File menu and select CONSTRAINT10 as the language
(alternatively create a new Project). Select it and add constraints in
the property editor. For more information about the different types of
constraints look at section \ref{section:PythonConstraints} and
\ref{section:QueryScriptConstraints}.

A ConstraintModel must be created in order to evaluate
constraints. The ConstraintModel is used to connect the constraints to
some arbitrary model and to store the results from an evaluation. The
ConstraintModel can be kept separately(in another project) from the
constraints since it only imports constraints, it does not own
them. Use the property editor to select a target and to bind the
constraints that should be evaluated. To activate and deactivate
checking right click on the ConstraintModel in the outline-editor.

\section{Defining constraints}
Constraints can be used to define a set of rules for properties of
modelelements and relationships between modelelements. There are two
types of constraints - PythonConstraints and
QueryScriptConstraints. PythonConstraints are generally evaluated
faster and are also simpler to create. For more elaborate constraints
involving many different elements, however, it is probably best to use
QueryScriptConstraints to avoid having to write unnecessarily long
scripts.  More info on how to create and define constraints can be
found in the subsections below. Already made constraints can be found
in the coral/addins/constraint/UML14Constraints folder.

\subsection{PythonConstraints}
\label{section:PythonConstraints}
A PythonConstraint is essentially a script that is evaluated for a
specific type of element. The \textbf{kind} slot determines on which
elements the script in the script-slot will be evaluated. The kind
slot can point to any language element from the meta-models loaded
into Coral. 

The ElementDefintion in the kind slot can be selected from the
coral/lang/ projects. This is done by opening the property editor for
the new PythonConstraint and clicking on the magnifying glass button
next to the kind field. To see the language projects containing the
ElementDefinitions you have to right click and select Show system
projects in the small pop-up window. Select the ElementDefinition by
simply opening the right language and click on it in the tree. By
selecting the kind ElementDefinition the Constraint will check all
elements which are instances of this type or a sub-class of it.

The \textbf{script} should be constructed so that it returns False in
situations where the constraint is supposed to fail and True in
situations where the constraint should pass. From within the script
the element being evaluated is accessible through the variable {\em
self}.

In the event of a failing constraint, a new Result element will be
created and the element that is being evaluated will automatically be
added to the list of offending elements. In some cases it may,
however, be necessary to manually add additional elements to the
offending list. By adding more elements to the offending elements slot
the Result will be listening to changes in all of those elements.
This means that a result will automatically be updated if any of its
offending elements change.

Additional offending elements can be added from within the script by
using the function {\em addOffending(elem)}. It is often necessary to
add the element causing the constraint to fail to the offending list
in case this is not the element being evaluated. If the element that
caused the constraint to fail is not listed as an offending element it
may cause the continuous evaluation of constraints not to function
properly. 

The \textbf{description}-slot should contain a message that explains
why the constraint fails. The text in the description-slot will be
used as message by the result elements created if the constraint
fails.
 
\subsection{QueryScriptConstraints}
\label{section:QueryScriptConstraints}
A QueryScriptConstraint is used to evaluate constraints that include
multiple connected elements. CQuery is used by QueryScriptConstraints
to find groups of elements to evaluate the script on. When a new
QueryScriptConstraint is created it will automatically contain a new
Query. By right-clicking on the Query in the out-line editor it is
possible to choose the language (and also a diagram if wanted) that
the Query will be constructed of.\\
\begin{center}
\includegraphics[scale=0.7]{graphics/selectLanguage.eps}
\end{center}
By selecting a language, a container (or container-diagram pair) is
created under the Query. A set of elements can now be created in the
container. This set of elements will be used as the query graph by the
matching routine. It is important to make sure that all elements that
will be used as a query are somehow connected to eachother, since the
query will not work otherwise.
\begin{center}
\includegraphics[scale=0.8]{graphics/populateQuery.eps}\\
\end{center}
After creating the query graph the user has to create a QueryElement
for each of the elements in the container for which a match is
wanted. This is done by right-clicking on the elements and selecting
populate query. A QueryElement for each element in the container will
be created, where the user can specify some additional information
about the individual query parts. These QueryElements will be used to
find matches for the constraint in the targetmodel and the script will
be evaluated on these matches. The script is automatically provided
with variables, named after the corresponding QueryElement, pointing
to the matching elements.

The QueryElement offer the possibility to ignore certain
properties of the element it represents. For instance, two
queryelements representing UML Classes and ignoring the name property
will find all pairs of Classes in the target model, regardless of
their names. The ignored properties can be edited by selecting the
QueryElement and opening the property editor. A list box shows the
properties which can be added to the ignore list. The list shows only
the properties which have to be ignored explicitely. If the query
language allows a slot to be empty the corresponding Property will not
be listed since the query graph can be altered instead. However, slots
created from properties which have lower multiplicity >0 can not be
empty in the query graph so these properties have to be ignored
explicitely.

Queryelements also have an isActive flag. If this flag is set to
false, the constraint will not be reevaluated during continuous
evaluation if the corresponding element in a match is changed. Setting
isActive to false for elements which are just used as containers or
links between the checked elements might speed up the continuous
evaluation since it is not necessary to evaluate the constraint every
time a container gets a new element. For more information how to
optimize using isActive look at section \ref{section:isActive}.

If a QSConstraint fails all elements in the match will be added as
offending elements. Unlike PythonConstraints there is no need (or even
possibility) to manually add additional offending elements.

The description-slot should contain a message that explains why the
constraint fails. The text in the description-slot will be used as
message by the result elements created if the constraint fails.

\section{Binding constraints to a target}
This section describes some important elements needed when working
with constraints - Packages and ConstraintModels. To see an example of
how ConstraintModels and Packages are used, select New Project From
Template from the file menu and choose UML14TemplateModel. A ready
made ConstraintModel with constraints and a target will be loaded.

\subsection{Packages}
Packages function as a sort of container elements. When creating a new
project using the CONSTRAINT10 language, a Package will be created as the
root element. A package can contain ConstraintModels, Constraints and
other packages.

\subsection{ConstraintModels}
ConstraintModels are used to bind a constraint or a set of constraints
to a targetmodel. When selecting which constraints a ConstraintModel
should bind, it is possible to select single constraints as well as
Packages containing constraints. It is also possible for these
Packages to contain other Packages containing constraints. The target
slot can contain any element that is inherited from
AnyAbstractElement.

The target slot can only point to one target element at a time but
everything that is part of that element will be evaluated so only the
root of a model needs to be included in order to check the whole
model.  ConstraintModels also contain any Result elements that are
created upon evaluation. This will be covered in greater detail in
section \ref{section:UserInterface}, dealing with the User Interface
and constraint evaluation.

\section{User Interface}
\label{section:UserInterface}

\subsection{Constraint tab}
The ConstraintModel can be viewed using the extension tool Constraint
found in the tool menu. At the top of the constraint tab there is a
label displaying the ConstraintModel that is loaded into the tab as
well as the target. The tool provides a couple of buttons for creating
and modifying the open ConstraintModels.
\begin{center}
\includegraphics[scale=0.52]{graphics/constraintTabWithResults.eps}\\
\end{center}
There is a ``new'' button for loading new constraints. It will recuire
a project containing constraints to be loaded. The constraint checking
model will go into the project that is in focus in the out line
editor, if possible. Else, a new project will be created. After
creating the ConstraintModel a target model has to be selected and
this can be done by clicking on the blue ``target'' button. Target
selection makes a pick box for AnyAbstractElement pop up from which
the user can select the wanted target element. If a ConstraintModel is
already created it can be shown by clicking on the magnifying glass
and selected from there. Multiple Constraint Models can be open at the
same time in different Constraint Tools. Continuous constraint
checking can be turned on and off by clicking on the black
``play/stop'' button. The ``traffic light'' is red when continuous
constraint evaluation is in progress and green otherwise.

When a ConstraintModel is viewed in the tab and a target has been
selected, the tab shows a list of constraints prefixed with an icon
showing the state of the constraint. Green indicates no conflicts and
red indicates one or more results. If the icons are grey the
continuous checking is turned off. The constraint definition is shown
if the user right-clicks on a constraint and chooses ``View constraint
definition''.

When a constraint is in conflict the corresponding result elements
will be placed as child elements to the constraint in the tree
structure. Selecting a result will show the offending elements in the
``Offending'' listview to the right. The message of the result is
displayed in the Message box under the Constraint and Offending
listviews.

Also worth mentioning is that it is possible to have many Constraint
extension tools open at the same time viewing different
ConstraintModels.

\subsection{Outline editor}
It is possible to activate and deactivate continuous checking of a
ConstraintModel from the outline editor by right-clicking on a
ConstraintModel and selecting activate/deactivate.

A ConstraintModel can also be opened in a constraint extension tool
from the outline editor by right-clicking on the ConstraintModel and
selecting Open in constraint tab.\\
\begin{center}
\includegraphics[scale=0.8]{graphics/openInConstraintTab.eps}
\end{center}

\section{Evaluating constraints and viewing results}
As mentioned above, there are several ways to activate constraint
checking. The most user friendly way is to use the constraint tab. If
continuous checking is deactivated it is still possible to evaluate
constraints by selecting one or many constraints (Ctrl/Shift) in the
constraint tab, right-clicking and choosing Evaluate constraint(s)
from the pop-up menu.
\begin{center}
\includegraphics[scale=0.8]{graphics/constraintTabRightClick.eps}
\end{center}
It is also possible to quickly find the elements that cause a
constraint to fail from the offending elements of a result. By
clicking on an offending element in the Offending listview in the
constraint tab the focus in the outline editor is set to that element.

\section{Command-line script for constraint checking}
It is also possible to evaluate constraints by running coral-start
with the evaluateconstraints tool. To get all possible options for the
tool, write {\em python coral-start.py evaluateconstraints --help}.
An example of using the tool could be: {\em python coral-start.py
evaluateconstraints -i constraintfile.xml -t targetfile.xml -o
outputfile.xml -q package1 package2}. In the example above,
constraintfile.xml is a file containing packages with constraints,
targetfile.xml contains a project with a targetmodel and
outputfile.xml is the file where the results will be saved (Saving the
results in an outputfile is optional). The -q (quiet) option prevents
the results from being printed to stdout. Finally, package1 and
package2 are the names of the packages in constraintfile.xml that will
be used for the evaluation. If these are omitted, all packages will be
used.

\section{Technical documentation}
\subsection{Meta-model elements}
\includegraphics[scale=0.8]{graphics/Constraint10-Metamodel}
\subsubsection{PythonConstraint}
Evaluated for every element in a model that matches the type in the
kind slot during the call to reEvaluateAll.\\ Evaluated after a
transaction for the changed element if the type matches.

\subsubsection{QueryScriptConstraint}
Evaluated for every match in the searched model.\\ Evaluated for a
changed element if the query includes an active element with the same
type as the changed element. 

\subsubsection*{isActive optimization}
\label{section:isActive}
If an element of the query is not
required to trigger evaluate the queryelement's isActive flag should
be set to false. This will help the evaluator to decide if the
constraint should be re-evaluated or not.

For example, imagine that we have a query which consists of a UML14
Model containing two Classes. Now this query would be matched every
time a Model or a Class changes in the target. However, in this case
we can safely set isActive to False for the Model so that the query is
not executed every time the Model gets a new element but only when a
change occurs in a Class element.

\subsubsection{ConstraintModel}
This element combines a target model with any number of constraints
and stores the results after evaluation.

\subsubsection{Result}
Contained in the constraint-model, defining the slots:\\
offending - (elements which created the conflict)\\
constraint - (the constraint from which the Result was created)\\
message - (string describing the conflict)\\
name - (copied from the constraint)\\

Results are filtered to include only unique ones.

\subsection{Implementation}

The constraint checking in Coral is implemented as an addin in {\em
coral.addins.constraint}. The following sub-section describes the
implementation of the constraint checking found in {\em engine.py} and
{\em evaluate.py}. The rest of the files are not explained since they
only contain the gui implementation which is not very different from
the other parts of Coral.

\subsubsection{The evaluate queue (engine.py)}
After each transaction the changed elements are appended to the queue
(No duplicates). A continuous observer evaluates the elements from the
queue, one by one. If the changed element is included in a result this
result will be deleted and all the other offending elements will also
be re-evaluated.

\subsubsection{Continuous evaluation (engine.py,evaluate.py)}
The evaluate queue contains the elements which will be evaluated by
evaluate() one by one. evaluate chooses the constraints by first going
through all the active constraint models, checking if the element is a
part of the target model. If so then all the constraints that the
constraint model contains will be checked for aplicability. This is
done by calling the appliesTo function of the evaluator object for the
corresponding constraint.

\subsubsection{Evaluators (evaluate.py)}
For every constraint type in the meta-model there should be an
Evaluator class. The evaluator implementation is found by extracting
the implementation path from the constraint element. The Evaluator
should derive from coral.addins.constraint.evaluate.ConstraintEvaluator
and override the functions in that class.

\end{document}
