You are on page 1of 9

Alloy Interface Walkthrough

back next
If you just want a quick reminder of what to do, load the abbreviated walkthrough as a sidenote
In this lesson, we take a look at the Alloy interface itself. We will walkthrough the basics of how to execute a command
to check an Alloy model and how to interpret the results. We will continue to use our running sample model of a File
system, and execute the check statements to verify the assertions made in the first version of the model.
The exact output that Alloy gives you (the messages that pop up, and the interface to the visualizer) is subject to change.
However, the basics of using the Alloy interface (what you can tell Alloy to do, the terminology we use, and the kind of
information Alloy returns) remains constant. This walkthrough uses version 2.0 of Alloy to analyze our File System
example, and to show examples of what the resulting output and visualizations might look like.
If you need additional help, or to report/clarify an inconsistency, feel free to contact us. View contact information for
additional help.
Basics of using Alloy
At this point, you should open Alloy. If you do not already have Alloy installed, you can downloaded it from the from the
Alloy home page. Once you get Alloy up and running, you will be presented with a screen with two sections, looking
something like this:
Create a new model with the 'New' button from the icon bar, or from the file menu. Paste in our current mode
(shown to the right of this window), and save it as 'models/examples/tutorial/fileSystem.als' (to
be consistent with the module statement at the top of the model).
Compile the model with the 'Build' icon or by selecting "Build" from the top of the Tools menu.
Select a command to run by choosing one from the 'Command selection' box in the icon bar. There will be
one entry in the menu for each run and each check command. For now, select the top choice: "check
acyclic for 5".
Execute the selected command with the 'Execute' icon or by choosing Execute from the Tools menu. You
will be told "no counterexamples found: acyclic may be valid.(00:05)", meaning that there are no counter
examples to the acyclic assertion within a scope of 5. Had there been solutions, one of them would have been
displayed in the right half of the screen in the visualizer. The number given at the end is the time taken to solve
the model.
Now let's check the second command the same way. Select the second command ("check oneRoot for
5") from the Commands menu, and execute it. There are no solutions found for this one either.
Finally, check the third command. You can do this one on your own.
In general, once you make a change to the model and want to see its effect on a run or a check, you will...
save (ctrl+s)
build (ctrl+b)
select (from Commands menu) (last selection will be preserved)
execute & visualize (ctrl+e)
We'll see an example of visualizing a solution next.
Visualizing a counterexample to an incorrect assertion
Just for fun, let's write and check an assertion which does have a solution (i.e. a counterexample).
//an assertion with a counterexample
assert Wrong {
all o,p: (FSObject - Root) | (o.parent = p.parent)
That is, we are claiming that any two non-root file system objects have the same parent. Of course, if our file system is at
all sane, then this assertion will fail and a counterexample will be found. Let's check it and see.
check Wrong for 3
Save the model, build it, select our latest command from the Commands menu, and execute it. The righthand side of the
screen will display something like this:
You can also browse a tree structure of the model by selecting the "tree" button from the righthand icon bar. The tree
view is harder to read than the diagramatic form, but allows you to see how the predicates and functions in your model
evaluated in this particular solution. You can return to the diagram view by choosing the "viz" button from the icon bar.
The exact appearance (and even the counter-example returned) may vary between versions of Alloy, so don't worry if it
looks a little different. Everything we say here will still apply.
You can make the visualization more readable by customizing the layout -- selection the "layout" button from the icon
bar. You can adjust what relations and sets are shown, and the style of their presentation. Here is a cleaner customization.
Now let's see what happens what would have happened if we'd chosen a smaller scope:
check Wrong for 2
Whoops! No solutions were found. If the scope is too small, there may be no solutions found, just because the smallest
solution is larger than you allowed. This is an unavoidable risk of Model Checking, but it is mitigated by the "small
scope hypothesis". Alloy does guarantee that if there is any example within the specified scope that an example will be
returned to the user. If there are several, you may not get the smallest one, so it is often helpful to try smaller and smaller
scopes to find the smallest scope that still generates a solution.
check Wrong for 15
We might get a solution such as this one:
Or, with some minor customizations, we get the much more readable:
Discussion: Non-Determinism
If you've gotten different results than we show here, don't be alarmed; it may be because you have a different version of
Alloy, or it may be because of Alloy's non-deterministic nature. That is, Alloy only guarantees that it will return a
solution, not the smallest and not even necessarily the same one each time. By default, an option is set which makes sure
that running identical commands will produce the same examples (if any). However, running syntactically different (but
semantically equivalent) commands may produce different examples.
Discussion: Facts vs. Assertions
While a fact is used to force something to be true of the model, an assert is a claim that something must already be
true due to the rest of the model. There are three ways of thinking about this difference, which are worth reading through
even if you think the difference is obvious.
One way of examining this difference is considering what happens if you accidentally write a constraint which is
trivially false.
A trivially false fact results in there being no solutions to the model no matter what the rest of the model looks
like. This is an extreme version of overconstraining your model. Overconstraint is dangerous, since it means that
any other assert statement that you check will trivially have no solutions, thus potentially masking both errors
in your model and (worse) failings in the subject matter you are modeling.
A trivially false assert will result in counterexamples being found when it is checked. Since anything makes
such an assertion false, any example of the system will be a counterexample. As a result, the solution returned
may appear completely unrelated to the assertion it falsifies. For this reason, vacuous assertions are easy to
identify but can be annoying to track down and repair.
Another way is to consider what happens if you mistakenly write a constraint with one construct when you should have
used the other.
An assertion which should have been a fact is something which is not necessarily true, but which you are
assuming is true. These are usually sanity constraints which you have simply forgotten to write down. This means
that your model is underconstrained; you are permitting possibilities you wished to discount. You can use the run
command to help identify underconstraint, since random instances of an underconstrained model tend to be absurd
in obvious ways.
A true fact which should have been an assertion is redundant; it is implied by the other constraints on your
model, and yet you have explicitly (and redundantly) forced it to hold.
A false fact which should have been an assertion is dangerous; it results in an overconstraint on your system,
potentially making all other check statements trivially find no counterexamples (even when they are checking
preposterous assertions).
Yet another way to think about the difference is in terms of their interaction.
Facts are "always on"; Alloy discounts any solution to the model which violates any fact. In this sense, every
fact interacts with every other fact, since all of them always apply.
Assertions can only be check one at a time, and thus do not interact at all. If you want to check more than one
assertion at a time (or you want to see a counterexample which satisfies several different assertions), then write a
new assertion which asserts the component assertions.
In the next lesson (Lesson II), we will learn about functions (fun) and predicates (pred) which fall somewhere
inbetween facts and assertions in terms of how they interact with each other. We will be able to say things like "if
A holds then each X must satisfy B"; these functions don't have to be checked one at a time (as opposes to
assertions) but they can be selectively applied (as opposed to facts).
Before Moving On
Before proceeding to the second version of the File System example, it is a good idea to read about the three levels of
abstraction for reading an Alloy model, if you have not already done so. You have now had enough opportunity to play
around with Alloy to benefit from seeing different ways of looking at it.
To backup to an earlier lesson, load the << previous lesson - file system I.
When you are ready to proceed, load the next lesson >> - file system II.
restart the tutorial from the beginning.