-
Notifications
You must be signed in to change notification settings - Fork 42
AddAutomataOperation
The automata support in Ultimate is split into two "modules".
- The actual automata library which contains the implementations of automata and their operations. If you want to integrate our automata library in your tool, this module is sufficient.
- The Automata Script interpreter which is a text-based user interface for the automata library. Automata Script is a file format that allows you to write down automata and to write down automata operations that should be executed by Ultimate. You can find several examples of these files on the Automata Library website
Implement an IOperation according to the conventions written in the interface documentation. If your class file is stored in one of the following packages or subfolders, it will be immediately available to the Automata Script interpreter.
- "de.uni_freiburg.informatik.ultimate.automata.alternating",
- "de.uni_freiburg.informatik.ultimate.automata.nestedword.buchi",
- "de.uni_freiburg.informatik.ultimate.automata.nestedword.operations",
- "de.uni_freiburg.informatik.ultimate.automata.petrinet",
- "de.uni_freiburg.informatik.ultimate.automata.tree.operations"
We note that automata operations in Automata Script are not case sensitive.
Ultimate does not have any capabilities to kill running operations. Ultimate provides only a service that knows if the timeout specified by the caller is already overdue or the operation was canceled externally for a different reason.
The constructor for each operation should take as first argument an AutomataLibraryServices
object, say, services
.
The cancelation request is queried by services.getProgressAwareTimer().continueProcessing()
.
This method should be called in every time-consuming loop.
In case this method returns false the operation should throw an AutomataOperationCanceledException
.
Callers of automata operations will catch this exception and handle it accordingly.
We consider finite automata as a special case of nested word automata (resp. visibly pushdown automata) where the call alphabet is empty, the return alphabet is empty, there are no call transitions and there are no return transitions.
We use the data structures for nested word automata to represent finite automata and you can use every operation for nested word automata also for finite automata.
If you implement an operation that works only on finite automata, you might want to use the static NestedWordAutomataUtil.isFiniteAutomaton(...)
method to check the operand(s) and throw an UnsupportedOperationException
if the operand is not a finite automaton.
Nonetheless, the syntax of Automata Script allows you to define a finite automaton (without explicitly setting empty call/return alphabets). This syntax can be seen in our finite automata demonstration example.
We do not encode the acceptance condition in automata data structures. Hence every automaton can be seen as a Büchi automaton or as an automaton on finite words. Operations for Büchi automata have the prefix buchi (e.g., BuchiAccepts
, BuchiIsEmpty
) whereas operations on finite words do not have this prefix (e.g., Accepts
, IsEmpty
).
Not yet, but if you want to implement support for these we are happy to assist you.
We construct states in our automata library according to the interface documentation of the IStateFactory.
If you want to construct an automaton, you can construct an instance of the NestedWordAutomaton
class.
This class provides methods for adding states and transitions.
In our applications, we often apply operations in a row. E.g., if we check an inclusion A ⊆ B, we check emptiness of an intersection where one operand is the complementation of a totalized and determinized input automaton B. If we performed determinization of B explicitly, this would probably be a waste of resources since in many cases the intersection does not have to see the full state space of the determinized automaton. In our program verification algorithm the problem is even more severe because the automaton B is not given explicitly and the check if a specific transition exists is costly (in fact, we do not check if a certain transition exists but we ask for all successors of a given state under a given symbol). We approach this problem by supporting on-demand automata implemementations. These implementations do not store all states and transitions of the automaton explicitly but must only be able to provide initial states and successor transitions for given states.
The most basic interface for the construction of on-demand operations is the INwaOutgoingLetterAndTransitionProvider, a more developer-friendly variation is the INwaSuccessorStateProvider. Examples for implementations are the BuchiComplementFKVNwa and the BuchiComplementNCSBNwa.
We do not use unit tests in the automata library. Instead, we write for each operation a bunch of .ats
files and use the testing framework of Ultimate to run the Automata Script interpreter on several files.
In order to get a well-tested operation you should do two things:
- Use
assert(...)
statements in you.ats
file. A test run of an.ats
file is considered erroneous if someassert
statement was evaluated to false. - Implement the
checkResult(...)
method of yourIOperation
. If you run the JavaVM with assertions enabled (parameter-ea
), the Automata Script interpreter will run thecheckResult(...)
methods after each run of anIOperation
and will throw anAssertionError
if the method returned false. Note that we only test theIOperation
that is explicitly called in the.ats
file, i.e., we ignore subcalls to otherIOperation
s.
A typical example for a test suite is the AutomataScriptTestSuite. It executes all .ats
files from the folders that are hardcoded in this test suite .java
file.
You run the test suite by opening this file in Eclipse and selecting "Run As > JUnit Plug-in Test" (not "JUnit Test"!).
Do not forget to set the enable assertions (-ea
) parameter for the Java virtual machine.
Every night we run all .ats
files that are in the trunk/examples/Automata/regression/
subfolder. You can see the results online. Furthermore you can see the line coverage of your tests.
In order to evaluate automata operations on several (hundreds, thousands) automata we also use our testing framework (see above). Typically, you have to provide two ingredients for an evaluation.
- Automata. You will find automata produced by Ultimate Automizer in our automata benchmark repository. If these are not appropriate for your purpose, ask Matthias for other automata.
- Support for statistics data. Use the AutomataOperationStatistics to collect interesting information, e.g., about input and output, of your operation.
Writing the operation that you want to evaluate into several (hundreds, thousands) of automata files can be tedious. Therefore the Automata Script interpreter has a special mode in which all operations written in the .ats
file are ignored and a user-defined expression is executed. In this expression $1
refers to the first automaton that is defined in the .ats
file, $2
refers to the second automaton, etc.
You find examples for preference files (.epf
) that enable this special mode in the Automata Script preference file folder.
Using your preference files, you write a test suite analogously to, e.g., the BuchiComplementationTestSuite, the BuchiIsIncludedTestSuite, or the AutomataMinimizationTestSuite. Please note that the name of operations typically occurs twice. First as name of the preference file, but second in a filter of the output CSV.
Next, you run the testfile as explained in the section on tests. However, for your benchmarks you probably want to drop the -ea
argument for the Java Virtual Machine.
After the test suite was run successfully, you find the output in the your trunk/source/UltimateTest/target/surefire-reports/
folder. The output also includes a CSV file that contains the collected statistics data of all operations.
The types supported by the Automata Script interpreter are
- bool
- int
- all types of automata supported by Ultimate
- various kinds of words (word, lasso-shaped ω-words, nested words, lasso-shaped ω-nested words, trees).
Hence, if your operation takes as input (or returns) a different type (e.g.,
HashSet
of automata) you will not be able to use the operation in the Automata Script interpreter.
- Home
- Ultimate Development
- Ultimate Build System
- Documentation
- Project Topics