<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://prob.hhu.de/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ivaylo+Dobrikov</id>
	<title>ProB Documentation - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://prob.hhu.de/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ivaylo+Dobrikov"/>
	<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Special:Contributions/Ivaylo_Dobrikov"/>
	<updated>2026-05-27T06:58:00Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Checking_CSP_Assertions&amp;diff=3695</id>
		<title>Checking CSP Assertions</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Checking_CSP_Assertions&amp;diff=3695"/>
		<updated>2016-09-23T09:28:13Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* CSP Assertions Viewer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;As of version 1.3.4, ProB provides support for refinement checking and various other assertions (deadlock, divergence, determinism, and LTL/CTL assertions) of CSP-M specifications. In this tutorial we give a short overview of the ProB’s implementations and features for checking CSP assertions. In the Tcl/Tk interface of ProB, CSP assertions can be assembled and checked in the &#039;&#039;CSP Assertions Viewer&#039;&#039;. A description of the &#039;&#039;CSP Assertions Viewer&#039;&#039; is also given.&lt;br /&gt;
&lt;br /&gt;
== Supported CSP Assertions in ProB ==&lt;br /&gt;
&lt;br /&gt;
ProB provides support for checking almost all types of CSP-M assertions that can be checked within FDR2. Besides the assertion types that can be checked in FDR2, in ProB one also can check temporal properties on processes expressed by means of LTL and CTL formulae.&amp;lt;ref&amp;gt;ProB provides support for LTL and CTL model checking (citations needed).&amp;lt;/ref&amp;gt; The following types of assertions are supported in ProB:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Refinement&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Refinement is one of the fundamental notions for construction and verification of systems specified in CSP. Given two CSP processes &#039;&#039;P&#039;&#039; and &#039;&#039;Q&#039;&#039; one can state in ProB the property that process &#039;&#039;Q&#039;&#039; is an ‘m’ refinement of &#039;&#039;P&#039;&#039; by the following assertion declaration:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;assert P [m= Q&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ‘m’ indicates one of the following types of comparison: ‘T’ for traces, ‘F’ for failures, ‘FD’ for failures-divergence, ‘R’ for refusals, and ‘RD’ for ‘refusals-divergence’. Note that the refinement types ‘V’ (revivals) and ‘VD’ (revivals-divergence) that are part of the refinement assertions supported by FDR2 are yet not supported by ProB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Deadlock&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Stating assertions about CSP processes to be deadlock-free is possible by the following assertion declaration:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;assert P :[deadlock free [m]]&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &#039;&#039;P&#039;&#039; is a process expression and ‘m’ indicates one of the following models: ‘F’ (failures) and ‘FD’ (failures-divergence).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Determinism&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Stating assertions about CSP processes to be deterministic is possible by the following assertion declaration:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;assert P :[deterministic [m]]&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &#039;&#039;P&#039;&#039; is a process expression and ‘m’ one of the following models: ‘F’ (failures) and ‘FD’ (failures-divergence).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Livelock&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Stating assertions about CSP processes to be livelock-free is possible by the following assertion declaration:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;assert P :[livelock free]&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &#039;&#039;P&#039;&#039; is a process expression.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Temporal Properties&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
In ProB it is also possible to make assertions about temporal properties of CSP processes both in LTL and CTL. Basically, one wants to check whether some process &#039;&#039;P&#039;&#039; satisfies a formula &#039;&#039;f&#039;&#039; expressed in a temporal logic (denoted by &amp;lt;tt&amp;gt;P |= f&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
To check whether a process &#039;&#039;P&#039;&#039; satisfies an LTL formula &#039;&#039;f&#039;&#039; write the following declaration:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;assert P |= LTL: “f”&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that &#039;&#039;f&#039;&#039; must be placed between quotes and that the satisfaction relation |= is immediately followed by `LTL:`. ProB supports LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt;, an extended version of LTL which provides additionally support for making propositions on transitions. The following LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; syntax for CSP-M specifications can be outlined by the following rules:&lt;br /&gt;
&lt;br /&gt;
*	Atomic propositions:&lt;br /&gt;
**	To check if an event `evt` is enabled in a state use `e(evt)`&lt;br /&gt;
*	Transition propositions:&lt;br /&gt;
**	To check whether an event `evt` is executed use `[evt]`&lt;br /&gt;
*	 Logical operators&lt;br /&gt;
**	`true` and `false`&lt;br /&gt;
**	`not`: negation&lt;br /&gt;
**	`&amp;amp;`,`or` and `=&amp;gt;`: conjunction, disjunction and implication&lt;br /&gt;
*	Temporal operators:&lt;br /&gt;
**	`G f`: globally&lt;br /&gt;
**	`F f`: finally&lt;br /&gt;
**	`X f`: next&lt;br /&gt;
**	`f U g`: until&lt;br /&gt;
**	`f W g`: weak-until&lt;br /&gt;
**	`f R g`: release&lt;br /&gt;
*	Fairness operators:&lt;br /&gt;
**	`WF(evt)` or `wf(evt)`: weak fairness, where `evt` is an event&lt;br /&gt;
**	`SF(evt)` or `sf(evt)`: strong fairness, where `evt` is an event&lt;br /&gt;
**	`WEF` and `SEF` for checking LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formulae on executions that are strongly and weakly fair with respect to all events, respectively&lt;br /&gt;
&lt;br /&gt;
An LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &#039;&#039;f&#039;&#039; is satisfied by some CSP process &#039;&#039;P&#039;&#039; if all executions of &#039;&#039;P&#039;&#039; satisfy &#039;&#039;f&#039;&#039;. If there is an execution of &#039;&#039;P&#039;&#039; which violates the property &#039;&#039;f&#039;&#039;, then the test &amp;lt;tt&amp;gt;P |= f&amp;lt;/tt&amp;gt; fails by providing a counterexample. Depending on whether &#039;&#039;f&#039;&#039; expresses, a safety or liveness property, a finite path or a path in a lasso-form (, i.e. a path leading to a cycle) is returned as a counterexample, respectively.&lt;br /&gt;
&lt;br /&gt;
Note that ProB supports also Past-LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt;. Past-LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt;, however, may be considered to be inappropriate for LTL assertions since the goal of this type of assertions is usually to check whether all executions starting at the initial states of the process satisfy the respective LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula.&lt;br /&gt;
&lt;br /&gt;
To check whether a process &#039;&#039;P&#039;&#039; satisfies a CTL formula &#039;&#039;f&#039;&#039; the following assertion should be made:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;assert P |= CTL: “f”&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As for LTL, CTL formulae should be put in between quotes. The CTL syntax for CSP-M specifications could be summarised as follows:&lt;br /&gt;
*	Atomic propositions:&lt;br /&gt;
**	To check if an event `evt` is enabled in a state use `e(evt)`&lt;br /&gt;
*	Transition propositions:&lt;br /&gt;
**	To check whether an event `evt` is executed use `[evt]`&lt;br /&gt;
*	State formulae, where f, f1 and f2 are path formulae:&lt;br /&gt;
**	true | false | `not` f | f1 `&amp;amp;` f2 | f1 `or` f2 | f1 `=&amp;gt;` f2,&lt;br /&gt;
**	E f : path quantifier `&amp;lt;math&amp;gt;\exists&amp;lt;/math&amp;gt;`, pronounced `for some path`&lt;br /&gt;
**	A f : path quantifier `&amp;lt;math&amp;gt;\forall&amp;lt;/math&amp;gt;`, pronounced `for all paths`&lt;br /&gt;
*	Path formulae, where g, g1 and g2 are state formulae:&lt;br /&gt;
**	`X g`: next&lt;br /&gt;
**	`g1 U g2`: until&lt;br /&gt;
**	`G g`: globally&lt;br /&gt;
**	`F g`: finally&lt;br /&gt;
*	Next executed event:&lt;br /&gt;
**	`EX [e] true`: &lt;br /&gt;
&lt;br /&gt;
Note that these two types of assertions, the LTL and CTL assertions, are not part of the CSP-M language supported by FDR2. Loading a CSP-M file in FDR2 having assertion declarations of this form will exit with a syntax error. Bear in mind to remove or comment out such LTL/CTL assertions in the CSP-M file before loading it in FDR2.&lt;br /&gt;
&lt;br /&gt;
== CSP Assertions Viewer ==&lt;br /&gt;
&lt;br /&gt;
When a CSP-M specification is loaded one can open the &#039;&#039;CSP Assertion Viewer&#039;&#039; either from the menu bar of the main window by selecting the `Check CSP-M Assertions` command in the `Verify` menu or from the Refinement button in the ‘’State Properties’’ pane. The viewer looks as follows:&lt;br /&gt;
&lt;br /&gt;
[[file:CSPAssertionsViewer.png]]&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;CSP Assertion Viewer&#039;&#039; of ProB has a similar design to the graphical user interface of FDR2. It consists basically of three main components: a menu bar, a list box and a tab pane. In the following each of the components and their corresponding functionalities are thoroughly described.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The Menu Bar&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
The menu bar is placed at the top of the window. On OS X, it is placed at the top of the screen. The menu bar includes several menus providing commands for adjusting, executing and changing the items in the list box, as well as some (standard) options for re-loading the model, saving the items to an external file or the loaded file, and launching some external tools related with the domain in which the list items are checked. Each menu can be popped up by a click with Mouse-1 (usually the left mouse button). The menu bar consists of the following menus and menu commands:&lt;br /&gt;
&lt;br /&gt;
*	&#039;&#039;&#039;File&#039;&#039;&#039;&lt;br /&gt;
**	&#039;&#039;Reopen File&#039;&#039;: Reopening (re-reading and re-loading) the currently loaded file, incorporating any changes that may have been made since the file was last loaded.&lt;br /&gt;
**	&#039;&#039;Copy new Assertions to File&#039;&#039;: All assertions that have been added to the list box since the currently loaded file was last read will be written to the file, i.e. all assertions that are yet not in the file are appended to it.&lt;br /&gt;
**	&#039;&#039;Save Assertions to External File&#039;&#039;: Selecting the option opens a standard Tk dialog box requesting a name of a file in which the assertions and their results in the list box could be saved.&lt;br /&gt;
**	&#039;&#039;Exit&#039;&#039;: Closing the CSP Assertion Viewer. Any assertion check results and any recently added assertions from the Tab Pane will get lost. The user will not be prompted to save these to the source file or an external file.&lt;br /&gt;
* &#039;&#039;&#039;Font&#039;&#039;&#039;&amp;lt;br/&amp;gt;Changing the font settings of the elements in the list box. Each of the items of this menu is a cascading menu that provides a number of options to be selected. The currently selected option in the cascading menu is marked by a tick symbol (✓).&lt;br /&gt;
**	&#039;&#039;Family-Name&#039;&#039;: Change the font family of the text in the list box. There are currently four font families that could be chosen: Arial, Curier, Helvetica, and Times. Default font is Curier. &lt;br /&gt;
**	&#039;&#039;Size&#039;&#039;: Change the font size of the text in the list box. Default font size is 10.&lt;br /&gt;
**	&#039;&#039;Background&#039;&#039;: Change the background color of the list box. Default background color is Gray90.&lt;br /&gt;
*	&#039;&#039;&#039;Assertions&#039;&#039;&#039;&amp;lt;br/&amp;gt;The menu provides a list of commands for checking different types of assertions. In case a particular type of assertions is checked the respective command checks only these assertions that are not checked yet.&lt;br /&gt;
**	&#039;&#039;Uncheck All Assertions&#039;&#039;: Set the status of all assertions in the list box to non-checked (`?`). &lt;br /&gt;
**	&#039;&#039;Delete All Assertions&#039;&#039;: Delete all assertions in the list box.&lt;br /&gt;
**	&#039;&#039;Check All Refinement…&#039;&#039;: The item is a cascading menu and provides commands to check all assertions of one of the following supported refinement types: Traces, Failures, Failures-Divergence, Refusals, and Refusals-Divergence.&lt;br /&gt;
**	&#039;&#039;Check Processes for…&#039;&#039;: The item is a cascading menu and provides commands to check all assertions of the following supported types of checks: Deadlock, Determinism and Livelock.&lt;br /&gt;
**	&#039;&#039;Check All LTL Assertions&#039;&#039;: Selecting this command causes ProB to check all LTL assertions in the list box that are not checked yet.&lt;br /&gt;
**	&#039;&#039;Check All CTL Assertions&#039;&#039;: Selecting this command causes ProB to check all CTL assertions in the list box that are not checked yet.&lt;br /&gt;
**	&#039;&#039;Check All Assertions&#039;&#039;: Selecting this command causes ProB to check of all assertions in the list box that are not checked yet.&lt;br /&gt;
*	&#039;&#039;&#039;External Tools&#039;&#039;&#039;&lt;br /&gt;
**	&#039;&#039;Open Specification with FDR&#039;&#039;: Open the currently loaded CSP-M specification in FDR2. The FDR2 tool is launched with the currently loaded specification in case the FDR2 is installed and the correct path to the `fdr2` command is set for the respective preference `Path to the FDR2 tool`. The value of the `Path to the FDR2 tool` preference can be changed from the “CSP Preferences…” window which can be opened by selecting the `CSP Preferences…` command in `Preferences` menu of the main window.&lt;br /&gt;
**	&#039;&#039;Evaluate with CSPM-Interpreter&#039;&#039;: Selecting this command opens a console in which one can evaluate CSP-M expressions using the CSP-M interpreter. The CSP-M interpreter is an external tool implemented independently from ProB. CSP-M expression can be evaluated if the `cspm` tool is installed and the path to the cspm-command is set for the respective preference `Path to CSPM tool`. The command is obsolete and its removal is considered in future.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The Assertion List Box&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
This part of the viewer lists all assertions stated in the currently loaded CSP-M specification and provides a set of features for checking, manipulating, and debugging of CSP assertions in the list. To each statement in the assertion list box a symbol is assigned, placed on the left side of it, that reveals the current status of the statement in the viewer:&lt;br /&gt;
&lt;br /&gt;
*	?    -  Assertion not checked yet.&lt;br /&gt;
*	✔ - Assertion check completed successfully.&lt;br /&gt;
*	✘ - Assertion check completed, but a counterexample was found to the stated property. The debugger can be used to explore the reason why the property does not hold.&lt;br /&gt;
*	⌚ - Assertion is currently checked.&lt;br /&gt;
*	! -  The check of the assertion not completed for some reason. Possible causes for the interruption may be: &lt;br /&gt;
**	Syntax error in the property was detected;&lt;br /&gt;
**	Assertion check failed because of missing implementation;&lt;br /&gt;
**	Assertion check interrupted by user. &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt; Note that in case of an LTL and a CTL assertion the check could fail to complete because of a syntax error in the respective formula. If an assertion check fails to complete an error box is popped up displaying an error message, which indicates why the assertion check could not be completed.&lt;br /&gt;
&lt;br /&gt;
An assertion can be selected by clicking on it with Mouse-1 and checked by double-clicking on it with Mouse-1. Alternatively, selecting an assertion and then pressing the Enter key can start the respective assertion check.  When an assertion check is in progress, the assertion will be marked by the clock symbol (⌚). If the assertion check is completed without interrupting it, a new status is assigned to the assertion: tick symbol (✔) indicating that the assertion was completed successfully or cross symbol (✘) indicating that a counterexample was found for the stated property. In case that the status is cross the counterexample can be explored by (second) double-click with Mouse-1 on the assertion or by selecting the assertion and then pressing the Enter key. If the respective assertion is negated, i.e. there is `not` in front of the assertion property, and marked with a cross, then no counterexample can be explored as the proper statement holds.&lt;br /&gt;
&lt;br /&gt;
The list box is equipped with a contextual menu (or a pop-up menu), which appears when you right-click on an assertion in the list. Depending on the type and the status of the assertion the contextual menu provides options for checking, debugging, modifying the respective assertion, as well as various other options. Take, for example, the selected assertion on which the contextual menu is popped up in the picture below.&lt;br /&gt;
&lt;br /&gt;
[[file: CSPAssertionsViewer_ctxmenu.png]]&lt;br /&gt;
&lt;br /&gt;
The assertion &amp;quot;&amp;lt;tt&amp;gt;ASSYSTEM |= LTL: “GF [eats.0]”&amp;lt;/tt&amp;gt;&amp;quot; intends to check if the process ASSYSTEM satisfies the LTL formula &amp;quot;&amp;lt;tt&amp;gt;GF [eats.0]&amp;lt;/tt&amp;gt;&amp;quot;. For the selected assertion above, for example, the options `Show LTL Counterexample` and `Show LTL Counterexample in State Space` are enabled as a counterexample was found for the check. On the other hand, the options `Check Assertion` and `Interrupt Assertion` are disabled as the assertion check was completed.&lt;br /&gt;
&lt;br /&gt;
The contextual menu has in general the following options:&lt;br /&gt;
&lt;br /&gt;
The following options affect only the assertion being selected.&lt;br /&gt;
*	&#039;&#039;&#039;Debug or Show LTL/CTL Counterexample…&#039;&#039;&#039;: Opens the graphical viewer for exploring the counterexample that was found for the respective LTL assertion check. Option is enabled if the assertion is not negated and its status is cross (✘), or if the assertion is negated and its status is tick (✔). Option appears if the assertion type is an LTL assertion or a CTL assertion.&lt;br /&gt;
*	&#039;&#039;&#039;Debug Assertion&#039;&#039;&#039;: Opens a trace-failure debugger window showing the reason why the corresponding assertion check failed. Option is enabled if the assertion is not negated and its status is cross (✘), or if the assertion is negated and its status is tick (✔). Option available for all types of assertions except for LTL and CTL assertions.&lt;br /&gt;
*	&#039;&#039;&#039;Check Assertion&#039;&#039;&#039;: Starts immediately the check of the assertion being selected before right clicking on it.&lt;br /&gt;
*	&#039;&#039;&#039;Interrupt Assertion Check&#039;&#039;&#039;: Interrupts the current assertion check.&lt;br /&gt;
*	&#039;&#039;&#039;Uncheck Assertion&#039;&#039;&#039;: If the assertion was checked and the result of the check is different from question mark (?), then the status of the assertion will be reset to question mark. Option is enabled only if the assertion result is different from question mark.&lt;br /&gt;
*	&#039;&#039;&#039;Delete Assertion&#039;&#039;&#039;: Removes the selected item from the assertion list.&lt;br /&gt;
*	&#039;&#039;&#039;Negate Assertion&#039;&#039;&#039;: Negates the respective assertion. If the result of the (proper) assertion check is cross (✘), then the result of the negated assertion becomes tick (✔). Otherwise, if the result of the (proper) assertion is tick (✔), the negated assertion becomes cross (✘).&lt;br /&gt;
*	&#039;&#039;&#039;Swap Processes&#039;&#039;&#039;: Option available only for refinement assertions. Performing the command causes the attachment of a new refinement assertion in which the process expressions on both sides of the refinement operator `[m=` are swapped. If, for example, we execute ‘’Swap Processes’’ on the assertion &amp;quot;&amp;lt;tt&amp;gt;P [T= Q&amp;lt;/tt&amp;gt;&amp;quot;, the command adds to the list of assertions the assertion &amp;quot;&amp;lt;tt&amp;gt;Q [T= P&amp;lt;/tt&amp;gt;&amp;quot;.&lt;br /&gt;
The following options affect all assertions in the list box.&lt;br /&gt;
*	&#039;&#039;&#039;Check All Assertions&#039;&#039;&#039;: The command causes the check of all assertions in the list box. The assertions that are already checked would not be checked again.&lt;br /&gt;
*	&#039;&#039;&#039;Uncheck All Assertions&#039;&#039;&#039;: The status of all assertions in the list box is reset to question mark.&lt;br /&gt;
*	&#039;&#039;&#039;Delete All Assertions&#039;&#039;&#039;: All entries in the list box are removed. As a result the message “No assertions were added.” appears in the list box.&lt;br /&gt;
Other options. The following options have no impact on the assertions in the list box.&lt;br /&gt;
*	&#039;&#039;&#039;Summary of the CSP Syntax&#039;&#039;&#039;: Opens a window in which the summary of the CSP-M syntax and features supported by the ProB tool is given.&lt;br /&gt;
*	&#039;&#039;&#039;Evaluate CSP Expressions&#039;&#039;&#039;: Opens the Eval console in which CSP expressions can be evaluated.&lt;br /&gt;
*	&#039;&#039;&#039;Open Specification with FDR&#039;&#039;&#039;: Opens the currently loaded CSP-M specification in FDR2. The FDR2 tool is launched with the currently loaded specification if FDR2 is installed and the correct path to the `fdr2` command is set for the respective preference `Path to the FDR2 tool`. The value of the `Path to the FDR2 tool` preference can be changed from the “CSP Preferences…” window which can be opened by selecting the `CSP Preferences…` command in `Preferences` menu of the main window.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The Tab Pane&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The tab pane is placed at the bottom of the window and enables the user to construct and check properties of processes of the currently loaded CSP-M file without adding explicitly assertions to the file.&lt;br /&gt;
&lt;br /&gt;
There are overall six tab pages. Each tab page is used to build up new assertion statements. The tab pages provide selectors, entries and command buttons for assembling, adding and checking new assertions. In each of the selectors all possible processes of the loaded CSP-M file are accessible. It is also possible to specify new process expressions by entering these in the respective entry of the process selector. The tab pages for creating LTL and CTL assertions provide additionally an appropriate entry for specifying the according LTL and CTL formula intended to be checked on the specified process, respectively.&lt;br /&gt;
&lt;br /&gt;
Each tab page is equipped with the following command buttons: &lt;br /&gt;
&lt;br /&gt;
*	&#039;&#039;&#039;Add&#039;&#039;&#039;: Attaching a new assertion to the list of assertions in the list box. If the entry in one of the selectors is empty no assertion will be added to list box and a warning message will appear informing the user that some of the entries were not specified. If the entered assertion in the tab page is already in the list box, then a warning box appears informing the user that the assertion is already in the list box. If the assertion is present in the list box it will not be added.&lt;br /&gt;
*	&#039;&#039;&#039;Check&#039;&#039;&#039;: Attaching a new assertion to the list of assertions in the list box and immediately starting checking the assertion. If the assertion is already in the list box, then the user will be informed that the assertion is already in the list box and in case it is not checked yet its check will be started.&lt;br /&gt;
*	&#039;&#039;&#039;Cancel/Interrupt&#039;&#039;&#039;: Closes the window or interrupts an assertion check. In case the “Cancel” command is executed all checks and new assertions will get lost. If an assertion is currently checked, then the button command “Cancel” is replaced by another button command ‘’Interrupt’’, which causes the interruption of the current assertion check when the button is clicked on.&lt;br /&gt;
&lt;br /&gt;
== Debugging Non-satisfied Assertions ==&lt;br /&gt;
&lt;br /&gt;
In case an assertion check has failed the user can explore the reason for the assertion violation. If the corresponding assertion is not negated and after finishing the assertion check is marked by cross, then this is an indication that ProB has found a counterexample for the check. The counterexample can be explored by a second double-click with the ‘Mouse-1’ button or by selecting the assertion and then pressing the ‘Enter’ button. Depending on the type of the assertion and the type of the counterexample a corresponding debugging window is opened.&lt;br /&gt;
&lt;br /&gt;
If a CSP process violates an LTL formula or a universally quantified CTL formula, then by performing a second double-click on the respective assertion one can explore the provided counterexample by means of the graphical viewer ([http://stups.hhu.de/ProB/w/Graphical_Viewer Graphical Viewer]).&lt;br /&gt;
&lt;br /&gt;
In the following we give an overview of the features for debugging counterexamples being found for different refinement checks. Consider the following CSP processes:&lt;br /&gt;
&lt;br /&gt;
P = a -&amp;gt; b -&amp;gt; c -&amp;gt; STOP&lt;br /&gt;
&lt;br /&gt;
Q = a -&amp;gt; (b -&amp;gt; Q [] c -&amp;gt; Q)&lt;br /&gt;
&lt;br /&gt;
R = a -&amp;gt; b -&amp;gt; R&lt;br /&gt;
&lt;br /&gt;
If we intend to check whether P is deadlock free, then we can state the assertion &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;assert P :[deadlock free [F]]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
The check of the assertion will finish by marking the assertion in the list box with a cross symbol (✘). The cross symbol indicates that a counterexample was found for the assertion check. The counterexample is basically given by the trace &amp;lt;math&amp;gt;\langle a,b,c \rangle&amp;lt;/math&amp;gt; as obviously `P` reaches a deadlock state after performing the trace &amp;lt;math&amp;gt;\langle a,b,c \rangle&amp;lt;/math&amp;gt;. Providing a second double-click on the assertion will open the following debugging window:&lt;br /&gt;
&lt;br /&gt;
[[file: CSP_Deadlock_Trace.png]]&lt;br /&gt;
&lt;br /&gt;
Considering the CSP processes `Q` and `R` one can see or check that `R` is a trace refinement of `Q` since `R` performs the same set of traces as `Q`. Thus, the assertion check for `Q [T= R` will mark the assertion statement in the list box by a tick symbol (✔). On the other hand, checking the assertion `R [T= Q` will find a counterexample for the refinement check. Performing a second double-click on the item `R [T= Q` will open the following trace debugger window with the counterexample displayed in it:&lt;br /&gt;
&lt;br /&gt;
[[file: CSP_Trace_Debugger.png]]&lt;br /&gt;
&lt;br /&gt;
A counterexample of a trace-refinement assertion is a trace leading to a state in which the implementation process performs an event that the specification process cannot perform. In the example above both processes `P` and `Q` perform the trace &amp;lt;math&amp;gt;\langle a \rangle&amp;lt;/math&amp;gt; and reach states in which the implementation process can perform an event that is not offered by the specification process &#039;&#039;R&#039;&#039;. One can easily deduce from the picture above that `Q` performs after `a` the event `c` which is not offered by `R` as `R` can perform only `b` after `a`. In the left most column `Accept` the debugger window lists all possible events that are offered by the specification process after performing the trace given in the `Trace` column next to `Accepts`.&lt;br /&gt;
&lt;br /&gt;
As we already mentioned above `R` is a trace-refinement of `Q`. On the other hand, checking whether `R` is a failures-refinement of `Q` will produce a counterexample since `R` refuses the event `c` that is offered by Q after executing `a`. Accordingly, the counterexample will be illustrated within the following trace debugger window:&lt;br /&gt;
&lt;br /&gt;
[[file: CSP_Failures_Debugger.png]]&lt;br /&gt;
&lt;br /&gt;
These are basically the three types of debugging windows that will appear when debugging a counterexample for an assertion check in case the respective assertion is not an LTL or a CTL assertion. When a counterexample for an LTL assertion is found it will be explored in the graphical viewer, the same graphical viewer that is used for visualizing the state space models in ProB. &lt;br /&gt;
&lt;br /&gt;
Let us observe again the CSP process `Q` and suppose we want to check whether `Q` satisfies the LTL formula `F [c]`. Then, the respective LTL assertion is declared as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;assert Q |= LTL: “F [c]”&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The assertion check will produce a counterexample as `Q` obviously reaches a cycle “(b -&amp;gt; a)+” that violates the property “F [c]”. Performing a second double-click on the assertion will display the following state space graph in the graphical viewer:&lt;br /&gt;
&lt;br /&gt;
[[file: CE_LTL_assertion.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above, the nodes and the transitions of the respective counterexample  &amp;quot;a -&amp;gt; (b -&amp;gt; a)+&amp;quot; are colored in red.&lt;br /&gt;
&lt;br /&gt;
== Checking CSP Assertions with `probcli` ==&lt;br /&gt;
It is also possible to check CSP assertions with the command line version of ProB. The command has the following syntax:&lt;br /&gt;
 probcli -csp_assertion &amp;quot;A&amp;quot; File&lt;br /&gt;
&lt;br /&gt;
where &#039;&#039;A&#039;&#039; is a CSP assertion and &#039;&#039;File&#039;&#039; the path to the CSP file. For example, if we want to check the refinement assertion `&amp;lt;tt&amp;gt;P [T= Q&amp;lt;/tt&amp;gt;` on some CSP specification `example.csp`, then we can do this by running the ProB command line version with the following options:&lt;br /&gt;
 probcli -csp_assertion &amp;quot;P [T= Q&amp;quot; example.csp&lt;br /&gt;
&lt;br /&gt;
Note that the assertion should be placed between quotes. In addition, when an assertion is checked with the &#039;-csp_assertion&#039; option the keyword &#039;&#039;&#039;assert&#039;&#039;&#039; should be omitted.&lt;br /&gt;
&lt;br /&gt;
Notice that for checking LTL and CTL assertions from the command line you need to escape the double quotes (&amp;quot;) wrapping the respective LTL/CTL formula by means of a backslash \.&lt;br /&gt;
 probcli -csp_assertion &amp;quot;Q |= LTL: \&amp;quot;F [c]\&amp;quot;&amp;quot; example.csp&lt;br /&gt;
&lt;br /&gt;
== References and Notes ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3649</id>
		<title>Tutorial Enabling Analysis</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3649"/>
		<updated>2016-06-06T10:44:01Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Performing Enabling Analysis within ProB */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The B-method and in particular its successor Event-B are methodologies for formal development and verification of systems. In Event-B, a machine is usually viewed as a reactive system executing continuously enabled (atomic) events in an interleaved fashion. Thus, parallel events of the system are easily modeled as an interleaving of operation executions. On the other hand, the introduction of abstract counters is required when events are supposed to be executed in some (sequential) order. This, however, can in some cases slow the work of understanding and verifying a model since identifying the sequential ordering of events in an Event-B model is not that obvious. Thus, using methods for determining the control flow can be sometimes very beneficial for understanding the model, as well as for techniques for automatic verification such as model checking.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we present a static analysis for B and Event-B that can be used to reveal the control flow of a machine and to optimize model checking of models written in B and Event-B (see also [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Guard_Evaluation Tutorial on Partial Guard Evaluation ]). The results of the analysis, designated also as ‘’enabling analysis’’, can be presented as relations by means of a table or by means of a graph. For simplicity, we will concentrate mainly on B and use the terminology of the formalism.&lt;br /&gt;
&lt;br /&gt;
== Enabling Relations ==&lt;br /&gt;
What we want to find out is how the operations influence each other within a B model. In other words, for each pair (op1,op2) of operations we try to determine as precise as possible how op1 can affect the guard condition of op2 with regard to enabledness. To determine the enabling relations between operations we use syntactic analyses, as well as the constraint-based abilities of ProB.&lt;br /&gt;
&lt;br /&gt;
Consider the following B machine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE Example&lt;br /&gt;
VARIABLES x, y, z&lt;br /&gt;
INVARIANT&lt;br /&gt;
    x:NATURAL&lt;br /&gt;
  &amp;amp; y:INTEGER&lt;br /&gt;
  &amp;amp; z:INTEGER&lt;br /&gt;
INITIALISATION &lt;br /&gt;
  x:=6 || y:=-2 || z:=0&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Op1 = PRE x + y&amp;gt;=4  THEN x:=x+2 || y:=2 END;&lt;br /&gt;
  Op2 = PRE x mod 2=1 THEN x:=x+1 || y:=2 END;&lt;br /&gt;
  Op3 = PRE x mod 2=0 THEN x:=x+2 END;&lt;br /&gt;
  Op4 = PRE x&amp;lt;0 THEN y:=y-1 END;&lt;br /&gt;
  Op5 = PRE y/=2 THEN z:=3 END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The machine has three variables x,y,z, where x ranges over the domain of natural numbers and y and z over the domain of all integers. For this machine we have 25 pairs of operations for which we want to determine the respective enabling relations. Additionally, we identify 5 further pairs that show the influence of the INITIALISATION on the guard conditions of all other operations. Consider, for example, the pair (Op2,Op1) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op1 is enabled in each state of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; where the predicate ‘x+y&amp;gt;=4’ is fulfilled. Since the effect of Op2 assigns 2 to y and increments x by one upon condition that x is a positive odd number in the before-state of Op2, we can assume that Op1 is always enabled after the execution of Op2. In other words, in all after-states of Op2 the operation Op1 is guaranteed to be enabled. This relation between Op2 and Op1 we can illustrate as follows: &lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above the green boxes denote that the evaluation of the guard of Op1 is true, whereas the red boxes denote that the evaluation of the guard of Op1 is false. &lt;br /&gt;
&lt;br /&gt;
Another pair of interest is (Op2,Op5) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op5 is enabled only in those states in which y is not equal to 2. Obviously, in each after-state of Op2 y is equal to 2 and thus we can conclude that Op5 is impossible to be enabled after each execution of Op2. Such a relation between two operations we denote as ‘’impossible’’ and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
Both arrows in the illustration of the ‘’impossible’’ relation indicate that whether the guard condition of Op5 is fulfilled or not in a before-state of Op2 operation Op5 will be disabled in the respective after-state of Op2. In order to recognize a tuple (op1,op2) as ‘’impossible’’ we require that op2 is always disabled after op1 without further considering whether op2 is always enabled or always disabled in the before-states of op1. &lt;br /&gt;
&lt;br /&gt;
Consider, for instance, the pair (Op2, Op2) in the machine above. We can easily conclude that Op2 becomes disabled after it is executed and clearly, the second case (\false -&amp;gt; \false) of the impossible relation is not possible for (Op2, Op2). This gives rise of introducing another (more precise) impossible relation:&lt;br /&gt;
 &lt;br /&gt;
[[File:ImpossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Accordingly, we can derive another relation from ‘’impossible’’ for which only the second case of the ‘’impossible’’ relation is fulfilled:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
As an example for a pair of operations that fulfills the ‘’impossible_keep’’ requirement you can take, for example, the pair (Op3,Op2) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Since Op2 and Op3 cannot be both enabled in a state and the execution of Op3 cannot enable Op2, then we can easily conclude that Op2 remains always disabled after Op3.&lt;br /&gt;
&lt;br /&gt;
Similarly as for ‘’impossible’’, one could derive two further enabling relations from ‘’guaranteed’’:&lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedEnableKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Another interesting class of enabling relations that could be helpful for better understanding and analyzing B and Event-B models is that of the ‘’keep’’ relations. We say that an operation op1 ‘’keeps’’ another operation op2 if op1 cannot change the status of the enabling condition of op2, i.e. op1 keeps op2 enabled respectively disabled. This relationship could be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:KeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
We can take (Op1,Op2) and (Op1,Op3) as examples of pairs in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; that are elements of the keep relation. ‘’keep’’ relations can sometimes be easily determined by analyzing just the syntactic structure of both operations, or more precisely the “read” and “write” sets of both operations.&amp;lt;ref&amp;gt;For an operation op the set read(op) denotes the set of variables that are read by op. Accordingly, by write(op) we denote the set of variables that are written by op.&amp;lt;/ref&amp;gt; If, for example, an operation op1 does not write any variable of the machine that is read in the guard condition of op2, then we can infer that op1 ‘’keeps’’ op2. In that case we also say that op1 does not change op2 syntactically. In the class of the ‘’keep’’ relations are included also relations such as independence. Two operations op1 and op2 are called independent if each of them cannot disable the other operation and the both orders of execution &amp;lt;op1,op2&amp;gt; and &amp;lt;op2,op1&amp;gt; have the same effect.&amp;lt;ref&amp;gt;See the [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Order_Reduction Tutorial on Partial Order Reduction] for more information on independence between operations.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three classes (‘’guaranteed’’, ‘’impossible’’ and ‘’keep’’) of enabling relations presented so far represent definite relations. That is, if a pair of operations (op1,op2) is confirmed to be a relation of one of this three classes, then we can certainly say what effect on the enabling condition of op2 would the execution of op1 have. However, for some pairs of operations we cannot certainly say what effect an operation would have on the enabling condition of another operation. This is due to the fact that the enabling status of an operation does not only depend on the effect of the executed operations, but also on the current variables’ evaluation. Take, for instance, the tuple (Op3,Op1) from the B machine above. Considering the action part of Op3 and the guard condition of Op1 we can assume that Op3 can enable Op1. Since the guard of Op1 depends not only on the current value of x, but also on y, there could be transitions s -&amp;gt; s&#039; of Op3 in the state space of the machine where Op1 is disabled in both states s and s’. Though, what we could definitely say is that Op3 cannot disable Op1. This relationship we can illustrate as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleEnableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
The opposite relation of “possible_enable” is the relation where an operation op2 can disable another operation op1. Formally, we say that op2 can disable op1 if op2 may disable op1 and op2 cannot enable op1. This relationship is denoted as “possible_disable” and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
In order to determine how operations influence each other we need to assure first that these are feasible. An operation ‘’op’’ is said to be feasible if there is a state of the machine that satisfies the invariant of the machine and in which ‘’op’’ is enabled. In the B machine above the operation Op4, for example, is not feasible. Obviously, Op4 is enabled only in states where x is a negative number and states in which x is a negative number are visibly not consistent with the invariant since &amp;quot;x : NATURAL&amp;quot;. Such incompatibilities are sometimes of great importance for the modeler and therefore they should be revealed in the process of computing the enabling relations. In our case for each pair of operations (Op4,-) and (-,Op4) the status “infeasible” will be returned.&lt;br /&gt;
&lt;br /&gt;
We can now list all possible enabling relations for the machine &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; by means of a table. For each entry in the table the operation in the row is the operation whose effect is studied on the status of the guard of the operation in the column.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingResults.png]]&lt;br /&gt;
&lt;br /&gt;
Rather than showing the enabling information for each pair of operations of the machine, one can display the enabling relations by means of a graph. The graph contains the operations as nodes and the above enabling relations as edges between the nodes, with the exception that relations marked as impossible, independent or infeasible are not shown in the graph. We denote such graphs as enable graphs. The enable graph of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; looks as follows.&lt;br /&gt;
&lt;br /&gt;
[[File: EnableGraph_Example.png]]&lt;br /&gt;
&lt;br /&gt;
From the enable graph one can recognize the control flow of the model and deduce some properties. For example, we can clearly see that &amp;lt;tt&amp;gt;Op4&amp;lt;/tt&amp;gt; cannot occur after the execution of another operation.&lt;br /&gt;
&lt;br /&gt;
== Summary of the Enabling Relations ==&lt;br /&gt;
&lt;br /&gt;
In the following, we summarize most of the enabling relations that we think can provide a useful feedback to the user. For each of the enabling relations we have given an appropriate example. In the examples below we compute the effect of executing ‘op1’ on the status of the guard of ‘op2’. The relation identifiers are the same as they appear as results in ProB.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;guaranteed&#039;&#039;: op2 guaranteed to be executable after op1.&lt;br /&gt;
[[File: GuaranteedExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_enable&#039;&#039;: op2 is guaranteed to become enabled after op1.&lt;br /&gt;
[[File: GuaranteedEnableExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_keep&#039;&#039;: op2 is guaranteed to stay enabled after op1.&lt;br /&gt;
[[File: GuaranteedKeepExample.png]]&lt;br /&gt;
* &#039;&#039;impossible&#039;&#039;: op2 is impossible to be executed after op1.&lt;br /&gt;
[[File: ImpossibleExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_disable&#039;&#039;: op2 is guaranteed to become disabled after op1.&lt;br /&gt;
[[File: ImpossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_keep&#039;&#039;: op2 is impossible to become enabled after op1.&lt;br /&gt;
[[File: ImpossibleKeepExample.png]]&lt;br /&gt;
* &#039;&#039;keep&#039;&#039;: op2 always stays enabled resp. disabled after op1.&lt;br /&gt;
[[File: KeepExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_unchanged&#039;&#039;: op1 does not write any variable read in the guard of op2, i.e. write(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticUnchangedExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_independent&#039;&#039;: op1 and op2 are syntactically independent, i.e. read(op1) /\ write(op2) = {} &amp;amp; write(op1) /\ read(op2) = {} &amp;amp; write(op1) /\ write(op2) = {}&lt;br /&gt;
[[File: SyntacticIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;syntactically_fully_independent&#039;&#039;: op1 and op2 are syntactically independent and additionally, read(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticFullyIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;possible_enable&#039;&#039;: op2 possible after op1, but op2 cannot be disabled by op1.&lt;br /&gt;
[[File: PossibleEnableExample.png]]&lt;br /&gt;
* &#039;&#039;possible_disable&#039;&#039;: op2 possible after op1, but op2 cannot be enabled by op1.&lt;br /&gt;
[[File: PossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;infeasible&#039;&#039;: op1 is not feasible and thus cannot influence op2.&lt;br /&gt;
[[File: InfeasibleExample.png]]&lt;br /&gt;
&lt;br /&gt;
== Performing Enabling Analysis within ProB  ==&lt;br /&gt;
&lt;br /&gt;
The enabling analysis has been implemented in the ProB toolset.  The computation of the enabling relations is based on syntactic and constraint-based techniques. The identification of relations such as ‘’syntactic_independent’’ and ‘’syntactic_unchanged’’ requires just a thorough study of the syntactic structure of the operations, i.e. no calls to the constraint solver have to be made. However, to confirm, for example, that an operation is guaranteed or impossible to be executed after another operation the use of the ProB’s constraint solver is unavoidable. For instance, consider the pair (Op2,Op1) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. As we have seen, in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; the operation Op1 is guaranteed to be enabled after each execution of Op2. In ProB this could be computed by feeding the (before-after) predicate “ (x mod 2 = 1) &amp;amp; (x&#039;=x+1 &amp;amp; y=2) &amp;amp; (x&#039;+y&#039;&amp;lt;4)” into the constraint solver. As a result, the constraint solver will not find a solution for the predicate, i.e. the constraint solver will not find a state ‘’s’’ satisfying “x mod 2 = 1” from which after executing Op2 at ‘’s’’ a solution state s’ will be found that fulfills “x+y&amp;lt;4”; note that “x+y&amp;lt;4” is the negation of the guard of Op1. Since there is no after-state of Op2 at which Op1 is disabled we can conclude that Op1 is guaranteed to be executed after Op2. When constraints are getting more complex the constraint solver may need more time for solving. Thus, the computation of the enabling relations may become a very time-expensive task. Therefore, a time-out for each constraint solver call is set. In other words, if the constraint solver does not find a solution in the given time by the user, then the respective relation will be denoted as time-outed. By default, in ProB the time-out for each constraint solver call is set to 300 ms.&lt;br /&gt;
&lt;br /&gt;
Within &amp;lt;tt&amp;gt;ProB Tcl/Tk&amp;lt;/tt&amp;gt; you can find the menu &amp;quot;Enabling Analysis&amp;quot; in the &amp;quot;Analysis&amp;quot; menu of the menu bar.&lt;br /&gt;
[[File: EnablingAnalysisMenu.png]]&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;Enabling Analysis&amp;quot; menu provides multiple commands:&lt;br /&gt;
* &amp;quot;Enabling Analysis (Table)&amp;quot;: this command performs a (fast) enabling analysis on the respective B model using a time-out of 300 ms for the constraint-solver calls. The result of the enabling analysis is shown in a table. The table lists all enabling relations between the operations of the loaded B model. These can be exported to a CSV file. The table for &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; at the end of the &#039;&#039;&#039; Enabling Relations&#039;&#039;&#039; section was constructed this way.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Precise, Table)&amp;quot;: this command performs an enabling analysis using a time-out of 2800 ms for each of the constraint-solver calls. As for the command above, the result of the analysis is shown in a table that can be exported to a CSV file.&lt;br /&gt;
* &amp;quot;Enabling Relations After...&amp;quot;: this command computes all the enabling relations involving an operation chosen by the user.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Graph)&amp;quot;: this command performs the fast enabling analysis but displays the results as a graph. In case the preference &amp;quot;DOT_SHOW_OP_READ_WRITES&amp;quot; is set for each operation the read/write information is displayed.&lt;br /&gt;
* &amp;quot;Enabling Analysis (POR)...&amp;quot;: this menu provides further commands for another form of enabling analysis the results of which are used for the partial guard evaluation optimisation in ProB.&lt;br /&gt;
* &amp;quot;Read/Write Matrix (Table)&amp;quot;: this command performs syntactic analysis on the model. The analysis determines the read and write sets for each operation of the machine.&lt;br /&gt;
* &amp;quot;Dependence Analysis (Table)&amp;quot;: this command performs a dependency analysis for each pair of operations. More specifically, the analysis determines which operations are dependent or independent to each other.&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB (probcli) one can perform an enabling analysis on a B or Event-B model by means of the &amp;lt;tt&amp;gt;-enabling_analysis&amp;lt;/tt&amp;gt; option. The results of the analysis, as well as intermediate data and some statistics are printed out on the console:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli Example.mch -enabling_analysis&lt;br /&gt;
CHECKING ENABLING AFTER INITIALISATION&lt;br /&gt;
INITIALISATION ---&amp;gt; Op1  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op2  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op3  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op4  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op5  :: ok : guaranteed&lt;br /&gt;
.....&lt;br /&gt;
CHECKING ENABLING AFTER: Op5 r:[y] / w:[z]&lt;br /&gt;
Op5 ---&amp;gt; Op1  :: Enable=syntactic_independent&lt;br /&gt;
Op5 ---&amp;gt; Op2  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op3  :: Enable=syntactic_fully_independent&lt;br /&gt;
Op5 ---&amp;gt; Op4  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op5  :: Enable=syntactic_unchanged&lt;br /&gt;
% Finished CBC Enabling Analysis 810 ms walltime (770 ms runtime), since start: 1650 ms&lt;br /&gt;
% CBC Enabling Stats:&lt;br /&gt;
% Nr of events: 5&lt;br /&gt;
% Nr of cbc calls: 30, Timeout results: 2&lt;br /&gt;
Origin,Op1,Op2,Op3,Op4,Op5&lt;br /&gt;
INITIALISATION,guaranteed,impossible,guaranteed,impossible,guaranteed&lt;br /&gt;
Op1,timeout_possible_disable,keep,keep,impossible_keep,syntactic_independent&lt;br /&gt;
Op2,guaranteed,impossible,guaranteed,impossible_keep,impossible&lt;br /&gt;
Op3,timeout_possible,impossible_keep,guaranteed,impossible_keep,syntactic_fully_independent&lt;br /&gt;
Op4,impossible_keep,syntactic_unchanged,syntactic_unchanged,syntactic_keep,impossible_keep&lt;br /&gt;
Op5,syntactic_independent,syntactic_unchanged,syntactic_fully_independent,syntactic_unchanged,syntactic_unchanged&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To perform enabling analysis from the command line and save the results into a CSV-file use the following commando:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli file.mch -enabling_analysis_csv FILE &amp;lt;/pre&amp;gt;&lt;br /&gt;
where FILE is the name of the CSV-file in which the results of the analysis are stored.&lt;br /&gt;
&lt;br /&gt;
== References and Footnotes ==&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=LTL_Model_Checking&amp;diff=3635</id>
		<title>LTL Model Checking</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=LTL_Model_Checking&amp;diff=3635"/>
		<updated>2016-05-04T13:53:31Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* LTL Model Checker Output */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]__NOTOC__&lt;br /&gt;
ProB provides support for LTL (linear temporal logic) model checking. For an introduction to LTL see the [http://en.wikipedia.org/wiki/Linear_temporal_logic Wikipedia Article].&lt;br /&gt;
&lt;br /&gt;
To use this feature, select &amp;quot;Check LTL/CTL Assertions&amp;quot; in the &amp;quot;Verify&amp;quot; menu. The feature can also be accessed by the key combination &amp;quot;Ctrl+L&amp;quot; under Windows and Linux, and by the key combination &amp;quot;Cmd+L&amp;quot; under MacOS. The following window appears:&lt;br /&gt;
&lt;br /&gt;
[[File:ltlviewer.png]]&lt;br /&gt;
&lt;br /&gt;
All LTL formulas that are given in the &amp;quot;DEFINTIONS&amp;quot; section of a B machine are displayed in the list box of the LTL/CTL Assertions Viewer. For CSP-M specifications all LTL formulas given in the LTL pragmas of the loaded CSP-M file will be shown in the viewer. (For more detailed information of how LTL/CTL assertions can be stored into B and CSP-M models see Section &#039;&#039;&#039;Storing LTL Assertions into a Model&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
A new LTL formula can be entered in the entry below the list box. (We explain the supported syntax below). The typed formula can then be either added to the list box by clicking the &amp;quot;Add&amp;quot; button or directly checked by clicking the &amp;quot;Check&amp;quot; button. Before doing that assure whether you are in the proper frame (&amp;quot;Add LTL Formula&amp;quot;) of the bottom part of the LTL viewer.&lt;br /&gt;
&lt;br /&gt;
The LTL model checker can be started for an LTL formula by performing a double-click on the respective formula or typing &amp;quot;Enter&amp;quot; after selecting the respective formula. Each LTL formula in the list box has on the left hand side a symbol that indicates what is the status of the respective formula. An LTL formula can have one of the following statuses (status symbols may differ under different operating systems):&lt;br /&gt;
&lt;br /&gt;
* ? – The formula has not been checked yet.&lt;br /&gt;
* ✔ – The formula is true for all valid paths.&lt;br /&gt;
* ✘ – A counterexample for the formula has been found, i.e. there is a path that violates the formula. In case the formula has been just checked on the model the animator is navigated to the last state of the counterexample. The full path can then be seen in the history. The counterexample can be also obtained by the dotty-viewer after a second double-click on the formula in the assertions’ viewer. &lt;br /&gt;
* ⌚ – The formula is currently checked.&lt;br /&gt;
* ! – The formula check has been aborted by an unexpected error occurrence.&lt;br /&gt;
* ∞ – The formula check is incomplete, i.e. no counterexample was found so far, but the absence of a path that does not satisfy the formula can not be guaranteed because the state space was not fully explored. A new check can be started by a double-click.&lt;br /&gt;
&lt;br /&gt;
All formulas can be checked by &amp;quot;Assertions -&amp;gt; Check All Assertions&amp;quot; in the menu bar. All formulas will be then checked from top to bottom in the list box.&lt;br /&gt;
&lt;br /&gt;
Additionally, the viewer provides a context menu for the list box elements. The context menu can be popped-up by a right-mouse-click on a formula from the list box, and it performs a set of actions available to be performed on the currently selected formula (see Figure below). &lt;br /&gt;
&lt;br /&gt;
[[File:ltlviewercontext.png]]&lt;br /&gt;
&lt;br /&gt;
The old LTL and CTL dialogs can be accessed from &amp;quot;OldLtlViewers&amp;quot; in the menu bar.&lt;br /&gt;
&lt;br /&gt;
==LTL Preferences==&lt;br /&gt;
&lt;br /&gt;
There is a set of options coming with the LTL model checker. In this section we give a brief overview of the preferences. The LTL preferences can be viewed by selecting &amp;quot;LTL Preferences&amp;quot; in the &amp;quot;Preferences&amp;quot; menu of the LTL/CTL Assertions Viewer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Exploring new states&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
The LTL model checker searches in the already explored search space of the model. If a state is encountered that has not been explored before, the state will be explored (i.e. all transitions to successor states are computed). The number of how often this can happen is limited by the field &amp;quot;Max no. of new states&amp;quot;. &lt;br /&gt;
Depending on the LTL formula, a partially explored state space can be sufficient to find a counterexample or to assure the absence of a counterexample. If there&#039;s still the possibility of a counterexample in the remaining unexplored state space, the user will get a message. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Optimizing the process of LTL model checking&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
The process of model checking can be optimized for B and Event-B models by using partial order reduction. The idea of partial order reduction is to execute only a subset of all enabled actions in each state. Thus, only a part of the original state space is checked for the checked property. The reduction of the state space depends on the number of concurrent and independent actions in the model, as well as on the property being checked.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Search Options&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
The model checker searches for a counterexample (i.e. a path that does not satisfy the current formula). Where the checked paths through the model&#039;s search space start depend on the following options in the LTL Preferences’ menu:&lt;br /&gt;
# &#039;&#039;Start search in initialization&#039;&#039;&amp;lt;br/&amp;gt;All paths that start in a state of the initialization of the machine are checked. &lt;br /&gt;
# &#039;&#039;Start search in current state&#039;&#039;&amp;lt;br/&amp;gt;All paths that start in the current state are checked. &lt;br /&gt;
# &#039;&#039;Start in initialization, but check formula in current state&#039;&#039;&amp;lt;br/&amp;gt;All paths that start in a state of the initialization of the machine are checked, but the formula is mapped to the current state. For example, this option can be used to check properties like &amp;quot;Is this state only reachable directly after executing operation `xy`?&amp;quot;: The formula would be `Y[xy]`. This is equivalent to &amp;quot;G (current =&amp;gt; f)&amp;quot; with f as the entered formula and using the option &amp;quot;Start search in initialization&amp;quot;. &lt;br /&gt;
Note: Whereas `Y true` is always false when checked with option 1 or 2, it is usually true (but not in all cases) for option 3.&lt;br /&gt;
&lt;br /&gt;
=== Supported Syntax ===&lt;br /&gt;
&lt;br /&gt;
ProB supports LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt;, an extended version of LTL. In contrast to the standard LTL, LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; provides also support for propositions on transitions, not only on states. In practice,  writing propositions on transitions is allowed by using the constructs `e(...)` and `[...]`. (see below). The LTL model checker of ProB supports Past-LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; as well.&lt;br /&gt;
&lt;br /&gt;
* Atomic propositions can be one of the following:&lt;br /&gt;
**  Predicates can be written in curly braces: `{...}`. E.g. `{card(someset) &amp;gt; 1}`&lt;br /&gt;
**  To check if an operation is enabled in a state use `e(Op)`, where `Op` is the name of the operation.&lt;br /&gt;
**  To start a search from the current state of the animation use `current` (see the section &#039;&#039;&#039;LTL Preferences&#039;&#039;&#039; for more information).&lt;br /&gt;
**  To check if a state has no outgoing transition leading to a different state use `sink`. This can be useful for finding &amp;quot;pseudo&amp;quot;-deadlocks, i.e. states where only query-operations are enabled that do not change the state. Note that `sink` holds for deadlock states as well.&lt;br /&gt;
** For checking if a state is a deadlock state the atomic proposition ` deadlock ` can be used.&lt;br /&gt;
**  To check if a set of operations is disabled in a state use `deadlock(Op1,Op2,...,Opk)`, where Op1,Op2,...,Opk with k&amp;gt;0 are operations of the model. It is also possible to check if specific representations of an operation with arguments are disabled in a state using pattern-matching, e.g.: `deadlock(Op(1),Op(3))`.&lt;br /&gt;
** By means of `deterministic(Op1,Op2,...,Opk)`, where Op1,Op2,...,Opk with k&amp;gt;0 are operations of the model, one can check if maximum one of the operations Op1,Op2,...,Opk is enabled in a state. &lt;br /&gt;
** To check if exactly one operation from a set of operations Op1,Op2,...,Opk is enabled in a state use `controller(Op1,Op2,…,Opk)`.&lt;br /&gt;
&lt;br /&gt;
* Transition propositions:&amp;lt;br&amp;gt;If the next executed operation in the path is `Op`, the expression `[Op]` can be used. Also patter-matching for the arguments of the operation is supported. E.g. `[Op(3,4*v)]` checks if the next operation is `Op` and that the first argument is 3 and the third argument is `4*v` where `v` is a variable of the machine. &amp;lt;br&amp;gt; Arbitrary B expressions can be used as patterns. Constants and variables of the machine can be used. Variables have the values of the state where the operations starts.&lt;br /&gt;
&lt;br /&gt;
* Logical operators&lt;br /&gt;
** `true` and `false`&lt;br /&gt;
**  `not`: negation&lt;br /&gt;
**  `&amp;amp;`, `or` and `=&amp;gt;`: conjunction, disjunction and implication&lt;br /&gt;
&lt;br /&gt;
* Temporal operators (future)&lt;br /&gt;
**  `G f`: globally&lt;br /&gt;
**  `F f`: finally&lt;br /&gt;
**  `X f`: next&lt;br /&gt;
**  `f U g`: until&lt;br /&gt;
**  `f W g`: weak until&lt;br /&gt;
**  `f R g`: release&lt;br /&gt;
&lt;br /&gt;
* Temporal operators (past)&lt;br /&gt;
**  `H f`: history (dual to G)&lt;br /&gt;
**  `O f`: once (dual to F)&lt;br /&gt;
**  `Y f`: yesterday (dual to X)&lt;br /&gt;
**  `f S g`: since (dual to until)&lt;br /&gt;
**  `f T g`: trigger (dual to release)&lt;br /&gt;
&lt;br /&gt;
* Fairness operators &lt;br /&gt;
**  `WF(Op)` or `wf(Op)`: weak fairness, where ` Op` is an operation&lt;br /&gt;
**  `SF(Op)`or `sf(Op)`:  strong fairness, where ` Op` is an operation&lt;br /&gt;
**  `WEF`: weak fairness for all possible operations&lt;br /&gt;
**  `SEF`: strong fairness for all possible operations&lt;br /&gt;
&lt;br /&gt;
==Setting Fairness Constraints==&lt;br /&gt;
&lt;br /&gt;
Fairness is a notion where the search for counterexamples is restricted to paths that do not ignore infinitely the execution of a set of enabled operations imposed by the user as &amp;quot;fair&amp;quot; constraints. One possibility to set fairness constraints in ProB is to encode them in the LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula intended to be checked. For example, for a given LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &amp;quot;f&amp;quot; a set of weak fairness conditions {a1,…,an} can be given as follows: &lt;br /&gt;
 (FG e(a1) =&amp;gt; GF [a1]) &amp;amp; … &amp;amp; (FG e(an) =&amp;gt; GF [an]) =&amp;gt; f.&lt;br /&gt;
In a similar way, strong fairness constraints can be imposed expressed by means of an LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula:&lt;br /&gt;
 (GF e(a1) =&amp;gt; GF [a1]) &amp;amp; … &amp;amp; (GF e(an) =&amp;gt; GF [an]) =&amp;gt; f.&lt;br /&gt;
&lt;br /&gt;
Checking fairness in this way is very often considered to be inefficient as usually the number of atoms (the possible valuations of the property) of the LTL property is exponential in the size of the formula.&amp;lt;ref&amp;gt;O. Lichtenstein and A. Pnueli: &#039;&#039;Checking that Finite State Concurrent Programs Satisfy Their Linear Specification&#039;&#039;. POPL &#039;85, Proceedings of the 12th ACM SIGACT-SIGPLAN Symposium on Principles of Programming Languages, ACM, 1985&amp;lt;/ref&amp;gt; For this reason, the search algorithm of the LTL model checker has been extended in order to allow fairness to be checked efficiently. In addition, new operators have been added to the ProB’s LTL parser for setting fairness constraints to an LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; property. The new operators are &#039;&#039;WF(-)&#039;&#039; and &#039;&#039;SF(-)&#039;&#039; and both accept as argument an operation. The fairness constraints must be given by means of implication: &amp;quot;fair =&amp;gt; f&amp;quot;, where &amp;quot;f&amp;quot; is the property to be checked and &amp;quot;fair&amp;quot; the fairness constraints.&lt;br /&gt;
&lt;br /&gt;
In particular, &amp;quot;fair&amp;quot; can have one of the forms: &amp;quot;wfair&amp;quot;, &amp;quot;sfair&amp;quot;, &amp;quot;wfair &amp;amp; sfair&amp;quot;, and &amp;quot;sfair &amp;amp; wfair&amp;quot;, where &amp;quot;wfair&amp;quot; and &amp;quot;sfair&amp;quot; represent the imposed weak and strong fairness constraints, respectively.&lt;br /&gt;
&lt;br /&gt;
Basically, &amp;quot;wfair&amp;quot; and &amp;quot;sfair&amp;quot; are expressed by means of logical formulas having the following syntax:&lt;br /&gt;
&lt;br /&gt;
* Weak fair conditions (&amp;quot;wfair&amp;quot;):&lt;br /&gt;
** `WF(a)`, where `a` is an operation&lt;br /&gt;
** `&amp;amp;` and `or`: conjunction and disjunction&lt;br /&gt;
&lt;br /&gt;
* Strong fair conditions (&amp;quot;sfair&amp;quot;):&lt;br /&gt;
** `SF(a)`, where `a` is an operation&lt;br /&gt;
** `&amp;amp;` and `or`: conjunction and disjunction&lt;br /&gt;
&lt;br /&gt;
For instance, if we want to check an LTL property &amp;quot;f&amp;quot; on paths that are weak fair in regard to the operations &amp;quot;a&amp;quot; and &amp;quot;b&amp;quot; and additionally strong fair in regard to &amp;quot;c&amp;quot; or &amp;quot;d&amp;quot;, then this can be given as follows:&lt;br /&gt;
 (WF(a) &amp;amp; WF(b)) &amp;amp; (SF(c) or SF(d)) =&amp;gt; f&lt;br /&gt;
&lt;br /&gt;
Note that the operators &#039;&#039;WF(-)&#039;&#039; and &#039;&#039;SF(-)&#039;&#039; cannot appear on the right side of the fairness implication. Basically, &#039;&#039;WF(-)&#039;&#039; and &#039;&#039;SF(-)&#039;&#039; can be described by the following equivalences:&lt;br /&gt;
 WF(a) ≡ (FG e(a) =&amp;gt; GF [a]) and SF(a) ≡ (GF e(a) =&amp;gt; GF [a]), where a is an operation.&lt;br /&gt;
&lt;br /&gt;
For setting fairness constraints on all possible operations of the model being checked use the operators &amp;quot;WEF&amp;quot; and &amp;quot;SEF&amp;quot;. For instance, if &amp;quot;f&amp;quot; is a liveness property and we want to restrict the search only to strongly fair paths, then we can impose the fairness constraints by means of the formula &amp;quot;SEF =&amp;gt; f&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The grammar for imposing fairness constraints by means of the fairness implication (&amp;quot;fair =&amp;gt; f&amp;quot;) looks as follows:&lt;br /&gt;
&lt;br /&gt;
 fair ::= WEF | SEF | wfair | sfair | wfair &amp;amp; sfair | sfair &amp;amp; wfair&amp;lt;br/&amp;gt;&lt;br /&gt;
          wfair ::= wf(a) | ( wfair ) | wfair &amp;amp; wfair | wfair or wfair&amp;lt;br/&amp;gt;&lt;br /&gt;
          sfair ::= sf(a) | ( sfair ) | sfair &amp;amp; sfair | sfair or sfair&lt;br /&gt;
&lt;br /&gt;
where &amp;quot;a&amp;quot; is a transition proposition.&lt;br /&gt;
&lt;br /&gt;
==Storing LTL Assertions in the Model==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Storing LTL formulas in B machines&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
LTL formulas can be stored in the `DEFINITIONS` section of a B machine. The name of the definition must start with `ASSERT_LTL` and a string must be specified. In case there is more than one LTL assertion given in the ‘DEFINITIONS’ section, the particular LTL assertions must be separated by semicolon. For example: &lt;br /&gt;
&lt;br /&gt;
 DEFINITIONS &lt;br /&gt;
   ASSERT_LTL  == &amp;quot;G (e(SetCruiseSpeed) =&amp;gt; e(CruiseBecomesNotAllowed))&amp;quot;;&lt;br /&gt;
   ASSERT_LTL1 == &amp;quot;G (e(CruiseBecomesNotAllowed) =&amp;gt; e(SetCruiseSpeed))&amp;quot;;&lt;br /&gt;
   ASSERT_LTL2 == &amp;quot;G (e(CruiseBecomesNotAllowed) =&amp;gt; (ObstacleDisappears))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Storing LTL formulas in CSP-M specifications&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
LTL formulas can be stored within pragmas in CSP-M specifications. A pragma in which a single LTL formula is stored is given by &amp;quot;{-# assert_ltl &amp;quot;f&amp;quot; &amp;quot;c&amp;quot; #-}&amp;quot;, where &amp;quot;assert_ltl&amp;quot; indicates the type of the information stored in the pragma (there are currently two types: assert_ltl and assert_ctl), and is followed by the LTL formula `f` and a comment `c` (the comment is optional). Both, the LTL formula and the comment, must be enclosed in double quotes. &lt;br /&gt;
It is also possible to give several LTL formulas in a single pragma within which the corresponding LTL assertions are separated by semicolon. For example:&lt;br /&gt;
&lt;br /&gt;
 {-# assert_ltl &amp;quot;SF(enter.1) &amp;amp; WF(req.1) =&amp;gt; GF([enter.1])&amp;quot;;&lt;br /&gt;
     assert_ltl &amp;quot;SF(enter.2) &amp;amp; WF(req.2) =&amp;gt; GF([enter.2])&amp;quot;;&lt;br /&gt;
     assert_ltl &amp;quot;GF [enter.1] &amp;amp; GF [enter.2]&amp;quot; &amp;quot;Should fail.&amp;quot;#-}&lt;br /&gt;
&lt;br /&gt;
Note that a semicolon must not follow the last assertion in a pragma.&lt;br /&gt;
&lt;br /&gt;
For CSP-M specifications, it is also possible to assert LTL-formulae to particular processes in the model. This is possible by means of ``assert`` declarations, which have been recently included to the CSP-M grammar of the ProB CSP-M parser:&lt;br /&gt;
&lt;br /&gt;
 assert P |= LTL: &amp;quot;ltl-formula&amp;quot;,&lt;br /&gt;
 where `P` is an arbitrary process and `ltl-formula` an LTL formula.&lt;br /&gt;
&lt;br /&gt;
==LTL Formulas in a Separate File==&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB it is possible to check several LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formulae with one call. The command has the following syntax &lt;br /&gt;
 probcli -ltlfile FILE ... &lt;br /&gt;
The file FILE contains one or more sections where each section has the form &lt;br /&gt;
 [Name]  Formula &lt;br /&gt;
The formula itself can spread several lines. Additional comments can be added with a leading #. &lt;br /&gt;
If a counter-example is found, the trace of the counter-example is saved into the file ltlce_Name.trace, where &amp;quot;Name&amp;quot; is the name of the formula in the LTL file.&lt;br /&gt;
&lt;br /&gt;
One also can check a single LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &#039;&#039;F&#039;&#039; using the option &#039;-ltlformula&#039; as follows:&lt;br /&gt;
 probcli -ltlformula &amp;quot;F&amp;quot; ...&lt;br /&gt;
&lt;br /&gt;
==LTL Formulae in a Separate File==&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB it is possible to check several LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formulae with one call. The command has the following syntax &lt;br /&gt;
 probcli -ltlfile FILE ... &lt;br /&gt;
The file FILE contains one or more sections where each section has the form &lt;br /&gt;
 [Name]  Formula &lt;br /&gt;
The formula itself can spread in several lines. Additional comments can be added with a leading #.&lt;br /&gt;
If a counter-example is found, the trace of the counter-example is saved into the file ltlce_Name.trace, where &amp;quot;Name&amp;quot; is the name of the formula in the LTL file.&lt;br /&gt;
&lt;br /&gt;
One also can check a single LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &#039;&#039;F&#039;&#039; using the option &#039;-ltlformula&#039; as follows:&lt;br /&gt;
 probcli -ltlformula &amp;quot;F&amp;quot; ...&lt;br /&gt;
&lt;br /&gt;
==LTL Model Checker Output==&lt;br /&gt;
The output provided by the LTL model checker can sometimes reveal some interesting statistical facts about the model and the property being checked on the model. The LTL model checker of ProB uses the tableau approach for checking an LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula on a formal model. To check whether a model &#039;&#039;M&#039;&#039; satisfies a given formula &#039;&#039;f&#039;&#039;, the algorithm generates a search graph, called also tableau graph, composed from the tableau of the formula and the state space of the model. If there is a path in the search graph that is a model for &#039;&#039;f&#039;&#039;, then the formula is satisfiable. The nodes of the search graph are called &#039;&#039;atoms&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Basically, using the tableau approach we prove that &#039;&#039;M&#039;&#039; satisfies &#039;&#039;f&#039;&#039; by negating the given formula and searching for a path fulfilling &#039;&#039;¬f&#039;&#039;. If such a path is found, then we infer that &#039;&#039;M&#039;&#039; violates &#039;&#039;f&#039;&#039;. Otherwise, if no path is found that satisfies &#039;&#039;¬f&#039;&#039;, we conclude that &#039;&#039;M |= f&#039;&#039;. The LTL model checking algorithm of ProB is based on searching for strongly connected components (SCCs) with certain properties to determine whether &#039;&#039;M&#039;&#039; satisfies &#039;&#039;f&#039;&#039;. Finding such an SCC that can be reached from an initial state of &#039;&#039;M&#039;&#039; is a witness for a counter-example for &#039;&#039;f&#039;&#039;. Sometimes, we use fairness to ignore such SCCs that do not fulfill the imposed fairness constraints in order to not impede proving a property by returning of non-fair paths as counter-examples.&lt;br /&gt;
&lt;br /&gt;
The LTL model checker algorithm of ProB is implemented in C using a callback mechanism for evaluating the atomic propositions and the outgoing transitions in SICStus Prolog. (For each state of the model a callback will be performed.) Additionally, the search for SCCs is based on the Tarjan&#039;s algorithm. In the terminal all messages coming from the LTL model checker are preceded either by &amp;quot;LTL (current statistics): &amp;quot; or &amp;quot;LTL model checking:&amp;quot;. The output from the LTL model checker can give helpful insights about the model and the model checking process.&lt;br /&gt;
&lt;br /&gt;
Consider the CSP specifications &amp;quot;dphil_ltl8.csp&amp;quot; representing a model of the dining philosophers problem for eight philosophers which resolves the starvation problem by always forcing the first philosopher to pick up first the right fork instead of the left one. In other words, &amp;quot;dphil_ltl8.csp&amp;quot; has no deadlock states. Checking the LTL formula &amp;quot;GF [eat.0]&amp;quot; from the command line will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ probcli -ltlformula &amp;quot;GF [eat.0]&amp;quot; dphil_ltl8.csp&lt;br /&gt;
....&lt;br /&gt;
LTL model checking formula&lt;br /&gt;
% parsing_ltl_formula&lt;br /&gt;
% initialising_ltlc&lt;br /&gt;
starting_model_checking&lt;br /&gt;
&lt;br /&gt;
LTL (current statistics): 13280 atoms, 10070 transitions generated, and  2631 callbacks needed.&lt;br /&gt;
&lt;br /&gt;
LTL model checking: found counter-example (lasso-form): intro length = 1126, path in SCC of length = 5&lt;br /&gt;
LTL model checking: memory usage approx. 1924 KiB, 14104 atoms and 10724 transitions generated&lt;br /&gt;
LTL model checking: total time 22492ms, 2803 callbacks needed 22465ms, netto 26ms.&lt;br /&gt;
! An error occurred !&lt;br /&gt;
! source(ltl)&lt;br /&gt;
! Model Check Counter-Example found for: &lt;br /&gt;
! GF [eat.0]&lt;br /&gt;
&lt;br /&gt;
Formula FALSE.&lt;br /&gt;
&lt;br /&gt;
Runtime: 22220 ms&lt;br /&gt;
! *** error occurred ***&lt;br /&gt;
! ltl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As one can clearly see from the output, the LTL model checker fails to prove &amp;quot;GF [eat.0]&amp;quot; on the model since it has found a counter-example for the formula. Note that the ProB LTL model checker explores the search graph and the state space dynamically. The above data is to be understand as follows:&lt;br /&gt;
* 14104 atoms - the LTL model checker needed to explore 14104 atoms to find a counter-example for the formula. &lt;br /&gt;
* 2803 callbacks needed - to explore the search graph the model checker makes callbacks in order to explore the state space of the model being checked (the exploration runs dynamically) and compute the successor states in the tableau graph. In this case the model checker has needed to explore 2803 states till it finds a counter-example for the formula&lt;br /&gt;
* memory usage approx. 1924 KiB - the memory needed to explore the tableau graph&lt;br /&gt;
* found counter-example (lasso-form) - means that the counter-example being found is path beginning in an initial state of the model and reaching a state that closes a cycle:&lt;br /&gt;
** intro length = 1126: the length of the sub-path from an initial state to the entry point of the cycle&lt;br /&gt;
** path in SCC of length = 5: the cycle is comprised of five states&lt;br /&gt;
* total time 22492ms - the LTL model checker needed about 23 seconds to find the counter-example. Here a distinction between the time needed to explore the state space of the model (2803 callbacks needed 22465ms) and the time spent for generating the tableau graph + the time for identifying the self-fulfilling SCC (netto 26ms)&lt;br /&gt;
* LTL (current statistics) - an intermediate data information is given each 20 seconds spent from the last current data information.&lt;br /&gt;
&lt;br /&gt;
In the example above one can prove the LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &amp;quot;GF [eat.0]&amp;quot; on dphil_ltl6.csp using fairness. One can impose, for example, strong fairness conditions on all transitions of the model and thus verify that &amp;quot;GF [eat.0]&amp;quot; is satisfied under strong fairness. The call looks as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ probcli -ltlformula &amp;quot;SEF =&amp;gt; GF [eat.0]&amp;quot; dphil_ltl8.csp&lt;br /&gt;
...&lt;br /&gt;
LTL model checking formula&lt;br /&gt;
% parsing_ltl_formula&lt;br /&gt;
% initialising_ltlc&lt;br /&gt;
starting_model_checking&lt;br /&gt;
LTL (current statistics): 13016 atoms, 9834 transitions generated, and  2578 callbacks needed.&lt;br /&gt;
LTL (fairness): 0 strongly connected components were rejected, 0 callbacks needed.&lt;br /&gt;
&lt;br /&gt;
LTL (current statistics): 27540 atoms, 44422 transitions generated, and  5123 callbacks needed.&lt;br /&gt;
LTL (fairness): 284 strongly connected components were rejected, 843 callbacks needed.&lt;br /&gt;
.....&lt;br /&gt;
LTL (current statistics): 85980 atoms, 267821 transitions generated, and  19733 callbacks needed.&lt;br /&gt;
LTL (fairness): 454 strongly connected components were rejected, 1924 callbacks needed.&lt;br /&gt;
&lt;br /&gt;
LTL (current statistics): 95648 atoms, 364288 transitions generated, and  22150 callbacks needed.&lt;br /&gt;
LTL (fairness): 773 strongly connected components were rejected, 3085 callbacks needed.&lt;br /&gt;
&lt;br /&gt;
LTL model checking: memory usage approx. 13829 KiB, 96500 atoms and 381625 transitions generated&lt;br /&gt;
LTL model checking: total time 190887ms, 22363 callbacks needed 186690ms, netto 467ms.&lt;br /&gt;
LTL model checking (fairness): 800 strongly connected components were rejected.&lt;br /&gt;
LTL model checking (fairness): total fairness checking time 3729ms, 3246 callbacks needed 3452ms, netto 277ms.&lt;br /&gt;
LTL Formula TRUE.&lt;br /&gt;
No counter example found for SEF =&amp;gt; GF [eat.0].&lt;br /&gt;
Runtime: 188370 ms&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above check no fair counter-example could be found for the formula &amp;quot;GF [eat.0]&amp;quot;. For this check the search graph comprises 96500 atoms and 381625  transitions, far more than the previous formula check (without fairness assumptions). Since no fair counter-example was found we can infer that the whole state space of the model was explored. Further, since we know from above that 22363 callbacks were needed to explore the search graph, we can infer that the state space of the model has in total 22363 states.&lt;br /&gt;
&lt;br /&gt;
In the output above there is also some information about the fairness checking being performed for the model checker run. Form the fairness statistics we can see that the model checker has refuted 800 SCCs in total, i.e. there were 800 SCCs in the search graph that could serve as a counter-example for &amp;quot;GF [eat.0]&amp;quot; in case no fairness constraints were imposed.&lt;br /&gt;
&lt;br /&gt;
== Other Relevant Tutorials about LTL Model Checking ==&lt;br /&gt;
A brief tutorial on visualizing LTL counter-examples in the Rodin tool can be found [http://www.stups.uni-duesseldorf.de/ProB/index.php5/Tutorial_LTL_Counter-example_View here].&lt;br /&gt;
&lt;br /&gt;
A tutorial of a simple case study, where setting fairness constraints to some of the LTL properties is required, can be found [http://www.stups.uni-duesseldorf.de/ProB/index.php5/Mutual_Exclusion_%28Fairness%29 here].&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=LTL_Model_Checking&amp;diff=3572</id>
		<title>LTL Model Checking</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=LTL_Model_Checking&amp;diff=3572"/>
		<updated>2016-03-11T13:58:55Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* LTL Model Checker Output */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]__NOTOC__&lt;br /&gt;
ProB provides support for LTL (linear temporal logic) model checking. For an introduction to LTL see the [http://en.wikipedia.org/wiki/Linear_temporal_logic Wikipedia Article].&lt;br /&gt;
&lt;br /&gt;
To use this feature, select &amp;quot;Check LTL/CTL Assertions&amp;quot; in the &amp;quot;Verify&amp;quot; menu. The feature can also be accessed by the key combination &amp;quot;Ctrl+L&amp;quot; under Windows and Linux, and by the key combination &amp;quot;Cmd+L&amp;quot; under MacOS. The following window appears:&lt;br /&gt;
&lt;br /&gt;
[[File:ltlviewer.png]]&lt;br /&gt;
&lt;br /&gt;
All LTL formulas that are given in the &amp;quot;DEFINTIONS&amp;quot; section of a B machine are displayed in the list box of the LTL/CTL Assertions Viewer. For CSP-M specifications all LTL formulas given in the LTL pragmas of the loaded CSP-M file will be shown in the viewer. (For more detailed information of how LTL/CTL assertions can be stored into B and CSP-M models see Section &#039;&#039;&#039;Storing LTL Assertions into a Model&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
A new LTL formula can be entered in the entry below the list box. (We explain the supported syntax below). The typed formula can then be either added to the list box by clicking the &amp;quot;Add&amp;quot; button or directly checked by clicking the &amp;quot;Check&amp;quot; button. Before doing that assure whether you are in the proper frame (&amp;quot;Add LTL Formula&amp;quot;) of the bottom part of the LTL viewer.&lt;br /&gt;
&lt;br /&gt;
The LTL model checker can be started for an LTL formula by performing a double-click on the respective formula or typing &amp;quot;Enter&amp;quot; after selecting the respective formula. Each LTL formula in the list box has on the left hand side a symbol that indicates what is the status of the respective formula. An LTL formula can have one of the following statuses (status symbols may differ under different operating systems):&lt;br /&gt;
&lt;br /&gt;
* ? – The formula has not been checked yet.&lt;br /&gt;
* ✔ – The formula is true for all valid paths.&lt;br /&gt;
* ✘ – A counterexample for the formula has been found, i.e. there is a path that violates the formula. In case the formula has been just checked on the model the animator is navigated to the last state of the counterexample. The full path can then be seen in the history. The counterexample can be also obtained by the dotty-viewer after a second double-click on the formula in the assertions’ viewer. &lt;br /&gt;
* ⌚ – The formula is currently checked.&lt;br /&gt;
* ! – The formula check has been aborted by an unexpected error occurrence.&lt;br /&gt;
* ∞ – The formula check is incomplete, i.e. no counterexample was found so far, but the absence of a path that does not satisfy the formula can not be guaranteed because the state space was not fully explored. A new check can be started by a double-click.&lt;br /&gt;
&lt;br /&gt;
All formulas can be checked by &amp;quot;Assertions -&amp;gt; Check All Assertions&amp;quot; in the menu bar. All formulas will be then checked from top to bottom in the list box.&lt;br /&gt;
&lt;br /&gt;
Additionally, the viewer provides a context menu for the list box elements. The context menu can be popped-up by a right-mouse-click on a formula from the list box, and it performs a set of actions available to be performed on the currently selected formula (see Figure below). &lt;br /&gt;
&lt;br /&gt;
[[File:ltlviewercontext.png]]&lt;br /&gt;
&lt;br /&gt;
The old LTL and CTL dialogs can be accessed from &amp;quot;OldLtlViewers&amp;quot; in the menu bar.&lt;br /&gt;
&lt;br /&gt;
==LTL Preferences==&lt;br /&gt;
&lt;br /&gt;
There is a set of options coming with the LTL model checker. In this section we give a brief overview of the preferences. The LTL preferences can be viewed by selecting &amp;quot;LTL Preferences&amp;quot; in the &amp;quot;Preferences&amp;quot; menu of the LTL/CTL Assertions Viewer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Exploring new states&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
The LTL model checker searches in the already explored search space of the model. If a state is encountered that has not been explored before, the state will be explored (i.e. all transitions to successor states are computed). The number of how often this can happen is limited by the field &amp;quot;Max no. of new states&amp;quot;. &lt;br /&gt;
Depending on the LTL formula, a partially explored state space can be sufficient to find a counterexample or to assure the absence of a counterexample. If there&#039;s still the possibility of a counterexample in the remaining unexplored state space, the user will get a message. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Optimizing the process of LTL model checking&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
The process of model checking can be optimized for B and Event-B models by using partial order reduction. The idea of partial order reduction is to execute only a subset of all enabled actions in each state. Thus, only a part of the original state space is checked for the checked property. The reduction of the state space depends on the number of concurrent and independent actions in the model, as well as on the property being checked.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Search Options&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
The model checker searches for a counterexample (i.e. a path that does not satisfy the current formula). Where the checked paths through the model&#039;s search space start depend on the following options in the LTL Preferences’ menu:&lt;br /&gt;
# &#039;&#039;Start search in initialization&#039;&#039;&amp;lt;br/&amp;gt;All paths that start in a state of the initialization of the machine are checked. &lt;br /&gt;
# &#039;&#039;Start search in current state&#039;&#039;&amp;lt;br/&amp;gt;All paths that start in the current state are checked. &lt;br /&gt;
# &#039;&#039;Start in initialization, but check formula in current state&#039;&#039;&amp;lt;br/&amp;gt;All paths that start in a state of the initialization of the machine are checked, but the formula is mapped to the current state. For example, this option can be used to check properties like &amp;quot;Is this state only reachable directly after executing operation `xy`?&amp;quot;: The formula would be `Y[xy]`. This is equivalent to &amp;quot;G (current =&amp;gt; f)&amp;quot; with f as the entered formula and using the option &amp;quot;Start search in initialization&amp;quot;. &lt;br /&gt;
Note: Whereas `Y true` is always false when checked with option 1 or 2, it is usually true (but not in all cases) for option 3.&lt;br /&gt;
&lt;br /&gt;
=== Supported Syntax ===&lt;br /&gt;
&lt;br /&gt;
ProB supports LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt;, an extended version of LTL. In contrast to the standard LTL, LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; provides also support for propositions on transitions, not only on states. In practice,  writing propositions on transitions is allowed by using the constructs `e(...)` and `[...]`. (see below). The LTL model checker of ProB supports Past-LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; as well.&lt;br /&gt;
&lt;br /&gt;
* Atomic propositions can be one of the following:&lt;br /&gt;
**  Predicates can be written in curly braces: `{...}`. E.g. `{card(someset) &amp;gt; 1}`&lt;br /&gt;
**  To check if an operation is enabled in a state use `e(Op)`, where `Op` is the name of the operation.&lt;br /&gt;
**  To start a search from the current state of the animation use `current` (see the section &#039;&#039;&#039;LTL Preferences&#039;&#039;&#039; for more information).&lt;br /&gt;
**  To check if a state has no outgoing transition leading to a different state use `sink`. This can be useful for finding &amp;quot;pseudo&amp;quot;-deadlocks, i.e. states where only query-operations are enabled that do not change the state. Note that `sink` holds for deadlock states as well.&lt;br /&gt;
** For checking if a state is a deadlock state the atomic proposition ` deadlock ` can be used.&lt;br /&gt;
**  To check if a set of operations is disabled in a state use `deadlock(Op1,Op2,...,Opk)`, where Op1,Op2,...,Opk with k&amp;gt;0 are operations of the model. It is also possible to check if specific representations of an operation with arguments are disabled in a state using pattern-matching, e.g.: `deadlock(Op(1),Op(3))`.&lt;br /&gt;
** By means of `deterministic(Op1,Op2,...,Opk)`, where Op1,Op2,...,Opk with k&amp;gt;0 are operations of the model, one can check if maximum one of the operations Op1,Op2,...,Opk is enabled in a state. &lt;br /&gt;
** To check if exactly one operation from a set of operations Op1,Op2,...,Opk is enabled in a state use `controller(Op1,Op2,…,Opk)`.&lt;br /&gt;
&lt;br /&gt;
* Transition propositions:&amp;lt;br&amp;gt;If the next executed operation in the path is `Op`, the expression `[Op]` can be used. Also patter-matching for the arguments of the operation is supported. E.g. `[Op(3,4*v)]` checks if the next operation is `Op` and that the first argument is 3 and the third argument is `4*v` where `v` is a variable of the machine. &amp;lt;br&amp;gt; Arbitrary B expressions can be used as patterns. Constants and variables of the machine can be used. Variables have the values of the state where the operations starts.&lt;br /&gt;
&lt;br /&gt;
* Logical operators&lt;br /&gt;
** `true` and `false`&lt;br /&gt;
**  `not`: negation&lt;br /&gt;
**  `&amp;amp;`, `or` and `=&amp;gt;`: conjunction, disjunction and implication&lt;br /&gt;
&lt;br /&gt;
* Temporal operators (future)&lt;br /&gt;
**  `G f`: globally&lt;br /&gt;
**  `F f`: finally&lt;br /&gt;
**  `X f`: next&lt;br /&gt;
**  `f U g`: until&lt;br /&gt;
**  `f W g`: weak until&lt;br /&gt;
**  `f R g`: release&lt;br /&gt;
&lt;br /&gt;
* Temporal operators (past)&lt;br /&gt;
**  `H f`: history (dual to G)&lt;br /&gt;
**  `O f`: once (dual to F)&lt;br /&gt;
**  `Y f`: yesterday (dual to X)&lt;br /&gt;
**  `f S g`: since (dual to until)&lt;br /&gt;
**  `f T g`: trigger (dual to release)&lt;br /&gt;
&lt;br /&gt;
* Fairness operators &lt;br /&gt;
**  `WF(Op)` or `wf(Op)`: weak fairness, where ` Op` is an operation&lt;br /&gt;
**  `SF(Op)`or `sf(Op)`:  strong fairness, where ` Op` is an operation&lt;br /&gt;
**  `WEF`: weak fairness for all possible operations&lt;br /&gt;
**  `SEF`: strong fairness for all possible operations&lt;br /&gt;
&lt;br /&gt;
==Setting Fairness Constraints==&lt;br /&gt;
&lt;br /&gt;
Fairness is a notion where the search for counterexamples is restricted to paths that do not ignore infinitely the execution of a set of enabled operations imposed by the user as &amp;quot;fair&amp;quot; constraints. One possibility to set fairness constraints in ProB is to encode them in the LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula intended to be checked. For example, for a given LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &amp;quot;f&amp;quot; a set of weak fairness conditions {a1,…,an} can be given as follows: &lt;br /&gt;
 (FG e(a1) =&amp;gt; GF [a1]) &amp;amp; … &amp;amp; (FG e(an) =&amp;gt; GF [an]) =&amp;gt; f.&lt;br /&gt;
In a similar way, strong fairness constraints can be imposed expressed by means of an LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula:&lt;br /&gt;
 (GF e(a1) =&amp;gt; GF [a1]) &amp;amp; … &amp;amp; (GF e(an) =&amp;gt; GF [an]) =&amp;gt; f.&lt;br /&gt;
&lt;br /&gt;
Checking fairness in this way is very often considered to be inefficient as usually the number of atoms (the possible valuations of the property) of the LTL property is exponential in the size of the formula.&amp;lt;ref&amp;gt;O. Lichtenstein and A. Pnueli: &#039;&#039;Checking that Finite State Concurrent Programs Satisfy Their Linear Specification&#039;&#039;. POPL &#039;85, Proceedings of the 12th ACM SIGACT-SIGPLAN Symposium on Principles of Programming Languages, ACM, 1985&amp;lt;/ref&amp;gt; For this reason, the search algorithm of the LTL model checker has been extended in order to allow fairness to be checked efficiently. In addition, new operators have been added to the ProB’s LTL parser for setting fairness constraints to an LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; property. The new operators are &#039;&#039;WF(-)&#039;&#039; and &#039;&#039;SF(-)&#039;&#039; and both accept as argument an operation. The fairness constraints must be given by means of implication: &amp;quot;fair =&amp;gt; f&amp;quot;, where &amp;quot;f&amp;quot; is the property to be checked and &amp;quot;fair&amp;quot; the fairness constraints.&lt;br /&gt;
&lt;br /&gt;
In particular, &amp;quot;fair&amp;quot; can have one of the forms: &amp;quot;wfair&amp;quot;, &amp;quot;sfair&amp;quot;, &amp;quot;wfair &amp;amp; sfair&amp;quot;, and &amp;quot;sfair &amp;amp; wfair&amp;quot;, where &amp;quot;wfair&amp;quot; and &amp;quot;sfair&amp;quot; represent the imposed weak and strong fairness constraints, respectively.&lt;br /&gt;
&lt;br /&gt;
Basically, &amp;quot;wfair&amp;quot; and &amp;quot;sfair&amp;quot; are expressed by means of logical formulas having the following syntax:&lt;br /&gt;
&lt;br /&gt;
* Weak fair conditions (&amp;quot;wfair&amp;quot;):&lt;br /&gt;
** `WF(a)`, where `a` is an operation&lt;br /&gt;
** `&amp;amp;` and `or`: conjunction and disjunction&lt;br /&gt;
&lt;br /&gt;
* Strong fair conditions (&amp;quot;sfair&amp;quot;):&lt;br /&gt;
** `SF(a)`, where `a` is an operation&lt;br /&gt;
** `&amp;amp;` and `or`: conjunction and disjunction&lt;br /&gt;
&lt;br /&gt;
For instance, if we want to check an LTL property &amp;quot;f&amp;quot; on paths that are weak fair in regard to the operations &amp;quot;a&amp;quot; and &amp;quot;b&amp;quot; and additionally strong fair in regard to &amp;quot;c&amp;quot; or &amp;quot;d&amp;quot;, then this can be given as follows:&lt;br /&gt;
 (WF(a) &amp;amp; WF(b)) &amp;amp; (SF(c) or SF(d)) =&amp;gt; f&lt;br /&gt;
&lt;br /&gt;
Note that the operators &#039;&#039;WF(-)&#039;&#039; and &#039;&#039;SF(-)&#039;&#039; cannot appear on the right side of the fairness implication. Basically, &#039;&#039;WF(-)&#039;&#039; and &#039;&#039;SF(-)&#039;&#039; can be described by the following equivalences:&lt;br /&gt;
 WF(a) ≡ (FG e(a) =&amp;gt; GF [a]) and SF(a) ≡ (GF e(a) =&amp;gt; GF [a]), where a is an operation.&lt;br /&gt;
&lt;br /&gt;
For setting fairness constraints on all possible operations of the model being checked use the operators &amp;quot;WEF&amp;quot; and &amp;quot;SEF&amp;quot;. For instance, if &amp;quot;f&amp;quot; is a liveness property and we want to restrict the search only to strongly fair paths, then we can impose the fairness constraints by means of the formula &amp;quot;SEF =&amp;gt; f&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The grammar for imposing fairness constraints by means of the fairness implication (&amp;quot;fair =&amp;gt; f&amp;quot;) looks as follows:&lt;br /&gt;
&lt;br /&gt;
 fair ::= WEF | SEF | wfair | sfair | wfair &amp;amp; sfair | sfair &amp;amp; wfair&amp;lt;br/&amp;gt;&lt;br /&gt;
          wfair ::= wf(a) | ( wfair ) | wfair &amp;amp; wfair | wfair or wfair&amp;lt;br/&amp;gt;&lt;br /&gt;
          sfair ::= sf(a) | ( sfair ) | sfair &amp;amp; sfair | sfair or sfair&lt;br /&gt;
&lt;br /&gt;
where &amp;quot;a&amp;quot; is a transition proposition.&lt;br /&gt;
&lt;br /&gt;
==Storing LTL Assertions in the Model==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Storing LTL formulas in B machines&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
LTL formulas can be stored in the `DEFINITIONS` section of a B machine. The name of the definition must start with `ASSERT_LTL` and a string must be specified. In case there is more than one LTL assertion given in the ‘DEFINITIONS’ section, the particular LTL assertions must be separated by semicolon. For example: &lt;br /&gt;
&lt;br /&gt;
 DEFINITIONS &lt;br /&gt;
   ASSERT_LTL  == &amp;quot;G (e(SetCruiseSpeed) =&amp;gt; e(CruiseBecomesNotAllowed))&amp;quot;;&lt;br /&gt;
   ASSERT_LTL1 == &amp;quot;G (e(CruiseBecomesNotAllowed) =&amp;gt; e(SetCruiseSpeed))&amp;quot;;&lt;br /&gt;
   ASSERT_LTL2 == &amp;quot;G (e(CruiseBecomesNotAllowed) =&amp;gt; (ObstacleDisappears))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Storing LTL formulas in CSP-M specifications&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
LTL formulas can be stored within pragmas in CSP-M specifications. A pragma in which a single LTL formula is stored is given by &amp;quot;{-# assert_ltl &amp;quot;f&amp;quot; &amp;quot;c&amp;quot; #-}&amp;quot;, where &amp;quot;assert_ltl&amp;quot; indicates the type of the information stored in the pragma (there are currently two types: assert_ltl and assert_ctl), and is followed by the LTL formula `f` and a comment `c` (the comment is optional). Both, the LTL formula and the comment, must be enclosed in double quotes. &lt;br /&gt;
It is also possible to give several LTL formulas in a single pragma within which the corresponding LTL assertions are separated by semicolon. For example:&lt;br /&gt;
&lt;br /&gt;
 {-# assert_ltl &amp;quot;SF(enter.1) &amp;amp; WF(req.1) =&amp;gt; GF([enter.1])&amp;quot;;&lt;br /&gt;
     assert_ltl &amp;quot;SF(enter.2) &amp;amp; WF(req.2) =&amp;gt; GF([enter.2])&amp;quot;;&lt;br /&gt;
     assert_ltl &amp;quot;GF [enter.1] &amp;amp; GF [enter.2]&amp;quot; &amp;quot;Should fail.&amp;quot;#-}&lt;br /&gt;
&lt;br /&gt;
Note that a semicolon must not follow the last assertion in a pragma.&lt;br /&gt;
&lt;br /&gt;
For CSP-M specifications, it is also possible to assert LTL-formulae to particular processes in the model. This is possible by means of ``assert`` declarations, which have been recently included to the CSP-M grammar of the ProB CSP-M parser:&lt;br /&gt;
&lt;br /&gt;
 assert P |= LTL: &amp;quot;ltl-formula&amp;quot;,&lt;br /&gt;
 where `P` is an arbitrary process and `ltl-formula` an LTL formula.&lt;br /&gt;
&lt;br /&gt;
==LTL Formulas in a Separate File==&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB it is possible to check several LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formulae with one call. The command has the following syntax &lt;br /&gt;
 probcli -ltlfile FILE ... &lt;br /&gt;
The file FILE contains one or more sections where each section has the form &lt;br /&gt;
 [Name]  Formula &lt;br /&gt;
The formula itself can spread several lines. Additional comments can be added with a leading #. &lt;br /&gt;
If a counter-example is found, the trace of the counter-example is saved into the file ltlce_Name.trace, where &amp;quot;Name&amp;quot; is the name of the formula in the LTL file.&lt;br /&gt;
&lt;br /&gt;
One also can check a single LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &#039;&#039;F&#039;&#039; using the option &#039;-ltlformula&#039; as follows:&lt;br /&gt;
 probcli -ltlformula &amp;quot;F&amp;quot; ...&lt;br /&gt;
&lt;br /&gt;
==LTL Formulae in a Separate File==&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB it is possible to check several LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formulae with one call. The command has the following syntax &lt;br /&gt;
 probcli -ltlfile FILE ... &lt;br /&gt;
The file FILE contains one or more sections where each section has the form &lt;br /&gt;
 [Name]  Formula &lt;br /&gt;
The formula itself can spread in several lines. Additional comments can be added with a leading #.&lt;br /&gt;
If a counter-example is found, the trace of the counter-example is saved into the file ltlce_Name.trace, where &amp;quot;Name&amp;quot; is the name of the formula in the LTL file.&lt;br /&gt;
&lt;br /&gt;
One also can check a single LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &#039;&#039;F&#039;&#039; using the option &#039;-ltlformula&#039; as follows:&lt;br /&gt;
 probcli -ltlformula &amp;quot;F&amp;quot; ...&lt;br /&gt;
&lt;br /&gt;
==LTL Model Checker Output==&lt;br /&gt;
The output provided by the LTL model checker can sometimes reveal some interesting statistical facts about the model and the property being checked on the model. The LTL model checker of ProB uses the tableau approach for checking an LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula on a formal model. To check whether a model &#039;&#039;M&#039;&#039; satisfies a given formula &#039;&#039;f&#039;&#039;, the algorithm generates a search graph, called also tableau graph, composed from the tableau of the formula and the state space of the model. If there is a path in the search graph that is a model for &#039;&#039;f&#039;&#039;, then the formula is satisfiable. The nodes of the search graph are called &#039;&#039;atoms&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Basically, using the tableau approach we prove that &#039;&#039;M&#039;&#039; satisfies &#039;&#039;f&#039;&#039; by negating the given formula and searching for a path fulfilling &#039;&#039;¬f&#039;&#039;. If such a path is found, then we infer that &#039;&#039;M&#039;&#039; violates &#039;&#039;f&#039;&#039;. Otherwise, if no path is found that satisfies &#039;&#039;¬f&#039;&#039;, we conclude that &#039;&#039;M |= f&#039;&#039;. The LTL model checking algorithm of ProB is based on searching for strongly connected components (SCCs) with certain properties to determine whether &#039;&#039;M&#039;&#039; satisfies &#039;&#039;f&#039;&#039;. Finding such an SCC that can be reached from an initial state of &#039;&#039;M&#039;&#039; is a witness for a counter-example for &#039;&#039;f&#039;&#039;. Sometimes, we use fairness to ignore such SCCs that do not fulfill the imposed fairness constraints in order to not impede proving a property by returning of non-fair paths as counter-examples.&lt;br /&gt;
&lt;br /&gt;
The LTL model checker algorithm of ProB is implemented in C using a callback mechanism for evaluating the atomic propositions and the outgoing transitions in SICStus Prolog. (For each state of the model a callback will be performed.) Additionally, the search for SCCs is based on the Tarjan&#039;s algorithm. In the terminal all messages coming from the LTL model checker are preceded either by &amp;quot;LTL (current statistics): &amp;quot; or &amp;quot;LTL model checking:&amp;quot;. The output from the LTL model checker can give helpful insights about the model and the model checking process.&lt;br /&gt;
&lt;br /&gt;
Consider the CSP specifications &amp;quot;dphil_ltl8.csp&amp;quot; representing a model of the dining philosophers problem for eight philosophers which resolves the starvation problem by always forcing the first philosopher to pick up first the right fork instead of the left one. In other words, &amp;quot;dphil_ltl8.csp&amp;quot; has no deadlock states. Checking the LTL formula &amp;quot;GF [eat.0]&amp;quot; from the command line will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ probcli -ltlformula &amp;quot;GF [eat.0]&amp;quot; dphil_ltl8.csp&lt;br /&gt;
....&lt;br /&gt;
LTL model checking formula&lt;br /&gt;
% parsing_ltl_formula&lt;br /&gt;
% initialising_ltlc&lt;br /&gt;
starting_model_checking&lt;br /&gt;
&lt;br /&gt;
LTL (current statistics): 13280 atoms, 10070 transitions generated, and  2631 callbacks needed.&lt;br /&gt;
&lt;br /&gt;
LTL model checking: found counter-example (lasso-form): intro length = 1126, path in SCC of length = 5&lt;br /&gt;
LTL model checking: memory usage approx. 1924 KiB, 14104 atoms and 10724 transitions generated&lt;br /&gt;
LTL model checking: total time 22492ms, 2803 callbacks needed 22465ms, netto 26ms.&lt;br /&gt;
! An error occurred !&lt;br /&gt;
! source(ltl)&lt;br /&gt;
! Model Check Counter-Example found for: &lt;br /&gt;
! GF [eat.0]&lt;br /&gt;
&lt;br /&gt;
Formula FALSE.&lt;br /&gt;
&lt;br /&gt;
Runtime: 22220 ms&lt;br /&gt;
! *** error occurred ***&lt;br /&gt;
! ltl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As one can clearly see from the output, the LTL model checker fails to prove &amp;quot;GF [eat.0]&amp;quot; on the model since it has found a counter-example for the formula. Note that the ProB LTL model checker explores the search graph and the state space dynamically. The above data is to be understand as follows:&lt;br /&gt;
* 14104 atoms - the LTL model checker needed to explore 14104 atoms to find a counter-example for the formula. &lt;br /&gt;
* 2803 callbacks needed - to explore the search graph the model checker makes callbacks in order to explore the state space of the model being checked (the exploration runs dynamically) and compute the successor states in the tableau graph. In this case the model checker has needed to explore 2803 states till it finds a counter-example for the formula&lt;br /&gt;
* memory usage approx. 1924 KiB - the memory needed to explore the tableau graph&lt;br /&gt;
* found counter-example (lasso-form) - means that the counter-example being found is path beginning in an initial state of the model and reaching a state that closes a cycle:&lt;br /&gt;
** intro length = 1126: the length of the sub-path from an initial state to the entry point of the cycle&lt;br /&gt;
** path in SCC of length = 5: the cycle is comprised of five states&lt;br /&gt;
* total time 22492ms - the LTL model checker needed about 23 seconds to find the counter-example. Here a distinction between the time needed to explore the state space of the model (2803 callbacks needed 22465ms) and the time spent for generating the tableau graph + the time for identifying the self-fulfilling SCC (netto 26ms)&lt;br /&gt;
* LTL (current statistics) - an intermediate data information is given each 20 seconds spent from the last current data information.&lt;br /&gt;
&lt;br /&gt;
In the example above one can prove the LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &amp;quot;GF [eat.0]&amp;quot; on dphil_ltl6.csp using fairness. One can impose, for example, strong fairness conditions on all transitions of the model and thus verify that &amp;quot;GF [eat.0]&amp;quot; is satisfied under strong fairness. The call looks as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ probcli -ltlformula &amp;quot;SEF =&amp;gt; GF [eat.0]&amp;quot; dphil_ltl8.csp&lt;br /&gt;
...&lt;br /&gt;
LTL model checking formula&lt;br /&gt;
% parsing_ltl_formula&lt;br /&gt;
% initialising_ltlc&lt;br /&gt;
starting_model_checking&lt;br /&gt;
LTL (current statistics): 13016 atoms, 9834 transitions generated, and  2578 callbacks needed.&lt;br /&gt;
LTL (fairness): 0 strongly connected components were rejected, 0 callbacks needed.&lt;br /&gt;
&lt;br /&gt;
LTL (current statistics): 27540 atoms, 44422 transitions generated, and  5123 callbacks needed.&lt;br /&gt;
LTL (fairness): 284 strongly connected components were rejected, 843 callbacks needed.&lt;br /&gt;
.....&lt;br /&gt;
LTL (current statistics): 85980 atoms, 267821 transitions generated, and  19733 callbacks needed.&lt;br /&gt;
LTL (fairness): 454 strongly connected components were rejected, 1924 callbacks needed.&lt;br /&gt;
&lt;br /&gt;
LTL (current statistics): 95648 atoms, 364288 transitions generated, and  22150 callbacks needed.&lt;br /&gt;
LTL (fairness): 773 strongly connected components were rejected, 3085 callbacks needed.&lt;br /&gt;
&lt;br /&gt;
LTL model checking: memory usage approx. 13829 KiB, 96500 atoms and 381625 transitions generated&lt;br /&gt;
LTL model checking: total time 190887ms, 22363 callbacks needed 186690ms, netto 467ms.&lt;br /&gt;
LTL model checking (fairness): 800 strongly connected components were rejected.&lt;br /&gt;
LTL model checking (fairness): total fairness checking time 3729ms, 3246 callbacks needed 3452ms, netto 277ms.&lt;br /&gt;
LTL Formula TRUE.&lt;br /&gt;
No counter example found for SEF =&amp;gt; GF [eat.0].&lt;br /&gt;
Runtime: 188370 ms&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above check no fair counter-example could be find for the formula &amp;quot;GF [eat.0]&amp;quot;. For this check the search graph comprises 96500 atoms and 381625  transitions, far more than the previous formula check (without fairness assumptions). Since no fair counter-example was found we can infer that the whole state space of the model was explored. Further, since we know from above that 22363 callbacks were needed to explore the search graph, we can infer that the state space of the model has in total 22363 states.&lt;br /&gt;
&lt;br /&gt;
In the output above there is also some information about the fairness checking being performed for the model checker run. Form the fairness statistics we can see that the model checker has refuted 800 SCCs in total, i.e. there were 800 SCCs in the search graph that could serve as a counter-example for &amp;quot;GF [eat.0]&amp;quot; in case no fairness constraints were imposed.&lt;br /&gt;
&lt;br /&gt;
== Other Relevant Tutorials about LTL Model Checking ==&lt;br /&gt;
A brief tutorial on visualizing LTL counter-examples in the Rodin tool can be found [http://www.stups.uni-duesseldorf.de/ProB/index.php5/Tutorial_LTL_Counter-example_View here].&lt;br /&gt;
&lt;br /&gt;
A tutorial of a simple case study, where setting fairness constraints to some of the LTL properties is required, can be found [http://www.stups.uni-duesseldorf.de/ProB/index.php5/Mutual_Exclusion_%28Fairness%29 here].&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=LTL_Model_Checking&amp;diff=3571</id>
		<title>LTL Model Checking</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=LTL_Model_Checking&amp;diff=3571"/>
		<updated>2016-03-11T13:48:24Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* LTL Model Checker Output */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]__NOTOC__&lt;br /&gt;
ProB provides support for LTL (linear temporal logic) model checking. For an introduction to LTL see the [http://en.wikipedia.org/wiki/Linear_temporal_logic Wikipedia Article].&lt;br /&gt;
&lt;br /&gt;
To use this feature, select &amp;quot;Check LTL/CTL Assertions&amp;quot; in the &amp;quot;Verify&amp;quot; menu. The feature can also be accessed by the key combination &amp;quot;Ctrl+L&amp;quot; under Windows and Linux, and by the key combination &amp;quot;Cmd+L&amp;quot; under MacOS. The following window appears:&lt;br /&gt;
&lt;br /&gt;
[[File:ltlviewer.png]]&lt;br /&gt;
&lt;br /&gt;
All LTL formulas that are given in the &amp;quot;DEFINTIONS&amp;quot; section of a B machine are displayed in the list box of the LTL/CTL Assertions Viewer. For CSP-M specifications all LTL formulas given in the LTL pragmas of the loaded CSP-M file will be shown in the viewer. (For more detailed information of how LTL/CTL assertions can be stored into B and CSP-M models see Section &#039;&#039;&#039;Storing LTL Assertions into a Model&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
A new LTL formula can be entered in the entry below the list box. (We explain the supported syntax below). The typed formula can then be either added to the list box by clicking the &amp;quot;Add&amp;quot; button or directly checked by clicking the &amp;quot;Check&amp;quot; button. Before doing that assure whether you are in the proper frame (&amp;quot;Add LTL Formula&amp;quot;) of the bottom part of the LTL viewer.&lt;br /&gt;
&lt;br /&gt;
The LTL model checker can be started for an LTL formula by performing a double-click on the respective formula or typing &amp;quot;Enter&amp;quot; after selecting the respective formula. Each LTL formula in the list box has on the left hand side a symbol that indicates what is the status of the respective formula. An LTL formula can have one of the following statuses (status symbols may differ under different operating systems):&lt;br /&gt;
&lt;br /&gt;
* ? – The formula has not been checked yet.&lt;br /&gt;
* ✔ – The formula is true for all valid paths.&lt;br /&gt;
* ✘ – A counterexample for the formula has been found, i.e. there is a path that violates the formula. In case the formula has been just checked on the model the animator is navigated to the last state of the counterexample. The full path can then be seen in the history. The counterexample can be also obtained by the dotty-viewer after a second double-click on the formula in the assertions’ viewer. &lt;br /&gt;
* ⌚ – The formula is currently checked.&lt;br /&gt;
* ! – The formula check has been aborted by an unexpected error occurrence.&lt;br /&gt;
* ∞ – The formula check is incomplete, i.e. no counterexample was found so far, but the absence of a path that does not satisfy the formula can not be guaranteed because the state space was not fully explored. A new check can be started by a double-click.&lt;br /&gt;
&lt;br /&gt;
All formulas can be checked by &amp;quot;Assertions -&amp;gt; Check All Assertions&amp;quot; in the menu bar. All formulas will be then checked from top to bottom in the list box.&lt;br /&gt;
&lt;br /&gt;
Additionally, the viewer provides a context menu for the list box elements. The context menu can be popped-up by a right-mouse-click on a formula from the list box, and it performs a set of actions available to be performed on the currently selected formula (see Figure below). &lt;br /&gt;
&lt;br /&gt;
[[File:ltlviewercontext.png]]&lt;br /&gt;
&lt;br /&gt;
The old LTL and CTL dialogs can be accessed from &amp;quot;OldLtlViewers&amp;quot; in the menu bar.&lt;br /&gt;
&lt;br /&gt;
==LTL Preferences==&lt;br /&gt;
&lt;br /&gt;
There is a set of options coming with the LTL model checker. In this section we give a brief overview of the preferences. The LTL preferences can be viewed by selecting &amp;quot;LTL Preferences&amp;quot; in the &amp;quot;Preferences&amp;quot; menu of the LTL/CTL Assertions Viewer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Exploring new states&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
The LTL model checker searches in the already explored search space of the model. If a state is encountered that has not been explored before, the state will be explored (i.e. all transitions to successor states are computed). The number of how often this can happen is limited by the field &amp;quot;Max no. of new states&amp;quot;. &lt;br /&gt;
Depending on the LTL formula, a partially explored state space can be sufficient to find a counterexample or to assure the absence of a counterexample. If there&#039;s still the possibility of a counterexample in the remaining unexplored state space, the user will get a message. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Optimizing the process of LTL model checking&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
The process of model checking can be optimized for B and Event-B models by using partial order reduction. The idea of partial order reduction is to execute only a subset of all enabled actions in each state. Thus, only a part of the original state space is checked for the checked property. The reduction of the state space depends on the number of concurrent and independent actions in the model, as well as on the property being checked.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Search Options&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
The model checker searches for a counterexample (i.e. a path that does not satisfy the current formula). Where the checked paths through the model&#039;s search space start depend on the following options in the LTL Preferences’ menu:&lt;br /&gt;
# &#039;&#039;Start search in initialization&#039;&#039;&amp;lt;br/&amp;gt;All paths that start in a state of the initialization of the machine are checked. &lt;br /&gt;
# &#039;&#039;Start search in current state&#039;&#039;&amp;lt;br/&amp;gt;All paths that start in the current state are checked. &lt;br /&gt;
# &#039;&#039;Start in initialization, but check formula in current state&#039;&#039;&amp;lt;br/&amp;gt;All paths that start in a state of the initialization of the machine are checked, but the formula is mapped to the current state. For example, this option can be used to check properties like &amp;quot;Is this state only reachable directly after executing operation `xy`?&amp;quot;: The formula would be `Y[xy]`. This is equivalent to &amp;quot;G (current =&amp;gt; f)&amp;quot; with f as the entered formula and using the option &amp;quot;Start search in initialization&amp;quot;. &lt;br /&gt;
Note: Whereas `Y true` is always false when checked with option 1 or 2, it is usually true (but not in all cases) for option 3.&lt;br /&gt;
&lt;br /&gt;
=== Supported Syntax ===&lt;br /&gt;
&lt;br /&gt;
ProB supports LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt;, an extended version of LTL. In contrast to the standard LTL, LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; provides also support for propositions on transitions, not only on states. In practice,  writing propositions on transitions is allowed by using the constructs `e(...)` and `[...]`. (see below). The LTL model checker of ProB supports Past-LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; as well.&lt;br /&gt;
&lt;br /&gt;
* Atomic propositions can be one of the following:&lt;br /&gt;
**  Predicates can be written in curly braces: `{...}`. E.g. `{card(someset) &amp;gt; 1}`&lt;br /&gt;
**  To check if an operation is enabled in a state use `e(Op)`, where `Op` is the name of the operation.&lt;br /&gt;
**  To start a search from the current state of the animation use `current` (see the section &#039;&#039;&#039;LTL Preferences&#039;&#039;&#039; for more information).&lt;br /&gt;
**  To check if a state has no outgoing transition leading to a different state use `sink`. This can be useful for finding &amp;quot;pseudo&amp;quot;-deadlocks, i.e. states where only query-operations are enabled that do not change the state. Note that `sink` holds for deadlock states as well.&lt;br /&gt;
** For checking if a state is a deadlock state the atomic proposition ` deadlock ` can be used.&lt;br /&gt;
**  To check if a set of operations is disabled in a state use `deadlock(Op1,Op2,...,Opk)`, where Op1,Op2,...,Opk with k&amp;gt;0 are operations of the model. It is also possible to check if specific representations of an operation with arguments are disabled in a state using pattern-matching, e.g.: `deadlock(Op(1),Op(3))`.&lt;br /&gt;
** By means of `deterministic(Op1,Op2,...,Opk)`, where Op1,Op2,...,Opk with k&amp;gt;0 are operations of the model, one can check if maximum one of the operations Op1,Op2,...,Opk is enabled in a state. &lt;br /&gt;
** To check if exactly one operation from a set of operations Op1,Op2,...,Opk is enabled in a state use `controller(Op1,Op2,…,Opk)`.&lt;br /&gt;
&lt;br /&gt;
* Transition propositions:&amp;lt;br&amp;gt;If the next executed operation in the path is `Op`, the expression `[Op]` can be used. Also patter-matching for the arguments of the operation is supported. E.g. `[Op(3,4*v)]` checks if the next operation is `Op` and that the first argument is 3 and the third argument is `4*v` where `v` is a variable of the machine. &amp;lt;br&amp;gt; Arbitrary B expressions can be used as patterns. Constants and variables of the machine can be used. Variables have the values of the state where the operations starts.&lt;br /&gt;
&lt;br /&gt;
* Logical operators&lt;br /&gt;
** `true` and `false`&lt;br /&gt;
**  `not`: negation&lt;br /&gt;
**  `&amp;amp;`, `or` and `=&amp;gt;`: conjunction, disjunction and implication&lt;br /&gt;
&lt;br /&gt;
* Temporal operators (future)&lt;br /&gt;
**  `G f`: globally&lt;br /&gt;
**  `F f`: finally&lt;br /&gt;
**  `X f`: next&lt;br /&gt;
**  `f U g`: until&lt;br /&gt;
**  `f W g`: weak until&lt;br /&gt;
**  `f R g`: release&lt;br /&gt;
&lt;br /&gt;
* Temporal operators (past)&lt;br /&gt;
**  `H f`: history (dual to G)&lt;br /&gt;
**  `O f`: once (dual to F)&lt;br /&gt;
**  `Y f`: yesterday (dual to X)&lt;br /&gt;
**  `f S g`: since (dual to until)&lt;br /&gt;
**  `f T g`: trigger (dual to release)&lt;br /&gt;
&lt;br /&gt;
* Fairness operators &lt;br /&gt;
**  `WF(Op)` or `wf(Op)`: weak fairness, where ` Op` is an operation&lt;br /&gt;
**  `SF(Op)`or `sf(Op)`:  strong fairness, where ` Op` is an operation&lt;br /&gt;
**  `WEF`: weak fairness for all possible operations&lt;br /&gt;
**  `SEF`: strong fairness for all possible operations&lt;br /&gt;
&lt;br /&gt;
==Setting Fairness Constraints==&lt;br /&gt;
&lt;br /&gt;
Fairness is a notion where the search for counterexamples is restricted to paths that do not ignore infinitely the execution of a set of enabled operations imposed by the user as &amp;quot;fair&amp;quot; constraints. One possibility to set fairness constraints in ProB is to encode them in the LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula intended to be checked. For example, for a given LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &amp;quot;f&amp;quot; a set of weak fairness conditions {a1,…,an} can be given as follows: &lt;br /&gt;
 (FG e(a1) =&amp;gt; GF [a1]) &amp;amp; … &amp;amp; (FG e(an) =&amp;gt; GF [an]) =&amp;gt; f.&lt;br /&gt;
In a similar way, strong fairness constraints can be imposed expressed by means of an LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula:&lt;br /&gt;
 (GF e(a1) =&amp;gt; GF [a1]) &amp;amp; … &amp;amp; (GF e(an) =&amp;gt; GF [an]) =&amp;gt; f.&lt;br /&gt;
&lt;br /&gt;
Checking fairness in this way is very often considered to be inefficient as usually the number of atoms (the possible valuations of the property) of the LTL property is exponential in the size of the formula.&amp;lt;ref&amp;gt;O. Lichtenstein and A. Pnueli: &#039;&#039;Checking that Finite State Concurrent Programs Satisfy Their Linear Specification&#039;&#039;. POPL &#039;85, Proceedings of the 12th ACM SIGACT-SIGPLAN Symposium on Principles of Programming Languages, ACM, 1985&amp;lt;/ref&amp;gt; For this reason, the search algorithm of the LTL model checker has been extended in order to allow fairness to be checked efficiently. In addition, new operators have been added to the ProB’s LTL parser for setting fairness constraints to an LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; property. The new operators are &#039;&#039;WF(-)&#039;&#039; and &#039;&#039;SF(-)&#039;&#039; and both accept as argument an operation. The fairness constraints must be given by means of implication: &amp;quot;fair =&amp;gt; f&amp;quot;, where &amp;quot;f&amp;quot; is the property to be checked and &amp;quot;fair&amp;quot; the fairness constraints.&lt;br /&gt;
&lt;br /&gt;
In particular, &amp;quot;fair&amp;quot; can have one of the forms: &amp;quot;wfair&amp;quot;, &amp;quot;sfair&amp;quot;, &amp;quot;wfair &amp;amp; sfair&amp;quot;, and &amp;quot;sfair &amp;amp; wfair&amp;quot;, where &amp;quot;wfair&amp;quot; and &amp;quot;sfair&amp;quot; represent the imposed weak and strong fairness constraints, respectively.&lt;br /&gt;
&lt;br /&gt;
Basically, &amp;quot;wfair&amp;quot; and &amp;quot;sfair&amp;quot; are expressed by means of logical formulas having the following syntax:&lt;br /&gt;
&lt;br /&gt;
* Weak fair conditions (&amp;quot;wfair&amp;quot;):&lt;br /&gt;
** `WF(a)`, where `a` is an operation&lt;br /&gt;
** `&amp;amp;` and `or`: conjunction and disjunction&lt;br /&gt;
&lt;br /&gt;
* Strong fair conditions (&amp;quot;sfair&amp;quot;):&lt;br /&gt;
** `SF(a)`, where `a` is an operation&lt;br /&gt;
** `&amp;amp;` and `or`: conjunction and disjunction&lt;br /&gt;
&lt;br /&gt;
For instance, if we want to check an LTL property &amp;quot;f&amp;quot; on paths that are weak fair in regard to the operations &amp;quot;a&amp;quot; and &amp;quot;b&amp;quot; and additionally strong fair in regard to &amp;quot;c&amp;quot; or &amp;quot;d&amp;quot;, then this can be given as follows:&lt;br /&gt;
 (WF(a) &amp;amp; WF(b)) &amp;amp; (SF(c) or SF(d)) =&amp;gt; f&lt;br /&gt;
&lt;br /&gt;
Note that the operators &#039;&#039;WF(-)&#039;&#039; and &#039;&#039;SF(-)&#039;&#039; cannot appear on the right side of the fairness implication. Basically, &#039;&#039;WF(-)&#039;&#039; and &#039;&#039;SF(-)&#039;&#039; can be described by the following equivalences:&lt;br /&gt;
 WF(a) ≡ (FG e(a) =&amp;gt; GF [a]) and SF(a) ≡ (GF e(a) =&amp;gt; GF [a]), where a is an operation.&lt;br /&gt;
&lt;br /&gt;
For setting fairness constraints on all possible operations of the model being checked use the operators &amp;quot;WEF&amp;quot; and &amp;quot;SEF&amp;quot;. For instance, if &amp;quot;f&amp;quot; is a liveness property and we want to restrict the search only to strongly fair paths, then we can impose the fairness constraints by means of the formula &amp;quot;SEF =&amp;gt; f&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The grammar for imposing fairness constraints by means of the fairness implication (&amp;quot;fair =&amp;gt; f&amp;quot;) looks as follows:&lt;br /&gt;
&lt;br /&gt;
 fair ::= WEF | SEF | wfair | sfair | wfair &amp;amp; sfair | sfair &amp;amp; wfair&amp;lt;br/&amp;gt;&lt;br /&gt;
          wfair ::= wf(a) | ( wfair ) | wfair &amp;amp; wfair | wfair or wfair&amp;lt;br/&amp;gt;&lt;br /&gt;
          sfair ::= sf(a) | ( sfair ) | sfair &amp;amp; sfair | sfair or sfair&lt;br /&gt;
&lt;br /&gt;
where &amp;quot;a&amp;quot; is a transition proposition.&lt;br /&gt;
&lt;br /&gt;
==Storing LTL Assertions in the Model==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Storing LTL formulas in B machines&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
LTL formulas can be stored in the `DEFINITIONS` section of a B machine. The name of the definition must start with `ASSERT_LTL` and a string must be specified. In case there is more than one LTL assertion given in the ‘DEFINITIONS’ section, the particular LTL assertions must be separated by semicolon. For example: &lt;br /&gt;
&lt;br /&gt;
 DEFINITIONS &lt;br /&gt;
   ASSERT_LTL  == &amp;quot;G (e(SetCruiseSpeed) =&amp;gt; e(CruiseBecomesNotAllowed))&amp;quot;;&lt;br /&gt;
   ASSERT_LTL1 == &amp;quot;G (e(CruiseBecomesNotAllowed) =&amp;gt; e(SetCruiseSpeed))&amp;quot;;&lt;br /&gt;
   ASSERT_LTL2 == &amp;quot;G (e(CruiseBecomesNotAllowed) =&amp;gt; (ObstacleDisappears))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Storing LTL formulas in CSP-M specifications&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
LTL formulas can be stored within pragmas in CSP-M specifications. A pragma in which a single LTL formula is stored is given by &amp;quot;{-# assert_ltl &amp;quot;f&amp;quot; &amp;quot;c&amp;quot; #-}&amp;quot;, where &amp;quot;assert_ltl&amp;quot; indicates the type of the information stored in the pragma (there are currently two types: assert_ltl and assert_ctl), and is followed by the LTL formula `f` and a comment `c` (the comment is optional). Both, the LTL formula and the comment, must be enclosed in double quotes. &lt;br /&gt;
It is also possible to give several LTL formulas in a single pragma within which the corresponding LTL assertions are separated by semicolon. For example:&lt;br /&gt;
&lt;br /&gt;
 {-# assert_ltl &amp;quot;SF(enter.1) &amp;amp; WF(req.1) =&amp;gt; GF([enter.1])&amp;quot;;&lt;br /&gt;
     assert_ltl &amp;quot;SF(enter.2) &amp;amp; WF(req.2) =&amp;gt; GF([enter.2])&amp;quot;;&lt;br /&gt;
     assert_ltl &amp;quot;GF [enter.1] &amp;amp; GF [enter.2]&amp;quot; &amp;quot;Should fail.&amp;quot;#-}&lt;br /&gt;
&lt;br /&gt;
Note that a semicolon must not follow the last assertion in a pragma.&lt;br /&gt;
&lt;br /&gt;
For CSP-M specifications, it is also possible to assert LTL-formulae to particular processes in the model. This is possible by means of ``assert`` declarations, which have been recently included to the CSP-M grammar of the ProB CSP-M parser:&lt;br /&gt;
&lt;br /&gt;
 assert P |= LTL: &amp;quot;ltl-formula&amp;quot;,&lt;br /&gt;
 where `P` is an arbitrary process and `ltl-formula` an LTL formula.&lt;br /&gt;
&lt;br /&gt;
==LTL Formulas in a Separate File==&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB it is possible to check several LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formulae with one call. The command has the following syntax &lt;br /&gt;
 probcli -ltlfile FILE ... &lt;br /&gt;
The file FILE contains one or more sections where each section has the form &lt;br /&gt;
 [Name]  Formula &lt;br /&gt;
The formula itself can spread several lines. Additional comments can be added with a leading #. &lt;br /&gt;
If a counter-example is found, the trace of the counter-example is saved into the file ltlce_Name.trace, where &amp;quot;Name&amp;quot; is the name of the formula in the LTL file.&lt;br /&gt;
&lt;br /&gt;
One also can check a single LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &#039;&#039;F&#039;&#039; using the option &#039;-ltlformula&#039; as follows:&lt;br /&gt;
 probcli -ltlformula &amp;quot;F&amp;quot; ...&lt;br /&gt;
&lt;br /&gt;
==LTL Formulae in a Separate File==&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB it is possible to check several LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formulae with one call. The command has the following syntax &lt;br /&gt;
 probcli -ltlfile FILE ... &lt;br /&gt;
The file FILE contains one or more sections where each section has the form &lt;br /&gt;
 [Name]  Formula &lt;br /&gt;
The formula itself can spread in several lines. Additional comments can be added with a leading #.&lt;br /&gt;
If a counter-example is found, the trace of the counter-example is saved into the file ltlce_Name.trace, where &amp;quot;Name&amp;quot; is the name of the formula in the LTL file.&lt;br /&gt;
&lt;br /&gt;
One also can check a single LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &#039;&#039;F&#039;&#039; using the option &#039;-ltlformula&#039; as follows:&lt;br /&gt;
 probcli -ltlformula &amp;quot;F&amp;quot; ...&lt;br /&gt;
&lt;br /&gt;
==LTL Model Checker Output==&lt;br /&gt;
The output provided by the LTL model checker can sometimes reveal some interesting statistical facts about the model and the property being checked on the model. The LTL model checker of ProB uses the tableau approach for checking an LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula on a formal model. To check whether a model &#039;&#039;M&#039;&#039; satisfies a given formula &#039;&#039;f&#039;&#039;, the algorithm generates a search graph, called also tableau graph, composed from the tableau of the formula and the state space of the model. If there is a path in the search graph that is a model for &#039;&#039;f&#039;&#039;, then the formula is satisfiable. The nodes of the search graph are called &#039;&#039;atoms&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Basically, using the tableau approach we prove that &#039;&#039;M&#039;&#039; satisfies &#039;&#039;f&#039;&#039; by negating the given formula and searching for a path fulfilling &#039;&#039;¬f&#039;&#039;. If such a path is found, then we infer that &#039;&#039;M&#039;&#039; violates &#039;&#039;f&#039;&#039;. Otherwise, if no path is found that satisfies &#039;&#039;¬f&#039;&#039;, we conclude that &#039;&#039;M |= f&#039;&#039;. The LTL model checking algorithm of ProB is based on searching for strongly connected components (SCCs) with certain properties to determine whether &#039;&#039;M&#039;&#039; satisfies &#039;&#039;f&#039;&#039;. Finding such an SCC that can be reached from an initial state of &#039;&#039;M&#039;&#039; is a witness for a counter-example for &#039;&#039;f&#039;&#039;. Sometimes, we use fairness to ignore such SCCs that do not fulfill the imposed fairness constraints in order to not impede proving a property by returning of non-fair paths as counter-examples.&lt;br /&gt;
&lt;br /&gt;
The LTL model checker algorithm of ProB is implemented in C using a callback mechanism for evaluating the atomic propositions and the outgoing transitions in SICStus Prolog. (For each state of the model a callback will be performed.) Additionally, the search for SCCs is based on the Tarjan&#039;s algorithm. In the terminal all messages coming from the LTL model checker are preceded either by &amp;quot;LTL (current statistics): &amp;quot; or &amp;quot;LTL model checking:&amp;quot;. The output from the LTL model checker can give helpful insights about the model and the model checking process.&lt;br /&gt;
&lt;br /&gt;
Consider the CSP specifications &amp;quot;dphil_ltl8.csp&amp;quot; representing a model of the dining philosophers problem for eight philosophers which resolves the starvation problem by always forcing the first philosopher to pick up first the right fork instead of the left one. In other words, &amp;quot;dphil_ltl8.csp&amp;quot; has no deadlock states. Checking the LTL formula &amp;quot;GF [eat.0]&amp;quot; from the command line will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ probcli -ltlformula &amp;quot;GF [eat.0]&amp;quot; dphil_ltl8.csp&lt;br /&gt;
....&lt;br /&gt;
LTL model checking formula&lt;br /&gt;
% parsing_ltl_formula&lt;br /&gt;
% initialising_ltlc&lt;br /&gt;
starting_model_checking&lt;br /&gt;
&lt;br /&gt;
LTL (current statistics): 13280 atoms, 10070 transitions generated, and  2631 callbacks needed.&lt;br /&gt;
&lt;br /&gt;
LTL model checking: found counter-example (lasso-form): intro length = 1126, path in SCC of length = 5&lt;br /&gt;
LTL model checking: memory usage approx. 1924 KiB, 14104 atoms and 10724 transitions generated&lt;br /&gt;
LTL model checking: total time 22492ms, 2803 callbacks needed 22465ms, netto 26ms.&lt;br /&gt;
! An error occurred !&lt;br /&gt;
! source(ltl)&lt;br /&gt;
! Model Check Counter-Example found for: &lt;br /&gt;
! GF [eat.0]&lt;br /&gt;
&lt;br /&gt;
Formula FALSE.&lt;br /&gt;
&lt;br /&gt;
Runtime: 22220 ms&lt;br /&gt;
! *** error occurred ***&lt;br /&gt;
! ltl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As one can clearly see from the output, the LTL model checker fails to prove &amp;quot;GF [eat.0]&amp;quot; on the model since it has found a counter-example for the formula. Note that the ProB LTL model checker explores the search graph and the state space dynamically. The above data is to be understand as follows:&lt;br /&gt;
* 14104 atoms - the LTL model checker needed to explore 14104 atoms to find a counter-example for the formula. &lt;br /&gt;
* 2803 callbacks needed - to explore the search graph the model checker makes callbacks in order to explore the state space of the model being checked (the exploration runs dynamically) and compute the successor states in the tableau graph. In this case the model checker has needed to explore 2803 states till it finds a counter-example for the formula&lt;br /&gt;
* memory usage approx. 1924 KiB - the memory needed to explore the tableau graph&lt;br /&gt;
* found counter-example (lasso-form) - means that the counter-example being found is path beginning in an initial state of the model and reaching a state that closes a cycle:&lt;br /&gt;
** intro length = 1126: the length of the sub-path from an initial state to the entry point of the cycle&lt;br /&gt;
** path in SCC of length = 5: the cycle is comprised of five states&lt;br /&gt;
* total time 22492ms - the LTL model checker needed about 23 seconds to find the counter-example. Here a distinction between the time needed to explore the state space of the model (2803 callbacks needed 22465ms) and the time spent for generating the tableau graph + the time for identifying the self-fulfilling SCC (netto 26ms)&lt;br /&gt;
* LTL (current statistics) - an intermediate data information is given each 20 seconds spent from the last current data information.&lt;br /&gt;
&lt;br /&gt;
In the example above one can prove the LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &amp;quot;GF [eat.0]&amp;quot; on dphil_ltl6.csp using fairness. One can impose, for example, strong fairness conditions on all transitions of the model and thus verify that &amp;quot;GF [eat.0]&amp;quot; is satisfied under strong fairness. The call looks as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ probcli -ltlformula &amp;quot;SEF =&amp;gt; GF [eat.0]&amp;quot; dphil_ltl8.csp&lt;br /&gt;
...&lt;br /&gt;
LTL model checking formula&lt;br /&gt;
% parsing_ltl_formula&lt;br /&gt;
% initialising_ltlc&lt;br /&gt;
starting_model_checking&lt;br /&gt;
LTL (current statistics): 13016 atoms, 9834 transitions generated, and  2578 callbacks needed.&lt;br /&gt;
LTL (fairness): 0 strongly connected components were rejected, 0 callbacks needed.&lt;br /&gt;
&lt;br /&gt;
LTL (current statistics): 27540 atoms, 44422 transitions generated, and  5123 callbacks needed.&lt;br /&gt;
LTL (fairness): 284 strongly connected components were rejected, 843 callbacks needed.&lt;br /&gt;
.....&lt;br /&gt;
LTL (current statistics): 85980 atoms, 267821 transitions generated, and  19733 callbacks needed.&lt;br /&gt;
LTL (fairness): 454 strongly connected components were rejected, 1924 callbacks needed.&lt;br /&gt;
&lt;br /&gt;
LTL (current statistics): 95648 atoms, 364288 transitions generated, and  22150 callbacks needed.&lt;br /&gt;
LTL (fairness): 773 strongly connected components were rejected, 3085 callbacks needed.&lt;br /&gt;
&lt;br /&gt;
LTL model checking: memory usage approx. 13829 KiB, 96500 atoms and 381625 transitions generated&lt;br /&gt;
LTL model checking: total time 190887ms, 22363 callbacks needed 186690ms, netto 467ms.&lt;br /&gt;
LTL model checking (fairness): 800 strongly connected components were rejected.&lt;br /&gt;
LTL model checking (fairness): total fairness checking time 3729ms, 3246 callbacks needed 3452ms, netto 277ms.&lt;br /&gt;
LTL Formula TRUE.&lt;br /&gt;
No counter example found for SEF =&amp;gt; GF [eat.0].&lt;br /&gt;
Runtime: 188370 ms&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above check no fair counter-example could be find for the formula &amp;quot;GF [eat.0]&amp;quot;. For this check the search graph comprises 96500 atoms and 381625  transitions, far more than the other formula check (without fairness assumptions). Since no fair counter-example was found we can infer that the whole state space of the was explored. Since we know from above 22363 callbacks were needed to explore the search graph, we can infer that the state space of the model has overall 22363 states.&lt;br /&gt;
&lt;br /&gt;
In the output above there is also some information about the fairness checking being performed for the model checker run. The LTL model checker has refuted 800 SCCs in total, i.e. there were found 800 SCCs in the search graph that could serve as a counter-example for &amp;quot;GF [eat.0]&amp;quot; in case no fairness constraints were imposed.&lt;br /&gt;
&lt;br /&gt;
== Other Relevant Tutorials about LTL Model Checking ==&lt;br /&gt;
A brief tutorial on visualizing LTL counter-examples in the Rodin tool can be found [http://www.stups.uni-duesseldorf.de/ProB/index.php5/Tutorial_LTL_Counter-example_View here].&lt;br /&gt;
&lt;br /&gt;
A tutorial of a simple case study, where setting fairness constraints to some of the LTL properties is required, can be found [http://www.stups.uni-duesseldorf.de/ProB/index.php5/Mutual_Exclusion_%28Fairness%29 here].&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=LTL_Model_Checking&amp;diff=3570</id>
		<title>LTL Model Checking</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=LTL_Model_Checking&amp;diff=3570"/>
		<updated>2016-03-11T13:39:18Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* LTL Model Checker Output */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]__NOTOC__&lt;br /&gt;
ProB provides support for LTL (linear temporal logic) model checking. For an introduction to LTL see the [http://en.wikipedia.org/wiki/Linear_temporal_logic Wikipedia Article].&lt;br /&gt;
&lt;br /&gt;
To use this feature, select &amp;quot;Check LTL/CTL Assertions&amp;quot; in the &amp;quot;Verify&amp;quot; menu. The feature can also be accessed by the key combination &amp;quot;Ctrl+L&amp;quot; under Windows and Linux, and by the key combination &amp;quot;Cmd+L&amp;quot; under MacOS. The following window appears:&lt;br /&gt;
&lt;br /&gt;
[[File:ltlviewer.png]]&lt;br /&gt;
&lt;br /&gt;
All LTL formulas that are given in the &amp;quot;DEFINTIONS&amp;quot; section of a B machine are displayed in the list box of the LTL/CTL Assertions Viewer. For CSP-M specifications all LTL formulas given in the LTL pragmas of the loaded CSP-M file will be shown in the viewer. (For more detailed information of how LTL/CTL assertions can be stored into B and CSP-M models see Section &#039;&#039;&#039;Storing LTL Assertions into a Model&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
A new LTL formula can be entered in the entry below the list box. (We explain the supported syntax below). The typed formula can then be either added to the list box by clicking the &amp;quot;Add&amp;quot; button or directly checked by clicking the &amp;quot;Check&amp;quot; button. Before doing that assure whether you are in the proper frame (&amp;quot;Add LTL Formula&amp;quot;) of the bottom part of the LTL viewer.&lt;br /&gt;
&lt;br /&gt;
The LTL model checker can be started for an LTL formula by performing a double-click on the respective formula or typing &amp;quot;Enter&amp;quot; after selecting the respective formula. Each LTL formula in the list box has on the left hand side a symbol that indicates what is the status of the respective formula. An LTL formula can have one of the following statuses (status symbols may differ under different operating systems):&lt;br /&gt;
&lt;br /&gt;
* ? – The formula has not been checked yet.&lt;br /&gt;
* ✔ – The formula is true for all valid paths.&lt;br /&gt;
* ✘ – A counterexample for the formula has been found, i.e. there is a path that violates the formula. In case the formula has been just checked on the model the animator is navigated to the last state of the counterexample. The full path can then be seen in the history. The counterexample can be also obtained by the dotty-viewer after a second double-click on the formula in the assertions’ viewer. &lt;br /&gt;
* ⌚ – The formula is currently checked.&lt;br /&gt;
* ! – The formula check has been aborted by an unexpected error occurrence.&lt;br /&gt;
* ∞ – The formula check is incomplete, i.e. no counterexample was found so far, but the absence of a path that does not satisfy the formula can not be guaranteed because the state space was not fully explored. A new check can be started by a double-click.&lt;br /&gt;
&lt;br /&gt;
All formulas can be checked by &amp;quot;Assertions -&amp;gt; Check All Assertions&amp;quot; in the menu bar. All formulas will be then checked from top to bottom in the list box.&lt;br /&gt;
&lt;br /&gt;
Additionally, the viewer provides a context menu for the list box elements. The context menu can be popped-up by a right-mouse-click on a formula from the list box, and it performs a set of actions available to be performed on the currently selected formula (see Figure below). &lt;br /&gt;
&lt;br /&gt;
[[File:ltlviewercontext.png]]&lt;br /&gt;
&lt;br /&gt;
The old LTL and CTL dialogs can be accessed from &amp;quot;OldLtlViewers&amp;quot; in the menu bar.&lt;br /&gt;
&lt;br /&gt;
==LTL Preferences==&lt;br /&gt;
&lt;br /&gt;
There is a set of options coming with the LTL model checker. In this section we give a brief overview of the preferences. The LTL preferences can be viewed by selecting &amp;quot;LTL Preferences&amp;quot; in the &amp;quot;Preferences&amp;quot; menu of the LTL/CTL Assertions Viewer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Exploring new states&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
The LTL model checker searches in the already explored search space of the model. If a state is encountered that has not been explored before, the state will be explored (i.e. all transitions to successor states are computed). The number of how often this can happen is limited by the field &amp;quot;Max no. of new states&amp;quot;. &lt;br /&gt;
Depending on the LTL formula, a partially explored state space can be sufficient to find a counterexample or to assure the absence of a counterexample. If there&#039;s still the possibility of a counterexample in the remaining unexplored state space, the user will get a message. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Optimizing the process of LTL model checking&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
The process of model checking can be optimized for B and Event-B models by using partial order reduction. The idea of partial order reduction is to execute only a subset of all enabled actions in each state. Thus, only a part of the original state space is checked for the checked property. The reduction of the state space depends on the number of concurrent and independent actions in the model, as well as on the property being checked.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Search Options&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
The model checker searches for a counterexample (i.e. a path that does not satisfy the current formula). Where the checked paths through the model&#039;s search space start depend on the following options in the LTL Preferences’ menu:&lt;br /&gt;
# &#039;&#039;Start search in initialization&#039;&#039;&amp;lt;br/&amp;gt;All paths that start in a state of the initialization of the machine are checked. &lt;br /&gt;
# &#039;&#039;Start search in current state&#039;&#039;&amp;lt;br/&amp;gt;All paths that start in the current state are checked. &lt;br /&gt;
# &#039;&#039;Start in initialization, but check formula in current state&#039;&#039;&amp;lt;br/&amp;gt;All paths that start in a state of the initialization of the machine are checked, but the formula is mapped to the current state. For example, this option can be used to check properties like &amp;quot;Is this state only reachable directly after executing operation `xy`?&amp;quot;: The formula would be `Y[xy]`. This is equivalent to &amp;quot;G (current =&amp;gt; f)&amp;quot; with f as the entered formula and using the option &amp;quot;Start search in initialization&amp;quot;. &lt;br /&gt;
Note: Whereas `Y true` is always false when checked with option 1 or 2, it is usually true (but not in all cases) for option 3.&lt;br /&gt;
&lt;br /&gt;
=== Supported Syntax ===&lt;br /&gt;
&lt;br /&gt;
ProB supports LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt;, an extended version of LTL. In contrast to the standard LTL, LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; provides also support for propositions on transitions, not only on states. In practice,  writing propositions on transitions is allowed by using the constructs `e(...)` and `[...]`. (see below). The LTL model checker of ProB supports Past-LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; as well.&lt;br /&gt;
&lt;br /&gt;
* Atomic propositions can be one of the following:&lt;br /&gt;
**  Predicates can be written in curly braces: `{...}`. E.g. `{card(someset) &amp;gt; 1}`&lt;br /&gt;
**  To check if an operation is enabled in a state use `e(Op)`, where `Op` is the name of the operation.&lt;br /&gt;
**  To start a search from the current state of the animation use `current` (see the section &#039;&#039;&#039;LTL Preferences&#039;&#039;&#039; for more information).&lt;br /&gt;
**  To check if a state has no outgoing transition leading to a different state use `sink`. This can be useful for finding &amp;quot;pseudo&amp;quot;-deadlocks, i.e. states where only query-operations are enabled that do not change the state. Note that `sink` holds for deadlock states as well.&lt;br /&gt;
** For checking if a state is a deadlock state the atomic proposition ` deadlock ` can be used.&lt;br /&gt;
**  To check if a set of operations is disabled in a state use `deadlock(Op1,Op2,...,Opk)`, where Op1,Op2,...,Opk with k&amp;gt;0 are operations of the model. It is also possible to check if specific representations of an operation with arguments are disabled in a state using pattern-matching, e.g.: `deadlock(Op(1),Op(3))`.&lt;br /&gt;
** By means of `deterministic(Op1,Op2,...,Opk)`, where Op1,Op2,...,Opk with k&amp;gt;0 are operations of the model, one can check if maximum one of the operations Op1,Op2,...,Opk is enabled in a state. &lt;br /&gt;
** To check if exactly one operation from a set of operations Op1,Op2,...,Opk is enabled in a state use `controller(Op1,Op2,…,Opk)`.&lt;br /&gt;
&lt;br /&gt;
* Transition propositions:&amp;lt;br&amp;gt;If the next executed operation in the path is `Op`, the expression `[Op]` can be used. Also patter-matching for the arguments of the operation is supported. E.g. `[Op(3,4*v)]` checks if the next operation is `Op` and that the first argument is 3 and the third argument is `4*v` where `v` is a variable of the machine. &amp;lt;br&amp;gt; Arbitrary B expressions can be used as patterns. Constants and variables of the machine can be used. Variables have the values of the state where the operations starts.&lt;br /&gt;
&lt;br /&gt;
* Logical operators&lt;br /&gt;
** `true` and `false`&lt;br /&gt;
**  `not`: negation&lt;br /&gt;
**  `&amp;amp;`, `or` and `=&amp;gt;`: conjunction, disjunction and implication&lt;br /&gt;
&lt;br /&gt;
* Temporal operators (future)&lt;br /&gt;
**  `G f`: globally&lt;br /&gt;
**  `F f`: finally&lt;br /&gt;
**  `X f`: next&lt;br /&gt;
**  `f U g`: until&lt;br /&gt;
**  `f W g`: weak until&lt;br /&gt;
**  `f R g`: release&lt;br /&gt;
&lt;br /&gt;
* Temporal operators (past)&lt;br /&gt;
**  `H f`: history (dual to G)&lt;br /&gt;
**  `O f`: once (dual to F)&lt;br /&gt;
**  `Y f`: yesterday (dual to X)&lt;br /&gt;
**  `f S g`: since (dual to until)&lt;br /&gt;
**  `f T g`: trigger (dual to release)&lt;br /&gt;
&lt;br /&gt;
* Fairness operators &lt;br /&gt;
**  `WF(Op)` or `wf(Op)`: weak fairness, where ` Op` is an operation&lt;br /&gt;
**  `SF(Op)`or `sf(Op)`:  strong fairness, where ` Op` is an operation&lt;br /&gt;
**  `WEF`: weak fairness for all possible operations&lt;br /&gt;
**  `SEF`: strong fairness for all possible operations&lt;br /&gt;
&lt;br /&gt;
==Setting Fairness Constraints==&lt;br /&gt;
&lt;br /&gt;
Fairness is a notion where the search for counterexamples is restricted to paths that do not ignore infinitely the execution of a set of enabled operations imposed by the user as &amp;quot;fair&amp;quot; constraints. One possibility to set fairness constraints in ProB is to encode them in the LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula intended to be checked. For example, for a given LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &amp;quot;f&amp;quot; a set of weak fairness conditions {a1,…,an} can be given as follows: &lt;br /&gt;
 (FG e(a1) =&amp;gt; GF [a1]) &amp;amp; … &amp;amp; (FG e(an) =&amp;gt; GF [an]) =&amp;gt; f.&lt;br /&gt;
In a similar way, strong fairness constraints can be imposed expressed by means of an LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula:&lt;br /&gt;
 (GF e(a1) =&amp;gt; GF [a1]) &amp;amp; … &amp;amp; (GF e(an) =&amp;gt; GF [an]) =&amp;gt; f.&lt;br /&gt;
&lt;br /&gt;
Checking fairness in this way is very often considered to be inefficient as usually the number of atoms (the possible valuations of the property) of the LTL property is exponential in the size of the formula.&amp;lt;ref&amp;gt;O. Lichtenstein and A. Pnueli: &#039;&#039;Checking that Finite State Concurrent Programs Satisfy Their Linear Specification&#039;&#039;. POPL &#039;85, Proceedings of the 12th ACM SIGACT-SIGPLAN Symposium on Principles of Programming Languages, ACM, 1985&amp;lt;/ref&amp;gt; For this reason, the search algorithm of the LTL model checker has been extended in order to allow fairness to be checked efficiently. In addition, new operators have been added to the ProB’s LTL parser for setting fairness constraints to an LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; property. The new operators are &#039;&#039;WF(-)&#039;&#039; and &#039;&#039;SF(-)&#039;&#039; and both accept as argument an operation. The fairness constraints must be given by means of implication: &amp;quot;fair =&amp;gt; f&amp;quot;, where &amp;quot;f&amp;quot; is the property to be checked and &amp;quot;fair&amp;quot; the fairness constraints.&lt;br /&gt;
&lt;br /&gt;
In particular, &amp;quot;fair&amp;quot; can have one of the forms: &amp;quot;wfair&amp;quot;, &amp;quot;sfair&amp;quot;, &amp;quot;wfair &amp;amp; sfair&amp;quot;, and &amp;quot;sfair &amp;amp; wfair&amp;quot;, where &amp;quot;wfair&amp;quot; and &amp;quot;sfair&amp;quot; represent the imposed weak and strong fairness constraints, respectively.&lt;br /&gt;
&lt;br /&gt;
Basically, &amp;quot;wfair&amp;quot; and &amp;quot;sfair&amp;quot; are expressed by means of logical formulas having the following syntax:&lt;br /&gt;
&lt;br /&gt;
* Weak fair conditions (&amp;quot;wfair&amp;quot;):&lt;br /&gt;
** `WF(a)`, where `a` is an operation&lt;br /&gt;
** `&amp;amp;` and `or`: conjunction and disjunction&lt;br /&gt;
&lt;br /&gt;
* Strong fair conditions (&amp;quot;sfair&amp;quot;):&lt;br /&gt;
** `SF(a)`, where `a` is an operation&lt;br /&gt;
** `&amp;amp;` and `or`: conjunction and disjunction&lt;br /&gt;
&lt;br /&gt;
For instance, if we want to check an LTL property &amp;quot;f&amp;quot; on paths that are weak fair in regard to the operations &amp;quot;a&amp;quot; and &amp;quot;b&amp;quot; and additionally strong fair in regard to &amp;quot;c&amp;quot; or &amp;quot;d&amp;quot;, then this can be given as follows:&lt;br /&gt;
 (WF(a) &amp;amp; WF(b)) &amp;amp; (SF(c) or SF(d)) =&amp;gt; f&lt;br /&gt;
&lt;br /&gt;
Note that the operators &#039;&#039;WF(-)&#039;&#039; and &#039;&#039;SF(-)&#039;&#039; cannot appear on the right side of the fairness implication. Basically, &#039;&#039;WF(-)&#039;&#039; and &#039;&#039;SF(-)&#039;&#039; can be described by the following equivalences:&lt;br /&gt;
 WF(a) ≡ (FG e(a) =&amp;gt; GF [a]) and SF(a) ≡ (GF e(a) =&amp;gt; GF [a]), where a is an operation.&lt;br /&gt;
&lt;br /&gt;
For setting fairness constraints on all possible operations of the model being checked use the operators &amp;quot;WEF&amp;quot; and &amp;quot;SEF&amp;quot;. For instance, if &amp;quot;f&amp;quot; is a liveness property and we want to restrict the search only to strongly fair paths, then we can impose the fairness constraints by means of the formula &amp;quot;SEF =&amp;gt; f&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The grammar for imposing fairness constraints by means of the fairness implication (&amp;quot;fair =&amp;gt; f&amp;quot;) looks as follows:&lt;br /&gt;
&lt;br /&gt;
 fair ::= WEF | SEF | wfair | sfair | wfair &amp;amp; sfair | sfair &amp;amp; wfair&amp;lt;br/&amp;gt;&lt;br /&gt;
          wfair ::= wf(a) | ( wfair ) | wfair &amp;amp; wfair | wfair or wfair&amp;lt;br/&amp;gt;&lt;br /&gt;
          sfair ::= sf(a) | ( sfair ) | sfair &amp;amp; sfair | sfair or sfair&lt;br /&gt;
&lt;br /&gt;
where &amp;quot;a&amp;quot; is a transition proposition.&lt;br /&gt;
&lt;br /&gt;
==Storing LTL Assertions in the Model==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Storing LTL formulas in B machines&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
LTL formulas can be stored in the `DEFINITIONS` section of a B machine. The name of the definition must start with `ASSERT_LTL` and a string must be specified. In case there is more than one LTL assertion given in the ‘DEFINITIONS’ section, the particular LTL assertions must be separated by semicolon. For example: &lt;br /&gt;
&lt;br /&gt;
 DEFINITIONS &lt;br /&gt;
   ASSERT_LTL  == &amp;quot;G (e(SetCruiseSpeed) =&amp;gt; e(CruiseBecomesNotAllowed))&amp;quot;;&lt;br /&gt;
   ASSERT_LTL1 == &amp;quot;G (e(CruiseBecomesNotAllowed) =&amp;gt; e(SetCruiseSpeed))&amp;quot;;&lt;br /&gt;
   ASSERT_LTL2 == &amp;quot;G (e(CruiseBecomesNotAllowed) =&amp;gt; (ObstacleDisappears))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Storing LTL formulas in CSP-M specifications&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
LTL formulas can be stored within pragmas in CSP-M specifications. A pragma in which a single LTL formula is stored is given by &amp;quot;{-# assert_ltl &amp;quot;f&amp;quot; &amp;quot;c&amp;quot; #-}&amp;quot;, where &amp;quot;assert_ltl&amp;quot; indicates the type of the information stored in the pragma (there are currently two types: assert_ltl and assert_ctl), and is followed by the LTL formula `f` and a comment `c` (the comment is optional). Both, the LTL formula and the comment, must be enclosed in double quotes. &lt;br /&gt;
It is also possible to give several LTL formulas in a single pragma within which the corresponding LTL assertions are separated by semicolon. For example:&lt;br /&gt;
&lt;br /&gt;
 {-# assert_ltl &amp;quot;SF(enter.1) &amp;amp; WF(req.1) =&amp;gt; GF([enter.1])&amp;quot;;&lt;br /&gt;
     assert_ltl &amp;quot;SF(enter.2) &amp;amp; WF(req.2) =&amp;gt; GF([enter.2])&amp;quot;;&lt;br /&gt;
     assert_ltl &amp;quot;GF [enter.1] &amp;amp; GF [enter.2]&amp;quot; &amp;quot;Should fail.&amp;quot;#-}&lt;br /&gt;
&lt;br /&gt;
Note that a semicolon must not follow the last assertion in a pragma.&lt;br /&gt;
&lt;br /&gt;
For CSP-M specifications, it is also possible to assert LTL-formulae to particular processes in the model. This is possible by means of ``assert`` declarations, which have been recently included to the CSP-M grammar of the ProB CSP-M parser:&lt;br /&gt;
&lt;br /&gt;
 assert P |= LTL: &amp;quot;ltl-formula&amp;quot;,&lt;br /&gt;
 where `P` is an arbitrary process and `ltl-formula` an LTL formula.&lt;br /&gt;
&lt;br /&gt;
==LTL Formulas in a Separate File==&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB it is possible to check several LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formulae with one call. The command has the following syntax &lt;br /&gt;
 probcli -ltlfile FILE ... &lt;br /&gt;
The file FILE contains one or more sections where each section has the form &lt;br /&gt;
 [Name]  Formula &lt;br /&gt;
The formula itself can spread several lines. Additional comments can be added with a leading #. &lt;br /&gt;
If a counter-example is found, the trace of the counter-example is saved into the file ltlce_Name.trace, where &amp;quot;Name&amp;quot; is the name of the formula in the LTL file.&lt;br /&gt;
&lt;br /&gt;
One also can check a single LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &#039;&#039;F&#039;&#039; using the option &#039;-ltlformula&#039; as follows:&lt;br /&gt;
 probcli -ltlformula &amp;quot;F&amp;quot; ...&lt;br /&gt;
&lt;br /&gt;
==LTL Formulae in a Separate File==&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB it is possible to check several LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formulae with one call. The command has the following syntax &lt;br /&gt;
 probcli -ltlfile FILE ... &lt;br /&gt;
The file FILE contains one or more sections where each section has the form &lt;br /&gt;
 [Name]  Formula &lt;br /&gt;
The formula itself can spread in several lines. Additional comments can be added with a leading #.&lt;br /&gt;
If a counter-example is found, the trace of the counter-example is saved into the file ltlce_Name.trace, where &amp;quot;Name&amp;quot; is the name of the formula in the LTL file.&lt;br /&gt;
&lt;br /&gt;
One also can check a single LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &#039;&#039;F&#039;&#039; using the option &#039;-ltlformula&#039; as follows:&lt;br /&gt;
 probcli -ltlformula &amp;quot;F&amp;quot; ...&lt;br /&gt;
&lt;br /&gt;
==LTL Model Checker Output==&lt;br /&gt;
The output provided by the LTL model checker can sometimes reveal some interesting statistical facts about the model and the property being checked on the model. The LTL model checker of ProB uses the tableau approach for checking an LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula on a formal model. To check whether a model &#039;&#039;M&#039;&#039; satisfies a given formula &#039;&#039;f&#039;&#039;, the algorithm generates a search graph composed from the tableau of the formula and the state space of the model. If there is a path in the search graph that is a model for &#039;&#039;f&#039;&#039;, then the formula is satisfiable. The nodes of the search graph are called also &#039;&#039;atoms&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Basically, using the tableau approach we prove that &#039;&#039;M&#039;&#039; satisfies &#039;&#039;f&#039;&#039; by negating the given formula and searching for a for a path fulfilling &#039;&#039;¬f&#039;&#039;. If such a path is found, then we infer that &#039;&#039;M&#039;&#039; violates &#039;&#039;f&#039;&#039;. Otherwise, if no path is found that satisfies &#039;&#039;¬f&#039;&#039;, we conclude that &#039;&#039;M |= f&#039;&#039;. The LTL model checking algorithm of ProB is based on searching for strongly connected components (SCCs) with certain properties to find out whether &#039;&#039;M&#039;&#039; satisfies &#039;&#039;f&#039;&#039;. Finding such an SCC that can be reached from an initial state of &#039;&#039;M&#039;&#039; is a witness for a counter-example for &#039;&#039;f&#039;&#039;. Sometimes, we use fairness to ignore such SCCs that do not fulfill the imposed fairness constraints in order to not impede proving a property by returning of non-fair paths as counter-examples.&lt;br /&gt;
&lt;br /&gt;
The LTL model checker algorithm of ProB is implemented is implemented in C using a callback mechanism for evaluating the atomic propositions and the outgoing transitions in SICStus Prolog. Additionally, the search for SCCs is based on the Tarjan&#039;s algorithm. In the terminal all messages coming from the LTL model checker are preceded either by &amp;quot;LTL (current statistics): &amp;quot; or &amp;quot;LTL model checking:&amp;quot;. The output from the LTL model checker can give helpful insights about the model and the model checking process.&lt;br /&gt;
&lt;br /&gt;
Consider the CSP specifications &amp;quot;dphil_ltl8.csp&amp;quot; representing a model of the dining philosophers problem which resolves the starvation problem by always forcing the first philosopher to pick up first the right fork instead of the left one. In other words, &amp;quot;dphil_ltl8.csp&amp;quot; has no deadlock states. The number of philosophers in the model is 8. Checking the LTL formula &amp;quot;GF [eat.0]&amp;quot; from the command line will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ probcli -ltlformula &amp;quot;GF [eat.0]&amp;quot; dphil_ltl8.csp&lt;br /&gt;
....&lt;br /&gt;
LTL model checking formula&lt;br /&gt;
% parsing_ltl_formula&lt;br /&gt;
% initialising_ltlc&lt;br /&gt;
starting_model_checking&lt;br /&gt;
&lt;br /&gt;
LTL (current statistics): 13280 atoms, 10070 transitions generated, and  2631 callbacks needed.&lt;br /&gt;
&lt;br /&gt;
LTL model checking: found counter-example (lasso-form): intro length = 1126, path in SCC of length = 5&lt;br /&gt;
LTL model checking: memory usage approx. 1924 KiB, 14104 atoms and 10724 transitions generated&lt;br /&gt;
LTL model checking: total time 22492ms, 2803 callbacks needed 22465ms, netto 26ms.&lt;br /&gt;
! An error occurred !&lt;br /&gt;
! source(ltl)&lt;br /&gt;
! Model Check Counter-Example found for: &lt;br /&gt;
! GF [eat.0]&lt;br /&gt;
&lt;br /&gt;
Formula FALSE.&lt;br /&gt;
&lt;br /&gt;
Runtime: 22220 ms&lt;br /&gt;
! *** error occurred ***&lt;br /&gt;
! ltl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As one can clearly see from the output, the LTL model checker fails to prove that &amp;quot;GF [eat.0]&amp;quot; since it has found a counter-example for the formula. Note that the ProB LTL model checker explores the search graph and the state space dynamically. The above data is to be understand as follows:&lt;br /&gt;
* 14104 atoms - the LTL model checker needed to explore 13280 atoms to find a counter-example for the formula. &lt;br /&gt;
* 2631 callbacks needed - to explore the search graph the model checker makes callbacks in order to explore the state space of the model being checked (the exploration runs dynamically). In this case the model checker has needed to explore 2803 states till it finds a counter-example for the formula&lt;br /&gt;
* memory usage approx. 1924 KiB - the memory needed to explore the tableau graph&lt;br /&gt;
* found counter-example (lasso-form) - means that the counter-example being found is path beginning in an initial state of the model and reaching a state that closes a cycle:&lt;br /&gt;
** intro length = 1126: the length of the sub-path from an initial state to the entry point of the cycle&lt;br /&gt;
** path in SCC of length = 5: the cycle is comprised of five states&lt;br /&gt;
* total time 22492ms - the LTL model checker needed about 23 seconds to find the counter-example. Here a distinction between the time needed to explore the state space of the model (2803 callbacks needed 22465ms) and the time spent for generating the tableau graph + the time for identifying the self-fulfilling SCC (netto 26ms)&lt;br /&gt;
* LTL (current statistics) - an intermediate data information is given each 20 seconds spent from the last current data information.&lt;br /&gt;
&lt;br /&gt;
In the example above one can prove the LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &amp;quot;GF [eat.0]&amp;quot; on dphil_ltl6.csp using fairness. One can impose, for example, strong fairness conditions on all transitions of the model and thus verify that &amp;quot;GF [eat.0]&amp;quot; is satisfied under strong fairness. The call looks as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ probcli -ltlformula &amp;quot;SEF =&amp;gt; GF [eat.0]&amp;quot; dphil_ltl8.csp&lt;br /&gt;
...&lt;br /&gt;
LTL model checking formula&lt;br /&gt;
% parsing_ltl_formula&lt;br /&gt;
% initialising_ltlc&lt;br /&gt;
starting_model_checking&lt;br /&gt;
LTL (current statistics): 13016 atoms, 9834 transitions generated, and  2578 callbacks needed.&lt;br /&gt;
LTL (fairness): 0 strongly connected components were rejected, 0 callbacks needed.&lt;br /&gt;
&lt;br /&gt;
LTL (current statistics): 27540 atoms, 44422 transitions generated, and  5123 callbacks needed.&lt;br /&gt;
LTL (fairness): 284 strongly connected components were rejected, 843 callbacks needed.&lt;br /&gt;
.....&lt;br /&gt;
LTL (current statistics): 85980 atoms, 267821 transitions generated, and  19733 callbacks needed.&lt;br /&gt;
LTL (fairness): 454 strongly connected components were rejected, 1924 callbacks needed.&lt;br /&gt;
&lt;br /&gt;
LTL (current statistics): 95648 atoms, 364288 transitions generated, and  22150 callbacks needed.&lt;br /&gt;
LTL (fairness): 773 strongly connected components were rejected, 3085 callbacks needed.&lt;br /&gt;
&lt;br /&gt;
LTL model checking: memory usage approx. 13829 KiB, 96500 atoms and 381625 transitions generated&lt;br /&gt;
LTL model checking: total time 190887ms, 22363 callbacks needed 186690ms, netto 467ms.&lt;br /&gt;
LTL model checking (fairness): 800 strongly connected components were rejected.&lt;br /&gt;
LTL model checking (fairness): total fairness checking time 3729ms, 3246 callbacks needed 3452ms, netto 277ms.&lt;br /&gt;
LTL Formula TRUE.&lt;br /&gt;
No counter example found for SEF =&amp;gt; GF [eat.0].&lt;br /&gt;
Runtime: 188370 ms&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above check no fair counter-example could be find for the formula &amp;quot;GF [eat.0]&amp;quot;. For this check the search graph comprises 96500 atoms and 381625  transitions, far more than the other formula check (without fairness assumptions). Since no fair counter-example was found we can infer that the whole state space of the was explored. Since we know from above 22363 callbacks were needed to explore the search graph, we can infer that the state space of the model has overall 22363 states.&lt;br /&gt;
&lt;br /&gt;
In the output above there is also some information about the fairness checking being performed for the model checker run. The LTL model checker has refuted 800 SCCs in total, i.e. there were found 800 SCCs in the search graph that could serve as a counter-example for &amp;quot;GF [eat.0]&amp;quot; in case no fairness constraints were imposed.&lt;br /&gt;
&lt;br /&gt;
== Other Relevant Tutorials about LTL Model Checking ==&lt;br /&gt;
A brief tutorial on visualizing LTL counter-examples in the Rodin tool can be found [http://www.stups.uni-duesseldorf.de/ProB/index.php5/Tutorial_LTL_Counter-example_View here].&lt;br /&gt;
&lt;br /&gt;
A tutorial of a simple case study, where setting fairness constraints to some of the LTL properties is required, can be found [http://www.stups.uni-duesseldorf.de/ProB/index.php5/Mutual_Exclusion_%28Fairness%29 here].&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=LTL_Model_Checking&amp;diff=3569</id>
		<title>LTL Model Checking</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=LTL_Model_Checking&amp;diff=3569"/>
		<updated>2016-03-11T13:38:25Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* LTL Model Checker Output */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]__NOTOC__&lt;br /&gt;
ProB provides support for LTL (linear temporal logic) model checking. For an introduction to LTL see the [http://en.wikipedia.org/wiki/Linear_temporal_logic Wikipedia Article].&lt;br /&gt;
&lt;br /&gt;
To use this feature, select &amp;quot;Check LTL/CTL Assertions&amp;quot; in the &amp;quot;Verify&amp;quot; menu. The feature can also be accessed by the key combination &amp;quot;Ctrl+L&amp;quot; under Windows and Linux, and by the key combination &amp;quot;Cmd+L&amp;quot; under MacOS. The following window appears:&lt;br /&gt;
&lt;br /&gt;
[[File:ltlviewer.png]]&lt;br /&gt;
&lt;br /&gt;
All LTL formulas that are given in the &amp;quot;DEFINTIONS&amp;quot; section of a B machine are displayed in the list box of the LTL/CTL Assertions Viewer. For CSP-M specifications all LTL formulas given in the LTL pragmas of the loaded CSP-M file will be shown in the viewer. (For more detailed information of how LTL/CTL assertions can be stored into B and CSP-M models see Section &#039;&#039;&#039;Storing LTL Assertions into a Model&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
A new LTL formula can be entered in the entry below the list box. (We explain the supported syntax below). The typed formula can then be either added to the list box by clicking the &amp;quot;Add&amp;quot; button or directly checked by clicking the &amp;quot;Check&amp;quot; button. Before doing that assure whether you are in the proper frame (&amp;quot;Add LTL Formula&amp;quot;) of the bottom part of the LTL viewer.&lt;br /&gt;
&lt;br /&gt;
The LTL model checker can be started for an LTL formula by performing a double-click on the respective formula or typing &amp;quot;Enter&amp;quot; after selecting the respective formula. Each LTL formula in the list box has on the left hand side a symbol that indicates what is the status of the respective formula. An LTL formula can have one of the following statuses (status symbols may differ under different operating systems):&lt;br /&gt;
&lt;br /&gt;
* ? – The formula has not been checked yet.&lt;br /&gt;
* ✔ – The formula is true for all valid paths.&lt;br /&gt;
* ✘ – A counterexample for the formula has been found, i.e. there is a path that violates the formula. In case the formula has been just checked on the model the animator is navigated to the last state of the counterexample. The full path can then be seen in the history. The counterexample can be also obtained by the dotty-viewer after a second double-click on the formula in the assertions’ viewer. &lt;br /&gt;
* ⌚ – The formula is currently checked.&lt;br /&gt;
* ! – The formula check has been aborted by an unexpected error occurrence.&lt;br /&gt;
* ∞ – The formula check is incomplete, i.e. no counterexample was found so far, but the absence of a path that does not satisfy the formula can not be guaranteed because the state space was not fully explored. A new check can be started by a double-click.&lt;br /&gt;
&lt;br /&gt;
All formulas can be checked by &amp;quot;Assertions -&amp;gt; Check All Assertions&amp;quot; in the menu bar. All formulas will be then checked from top to bottom in the list box.&lt;br /&gt;
&lt;br /&gt;
Additionally, the viewer provides a context menu for the list box elements. The context menu can be popped-up by a right-mouse-click on a formula from the list box, and it performs a set of actions available to be performed on the currently selected formula (see Figure below). &lt;br /&gt;
&lt;br /&gt;
[[File:ltlviewercontext.png]]&lt;br /&gt;
&lt;br /&gt;
The old LTL and CTL dialogs can be accessed from &amp;quot;OldLtlViewers&amp;quot; in the menu bar.&lt;br /&gt;
&lt;br /&gt;
==LTL Preferences==&lt;br /&gt;
&lt;br /&gt;
There is a set of options coming with the LTL model checker. In this section we give a brief overview of the preferences. The LTL preferences can be viewed by selecting &amp;quot;LTL Preferences&amp;quot; in the &amp;quot;Preferences&amp;quot; menu of the LTL/CTL Assertions Viewer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Exploring new states&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
The LTL model checker searches in the already explored search space of the model. If a state is encountered that has not been explored before, the state will be explored (i.e. all transitions to successor states are computed). The number of how often this can happen is limited by the field &amp;quot;Max no. of new states&amp;quot;. &lt;br /&gt;
Depending on the LTL formula, a partially explored state space can be sufficient to find a counterexample or to assure the absence of a counterexample. If there&#039;s still the possibility of a counterexample in the remaining unexplored state space, the user will get a message. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Optimizing the process of LTL model checking&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
The process of model checking can be optimized for B and Event-B models by using partial order reduction. The idea of partial order reduction is to execute only a subset of all enabled actions in each state. Thus, only a part of the original state space is checked for the checked property. The reduction of the state space depends on the number of concurrent and independent actions in the model, as well as on the property being checked.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Search Options&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
The model checker searches for a counterexample (i.e. a path that does not satisfy the current formula). Where the checked paths through the model&#039;s search space start depend on the following options in the LTL Preferences’ menu:&lt;br /&gt;
# &#039;&#039;Start search in initialization&#039;&#039;&amp;lt;br/&amp;gt;All paths that start in a state of the initialization of the machine are checked. &lt;br /&gt;
# &#039;&#039;Start search in current state&#039;&#039;&amp;lt;br/&amp;gt;All paths that start in the current state are checked. &lt;br /&gt;
# &#039;&#039;Start in initialization, but check formula in current state&#039;&#039;&amp;lt;br/&amp;gt;All paths that start in a state of the initialization of the machine are checked, but the formula is mapped to the current state. For example, this option can be used to check properties like &amp;quot;Is this state only reachable directly after executing operation `xy`?&amp;quot;: The formula would be `Y[xy]`. This is equivalent to &amp;quot;G (current =&amp;gt; f)&amp;quot; with f as the entered formula and using the option &amp;quot;Start search in initialization&amp;quot;. &lt;br /&gt;
Note: Whereas `Y true` is always false when checked with option 1 or 2, it is usually true (but not in all cases) for option 3.&lt;br /&gt;
&lt;br /&gt;
=== Supported Syntax ===&lt;br /&gt;
&lt;br /&gt;
ProB supports LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt;, an extended version of LTL. In contrast to the standard LTL, LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; provides also support for propositions on transitions, not only on states. In practice,  writing propositions on transitions is allowed by using the constructs `e(...)` and `[...]`. (see below). The LTL model checker of ProB supports Past-LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; as well.&lt;br /&gt;
&lt;br /&gt;
* Atomic propositions can be one of the following:&lt;br /&gt;
**  Predicates can be written in curly braces: `{...}`. E.g. `{card(someset) &amp;gt; 1}`&lt;br /&gt;
**  To check if an operation is enabled in a state use `e(Op)`, where `Op` is the name of the operation.&lt;br /&gt;
**  To start a search from the current state of the animation use `current` (see the section &#039;&#039;&#039;LTL Preferences&#039;&#039;&#039; for more information).&lt;br /&gt;
**  To check if a state has no outgoing transition leading to a different state use `sink`. This can be useful for finding &amp;quot;pseudo&amp;quot;-deadlocks, i.e. states where only query-operations are enabled that do not change the state. Note that `sink` holds for deadlock states as well.&lt;br /&gt;
** For checking if a state is a deadlock state the atomic proposition ` deadlock ` can be used.&lt;br /&gt;
**  To check if a set of operations is disabled in a state use `deadlock(Op1,Op2,...,Opk)`, where Op1,Op2,...,Opk with k&amp;gt;0 are operations of the model. It is also possible to check if specific representations of an operation with arguments are disabled in a state using pattern-matching, e.g.: `deadlock(Op(1),Op(3))`.&lt;br /&gt;
** By means of `deterministic(Op1,Op2,...,Opk)`, where Op1,Op2,...,Opk with k&amp;gt;0 are operations of the model, one can check if maximum one of the operations Op1,Op2,...,Opk is enabled in a state. &lt;br /&gt;
** To check if exactly one operation from a set of operations Op1,Op2,...,Opk is enabled in a state use `controller(Op1,Op2,…,Opk)`.&lt;br /&gt;
&lt;br /&gt;
* Transition propositions:&amp;lt;br&amp;gt;If the next executed operation in the path is `Op`, the expression `[Op]` can be used. Also patter-matching for the arguments of the operation is supported. E.g. `[Op(3,4*v)]` checks if the next operation is `Op` and that the first argument is 3 and the third argument is `4*v` where `v` is a variable of the machine. &amp;lt;br&amp;gt; Arbitrary B expressions can be used as patterns. Constants and variables of the machine can be used. Variables have the values of the state where the operations starts.&lt;br /&gt;
&lt;br /&gt;
* Logical operators&lt;br /&gt;
** `true` and `false`&lt;br /&gt;
**  `not`: negation&lt;br /&gt;
**  `&amp;amp;`, `or` and `=&amp;gt;`: conjunction, disjunction and implication&lt;br /&gt;
&lt;br /&gt;
* Temporal operators (future)&lt;br /&gt;
**  `G f`: globally&lt;br /&gt;
**  `F f`: finally&lt;br /&gt;
**  `X f`: next&lt;br /&gt;
**  `f U g`: until&lt;br /&gt;
**  `f W g`: weak until&lt;br /&gt;
**  `f R g`: release&lt;br /&gt;
&lt;br /&gt;
* Temporal operators (past)&lt;br /&gt;
**  `H f`: history (dual to G)&lt;br /&gt;
**  `O f`: once (dual to F)&lt;br /&gt;
**  `Y f`: yesterday (dual to X)&lt;br /&gt;
**  `f S g`: since (dual to until)&lt;br /&gt;
**  `f T g`: trigger (dual to release)&lt;br /&gt;
&lt;br /&gt;
* Fairness operators &lt;br /&gt;
**  `WF(Op)` or `wf(Op)`: weak fairness, where ` Op` is an operation&lt;br /&gt;
**  `SF(Op)`or `sf(Op)`:  strong fairness, where ` Op` is an operation&lt;br /&gt;
**  `WEF`: weak fairness for all possible operations&lt;br /&gt;
**  `SEF`: strong fairness for all possible operations&lt;br /&gt;
&lt;br /&gt;
==Setting Fairness Constraints==&lt;br /&gt;
&lt;br /&gt;
Fairness is a notion where the search for counterexamples is restricted to paths that do not ignore infinitely the execution of a set of enabled operations imposed by the user as &amp;quot;fair&amp;quot; constraints. One possibility to set fairness constraints in ProB is to encode them in the LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula intended to be checked. For example, for a given LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &amp;quot;f&amp;quot; a set of weak fairness conditions {a1,…,an} can be given as follows: &lt;br /&gt;
 (FG e(a1) =&amp;gt; GF [a1]) &amp;amp; … &amp;amp; (FG e(an) =&amp;gt; GF [an]) =&amp;gt; f.&lt;br /&gt;
In a similar way, strong fairness constraints can be imposed expressed by means of an LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula:&lt;br /&gt;
 (GF e(a1) =&amp;gt; GF [a1]) &amp;amp; … &amp;amp; (GF e(an) =&amp;gt; GF [an]) =&amp;gt; f.&lt;br /&gt;
&lt;br /&gt;
Checking fairness in this way is very often considered to be inefficient as usually the number of atoms (the possible valuations of the property) of the LTL property is exponential in the size of the formula.&amp;lt;ref&amp;gt;O. Lichtenstein and A. Pnueli: &#039;&#039;Checking that Finite State Concurrent Programs Satisfy Their Linear Specification&#039;&#039;. POPL &#039;85, Proceedings of the 12th ACM SIGACT-SIGPLAN Symposium on Principles of Programming Languages, ACM, 1985&amp;lt;/ref&amp;gt; For this reason, the search algorithm of the LTL model checker has been extended in order to allow fairness to be checked efficiently. In addition, new operators have been added to the ProB’s LTL parser for setting fairness constraints to an LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; property. The new operators are &#039;&#039;WF(-)&#039;&#039; and &#039;&#039;SF(-)&#039;&#039; and both accept as argument an operation. The fairness constraints must be given by means of implication: &amp;quot;fair =&amp;gt; f&amp;quot;, where &amp;quot;f&amp;quot; is the property to be checked and &amp;quot;fair&amp;quot; the fairness constraints.&lt;br /&gt;
&lt;br /&gt;
In particular, &amp;quot;fair&amp;quot; can have one of the forms: &amp;quot;wfair&amp;quot;, &amp;quot;sfair&amp;quot;, &amp;quot;wfair &amp;amp; sfair&amp;quot;, and &amp;quot;sfair &amp;amp; wfair&amp;quot;, where &amp;quot;wfair&amp;quot; and &amp;quot;sfair&amp;quot; represent the imposed weak and strong fairness constraints, respectively.&lt;br /&gt;
&lt;br /&gt;
Basically, &amp;quot;wfair&amp;quot; and &amp;quot;sfair&amp;quot; are expressed by means of logical formulas having the following syntax:&lt;br /&gt;
&lt;br /&gt;
* Weak fair conditions (&amp;quot;wfair&amp;quot;):&lt;br /&gt;
** `WF(a)`, where `a` is an operation&lt;br /&gt;
** `&amp;amp;` and `or`: conjunction and disjunction&lt;br /&gt;
&lt;br /&gt;
* Strong fair conditions (&amp;quot;sfair&amp;quot;):&lt;br /&gt;
** `SF(a)`, where `a` is an operation&lt;br /&gt;
** `&amp;amp;` and `or`: conjunction and disjunction&lt;br /&gt;
&lt;br /&gt;
For instance, if we want to check an LTL property &amp;quot;f&amp;quot; on paths that are weak fair in regard to the operations &amp;quot;a&amp;quot; and &amp;quot;b&amp;quot; and additionally strong fair in regard to &amp;quot;c&amp;quot; or &amp;quot;d&amp;quot;, then this can be given as follows:&lt;br /&gt;
 (WF(a) &amp;amp; WF(b)) &amp;amp; (SF(c) or SF(d)) =&amp;gt; f&lt;br /&gt;
&lt;br /&gt;
Note that the operators &#039;&#039;WF(-)&#039;&#039; and &#039;&#039;SF(-)&#039;&#039; cannot appear on the right side of the fairness implication. Basically, &#039;&#039;WF(-)&#039;&#039; and &#039;&#039;SF(-)&#039;&#039; can be described by the following equivalences:&lt;br /&gt;
 WF(a) ≡ (FG e(a) =&amp;gt; GF [a]) and SF(a) ≡ (GF e(a) =&amp;gt; GF [a]), where a is an operation.&lt;br /&gt;
&lt;br /&gt;
For setting fairness constraints on all possible operations of the model being checked use the operators &amp;quot;WEF&amp;quot; and &amp;quot;SEF&amp;quot;. For instance, if &amp;quot;f&amp;quot; is a liveness property and we want to restrict the search only to strongly fair paths, then we can impose the fairness constraints by means of the formula &amp;quot;SEF =&amp;gt; f&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The grammar for imposing fairness constraints by means of the fairness implication (&amp;quot;fair =&amp;gt; f&amp;quot;) looks as follows:&lt;br /&gt;
&lt;br /&gt;
 fair ::= WEF | SEF | wfair | sfair | wfair &amp;amp; sfair | sfair &amp;amp; wfair&amp;lt;br/&amp;gt;&lt;br /&gt;
          wfair ::= wf(a) | ( wfair ) | wfair &amp;amp; wfair | wfair or wfair&amp;lt;br/&amp;gt;&lt;br /&gt;
          sfair ::= sf(a) | ( sfair ) | sfair &amp;amp; sfair | sfair or sfair&lt;br /&gt;
&lt;br /&gt;
where &amp;quot;a&amp;quot; is a transition proposition.&lt;br /&gt;
&lt;br /&gt;
==Storing LTL Assertions in the Model==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Storing LTL formulas in B machines&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
LTL formulas can be stored in the `DEFINITIONS` section of a B machine. The name of the definition must start with `ASSERT_LTL` and a string must be specified. In case there is more than one LTL assertion given in the ‘DEFINITIONS’ section, the particular LTL assertions must be separated by semicolon. For example: &lt;br /&gt;
&lt;br /&gt;
 DEFINITIONS &lt;br /&gt;
   ASSERT_LTL  == &amp;quot;G (e(SetCruiseSpeed) =&amp;gt; e(CruiseBecomesNotAllowed))&amp;quot;;&lt;br /&gt;
   ASSERT_LTL1 == &amp;quot;G (e(CruiseBecomesNotAllowed) =&amp;gt; e(SetCruiseSpeed))&amp;quot;;&lt;br /&gt;
   ASSERT_LTL2 == &amp;quot;G (e(CruiseBecomesNotAllowed) =&amp;gt; (ObstacleDisappears))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Storing LTL formulas in CSP-M specifications&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
LTL formulas can be stored within pragmas in CSP-M specifications. A pragma in which a single LTL formula is stored is given by &amp;quot;{-# assert_ltl &amp;quot;f&amp;quot; &amp;quot;c&amp;quot; #-}&amp;quot;, where &amp;quot;assert_ltl&amp;quot; indicates the type of the information stored in the pragma (there are currently two types: assert_ltl and assert_ctl), and is followed by the LTL formula `f` and a comment `c` (the comment is optional). Both, the LTL formula and the comment, must be enclosed in double quotes. &lt;br /&gt;
It is also possible to give several LTL formulas in a single pragma within which the corresponding LTL assertions are separated by semicolon. For example:&lt;br /&gt;
&lt;br /&gt;
 {-# assert_ltl &amp;quot;SF(enter.1) &amp;amp; WF(req.1) =&amp;gt; GF([enter.1])&amp;quot;;&lt;br /&gt;
     assert_ltl &amp;quot;SF(enter.2) &amp;amp; WF(req.2) =&amp;gt; GF([enter.2])&amp;quot;;&lt;br /&gt;
     assert_ltl &amp;quot;GF [enter.1] &amp;amp; GF [enter.2]&amp;quot; &amp;quot;Should fail.&amp;quot;#-}&lt;br /&gt;
&lt;br /&gt;
Note that a semicolon must not follow the last assertion in a pragma.&lt;br /&gt;
&lt;br /&gt;
For CSP-M specifications, it is also possible to assert LTL-formulae to particular processes in the model. This is possible by means of ``assert`` declarations, which have been recently included to the CSP-M grammar of the ProB CSP-M parser:&lt;br /&gt;
&lt;br /&gt;
 assert P |= LTL: &amp;quot;ltl-formula&amp;quot;,&lt;br /&gt;
 where `P` is an arbitrary process and `ltl-formula` an LTL formula.&lt;br /&gt;
&lt;br /&gt;
==LTL Formulas in a Separate File==&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB it is possible to check several LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formulae with one call. The command has the following syntax &lt;br /&gt;
 probcli -ltlfile FILE ... &lt;br /&gt;
The file FILE contains one or more sections where each section has the form &lt;br /&gt;
 [Name]  Formula &lt;br /&gt;
The formula itself can spread several lines. Additional comments can be added with a leading #. &lt;br /&gt;
If a counter-example is found, the trace of the counter-example is saved into the file ltlce_Name.trace, where &amp;quot;Name&amp;quot; is the name of the formula in the LTL file.&lt;br /&gt;
&lt;br /&gt;
One also can check a single LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &#039;&#039;F&#039;&#039; using the option &#039;-ltlformula&#039; as follows:&lt;br /&gt;
 probcli -ltlformula &amp;quot;F&amp;quot; ...&lt;br /&gt;
&lt;br /&gt;
==LTL Formulae in a Separate File==&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB it is possible to check several LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formulae with one call. The command has the following syntax &lt;br /&gt;
 probcli -ltlfile FILE ... &lt;br /&gt;
The file FILE contains one or more sections where each section has the form &lt;br /&gt;
 [Name]  Formula &lt;br /&gt;
The formula itself can spread in several lines. Additional comments can be added with a leading #.&lt;br /&gt;
If a counter-example is found, the trace of the counter-example is saved into the file ltlce_Name.trace, where &amp;quot;Name&amp;quot; is the name of the formula in the LTL file.&lt;br /&gt;
&lt;br /&gt;
One also can check a single LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &#039;&#039;F&#039;&#039; using the option &#039;-ltlformula&#039; as follows:&lt;br /&gt;
 probcli -ltlformula &amp;quot;F&amp;quot; ...&lt;br /&gt;
&lt;br /&gt;
==LTL Model Checker Output==&lt;br /&gt;
The output provided by the LTL model checker can sometimes reveal some interesting statistical facts about the model and the property being checked on the model. The LTL model checker of ProB uses the tableau approach for checking an LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula on a formal model. To check whether a model &#039;&#039;M&#039;&#039; satisfies a given formula &#039;&#039;f&#039;&#039;, the algorithm generates a search graph composed from the tableau of the formula and the state space of the model. If there is a path in the search graph that is a model for &#039;&#039;f&#039;&#039;, then the formula is satisfiable. The nodes of the search graph are called also &#039;&#039;atoms&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Basically, using the tableau approach we prove that &#039;&#039;M&#039;&#039; satisfies &#039;&#039;f&#039;&#039; by negating the given formula and searching for a for a path fulfilling &#039;&#039;¬f&#039;&#039;. If such a path is found, then we infer that &#039;&#039;M&#039;&#039; violates &#039;&#039;f&#039;&#039;. Otherwise, if no path is found that satisfies &#039;&#039;¬f&#039;&#039;, we conclude that &#039;&#039;M |= f&#039;&#039;. The LTL model checking algorithm of ProB is based on searching for strongly connected components (SCCs) with certain properties to find out whether &#039;&#039;M&#039;&#039; satisfies &#039;&#039;f&#039;&#039;. Finding such an SCC that can be reached from an initial state of &#039;&#039;M&#039;&#039; is a witness for a counter-example for &#039;&#039;f&#039;&#039;. Sometimes, we use fairness to ignore such SCCs that do not fulfill the imposed fairness constraints in order to not impede proving a property by returning of non-fair paths as counter-examples.&lt;br /&gt;
&lt;br /&gt;
The LTL model checker algorithm of ProB is implemented is implemented in C using a callback mechanism for evaluating the atomic propositions and the outgoing transitions in SICStus Prolog. Additionally, the search for SCCs is based on the Tarjan&#039;s algorithm. In the terminal all messages coming from the LTL model checker are preceded either by &amp;quot;LTL (current statistics): &amp;quot; or &amp;quot;LTL model checking:&amp;quot;. The output from the LTL model checker can give helpful insights about the model and the model checking process.&lt;br /&gt;
&lt;br /&gt;
Consider the CSP specifications &amp;quot;dphil_ltl8.csp&amp;quot; representing a model of the dining philosophers problem which resolves the starvation problem by always forcing the first philosopher to pick up first the right fork instead of the left one. In other words, &amp;quot;dphil_ltl8.csp&amp;quot; has no deadlock states. The number of philosophers in the model is 8. Checking the LTL formula &amp;quot;GF [eat.0]&amp;quot; from the command line will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ probcli -ltlformula &amp;quot;GF [eat.0]&amp;quot; dphil_ltl8.csp&lt;br /&gt;
....&lt;br /&gt;
LTL model checking formula&lt;br /&gt;
% parsing_ltl_formula&lt;br /&gt;
% initialising_ltlc&lt;br /&gt;
starting_model_checking&lt;br /&gt;
&lt;br /&gt;
LTL (current statistics): 13280 atoms, 10070 transitions generated, and  2631 callbacks needed.&lt;br /&gt;
&lt;br /&gt;
LTL model checking: found counter-example (lasso-form): intro length = 1126, path in SCC of length = 5&lt;br /&gt;
LTL model checking: memory usage approx. 1924 KiB, 14104 atoms and 10724 transitions generated&lt;br /&gt;
LTL model checking: total time 22492ms, 2803 callbacks needed 22465ms, netto 26ms.&lt;br /&gt;
! An error occurred !&lt;br /&gt;
! source(ltl)&lt;br /&gt;
! Model Check Counter-Example found for: &lt;br /&gt;
! GF [eat.0]&lt;br /&gt;
&lt;br /&gt;
Formula FALSE.&lt;br /&gt;
&lt;br /&gt;
Runtime: 22220 ms&lt;br /&gt;
! *** error occurred ***&lt;br /&gt;
! ltl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As one can clearly see from the output, the LTL model checker fails to prove that &amp;quot;GF [eat.0]&amp;quot; since it has found a counter-example for the formula. Note that the ProB LTL model checker explores the search graph and the state space dynamically. The above data is to be understand as follows:&lt;br /&gt;
* 14104 atoms - the LTL model checker needed to explore 13280 atoms to find a counter-example for the formula. &lt;br /&gt;
* 2631 callbacks needed - to explore the search graph the model checker makes callbacks in order to explore the state space of the model being checked (the exploration runs dynamically). In this case the model checker has needed to explore 2803 states till it finds a counter-example for the formula&lt;br /&gt;
* memory usage approx. 1924 KiB - the memory needed to explore the tableau graph&lt;br /&gt;
* found counter-example (lasso-form) - means that the counter-example being found is path beginning in an initial state of the model and reaching a state that closes a cycle:&lt;br /&gt;
** intro length = 1126: the length of the sub-path from initial state to the entry point of the cycle&lt;br /&gt;
** path in SCC of length = 5: the cycle is comprised of five states&lt;br /&gt;
* total time 22492ms - the LTL model checker needed about 23 seconds to find the counter-example. Here a distinction between the time needed to explore the state space of the model (2803 callbacks needed 22465ms) and the time spent for generating the tableau graph + the time for identifying the self-fulfilling SCC (netto 26ms)&lt;br /&gt;
* LTL (current statistics) - an intermediate data information is given each 20 seconds spent from the last current data information.&lt;br /&gt;
&lt;br /&gt;
In the example above one can prove the LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &amp;quot;GF [eat.0]&amp;quot; on dphil_ltl6.csp using fairness. One can impose, for example, strong fairness conditions on all transitions of the model and thus verify that &amp;quot;GF [eat.0]&amp;quot; is satisfied under strong fairness. The call looks as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ probcli -ltlformula &amp;quot;SEF =&amp;gt; GF [eat.0]&amp;quot; dphil_ltl8.csp&lt;br /&gt;
...&lt;br /&gt;
LTL model checking formula&lt;br /&gt;
% parsing_ltl_formula&lt;br /&gt;
% initialising_ltlc&lt;br /&gt;
starting_model_checking&lt;br /&gt;
LTL (current statistics): 13016 atoms, 9834 transitions generated, and  2578 callbacks needed.&lt;br /&gt;
LTL (fairness): 0 strongly connected components were rejected, 0 callbacks needed.&lt;br /&gt;
&lt;br /&gt;
LTL (current statistics): 27540 atoms, 44422 transitions generated, and  5123 callbacks needed.&lt;br /&gt;
LTL (fairness): 284 strongly connected components were rejected, 843 callbacks needed.&lt;br /&gt;
.....&lt;br /&gt;
LTL (current statistics): 85980 atoms, 267821 transitions generated, and  19733 callbacks needed.&lt;br /&gt;
LTL (fairness): 454 strongly connected components were rejected, 1924 callbacks needed.&lt;br /&gt;
&lt;br /&gt;
LTL (current statistics): 95648 atoms, 364288 transitions generated, and  22150 callbacks needed.&lt;br /&gt;
LTL (fairness): 773 strongly connected components were rejected, 3085 callbacks needed.&lt;br /&gt;
&lt;br /&gt;
LTL model checking: memory usage approx. 13829 KiB, 96500 atoms and 381625 transitions generated&lt;br /&gt;
LTL model checking: total time 190887ms, 22363 callbacks needed 186690ms, netto 467ms.&lt;br /&gt;
LTL model checking (fairness): 800 strongly connected components were rejected.&lt;br /&gt;
LTL model checking (fairness): total fairness checking time 3729ms, 3246 callbacks needed 3452ms, netto 277ms.&lt;br /&gt;
LTL Formula TRUE.&lt;br /&gt;
No counter example found for SEF =&amp;gt; GF [eat.0].&lt;br /&gt;
Runtime: 188370 ms&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above check no fair counter-example could be find for the formula &amp;quot;GF [eat.0]&amp;quot;. For this check the search graph comprises 96500 atoms and 381625  transitions, far more than the other formula check (without fairness assumptions). Since no fair counter-example was found we can infer that the whole state space of the was explored. Since we know from above 22363 callbacks were needed to explore the search graph, we can infer that the state space of the model has overall 22363 states.&lt;br /&gt;
&lt;br /&gt;
In the output above there is also some information about the fairness checking being performed for the model checker run. The LTL model checker has refuted 800 SCCs in total, i.e. there were found 800 SCCs in the search graph that could serve as a counter-example for &amp;quot;GF [eat.0]&amp;quot; in case no fairness constraints were imposed.&lt;br /&gt;
&lt;br /&gt;
== Other Relevant Tutorials about LTL Model Checking ==&lt;br /&gt;
A brief tutorial on visualizing LTL counter-examples in the Rodin tool can be found [http://www.stups.uni-duesseldorf.de/ProB/index.php5/Tutorial_LTL_Counter-example_View here].&lt;br /&gt;
&lt;br /&gt;
A tutorial of a simple case study, where setting fairness constraints to some of the LTL properties is required, can be found [http://www.stups.uni-duesseldorf.de/ProB/index.php5/Mutual_Exclusion_%28Fairness%29 here].&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=LTL_Model_Checking&amp;diff=3568</id>
		<title>LTL Model Checking</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=LTL_Model_Checking&amp;diff=3568"/>
		<updated>2016-03-11T11:29:49Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* LTL formulae in a separate file */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]__NOTOC__&lt;br /&gt;
ProB provides support for LTL (linear temporal logic) model checking. For an introduction to LTL see the [http://en.wikipedia.org/wiki/Linear_temporal_logic Wikipedia Article].&lt;br /&gt;
&lt;br /&gt;
To use this feature, select &amp;quot;Check LTL/CTL Assertions&amp;quot; in the &amp;quot;Verify&amp;quot; menu. The feature can also be accessed by the key combination &amp;quot;Ctrl+L&amp;quot; under Windows and Linux, and by the key combination &amp;quot;Cmd+L&amp;quot; under MacOS. The following window appears:&lt;br /&gt;
&lt;br /&gt;
[[File:ltlviewer.png]]&lt;br /&gt;
&lt;br /&gt;
All LTL formulas that are given in the &amp;quot;DEFINTIONS&amp;quot; section of a B machine are displayed in the list box of the LTL/CTL Assertions Viewer. For CSP-M specifications all LTL formulas given in the LTL pragmas of the loaded CSP-M file will be shown in the viewer. (For more detailed information of how LTL/CTL assertions can be stored into B and CSP-M models see Section &#039;&#039;&#039;Storing LTL Assertions into a Model&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
A new LTL formula can be entered in the entry below the list box. (We explain the supported syntax below). The typed formula can then be either added to the list box by clicking the &amp;quot;Add&amp;quot; button or directly checked by clicking the &amp;quot;Check&amp;quot; button. Before doing that assure whether you are in the proper frame (&amp;quot;Add LTL Formula&amp;quot;) of the bottom part of the LTL viewer.&lt;br /&gt;
&lt;br /&gt;
The LTL model checker can be started for an LTL formula by performing a double-click on the respective formula or typing &amp;quot;Enter&amp;quot; after selecting the respective formula. Each LTL formula in the list box has on the left hand side a symbol that indicates what is the status of the respective formula. An LTL formula can have one of the following statuses (status symbols may differ under different operating systems):&lt;br /&gt;
&lt;br /&gt;
* ? – The formula has not been checked yet.&lt;br /&gt;
* ✔ – The formula is true for all valid paths.&lt;br /&gt;
* ✘ – A counterexample for the formula has been found, i.e. there is a path that violates the formula. In case the formula has been just checked on the model the animator is navigated to the last state of the counterexample. The full path can then be seen in the history. The counterexample can be also obtained by the dotty-viewer after a second double-click on the formula in the assertions’ viewer. &lt;br /&gt;
* ⌚ – The formula is currently checked.&lt;br /&gt;
* ! – The formula check has been aborted by an unexpected error occurrence.&lt;br /&gt;
* ∞ – The formula check is incomplete, i.e. no counterexample was found so far, but the absence of a path that does not satisfy the formula can not be guaranteed because the state space was not fully explored. A new check can be started by a double-click.&lt;br /&gt;
&lt;br /&gt;
All formulas can be checked by &amp;quot;Assertions -&amp;gt; Check All Assertions&amp;quot; in the menu bar. All formulas will be then checked from top to bottom in the list box.&lt;br /&gt;
&lt;br /&gt;
Additionally, the viewer provides a context menu for the list box elements. The context menu can be popped-up by a right-mouse-click on a formula from the list box, and it performs a set of actions available to be performed on the currently selected formula (see Figure below). &lt;br /&gt;
&lt;br /&gt;
[[File:ltlviewercontext.png]]&lt;br /&gt;
&lt;br /&gt;
The old LTL and CTL dialogs can be accessed from &amp;quot;OldLtlViewers&amp;quot; in the menu bar.&lt;br /&gt;
&lt;br /&gt;
==LTL Preferences==&lt;br /&gt;
&lt;br /&gt;
There is a set of options coming with the LTL model checker. In this section we give a brief overview of the preferences. The LTL preferences can be viewed by selecting &amp;quot;LTL Preferences&amp;quot; in the &amp;quot;Preferences&amp;quot; menu of the LTL/CTL Assertions Viewer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Exploring new states&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
The LTL model checker searches in the already explored search space of the model. If a state is encountered that has not been explored before, the state will be explored (i.e. all transitions to successor states are computed). The number of how often this can happen is limited by the field &amp;quot;Max no. of new states&amp;quot;. &lt;br /&gt;
Depending on the LTL formula, a partially explored state space can be sufficient to find a counterexample or to assure the absence of a counterexample. If there&#039;s still the possibility of a counterexample in the remaining unexplored state space, the user will get a message. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Optimizing the process of LTL model checking&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
The process of model checking can be optimized for B and Event-B models by using partial order reduction. The idea of partial order reduction is to execute only a subset of all enabled actions in each state. Thus, only a part of the original state space is checked for the checked property. The reduction of the state space depends on the number of concurrent and independent actions in the model, as well as on the property being checked.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Search Options&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
The model checker searches for a counterexample (i.e. a path that does not satisfy the current formula). Where the checked paths through the model&#039;s search space start depend on the following options in the LTL Preferences’ menu:&lt;br /&gt;
# &#039;&#039;Start search in initialization&#039;&#039;&amp;lt;br/&amp;gt;All paths that start in a state of the initialization of the machine are checked. &lt;br /&gt;
# &#039;&#039;Start search in current state&#039;&#039;&amp;lt;br/&amp;gt;All paths that start in the current state are checked. &lt;br /&gt;
# &#039;&#039;Start in initialization, but check formula in current state&#039;&#039;&amp;lt;br/&amp;gt;All paths that start in a state of the initialization of the machine are checked, but the formula is mapped to the current state. For example, this option can be used to check properties like &amp;quot;Is this state only reachable directly after executing operation `xy`?&amp;quot;: The formula would be `Y[xy]`. This is equivalent to &amp;quot;G (current =&amp;gt; f)&amp;quot; with f as the entered formula and using the option &amp;quot;Start search in initialization&amp;quot;. &lt;br /&gt;
Note: Whereas `Y true` is always false when checked with option 1 or 2, it is usually true (but not in all cases) for option 3.&lt;br /&gt;
&lt;br /&gt;
=== Supported Syntax ===&lt;br /&gt;
&lt;br /&gt;
ProB supports LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt;, an extended version of LTL. In contrast to the standard LTL, LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; provides also support for propositions on transitions, not only on states. In practice,  writing propositions on transitions is allowed by using the constructs `e(...)` and `[...]`. (see below). The LTL model checker of ProB supports Past-LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; as well.&lt;br /&gt;
&lt;br /&gt;
* Atomic propositions can be one of the following:&lt;br /&gt;
**  Predicates can be written in curly braces: `{...}`. E.g. `{card(someset) &amp;gt; 1}`&lt;br /&gt;
**  To check if an operation is enabled in a state use `e(Op)`, where `Op` is the name of the operation.&lt;br /&gt;
**  To start a search from the current state of the animation use `current` (see the section &#039;&#039;&#039;LTL Preferences&#039;&#039;&#039; for more information).&lt;br /&gt;
**  To check if a state has no outgoing transition leading to a different state use `sink`. This can be useful for finding &amp;quot;pseudo&amp;quot;-deadlocks, i.e. states where only query-operations are enabled that do not change the state. Note that `sink` holds for deadlock states as well.&lt;br /&gt;
** For checking if a state is a deadlock state the atomic proposition ` deadlock ` can be used.&lt;br /&gt;
**  To check if a set of operations is disabled in a state use `deadlock(Op1,Op2,...,Opk)`, where Op1,Op2,...,Opk with k&amp;gt;0 are operations of the model. It is also possible to check if specific representations of an operation with arguments are disabled in a state using pattern-matching, e.g.: `deadlock(Op(1),Op(3))`.&lt;br /&gt;
** By means of `deterministic(Op1,Op2,...,Opk)`, where Op1,Op2,...,Opk with k&amp;gt;0 are operations of the model, one can check if maximum one of the operations Op1,Op2,...,Opk is enabled in a state. &lt;br /&gt;
** To check if exactly one operation from a set of operations Op1,Op2,...,Opk is enabled in a state use `controller(Op1,Op2,…,Opk)`.&lt;br /&gt;
&lt;br /&gt;
* Transition propositions:&amp;lt;br&amp;gt;If the next executed operation in the path is `Op`, the expression `[Op]` can be used. Also patter-matching for the arguments of the operation is supported. E.g. `[Op(3,4*v)]` checks if the next operation is `Op` and that the first argument is 3 and the third argument is `4*v` where `v` is a variable of the machine. &amp;lt;br&amp;gt; Arbitrary B expressions can be used as patterns. Constants and variables of the machine can be used. Variables have the values of the state where the operations starts.&lt;br /&gt;
&lt;br /&gt;
* Logical operators&lt;br /&gt;
** `true` and `false`&lt;br /&gt;
**  `not`: negation&lt;br /&gt;
**  `&amp;amp;`, `or` and `=&amp;gt;`: conjunction, disjunction and implication&lt;br /&gt;
&lt;br /&gt;
* Temporal operators (future)&lt;br /&gt;
**  `G f`: globally&lt;br /&gt;
**  `F f`: finally&lt;br /&gt;
**  `X f`: next&lt;br /&gt;
**  `f U g`: until&lt;br /&gt;
**  `f W g`: weak until&lt;br /&gt;
**  `f R g`: release&lt;br /&gt;
&lt;br /&gt;
* Temporal operators (past)&lt;br /&gt;
**  `H f`: history (dual to G)&lt;br /&gt;
**  `O f`: once (dual to F)&lt;br /&gt;
**  `Y f`: yesterday (dual to X)&lt;br /&gt;
**  `f S g`: since (dual to until)&lt;br /&gt;
**  `f T g`: trigger (dual to release)&lt;br /&gt;
&lt;br /&gt;
* Fairness operators &lt;br /&gt;
**  `WF(Op)` or `wf(Op)`: weak fairness, where ` Op` is an operation&lt;br /&gt;
**  `SF(Op)`or `sf(Op)`:  strong fairness, where ` Op` is an operation&lt;br /&gt;
**  `WEF`: weak fairness for all possible operations&lt;br /&gt;
**  `SEF`: strong fairness for all possible operations&lt;br /&gt;
&lt;br /&gt;
==Setting Fairness Constraints==&lt;br /&gt;
&lt;br /&gt;
Fairness is a notion where the search for counterexamples is restricted to paths that do not ignore infinitely the execution of a set of enabled operations imposed by the user as &amp;quot;fair&amp;quot; constraints. One possibility to set fairness constraints in ProB is to encode them in the LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula intended to be checked. For example, for a given LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &amp;quot;f&amp;quot; a set of weak fairness conditions {a1,…,an} can be given as follows: &lt;br /&gt;
 (FG e(a1) =&amp;gt; GF [a1]) &amp;amp; … &amp;amp; (FG e(an) =&amp;gt; GF [an]) =&amp;gt; f.&lt;br /&gt;
In a similar way, strong fairness constraints can be imposed expressed by means of an LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula:&lt;br /&gt;
 (GF e(a1) =&amp;gt; GF [a1]) &amp;amp; … &amp;amp; (GF e(an) =&amp;gt; GF [an]) =&amp;gt; f.&lt;br /&gt;
&lt;br /&gt;
Checking fairness in this way is very often considered to be inefficient as usually the number of atoms (the possible valuations of the property) of the LTL property is exponential in the size of the formula.&amp;lt;ref&amp;gt;O. Lichtenstein and A. Pnueli: &#039;&#039;Checking that Finite State Concurrent Programs Satisfy Their Linear Specification&#039;&#039;. POPL &#039;85, Proceedings of the 12th ACM SIGACT-SIGPLAN Symposium on Principles of Programming Languages, ACM, 1985&amp;lt;/ref&amp;gt; For this reason, the search algorithm of the LTL model checker has been extended in order to allow fairness to be checked efficiently. In addition, new operators have been added to the ProB’s LTL parser for setting fairness constraints to an LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; property. The new operators are &#039;&#039;WF(-)&#039;&#039; and &#039;&#039;SF(-)&#039;&#039; and both accept as argument an operation. The fairness constraints must be given by means of implication: &amp;quot;fair =&amp;gt; f&amp;quot;, where &amp;quot;f&amp;quot; is the property to be checked and &amp;quot;fair&amp;quot; the fairness constraints.&lt;br /&gt;
&lt;br /&gt;
In particular, &amp;quot;fair&amp;quot; can have one of the forms: &amp;quot;wfair&amp;quot;, &amp;quot;sfair&amp;quot;, &amp;quot;wfair &amp;amp; sfair&amp;quot;, and &amp;quot;sfair &amp;amp; wfair&amp;quot;, where &amp;quot;wfair&amp;quot; and &amp;quot;sfair&amp;quot; represent the imposed weak and strong fairness constraints, respectively.&lt;br /&gt;
&lt;br /&gt;
Basically, &amp;quot;wfair&amp;quot; and &amp;quot;sfair&amp;quot; are expressed by means of logical formulas having the following syntax:&lt;br /&gt;
&lt;br /&gt;
* Weak fair conditions (&amp;quot;wfair&amp;quot;):&lt;br /&gt;
** `WF(a)`, where `a` is an operation&lt;br /&gt;
** `&amp;amp;` and `or`: conjunction and disjunction&lt;br /&gt;
&lt;br /&gt;
* Strong fair conditions (&amp;quot;sfair&amp;quot;):&lt;br /&gt;
** `SF(a)`, where `a` is an operation&lt;br /&gt;
** `&amp;amp;` and `or`: conjunction and disjunction&lt;br /&gt;
&lt;br /&gt;
For instance, if we want to check an LTL property &amp;quot;f&amp;quot; on paths that are weak fair in regard to the operations &amp;quot;a&amp;quot; and &amp;quot;b&amp;quot; and additionally strong fair in regard to &amp;quot;c&amp;quot; or &amp;quot;d&amp;quot;, then this can be given as follows:&lt;br /&gt;
 (WF(a) &amp;amp; WF(b)) &amp;amp; (SF(c) or SF(d)) =&amp;gt; f&lt;br /&gt;
&lt;br /&gt;
Note that the operators &#039;&#039;WF(-)&#039;&#039; and &#039;&#039;SF(-)&#039;&#039; cannot appear on the right side of the fairness implication. Basically, &#039;&#039;WF(-)&#039;&#039; and &#039;&#039;SF(-)&#039;&#039; can be described by the following equivalences:&lt;br /&gt;
 WF(a) ≡ (FG e(a) =&amp;gt; GF [a]) and SF(a) ≡ (GF e(a) =&amp;gt; GF [a]), where a is an operation.&lt;br /&gt;
&lt;br /&gt;
For setting fairness constraints on all possible operations of the model being checked use the operators &amp;quot;WEF&amp;quot; and &amp;quot;SEF&amp;quot;. For instance, if &amp;quot;f&amp;quot; is a liveness property and we want to restrict the search only to strongly fair paths, then we can impose the fairness constraints by means of the formula &amp;quot;SEF =&amp;gt; f&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The grammar for imposing fairness constraints by means of the fairness implication (&amp;quot;fair =&amp;gt; f&amp;quot;) looks as follows:&lt;br /&gt;
&lt;br /&gt;
 fair ::= WEF | SEF | wfair | sfair | wfair &amp;amp; sfair | sfair &amp;amp; wfair&amp;lt;br/&amp;gt;&lt;br /&gt;
          wfair ::= wf(a) | ( wfair ) | wfair &amp;amp; wfair | wfair or wfair&amp;lt;br/&amp;gt;&lt;br /&gt;
          sfair ::= sf(a) | ( sfair ) | sfair &amp;amp; sfair | sfair or sfair&lt;br /&gt;
&lt;br /&gt;
where &amp;quot;a&amp;quot; is a transition proposition.&lt;br /&gt;
&lt;br /&gt;
==Storing LTL Assertions in the Model==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Storing LTL formulas in B machines&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
LTL formulas can be stored in the `DEFINITIONS` section of a B machine. The name of the definition must start with `ASSERT_LTL` and a string must be specified. In case there is more than one LTL assertion given in the ‘DEFINITIONS’ section, the particular LTL assertions must be separated by semicolon. For example: &lt;br /&gt;
&lt;br /&gt;
 DEFINITIONS &lt;br /&gt;
   ASSERT_LTL  == &amp;quot;G (e(SetCruiseSpeed) =&amp;gt; e(CruiseBecomesNotAllowed))&amp;quot;;&lt;br /&gt;
   ASSERT_LTL1 == &amp;quot;G (e(CruiseBecomesNotAllowed) =&amp;gt; e(SetCruiseSpeed))&amp;quot;;&lt;br /&gt;
   ASSERT_LTL2 == &amp;quot;G (e(CruiseBecomesNotAllowed) =&amp;gt; (ObstacleDisappears))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Storing LTL formulas in CSP-M specifications&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
LTL formulas can be stored within pragmas in CSP-M specifications. A pragma in which a single LTL formula is stored is given by &amp;quot;{-# assert_ltl &amp;quot;f&amp;quot; &amp;quot;c&amp;quot; #-}&amp;quot;, where &amp;quot;assert_ltl&amp;quot; indicates the type of the information stored in the pragma (there are currently two types: assert_ltl and assert_ctl), and is followed by the LTL formula `f` and a comment `c` (the comment is optional). Both, the LTL formula and the comment, must be enclosed in double quotes. &lt;br /&gt;
It is also possible to give several LTL formulas in a single pragma within which the corresponding LTL assertions are separated by semicolon. For example:&lt;br /&gt;
&lt;br /&gt;
 {-# assert_ltl &amp;quot;SF(enter.1) &amp;amp; WF(req.1) =&amp;gt; GF([enter.1])&amp;quot;;&lt;br /&gt;
     assert_ltl &amp;quot;SF(enter.2) &amp;amp; WF(req.2) =&amp;gt; GF([enter.2])&amp;quot;;&lt;br /&gt;
     assert_ltl &amp;quot;GF [enter.1] &amp;amp; GF [enter.2]&amp;quot; &amp;quot;Should fail.&amp;quot;#-}&lt;br /&gt;
&lt;br /&gt;
Note that a semicolon must not follow the last assertion in a pragma.&lt;br /&gt;
&lt;br /&gt;
For CSP-M specifications, it is also possible to assert LTL-formulae to particular processes in the model. This is possible by means of ``assert`` declarations, which have been recently included to the CSP-M grammar of the ProB CSP-M parser:&lt;br /&gt;
&lt;br /&gt;
 assert P |= LTL: &amp;quot;ltl-formula&amp;quot;,&lt;br /&gt;
 where `P` is an arbitrary process and `ltl-formula` an LTL formula.&lt;br /&gt;
&lt;br /&gt;
==LTL Formulas in a Separate File==&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB it is possible to check several LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formulae with one call. The command has the following syntax &lt;br /&gt;
 probcli -ltlfile FILE ... &lt;br /&gt;
The file FILE contains one or more sections where each section has the form &lt;br /&gt;
 [Name]  Formula &lt;br /&gt;
The formula itself can spread several lines. Additional comments can be added with a leading #. &lt;br /&gt;
If a counter-example is found, the trace of the counter-example is saved into the file ltlce_Name.trace, where &amp;quot;Name&amp;quot; is the name of the formula in the LTL file.&lt;br /&gt;
&lt;br /&gt;
One also can check a single LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &#039;&#039;F&#039;&#039; using the option &#039;-ltlformula&#039; as follows:&lt;br /&gt;
 probcli -ltlformula &amp;quot;F&amp;quot; ...&lt;br /&gt;
&lt;br /&gt;
==LTL Formulae in a Separate File==&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB it is possible to check several LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formulae with one call. The command has the following syntax &lt;br /&gt;
 probcli -ltlfile FILE ... &lt;br /&gt;
The file FILE contains one or more sections where each section has the form &lt;br /&gt;
 [Name]  Formula &lt;br /&gt;
The formula itself can spread in several lines. Additional comments can be added with a leading #.&lt;br /&gt;
If a counter-example is found, the trace of the counter-example is saved into the file ltlce_Name.trace, where &amp;quot;Name&amp;quot; is the name of the formula in the LTL file.&lt;br /&gt;
&lt;br /&gt;
One also can check a single LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &#039;&#039;F&#039;&#039; using the option &#039;-ltlformula&#039; as follows:&lt;br /&gt;
 probcli -ltlformula &amp;quot;F&amp;quot; ...&lt;br /&gt;
&lt;br /&gt;
==LTL Model Checker Output==&lt;br /&gt;
The output provided by the LTL model checker can sometimes reveal some interesting statistical facts about the model and the property being checked on the model. The LTL model checker of ProB uses the tableau approach for checking an LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula on a formal model. To check whether a model &#039;&#039;M&#039;&#039; satisfies a given formula &#039;&#039;f&#039;&#039;, the algorithm generates a search graph composed from the tableau of the formula and the state space of the model. If there is a path in the search graph that is a model for &#039;&#039;f&#039;&#039;, then the formula is satisfiable. The nodes of the search graph are called also &#039;&#039;atoms&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Basically, using the tableau approach we prove that &#039;&#039;M&#039;&#039; satisfies &#039;&#039;f&#039;&#039; by negating the given formula and searching for a for a path fulfilling &#039;&#039;¬f&#039;&#039;. If such a path is found, then we infer that &#039;&#039;M&#039;&#039; violates &#039;&#039;f&#039;&#039;. Otherwise, if no path is found that satisfies &#039;&#039;¬f&#039;&#039;, we conclude that &#039;&#039;M |= f&#039;&#039;. The LTL model checking algorithm of ProB is based on searching for strongly connected components (SCCs) with certain properties to find out whether &#039;&#039;M&#039;&#039; satisfies &#039;&#039;f&#039;&#039;. Finding such an SCC that can be reached from an initial state of &#039;&#039;M&#039;&#039; is a witness for a counter-example for &#039;&#039;f&#039;&#039;. Sometimes, we use fairness to ignore such SCCs that do not fulfill the imposed fairness constraints in order to not impede proving a property by returning of non-fair paths as counter-examples.&lt;br /&gt;
&lt;br /&gt;
The LTL model checker algorithm of ProB is implemented is implemented in C using a callback mechanism for evaluating the atomic propositions and the outgoing transitions in SICStus Prolog. Additionally, the search for SCCs is based on the Tarjan&#039;s algorithm. In the terminal all messages coming from the LTL model checker are preceded either by &amp;quot;LTL (current statistics): &amp;quot; or &amp;quot;LTL model checking:&amp;quot;. The output from the LTL model checker can give helpful insights about the model and the model checking process.&lt;br /&gt;
&lt;br /&gt;
Consider the CSP specifications &amp;quot;dphil_ltl8.csp&amp;quot; representing a model of the dining philosophers problem which resolves the starvation problem by always forcing the first philosopher to pick up first the right fork instead of the left one. In other words, &amp;quot;dphil_ltl8.csp&amp;quot; has no deadlock states. The number of philosophers in the model is 8. Checking the LTL formula &amp;quot;GF [eat.0]&amp;quot; from the command line will produce the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ probcli -ltlformula &amp;quot;GF [eat.0]&amp;quot; dphil_ltl8.csp&lt;br /&gt;
....&lt;br /&gt;
LTL model checking formula&lt;br /&gt;
% parsing_ltl_formula&lt;br /&gt;
% initialising_ltlc&lt;br /&gt;
starting_model_checking&lt;br /&gt;
LTL (current statistics): 13280 atoms, 10070 transitions generated, and  2631 callbacks needed.&lt;br /&gt;
LTL model checking: found counter-example (lasso-form): intro length = 1126, path in SCC of length = 5&lt;br /&gt;
LTL model checking: memory usage approx. 1924 KiB, 14104 atoms and 10724 transitions generated&lt;br /&gt;
LTL model checking: total time 22492ms, 2803 callbacks needed 22465ms, netto 26ms.&lt;br /&gt;
! An error occurred !&lt;br /&gt;
! source(ltl)&lt;br /&gt;
! Model Check Counter-Example found for: &lt;br /&gt;
! GF [eat.0]&lt;br /&gt;
&lt;br /&gt;
Formula FALSE.&lt;br /&gt;
&lt;br /&gt;
Runtime: 22220 ms&lt;br /&gt;
! *** error occurred ***&lt;br /&gt;
! ltl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As one can clearly see from the output, the LTL model checker fails to prove that &amp;quot;GF [eat.0]&amp;quot; since it has found a counter-example for the formula. The data coming from the LTL model checker is to be understand as follows:&lt;br /&gt;
&lt;br /&gt;
== Other Relevant Tutorials about LTL Model Checking ==&lt;br /&gt;
A brief tutorial on visualizing LTL counter-examples in the Rodin tool can be found [http://www.stups.uni-duesseldorf.de/ProB/index.php5/Tutorial_LTL_Counter-example_View here].&lt;br /&gt;
&lt;br /&gt;
A tutorial of a simple case study, where setting fairness constraints to some of the LTL properties is required, can be found [http://www.stups.uni-duesseldorf.de/ProB/index.php5/Mutual_Exclusion_%28Fairness%29 here].&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3515</id>
		<title>Tutorial Enabling Analysis</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3515"/>
		<updated>2016-02-23T09:36:07Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Performing Enabling Analysis within ProB */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The B-method and in particular its successor Event-B are methodologies for formal development and verification of systems. In Event-B, a machine is usually viewed as a reactive system executing continuously enabled (atomic) events in an interleaved fashion. Thus, parallel events of the system are easily modeled as an interleaving of operation executions. On the other hand, the introduction of abstract counters is required when events are supposed to be executed in some (sequential) order. This, however, can in some cases slow the work of understanding and verifying a model since identifying the sequential ordering of events in an Event-B model is not that obvious. Thus, using methods for determining the control flow can be sometimes very beneficial for understanding the model, as well as for techniques for automatic verification such as model checking.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we present a static analysis for B and Event-B that can be used to reveal the control flow of a machine and to optimize model checking of models written in B and Event-B (see also [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Guard_Evaluation Tutorial on Partial Guard Evaluation ]). The results of the analysis, designated also as ‘’enabling analysis’’, can be presented as relations by means of a table or by means of a graph. For simplicity, we will concentrate mainly on B and use the terminology of the formalism.&lt;br /&gt;
&lt;br /&gt;
== Enabling Relations ==&lt;br /&gt;
What we want to find out is how the operations influence each other within a B model. In other words, for each pair (op1,op2) of operations we try to determine as precise as possible how op1 can affect the guard condition of op2 with regard to enabledness. To determine the enabling relations between operations we use syntactic analyses, as well as the constraint-based abilities of ProB.&lt;br /&gt;
&lt;br /&gt;
Consider the following B machine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE Example&lt;br /&gt;
VARIABLES x, y, z&lt;br /&gt;
INVARIANT&lt;br /&gt;
    x:NATURAL&lt;br /&gt;
  &amp;amp; y:INTEGER&lt;br /&gt;
  &amp;amp; z:INTEGER&lt;br /&gt;
INITIALISATION &lt;br /&gt;
  x:=6 || y:=-2 || z:=0&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Op1 = PRE x + y&amp;gt;=4  THEN x:=x+2 || y:=2 END;&lt;br /&gt;
  Op2 = PRE x mod 2=1 THEN x:=x+1 || y:=2 END;&lt;br /&gt;
  Op3 = PRE x mod 2=0 THEN x:=x+2 END;&lt;br /&gt;
  Op4 = PRE x&amp;lt;0 THEN y:=y-1 END;&lt;br /&gt;
  Op5 = PRE y/=2 THEN z:=3 END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The machine has three variables x,y,z, where x ranges over the domain of natural numbers and y and z over the domain of all integers. For this machine we have 25 pairs of operations for which we want to determine the respective enabling relations. Additionally, we identify 5 further pairs that show the influence of the INITIALISATION on the guard conditions of all other operations. Consider, for example, the pair (Op2,Op1) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op1 is enabled in each state of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; where the predicate ‘x+y&amp;gt;=4’ is fulfilled. Since the effect of Op2 assigns 2 to y and increments x by one upon condition that x is a positive odd number in the before-state of Op2, we can assume that Op1 is always enabled after the execution of Op2. In other words, in all after-states of Op2 the operation Op1 is guaranteed to be enabled. This relation between Op2 and Op1 we can illustrate as follows: &lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above the green boxes denote that the evaluation of the guard of Op1 is true, whereas the red boxes denote that the evaluation of the guard of Op1 is false. &lt;br /&gt;
&lt;br /&gt;
Another pair of interest is (Op2,Op5) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op5 is enabled only in those states in which y is not equal to 2. Obviously, in each after-state of Op2 y is equal to 2 and thus we can conclude that Op5 is impossible to be enabled after each execution of Op2. Such a relation between two operations we denote as ‘’impossible’’ and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
Both arrows in the illustration of the ‘’impossible’’ relation indicate that whether the guard condition of Op5 is fulfilled or not in a before-state of Op2 operation Op5 will be disabled in the respective after-state of Op2. In order to recognize a tuple (op1,op2) as ‘’impossible’’ we require that op2 is always disabled after op1 without further considering whether op2 is always enabled or always disabled in the before-states of op1. &lt;br /&gt;
&lt;br /&gt;
Consider, for instance, the pair (Op2, Op2) in the machine above. We can easily conclude that Op2 becomes disabled after it is executed and clearly, the second case (\false -&amp;gt; \false) of the impossible relation is not possible for (Op2, Op2). This gives rise of introducing another (more precise) impossible relation:&lt;br /&gt;
 &lt;br /&gt;
[[File:ImpossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Accordingly, we can derive another relation from ‘’impossible’’ for which only the second case of the ‘’impossible’’ relation is fulfilled:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
As an example for a pair of operations that fulfills the ‘’impossible_keep’’ requirement you can take, for example, the pair (Op3,Op2) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Since Op2 and Op3 cannot be both enabled in a state and the execution of Op3 cannot enable Op2, then we can easily conclude that Op2 remains always disabled after Op3.&lt;br /&gt;
&lt;br /&gt;
Similarly as for ‘’impossible’’, one could derive two further enabling relations from ‘’guaranteed’’:&lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedEnableKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Another interesting class of enabling relations that could be helpful for better understanding and analyzing B and Event-B models is that of the ‘’keep’’ relations. We say that an operation op1 ‘’keeps’’ another operation op2 if op1 cannot change the status of the enabling condition of op2, i.e. op1 keeps op2 enabled respectively disabled. This relationship could be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:KeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
We can take (Op1,Op2) and (Op1,Op3) as examples of pairs in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; that are elements of the keep relation. ‘’keep’’ relations can sometimes be easily determined by analyzing just the syntactic structure of both operations, or more precisely the “read” and “write” sets of both operations.&amp;lt;ref&amp;gt;For an operation op the set read(op) denotes the set of variables that are read by op. Accordingly, by write(op) we denote the set of variables that are written by op.&amp;lt;/ref&amp;gt; If, for example, an operation op1 does not write any variable of the machine that is read in the guard condition of op2, then we can infer that op1 ‘’keeps’’ op2. In that case we also say that op1 does not change op2 syntactically. In the class of the ‘’keep’’ relations are included also relations such as independence. Two operations op1 and op2 are called independent if each of them cannot disable the other operation and the both orders of execution &amp;lt;op1,op2&amp;gt; and &amp;lt;op2,op1&amp;gt; have the same effect.&amp;lt;ref&amp;gt;See the [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Order_Reduction Tutorial on Partial Order Reduction] for more information on independence between operations.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three classes (‘’guaranteed’’, ‘’impossible’’ and ‘’keep’’) of enabling relations presented so far represent definite relations. That is, if a pair of operations (op1,op2) is confirmed to be a relation of one of this three classes, then we can certainly say what effect on the enabling condition of op2 would the execution of op1 have. However, for some pairs of operations we cannot certainly say what effect an operation would have on the enabling condition of another operation. This is due to the fact that the enabling status of an operation does not only depend on the effect of the executed operations, but also on the current variables’ evaluation. Take, for instance, the tuple (Op3,Op1) from the B machine above. Considering the action part of Op3 and the guard condition of Op1 we can assume that Op3 can enable Op1. Since the guard of Op1 depends not only on the current value of x, but also on y, there could be transitions s -&amp;gt; s&#039; of Op3 in the state space of the machine where Op1 is disabled in both states s and s’. Though, what we could definitely say is that Op3 cannot disable Op1. This relationship we can illustrate as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleEnableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
The opposite relation of “possible_enable” is the relation where an operation op2 can disable another operation op1. Formally, we say that op2 can disable op1 if op2 may disable op1 and op2 cannot enable op1. This relationship is denoted as “possible_disable” and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
In order to determine how operations influence each other we need to assure first that these are feasible. An operation ‘’op’’ is said to be feasible if there is a state of the machine that satisfies the invariant of the machine and in which ‘’op’’ is enabled. In the B machine above the operation Op4, for example, is not feasible. Obviously, Op4 is enabled only in states where x is a negative number and states in which x is a negative number are visibly not consistent with the invariant since &amp;quot;x : NATURAL&amp;quot;. Such incompatibilities are sometimes of great importance for the modeler and therefore they should be revealed in the process of computing the enabling relations. In our case for each pair of operations (Op4,-) and (-,Op4) the status “infeasible” will be returned.&lt;br /&gt;
&lt;br /&gt;
We can now list all possible enabling relations for the machine &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; by means of a table. For each entry in the table the operation in the row is the operation whose effect is studied on the status of the guard of the operation in the column.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingResults.png]]&lt;br /&gt;
&lt;br /&gt;
Rather than showing the enabling information for each pair of operations of the machine, one can display the enabling relations by means of a graph. The graph contains the operations as nodes and the above enabling relations as edges between the nodes, with the exception that relations marked as impossible, independent or infeasible are not shown in the graph. We denote such graphs as enable graphs. The enable graph of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; looks as follows.&lt;br /&gt;
&lt;br /&gt;
[[File: EnableGraph_Example.png]]&lt;br /&gt;
&lt;br /&gt;
From the enable graph one can recognize the control flow of the model and deduce some properties. For example, we can clearly see that &amp;lt;tt&amp;gt;Op4&amp;lt;/tt&amp;gt; cannot occur after the execution of another operation.&lt;br /&gt;
&lt;br /&gt;
== Summary of the Enabling Relations ==&lt;br /&gt;
&lt;br /&gt;
In the following, we summarize most of the enabling relations that we think can provide a useful feedback to the user. For each of the enabling relations we have given an appropriate example. In the examples below we compute the effect of executing ‘op1’ on the status of the guard of ‘op2’. The relation identifiers are the same as they appear as results in ProB.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;guaranteed&#039;&#039;: op2 guaranteed to be executable after op1.&lt;br /&gt;
[[File: GuaranteedExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_enable&#039;&#039;: op2 is guaranteed to become enabled after op1.&lt;br /&gt;
[[File: GuaranteedEnableExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_keep&#039;&#039;: op2 is guaranteed to stay enabled after op1.&lt;br /&gt;
[[File: GuaranteedKeepExample.png]]&lt;br /&gt;
* &#039;&#039;impossible&#039;&#039;: op2 is impossible to be executed after op1.&lt;br /&gt;
[[File: ImpossibleExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_disable&#039;&#039;: op2 is guaranteed to become disabled after op1.&lt;br /&gt;
[[File: ImpossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_keep&#039;&#039;: op2 is impossible to become enabled after op1.&lt;br /&gt;
[[File: ImpossibleKeepExample.png]]&lt;br /&gt;
* &#039;&#039;keep&#039;&#039;: op2 always stays enabled resp. disabled after op1.&lt;br /&gt;
[[File: KeepExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_unchanged&#039;&#039;: op1 does not write any variable read in the guard of op2, i.e. write(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticUnchangedExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_independent&#039;&#039;: op1 and op2 are syntactically independent, i.e. read(op1) /\ write(op2) = {} &amp;amp; write(op1) /\ read(op2) = {} &amp;amp; write(op1) /\ write(op2) = {}&lt;br /&gt;
[[File: SyntacticIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;syntactically_fully_independent&#039;&#039;: op1 and op2 are syntactically independent and additionally, read(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticFullyIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;possible_enable&#039;&#039;: op2 possible after op1, but op2 cannot be disabled by op1.&lt;br /&gt;
[[File: PossibleEnableExample.png]]&lt;br /&gt;
* &#039;&#039;possible_disable&#039;&#039;: op2 possible after op1, but op2 cannot be enabled by op1.&lt;br /&gt;
[[File: PossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;infeasible&#039;&#039;: op1 is not feasible and thus cannot influence op2.&lt;br /&gt;
[[File: InfeasibleExample.png]]&lt;br /&gt;
&lt;br /&gt;
== Performing Enabling Analysis within ProB  ==&lt;br /&gt;
&lt;br /&gt;
The enabling analysis has been implemented in the ProB toolset.  The computation of the enabling relations is based on syntactic and constraint-based techniques. The identification of relations such as ‘’syntactic_independent’’ and ‘’syntactic_unchanged’’ requires just a thorough study of the syntactic structure of the operations, i.e. no calls to the constraint solver have to be made. However, to confirm, for example, that an operation is guaranteed or impossible to be executed after another operation the use of the ProB’s constraint solver is unavoidable. For instance, consider the pair (Op2,Op1) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. As we have seen, in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; the operation Op1 is guaranteed to be enabled after each execution of Op2. In ProB this could be computed by feeding the (before-after) predicate “ (x mod 2 = 1) =&amp;gt; [x:=x+1 || y:=2] (x+y&amp;lt;4)” into the constraint solver. As a result, the constraint solver will not find a solution for the predicate, i.e. the constraint solver will not find a state ‘’s’’ satisfying “x mod 2 = 1” from which after executing Op2 at ‘’s’’ a solution state s’ will be found that fulfills “x+y&amp;lt;4”; note that “x+y&amp;lt;4” is the negation of the guard of Op1. Since there is no after-state of Op2 at which Op1 is disabled we can conclude that Op1 is guaranteed to be executed after Op2. When constraints are getting more complex the constraint solver may need more time for solving and determining the enabling relations may become a very time-expensive task. Therefore, a time-out for each constraint solver call is set. In other words, if the constraint solver does not find a solution in the given time by the user, then the respective relation will be denoted as time-outed. By default, in ProB the time-out for each constraint solver call is set to 300 ms.&lt;br /&gt;
&lt;br /&gt;
Within &amp;lt;tt&amp;gt;ProB Tcl/Tk&amp;lt;/tt&amp;gt; you can find the menu &amp;quot;Enabling Analysis&amp;quot; in the &amp;quot;Analysis&amp;quot; menu of the menu bar.&lt;br /&gt;
[[File: EnablingAnalysisMenu.png]]&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;Enabling Analysis&amp;quot; menu provides multiple commands:&lt;br /&gt;
* &amp;quot;Enabling Analysis (Table)&amp;quot;: this command performs a (fast) enabling analysis on the respective B model using a time-out of 300 ms for the constraint-solver calls. The result of the enabling analysis is shown in a table. The table lists all enabling relations between the operations of the loaded B model. These can be exported to a CSV file. The table for &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; at the end of the &#039;&#039;&#039; Enabling Relations&#039;&#039;&#039; section was constructed this way.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Precise, Table)&amp;quot;: this command performs an enabling analysis using a time-out of 2800 ms for each of the constraint-solver calls. As for the command above, the result of the analysis is shown in a table that can be exported to a CSV file.&lt;br /&gt;
* &amp;quot;Enabling Relations After...&amp;quot;: this command computes all the enabling relations involving an operation chosen by the user.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Graph)&amp;quot;: this command performs the fast enabling analysis but displays the results as a graph. In case the preference &amp;quot;DOT_SHOW_OP_READ_WRITES&amp;quot; is set for each operation the read/write information is displayed.&lt;br /&gt;
* &amp;quot;Enabling Analysis (POR)...&amp;quot;: this menu provides further commands for another form of enabling analysis the results of which are used for the partial guard evaluation optimisation in ProB.&lt;br /&gt;
* &amp;quot;Read/Write Matrix (Table)&amp;quot;: this command performs syntactic analysis on the model. The analysis determines the read and write sets for each operation of the machine.&lt;br /&gt;
* &amp;quot;Dependence Analysis (Table)&amp;quot;: this command performs a dependency analysis for each pair of operations. More specifically, the analysis determines which operations are dependent or independent to each other.&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB (probcli) one can perform an enabling analysis on a B or Event-B model by means of the &amp;lt;tt&amp;gt;-enabling_analysis&amp;lt;/tt&amp;gt; option. The results of the analysis, as well as intermediate data and some statistics are printed out on the console:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli Example.mch -enabling_analysis&lt;br /&gt;
CHECKING ENABLING AFTER INITIALISATION&lt;br /&gt;
INITIALISATION ---&amp;gt; Op1  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op2  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op3  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op4  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op5  :: ok : guaranteed&lt;br /&gt;
.....&lt;br /&gt;
CHECKING ENABLING AFTER: Op5 r:[y] / w:[z]&lt;br /&gt;
Op5 ---&amp;gt; Op1  :: Enable=syntactic_independent&lt;br /&gt;
Op5 ---&amp;gt; Op2  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op3  :: Enable=syntactic_fully_independent&lt;br /&gt;
Op5 ---&amp;gt; Op4  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op5  :: Enable=syntactic_unchanged&lt;br /&gt;
% Finished CBC Enabling Analysis 810 ms walltime (770 ms runtime), since start: 1650 ms&lt;br /&gt;
% CBC Enabling Stats:&lt;br /&gt;
% Nr of events: 5&lt;br /&gt;
% Nr of cbc calls: 30, Timeout results: 2&lt;br /&gt;
Origin,Op1,Op2,Op3,Op4,Op5&lt;br /&gt;
INITIALISATION,guaranteed,impossible,guaranteed,impossible,guaranteed&lt;br /&gt;
Op1,timeout_possible_disable,keep,keep,impossible_keep,syntactic_independent&lt;br /&gt;
Op2,guaranteed,impossible,guaranteed,impossible_keep,impossible&lt;br /&gt;
Op3,timeout_possible,impossible_keep,guaranteed,impossible_keep,syntactic_fully_independent&lt;br /&gt;
Op4,impossible_keep,syntactic_unchanged,syntactic_unchanged,syntactic_keep,impossible_keep&lt;br /&gt;
Op5,syntactic_independent,syntactic_unchanged,syntactic_fully_independent,syntactic_unchanged,syntactic_unchanged&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To perform enabling analysis from the command line and save the results into a CSV-file use the following commando:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli file.mch -enabling_analysis_csv FILE &amp;lt;/pre&amp;gt;&lt;br /&gt;
where FILE is the name of the CSV-file in which the results of the analysis are stored.&lt;br /&gt;
&lt;br /&gt;
== References and Footnotes ==&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3514</id>
		<title>Tutorial Enabling Analysis</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3514"/>
		<updated>2016-02-23T09:35:54Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Summary of the Enabling Relations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The B-method and in particular its successor Event-B are methodologies for formal development and verification of systems. In Event-B, a machine is usually viewed as a reactive system executing continuously enabled (atomic) events in an interleaved fashion. Thus, parallel events of the system are easily modeled as an interleaving of operation executions. On the other hand, the introduction of abstract counters is required when events are supposed to be executed in some (sequential) order. This, however, can in some cases slow the work of understanding and verifying a model since identifying the sequential ordering of events in an Event-B model is not that obvious. Thus, using methods for determining the control flow can be sometimes very beneficial for understanding the model, as well as for techniques for automatic verification such as model checking.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we present a static analysis for B and Event-B that can be used to reveal the control flow of a machine and to optimize model checking of models written in B and Event-B (see also [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Guard_Evaluation Tutorial on Partial Guard Evaluation ]). The results of the analysis, designated also as ‘’enabling analysis’’, can be presented as relations by means of a table or by means of a graph. For simplicity, we will concentrate mainly on B and use the terminology of the formalism.&lt;br /&gt;
&lt;br /&gt;
== Enabling Relations ==&lt;br /&gt;
What we want to find out is how the operations influence each other within a B model. In other words, for each pair (op1,op2) of operations we try to determine as precise as possible how op1 can affect the guard condition of op2 with regard to enabledness. To determine the enabling relations between operations we use syntactic analyses, as well as the constraint-based abilities of ProB.&lt;br /&gt;
&lt;br /&gt;
Consider the following B machine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE Example&lt;br /&gt;
VARIABLES x, y, z&lt;br /&gt;
INVARIANT&lt;br /&gt;
    x:NATURAL&lt;br /&gt;
  &amp;amp; y:INTEGER&lt;br /&gt;
  &amp;amp; z:INTEGER&lt;br /&gt;
INITIALISATION &lt;br /&gt;
  x:=6 || y:=-2 || z:=0&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Op1 = PRE x + y&amp;gt;=4  THEN x:=x+2 || y:=2 END;&lt;br /&gt;
  Op2 = PRE x mod 2=1 THEN x:=x+1 || y:=2 END;&lt;br /&gt;
  Op3 = PRE x mod 2=0 THEN x:=x+2 END;&lt;br /&gt;
  Op4 = PRE x&amp;lt;0 THEN y:=y-1 END;&lt;br /&gt;
  Op5 = PRE y/=2 THEN z:=3 END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The machine has three variables x,y,z, where x ranges over the domain of natural numbers and y and z over the domain of all integers. For this machine we have 25 pairs of operations for which we want to determine the respective enabling relations. Additionally, we identify 5 further pairs that show the influence of the INITIALISATION on the guard conditions of all other operations. Consider, for example, the pair (Op2,Op1) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op1 is enabled in each state of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; where the predicate ‘x+y&amp;gt;=4’ is fulfilled. Since the effect of Op2 assigns 2 to y and increments x by one upon condition that x is a positive odd number in the before-state of Op2, we can assume that Op1 is always enabled after the execution of Op2. In other words, in all after-states of Op2 the operation Op1 is guaranteed to be enabled. This relation between Op2 and Op1 we can illustrate as follows: &lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above the green boxes denote that the evaluation of the guard of Op1 is true, whereas the red boxes denote that the evaluation of the guard of Op1 is false. &lt;br /&gt;
&lt;br /&gt;
Another pair of interest is (Op2,Op5) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op5 is enabled only in those states in which y is not equal to 2. Obviously, in each after-state of Op2 y is equal to 2 and thus we can conclude that Op5 is impossible to be enabled after each execution of Op2. Such a relation between two operations we denote as ‘’impossible’’ and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
Both arrows in the illustration of the ‘’impossible’’ relation indicate that whether the guard condition of Op5 is fulfilled or not in a before-state of Op2 operation Op5 will be disabled in the respective after-state of Op2. In order to recognize a tuple (op1,op2) as ‘’impossible’’ we require that op2 is always disabled after op1 without further considering whether op2 is always enabled or always disabled in the before-states of op1. &lt;br /&gt;
&lt;br /&gt;
Consider, for instance, the pair (Op2, Op2) in the machine above. We can easily conclude that Op2 becomes disabled after it is executed and clearly, the second case (\false -&amp;gt; \false) of the impossible relation is not possible for (Op2, Op2). This gives rise of introducing another (more precise) impossible relation:&lt;br /&gt;
 &lt;br /&gt;
[[File:ImpossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Accordingly, we can derive another relation from ‘’impossible’’ for which only the second case of the ‘’impossible’’ relation is fulfilled:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
As an example for a pair of operations that fulfills the ‘’impossible_keep’’ requirement you can take, for example, the pair (Op3,Op2) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Since Op2 and Op3 cannot be both enabled in a state and the execution of Op3 cannot enable Op2, then we can easily conclude that Op2 remains always disabled after Op3.&lt;br /&gt;
&lt;br /&gt;
Similarly as for ‘’impossible’’, one could derive two further enabling relations from ‘’guaranteed’’:&lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedEnableKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Another interesting class of enabling relations that could be helpful for better understanding and analyzing B and Event-B models is that of the ‘’keep’’ relations. We say that an operation op1 ‘’keeps’’ another operation op2 if op1 cannot change the status of the enabling condition of op2, i.e. op1 keeps op2 enabled respectively disabled. This relationship could be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:KeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
We can take (Op1,Op2) and (Op1,Op3) as examples of pairs in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; that are elements of the keep relation. ‘’keep’’ relations can sometimes be easily determined by analyzing just the syntactic structure of both operations, or more precisely the “read” and “write” sets of both operations.&amp;lt;ref&amp;gt;For an operation op the set read(op) denotes the set of variables that are read by op. Accordingly, by write(op) we denote the set of variables that are written by op.&amp;lt;/ref&amp;gt; If, for example, an operation op1 does not write any variable of the machine that is read in the guard condition of op2, then we can infer that op1 ‘’keeps’’ op2. In that case we also say that op1 does not change op2 syntactically. In the class of the ‘’keep’’ relations are included also relations such as independence. Two operations op1 and op2 are called independent if each of them cannot disable the other operation and the both orders of execution &amp;lt;op1,op2&amp;gt; and &amp;lt;op2,op1&amp;gt; have the same effect.&amp;lt;ref&amp;gt;See the [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Order_Reduction Tutorial on Partial Order Reduction] for more information on independence between operations.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three classes (‘’guaranteed’’, ‘’impossible’’ and ‘’keep’’) of enabling relations presented so far represent definite relations. That is, if a pair of operations (op1,op2) is confirmed to be a relation of one of this three classes, then we can certainly say what effect on the enabling condition of op2 would the execution of op1 have. However, for some pairs of operations we cannot certainly say what effect an operation would have on the enabling condition of another operation. This is due to the fact that the enabling status of an operation does not only depend on the effect of the executed operations, but also on the current variables’ evaluation. Take, for instance, the tuple (Op3,Op1) from the B machine above. Considering the action part of Op3 and the guard condition of Op1 we can assume that Op3 can enable Op1. Since the guard of Op1 depends not only on the current value of x, but also on y, there could be transitions s -&amp;gt; s&#039; of Op3 in the state space of the machine where Op1 is disabled in both states s and s’. Though, what we could definitely say is that Op3 cannot disable Op1. This relationship we can illustrate as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleEnableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
The opposite relation of “possible_enable” is the relation where an operation op2 can disable another operation op1. Formally, we say that op2 can disable op1 if op2 may disable op1 and op2 cannot enable op1. This relationship is denoted as “possible_disable” and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
In order to determine how operations influence each other we need to assure first that these are feasible. An operation ‘’op’’ is said to be feasible if there is a state of the machine that satisfies the invariant of the machine and in which ‘’op’’ is enabled. In the B machine above the operation Op4, for example, is not feasible. Obviously, Op4 is enabled only in states where x is a negative number and states in which x is a negative number are visibly not consistent with the invariant since &amp;quot;x : NATURAL&amp;quot;. Such incompatibilities are sometimes of great importance for the modeler and therefore they should be revealed in the process of computing the enabling relations. In our case for each pair of operations (Op4,-) and (-,Op4) the status “infeasible” will be returned.&lt;br /&gt;
&lt;br /&gt;
We can now list all possible enabling relations for the machine &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; by means of a table. For each entry in the table the operation in the row is the operation whose effect is studied on the status of the guard of the operation in the column.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingResults.png]]&lt;br /&gt;
&lt;br /&gt;
Rather than showing the enabling information for each pair of operations of the machine, one can display the enabling relations by means of a graph. The graph contains the operations as nodes and the above enabling relations as edges between the nodes, with the exception that relations marked as impossible, independent or infeasible are not shown in the graph. We denote such graphs as enable graphs. The enable graph of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; looks as follows.&lt;br /&gt;
&lt;br /&gt;
[[File: EnableGraph_Example.png]]&lt;br /&gt;
&lt;br /&gt;
From the enable graph one can recognize the control flow of the model and deduce some properties. For example, we can clearly see that &amp;lt;tt&amp;gt;Op4&amp;lt;/tt&amp;gt; cannot occur after the execution of another operation.&lt;br /&gt;
&lt;br /&gt;
== Summary of the Enabling Relations ==&lt;br /&gt;
&lt;br /&gt;
In the following, we summarize most of the enabling relations that we think can provide a useful feedback to the user. For each of the enabling relations we have given an appropriate example. In the examples below we compute the effect of executing ‘op1’ on the status of the guard of ‘op2’. The relation identifiers are the same as they appear as results in ProB.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;guaranteed&#039;&#039;: op2 guaranteed to be executable after op1.&lt;br /&gt;
[[File: GuaranteedExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_enable&#039;&#039;: op2 is guaranteed to become enabled after op1.&lt;br /&gt;
[[File: GuaranteedEnableExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_keep&#039;&#039;: op2 is guaranteed to stay enabled after op1.&lt;br /&gt;
[[File: GuaranteedKeepExample.png]]&lt;br /&gt;
* &#039;&#039;impossible&#039;&#039;: op2 is impossible to be executed after op1.&lt;br /&gt;
[[File: ImpossibleExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_disable&#039;&#039;: op2 is guaranteed to become disabled after op1.&lt;br /&gt;
[[File: ImpossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_keep&#039;&#039;: op2 is impossible to become enabled after op1.&lt;br /&gt;
[[File: ImpossibleKeepExample.png]]&lt;br /&gt;
* &#039;&#039;keep&#039;&#039;: op2 always stays enabled resp. disabled after op1.&lt;br /&gt;
[[File: KeepExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_unchanged&#039;&#039;: op1 does not write any variable read in the guard of op2, i.e. write(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticUnchangedExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_independent&#039;&#039;: op1 and op2 are syntactically independent, i.e. read(op1) /\ write(op2) = {} &amp;amp; write(op1) /\ read(op2) = {} &amp;amp; write(op1) /\ write(op2) = {}&lt;br /&gt;
[[File: SyntacticIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;syntactically_fully_independent&#039;&#039;: op1 and op2 are syntactically independent and additionally, read(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticFullyIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;possible_enable&#039;&#039;: op2 possible after op1, but op2 cannot be disabled by op1.&lt;br /&gt;
[[File: PossibleEnableExample.png]]&lt;br /&gt;
* &#039;&#039;possible_disable&#039;&#039;: op2 possible after op1, but op2 cannot be enabled by op1.&lt;br /&gt;
[[File: PossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;infeasible&#039;&#039;: op1 is not feasible and thus cannot influence op2.&lt;br /&gt;
[[File: InfeasibleExample.png]]&lt;br /&gt;
&lt;br /&gt;
== Performing Enabling Analysis within ProB  ==&lt;br /&gt;
&lt;br /&gt;
The enabling analysis has been implemented in the ProB toolset.  The computation of the enabling relations is based on syntactic and constraint-based techniques. The identification of relations such as ‘’syntactic_independent’’ and ‘’syntactic_unchanged’’ requires just a thorough study of the syntactic structure of the operations, i.e. no calls to the constraint solver have to be made. However, to confirm, for example, that an operation is guaranteed or impossible to be executed after another operation the use of the ProB’s constraint solver is unavoidable. For instance, consider the pair (Op2,Op1) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. As we have seen, in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; the operation Op1 is guaranteed to be enabled after each execution of Op2. In ProB this could be computed by feeding the (before-after) predicate “ (x mod 2 = 1) =&amp;gt; [x:=x+1 || y:=2] (x+y&amp;lt;4)” into the constraint solver. As a result, the constraint solver will not find a solution for the predicate, i.e. the constraint solver will not find a state ‘’s’’ satisfying “x mod 2 = 1” from which after executing Op2 at ‘’s’’ a solution state s’ will be found that fulfills “x+y&amp;lt;4”; note that “x+y&amp;lt;4” is the negation of the guard of Op1. Since there is no after-state of Op2 at which Op1 is disabled we can conclude that Op1 is guaranteed to be executed after Op2. When constraints are getting more complex the constraint solver may need more time for solving and determining the enabling relations may become a very time-expensive task. Therefore, a time-out for each constraint solver call is set. In other words, if the constraint solver does not find a solution in the given time by the user, then the respective relation will be denoted as time-outed. By default, in ProB the time-out for each constraint solver call is set to 300 ms.&lt;br /&gt;
&lt;br /&gt;
Within &amp;lt;tt&amp;gt;ProB Tcl/Tk&amp;lt;/tt&amp;gt; you can find the menu &amp;quot;Enabling Analysis&amp;quot; in the &amp;quot;Analysis&amp;quot; menu of the menu bar.&lt;br /&gt;
[[File: EnablingAnalysisMenu.png]]&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;Enabling Analysis&amp;quot; menu provides multiple commands:&lt;br /&gt;
* &amp;quot;Enabling Analysis (Table)&amp;quot;: this command performs a (fast) enabling analysis on the respective B model using a time-out of 300 ms for the constraint-solver calls. The result of the enabling analysis is shown in a table. The table lists all enabling relations between the operations of the loaded B model. These can be exported to a CSV file. The table for &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; at the end of the &#039;&#039;&#039; Enabling Relations&#039;&#039;&#039; section was constructed this way.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Precise, Table)&amp;quot;: this command performs an enabling analysis using a time-out of 2800 ms for each of the constraint-solver calls. As for the command above, the result of the analysis is shown in a table that can be exported to a CSV file.&lt;br /&gt;
* &amp;quot;Enabling Relations After...&amp;quot;: this command computes all the enabling relations involving an operation chosen by the user.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Graph)&amp;quot;: this command performs the fast enabling analysis but displays the results as a graph. In case the preference &amp;quot;DOT_SHOW_OP_READ_WRITES&amp;quot; is set for each operation the read/write information is displayed.&lt;br /&gt;
* &amp;quot;Enabling Analysis (POR)...&amp;quot;: this menu provides further commands for another form of enabling analysis the results of which are used for the partial guard evaluation optimisation in ProB.&lt;br /&gt;
* &amp;quot;Read/Write Matrix (Table)&amp;quot;: this command performs syntactic analysis on the model. The analysis determines the read and write sets for each operation of the machine.&lt;br /&gt;
* &amp;quot;Dependence Analysis (Table)&amp;quot;: this command performs a dependency analysis for each pair of operations. More specifically, the analysis determines which operations are dependent or independent to each other.&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB (probcli) one can perform an enabling analysis on a B or Event-B model by means of the &amp;lt;tt&amp;gt;-enabling_analysis&amp;lt;/tt&amp;gt; option. The results of the analysis, as well as intermediate data and some statistics are printed out on the console:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli Example.mch -enabling_analysis&lt;br /&gt;
CHECKING ENABLING AFTER INITIALISATION&lt;br /&gt;
INITIALISATION ---&amp;gt; Op1  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op2  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op3  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op4  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op5  :: ok : guaranteed&lt;br /&gt;
.....&lt;br /&gt;
CHECKING ENABLING AFTER: Op5 r:[y] / w:[z]&lt;br /&gt;
Op5 ---&amp;gt; Op1  :: Enable=syntactic_independent&lt;br /&gt;
Op5 ---&amp;gt; Op2  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op3  :: Enable=syntactic_fully_independent&lt;br /&gt;
Op5 ---&amp;gt; Op4  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op5  :: Enable=syntactic_unchanged&lt;br /&gt;
% Finished CBC Enabling Analysis 810 ms walltime (770 ms runtime), since start: 1650 ms&lt;br /&gt;
% CBC Enabling Stats:&lt;br /&gt;
% Nr of events: 5&lt;br /&gt;
% Nr of cbc calls: 30, Timeout results: 2&lt;br /&gt;
Origin,Op1,Op2,Op3,Op4,Op5&lt;br /&gt;
INITIALISATION,guaranteed,impossible,guaranteed,impossible,guaranteed&lt;br /&gt;
Op1,timeout_possible_disable,keep,keep,impossible_keep,syntactic_independent&lt;br /&gt;
Op2,guaranteed,impossible,guaranteed,impossible_keep,impossible&lt;br /&gt;
Op3,timeout_possible,impossible_keep,guaranteed,impossible_keep,syntactic_fully_independent&lt;br /&gt;
Op4,impossible_keep,syntactic_unchanged,syntactic_unchanged,syntactic_keep,impossible_keep&lt;br /&gt;
Op5,syntactic_independent,syntactic_unchanged,syntactic_fully_independent,syntactic_unchanged,syntactic_unchanged&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To perform enabling analysis from the command line and save the results to a CSV-file use the following commando:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli file.mch -enabling_analysis_csv FILE &amp;lt;/pre&amp;gt;&lt;br /&gt;
where FILE is the name of the CSV-file in which the results of the analysis are stored.&lt;br /&gt;
&lt;br /&gt;
== References and Footnotes ==&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_CSP_First_Step&amp;diff=3513</id>
		<title>Tutorial CSP First Step</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_CSP_First_Step&amp;diff=3513"/>
		<updated>2016-02-22T16:02:45Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Other Features */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[Category:User Manual]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Startup ==&lt;br /&gt;
&lt;br /&gt;
Start off by installing the standalone Tcl/Tk version of ProB.&lt;br /&gt;
Follow the instructions in [[Installation]].&lt;br /&gt;
Start ProB by double-clicking on &amp;lt;tt&amp;gt;ProBWin&amp;lt;/tt&amp;gt; (for Windows users), or by launching &amp;lt;tt&amp;gt;StartProB.sh&amp;lt;/tt&amp;gt; from a Terminal (for Linux and Mac users).&lt;br /&gt;
&lt;br /&gt;
== Loading a first CSP specification ==&lt;br /&gt;
&lt;br /&gt;
Use the &amp;quot;Open...&amp;quot; command in the &amp;quot;File&amp;quot; menu and then navigate to the &amp;quot;Examples&amp;quot; directory that came with your ProB installation. Inside the &amp;quot;CSP&amp;quot; subfolder, open the &amp;quot;buses.csp&amp;quot; specification.&lt;br /&gt;
Your main ProB window should now look as follows:&lt;br /&gt;
&lt;br /&gt;
[[file:ProB_BusesAfterLoad.png|center||500px]]&lt;br /&gt;
&lt;br /&gt;
== First Steps in Animation ==&lt;br /&gt;
&lt;br /&gt;
We have now loaded a first simple CSP model. Let us look at the contents of the ProB window (ignoring the menu bar).&lt;br /&gt;
* The upper half of the ProB window contains the source code of the CSP specification.&lt;br /&gt;
* The lower half contains three panes.&lt;br /&gt;
** The &amp;quot;State Properties&amp;quot; pane contains information about the current state of the specification. We will explain the contents of this pane in more detail later.&lt;br /&gt;
** The Pane called &amp;quot;Enabled Operations&amp;quot; contains a list of events  that your CSP specification offers. At the very first step you have to choose a process to animate. If your CSP specification contains a MAIN process (as is the case in buses.csp), only this process will be shown.&lt;br /&gt;
** The &amp;quot;History&amp;quot; pane contains the list of operations you have executed to reach the current state of the animator. Obviously, this list is initially empty.&lt;br /&gt;
&lt;br /&gt;
Now, double click on &amp;quot;&amp;lt;tt&amp;gt;MAIN&amp;lt;/tt&amp;gt;&amp;quot; process in the &amp;quot;Enabled Operations&amp;quot; Pane. This has the effect of computing the events offered by &amp;lt;tt&amp;gt;MAIN&amp;lt;/tt&amp;gt;. The ProB window should now look as follows (the upper half will remain unchanged):&lt;br /&gt;
 &lt;br /&gt;
[[file:ProB_CSPAfterInit.png|center||500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the &amp;quot;Enabled Operations&amp;quot; pane we can see that two tau events are offered: &amp;lt;tt&amp;gt;tau(int_choice_left)&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;tau(int_choice_right)&amp;lt;/tt&amp;gt;. The &amp;quot;History&amp;quot; pane shows us that we have started the  &amp;quot;&amp;lt;tt&amp;gt;MAIN&amp;lt;/tt&amp;gt;&amp;quot; process to reach the current state. &lt;br /&gt;
By single-clicking on an event, we can see which parts of the CSP specification contributed to the event. For example, single clicking on the first tau event yields in the following picture:&lt;br /&gt;
&lt;br /&gt;
[[file:ProB_CSPAfterTauSingleClick.png|center||500px]]&lt;br /&gt;
&lt;br /&gt;
By repeatedly single clicking on the event you can cycle through the various locations that contributed to the event. To execute an event, simply double-click on it.&lt;br /&gt;
Try this out for yourself: double-click on &amp;lt;tt&amp;gt;tau(int_choice_left)&amp;lt;/tt&amp;gt; and then single-click on the &amp;lt;tt&amp;gt;board37&amp;lt;/tt&amp;gt; event which is offered. This time the event is a synchronization of two events(note that ProB uses a different colour for highlighting the source locations). The source highlighting should look as follows:&lt;br /&gt;
[[file:ProB_CSPAfterBoardSingleClick.png|center||500px]]&lt;br /&gt;
&lt;br /&gt;
== First Steps in Model Checking ==&lt;br /&gt;
You can use the model checker to search for certain errors.&lt;br /&gt;
Execute the &amp;quot;Model Check...&amp;quot; command in the &amp;quot;Verify Menu&amp;quot;.&lt;br /&gt;
The following dialog box will appear:&lt;br /&gt;
[[file:ProB_CSPModelCheck.png|center||200px]]&lt;br /&gt;
&lt;br /&gt;
By default, ProB will search for deadlocks, illegal channel values and events on the &amp;quot;error&amp;quot; channel.&lt;br /&gt;
To turn the latter off, uncheck the &amp;quot;Find Invariant Violation&amp;quot; check box.&lt;br /&gt;
You can also search for events on the &amp;quot;goal&amp;quot;channel, by checking the corresponding check box (&amp;quot;Find event on goal CSP channel&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Now press the &amp;quot;Model Check&amp;quot; button. ProB should find a deadlock and insert the counter-example into the history as follows:&lt;br /&gt;
[[file:ProB_CSPAfterModelCheck.png|center||700px]]&lt;br /&gt;
&lt;br /&gt;
== Error Highlighting ==&lt;br /&gt;
&lt;br /&gt;
Now edit the definition of the BUS37 process and add an illegal output of value 1 on the alight37B channel:&lt;br /&gt;
&lt;br /&gt;
   BUS37 = board37A -&amp;gt; (pay90 -&amp;gt; alight37B!1 -&amp;gt; STOP&lt;br /&gt;
                     [] alight37A -&amp;gt; STOP)&lt;br /&gt;
&lt;br /&gt;
Now save and reload the specification and again choose the &amp;quot;Model Check...&amp;quot; command in the Verify menu. Now uncheck the &amp;quot;Find Deadlocks&amp;quot; check-box and press &amp;quot;Model Check&amp;quot;.&lt;br /&gt;
ProB will report the following error:&lt;br /&gt;
&lt;br /&gt;
 Mismatch in number of arguments for synchronisation on channel alight37B with extra argument(s): &lt;br /&gt;
 1&lt;br /&gt;
   ### Line: 11, Column: 30&lt;br /&gt;
&lt;br /&gt;
display the trace to the error in the History pane and highlight the error location in the source as follows:&lt;br /&gt;
[[file:ProB_CSPAfterModelCheck2.png|center||600px]]&lt;br /&gt;
&lt;br /&gt;
== Other Features ==&lt;br /&gt;
&lt;br /&gt;
You can check more sophisticated temporal properties using the LTL model checker of ProB; see the [[LTL_Model_Checking|corresponding part of the tutorial]]. For example, you can try and validate the following LTL formula &amp;lt;tt&amp;gt;G([board37A] =&amp;gt; F [alight37B])&amp;lt;/tt&amp;gt;.&lt;br /&gt;
ProB should respond: &amp;lt;tt&amp;gt;Formula TRUE. No counterexample found.&amp;lt;/tt&amp;gt;&lt;br /&gt;
Similarly, you can check the absence of divergence by checking the LTL formula &amp;lt;tt&amp;gt;G not G [tau]&amp;lt;/tt&amp;gt;.&lt;br /&gt;
It is also possible to perform various refinement checks and other assertion checks (see [http://stups.hhu.de/ProB/w/Checking_CSP_Assertions Checking CSP Assertions&#039; tutorial]).&lt;br /&gt;
The state space visualization features of ProB are also available for CSP; see [[State_Space_Visualization|the corresponding part of the tutorial]].&lt;br /&gt;
For example, if you select the command &amp;quot;Statespace&amp;quot; in the &amp;quot;Visualize&amp;quot; menu  (after having fully explored the system), the following graph will be displayed:&lt;br /&gt;
[[file:ProB_CSPBusStatespace.png|center||200px]]&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Checking_CSP_Assertions&amp;diff=3512</id>
		<title>Checking CSP Assertions</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Checking_CSP_Assertions&amp;diff=3512"/>
		<updated>2016-02-22T15:59:19Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Checking CSP Assertions with `probcli` */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;As of version 1.3.4, ProB provides support for refinement checking and various other assertions (deadlock, divergence, determinism, and LTL/CTL assertions) of CSP-M specifications. In this tutorial we give a short overview of the ProB’s implementations and features for checking CSP assertions. In the Tcl/Tk interface of ProB, CSP assertions can be assembled and checked in the &#039;&#039;CSP Assertions Viewer&#039;&#039;. A description of the &#039;&#039;CSP Assertions Viewer&#039;&#039; is also given.&lt;br /&gt;
&lt;br /&gt;
== Supported CSP Assertions in ProB ==&lt;br /&gt;
&lt;br /&gt;
ProB provides support for checking almost all types of CSP-M assertions that can be checked within FDR2. Besides the assertion types that can be checked in FDR2, in ProB one also can check temporal properties on processes expressed by means of LTL and CTL formulae.&amp;lt;ref&amp;gt;ProB provides support for LTL and CTL model checking (citations needed).&amp;lt;/ref&amp;gt; The following types of assertions are supported in ProB:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Refinement&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Refinement is one of the fundamental notions for construction and verification of systems specified in CSP. Given two CSP processes &#039;&#039;P&#039;&#039; and &#039;&#039;Q&#039;&#039; one can state in ProB the property that process &#039;&#039;Q&#039;&#039; is an ‘m’ refinement of &#039;&#039;P&#039;&#039; by the following assertion declaration:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;assert P [m= Q&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ‘m’ indicates one of the following types of comparison: ‘T’ for traces, ‘F’ for failures, ‘FD’ for failures-divergence, ‘R’ for refusals, and ‘RD’ for ‘refusals-divergence’. Note that the refinement types ‘V’ (revivals) and ‘VD’ (revivals-divergence) that are part of the refinement assertions supported by FDR2 are yet not supported by ProB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Deadlock&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Stating assertions about CSP processes to be deadlock-free is possible by the following assertion declaration:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;assert P :[deadlock free [m]]&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &#039;&#039;P&#039;&#039; is a process expression and ‘m’ indicates one of the following models: ‘F’ (failures) and ‘FD’ (failures-divergence).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Determinism&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Stating assertions about CSP processes to be deterministic is possible by the following assertion declaration:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;assert P :[deterministic [m]]&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &#039;&#039;P&#039;&#039; is a process expression and ‘m’ one of the following models: ‘F’ (failures) and ‘FD’ (failures-divergence).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Livelock&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Stating assertions about CSP processes to be livelock-free is possible by the following assertion declaration:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;assert P :[livelock free]&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &#039;&#039;P&#039;&#039; is a process expression.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Temporal Properties&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
In ProB it is also possible to make assertions about temporal properties of CSP processes both in LTL and CTL. Basically, one wants to check whether some process &#039;&#039;P&#039;&#039; satisfies a formula &#039;&#039;f&#039;&#039; expressed in a temporal logic (denoted by &amp;lt;tt&amp;gt;P |= f&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
To check whether a process &#039;&#039;P&#039;&#039; satisfies an LTL formula &#039;&#039;f&#039;&#039; write the following declaration:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;assert P |= LTL: “f”&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that &#039;&#039;f&#039;&#039; must be placed between quotes and that the satisfaction relation |= is immediately followed by `LTL:`. ProB supports LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt;, an extended version of LTL which provides additionally support for making propositions on transitions. The following LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; syntax for CSP-M specifications can be outlined by the following rules:&lt;br /&gt;
&lt;br /&gt;
*	Atomic propositions:&lt;br /&gt;
**	To check if an event `evt` is enabled in a state use `e(evt)`&lt;br /&gt;
*	Transition propositions:&lt;br /&gt;
**	To check whether an event `evt` is executed use `[evt]`&lt;br /&gt;
*	 Logical operators&lt;br /&gt;
**	`true` and `false`&lt;br /&gt;
**	`not`: negation&lt;br /&gt;
**	`&amp;amp;`,`or` and `=&amp;gt;`: conjunction, disjunction and implication&lt;br /&gt;
*	Temporal operators:&lt;br /&gt;
**	`G f`: globally&lt;br /&gt;
**	`F f`: finally&lt;br /&gt;
**	`X f`: next&lt;br /&gt;
**	`f U g`: until&lt;br /&gt;
**	`f W g`: weak-until&lt;br /&gt;
**	`f R g`: release&lt;br /&gt;
*	Fairness operators:&lt;br /&gt;
**	`WF(evt)` or `wf(evt)`: weak fairness, where `evt` is an event&lt;br /&gt;
**	`SF(evt)` or `sf(evt)`: strong fairness, where `evt` is an event&lt;br /&gt;
**	`WEF` and `SEF` for checking LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formulae on executions that are strongly and weakly fair with respect to all events, respectively&lt;br /&gt;
&lt;br /&gt;
An LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &#039;&#039;f&#039;&#039; is satisfied by some CSP process &#039;&#039;P&#039;&#039; if all executions of &#039;&#039;P&#039;&#039; satisfy &#039;&#039;f&#039;&#039;. If there is an execution of &#039;&#039;P&#039;&#039; which violates the property &#039;&#039;f&#039;&#039;, then the test &amp;lt;tt&amp;gt;P |= f&amp;lt;/tt&amp;gt; fails by providing a counterexample. Depending on whether &#039;&#039;f&#039;&#039; expresses, a safety or liveness property, a finite path or a path in a lasso-form (, i.e. a path leading to a cycle) is returned as a counterexample, respectively.&lt;br /&gt;
&lt;br /&gt;
Note that ProB supports also Past-LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt;. Past-LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt;, however, may be considered to be inappropriate for LTL assertions since the goal of this type of assertions is usually to check whether all executions starting at the initial states of the process satisfy the respective LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula.&lt;br /&gt;
&lt;br /&gt;
To check whether a process &#039;&#039;P&#039;&#039; satisfies a CTL formula &#039;&#039;f&#039;&#039; the following assertion should be made:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;assert P |= CTL: “f”&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As for LTL, CTL formulae should be put in between quotes. The CTL syntax for CSP-M specifications could be summarised as follows:&lt;br /&gt;
*	Atomic propositions:&lt;br /&gt;
**	To check if an event `evt` is enabled in a state use `e(evt)`&lt;br /&gt;
*	Transition propositions:&lt;br /&gt;
**	To check whether an event `evt` is executed use `[evt]`&lt;br /&gt;
*	State formulae, where f, f1 and f2 are path formulae:&lt;br /&gt;
**	true | false | `not` f | f1 `&amp;amp;` f2 | f1 `or` f2 | f1 `=&amp;gt;` f2,&lt;br /&gt;
**	E f : path quantifier `&amp;lt;math&amp;gt;\exists&amp;lt;/math&amp;gt;`, pronounced `for some path`&lt;br /&gt;
**	A f : path quantifier `&amp;lt;math&amp;gt;\forall&amp;lt;/math&amp;gt;`, pronounced `for all paths`&lt;br /&gt;
*	Path formulae, where g, g1 and g2 are state formulae:&lt;br /&gt;
**	`X g`: next&lt;br /&gt;
**	`g1 U g2`: until&lt;br /&gt;
**	`G g`: globally&lt;br /&gt;
**	`F g`: finally&lt;br /&gt;
*	Next executed event:&lt;br /&gt;
**	`EX [e] true`: &lt;br /&gt;
&lt;br /&gt;
Note that these two types of assertions, the LTL and CTL assertions, are not part of the CSP-M language supported by FDR2. Loading a CSP-M file in FDR2 having assertion declarations of this form will exit with a syntax error. Bear in mind to remove or comment out such LTL/CTL assertions in the CSP-M file before loading it in FDR2.&lt;br /&gt;
&lt;br /&gt;
== CSP Assertions Viewer ==&lt;br /&gt;
&lt;br /&gt;
When a CSP-M specification is loaded one can open the &#039;&#039;CSP Assertion Viewer&#039;&#039; either from the menu bar of the main window by selecting the `Check CSP-M Assertions` command in the `Verify` menu or from the Refinement button in the ‘’State Properties’’ pane. The viewer looks as follows:&lt;br /&gt;
&lt;br /&gt;
[[file:CSPAssertionsViewer.png]]&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;CSP Assertion Viewer&#039;&#039; of ProB has a similar design to the graphical user interface of FDR2. It consists basically of three main components: a menu bar, a list box and a tab pane. In the following each of the components and their corresponding functionalities are thoroughly described.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The Menu Bar&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
The menu bar is placed at the top of the window. On OS X, it is placed at the top of the screen. The menu bar includes several menus providing commands for adjusting, executing and changing the items in the list box, as well as some (standard) options for re-loading the model, saving the items to an external file or the loaded file, and launching some external tools related with the domain in which the list items are checked. Each menu can be popped up by a click with Mouse-1 (usually the left mouse button). The menu bar consists of the following menus and menu commands:&lt;br /&gt;
&lt;br /&gt;
*	&#039;&#039;&#039;File&#039;&#039;&#039;&lt;br /&gt;
**	&#039;&#039;Reopen File&#039;&#039;: Reopening (re-reading and re-loading) the currently loaded file, incorporating any changes that may have been made since the file was last loaded.&lt;br /&gt;
**	&#039;&#039;Copy new Assertions to File&#039;&#039;: All assertions that have been added to the list box since the currently loaded file was last read will be written to the file, i.e. all assertions that are yet not in the file are appended to it.&lt;br /&gt;
**	&#039;&#039;Save Assertions to External File&#039;&#039;: Selecting the option opens a standard Tk dialog box requesting a name of a file in which the assertions and their results in the list box could be saved.&lt;br /&gt;
**	&#039;&#039;Exit&#039;&#039;: Closing the CSP Assertion Viewer. Any assertion check results and any recently added assertions from the Tab Pane will get lost. The user will not be prompted to save these to the source file or an external file.&lt;br /&gt;
* &#039;&#039;&#039;Font&#039;&#039;&#039;&amp;lt;br/&amp;gt;Changing the font settings of the elements in the list box. Each of the items of this menu is a cascading menu that provides a number of options to be selected. The currently selected option in the cascading menu is marked by a tick symbol (✓).&lt;br /&gt;
**	&#039;&#039;Family-Name&#039;&#039;: Change the font family of the text in the list box. There are currently four font families that could be chosen: Arial, Curier, Helvetica, and Times. Default font is Curier. &lt;br /&gt;
**	&#039;&#039;Size&#039;&#039;: Change the font size of the text in the list box. Default font size is 10.&lt;br /&gt;
**	&#039;&#039;Background&#039;&#039;: Change the background color of the list box. Default background color is Gray90.&lt;br /&gt;
*	&#039;&#039;&#039;Assertions&#039;&#039;&#039;&amp;lt;br/&amp;gt;The menu provides a list of commands for checking different types of assertions. In case a particular type of assertions is checked the respective command checks only these assertions that are not checked yet.&lt;br /&gt;
**	&#039;&#039;Uncheck All Assertions&#039;&#039;: Set the status of all assertions in the list box to non-checked (`?`). &lt;br /&gt;
**	&#039;&#039;Delete All Assertions&#039;&#039;: Delete all assertions in the list box.&lt;br /&gt;
**	&#039;&#039;Check All Refinement…&#039;&#039;: The item is a cascading menu and provides commands to check all assertions of one of the following supported refinement types: Traces, Failures, Failures-Divergence, Refusals, and Refusals-Divergence.&lt;br /&gt;
**	&#039;&#039;Check Processes for…&#039;&#039;: The item is a cascading menu and provides commands to check all assertions of the following supported types of checks: Deadlock, Determinism and Livelock.&lt;br /&gt;
**	&#039;&#039;Check All LTL Assertions&#039;&#039;: Selecting this command causes ProB to check all LTL assertions in the list box that are not checked yet.&lt;br /&gt;
**	&#039;&#039;Check All CTL Assertions&#039;&#039;: Selecting this command causes ProB to check all CTL assertions in the list box that are not checked yet.&lt;br /&gt;
**	&#039;&#039;Check All Assertions&#039;&#039;: Selecting this command causes ProB to check of all assertions in the list box that are not checked yet.&lt;br /&gt;
*	&#039;&#039;&#039;External Tools&#039;&#039;&#039;&lt;br /&gt;
**	&#039;&#039;Open Specification with FDR&#039;&#039;: Open the currently loaded CSP-M specification in FDR2. The FDR2 tool is launched with the currently loaded specification in case the FDR2 is installed and the correct path to the `fdr2` command is set for the respective preference `Path to the FDR2 tool`. The value of the `Path to the FDR2 tool` preference can be changed from the “CSP Preferences…” window which can be opened by selecting the `CSP Preferences…` command in `Preferences` menu of the main window.&lt;br /&gt;
**	&#039;&#039;Evaluate with CSPM-Interpreter&#039;&#039;: Selecting this command opens a console in which one can evaluate CSP-M expressions using the CSP-M interpreter. The CSP-M interpreter is an external tool implemented independently from ProB. CSP-M expression can be evaluated if the `cspm` tool is installed and the path to the cspm-command is set for the respective preference `Path to CSPM tool`. The command is obsolete and its removal is considered in future.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The Assertion List Box&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
This part of the viewer lists all assertions stated in the currently loaded CSP-M specification and provides a set of features for checking, manipulating, and debugging of CSP assertions in the list. To each statement in the assertion list box a symbol is assigned, placed on the left side of it, that reveals the current status of the statement in the viewer:&lt;br /&gt;
&lt;br /&gt;
*	?    -  Assertion not checked yet.&lt;br /&gt;
*	✔ - Assertion check completed successfully.&lt;br /&gt;
*	✘ - Assertion check completed, but a counterexample was found to the stated property. The debugger can be used to explore the reason why the property does not hold.&lt;br /&gt;
*	⌚ - Assertion is currently checked.&lt;br /&gt;
*	! -  The check of the assertion not completed for some reason. Possible causes for the interruption may be: &lt;br /&gt;
**	Syntax error in the property was detected;&lt;br /&gt;
**	Assertion check failed because of missing implementation;&lt;br /&gt;
**	Assertion check interrupted by user. &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt; Note that in case of an LTL and a CTL assertion the check could fail to complete because of a syntax error in the respective formula. If an assertion check fails to complete an error box is popped up displaying an error message, which indicates why the assertion check could not be completed.&lt;br /&gt;
&lt;br /&gt;
An assertion can be selected by clicking on it with Mouse-1 and checked by double-clicking on it with Mouse-1. Alternatively, selecting an assertion and then pressing the Enter key can start the respective assertion check.  When an assertion check is in progress, the assertion will be marked by the clock symbol (⌚). If the assertion check is completed without interrupting it, a new status is assigned to the assertion: tick symbol (✔) indicating that the assertion was completed successfully or cross symbol (✘) indicating that a counterexample was found to the stated property. In case that the status is cross the counterexample can be explored by (second) double-click with Mouse-1 on the assertion or by selecting the assertion and then pressing the Enter key. If the respective assertion is negated, i.e. there is `not` in front of the assertion property, and marked with a cross, then no counterexample can be explored as the proper statement holds.&lt;br /&gt;
&lt;br /&gt;
The list box is equipped with a contextual menu (or a pop-up menu), which appears when you right-click on an assertion in the list. Depending on the type and the status of the assertion the contextual menu provides options for checking, debugging, modifying the respective assertion, as well as various other options. Take, for example, the selected assertion on which the contextual menu is popped up in the picture below.&lt;br /&gt;
&lt;br /&gt;
[[file: CSPAssertionsViewer_ctxmenu.png]]&lt;br /&gt;
&lt;br /&gt;
The assertion &amp;quot;&amp;lt;tt&amp;gt;ASSYSTEM |= LTL: “GF [eats.0]”&amp;lt;/tt&amp;gt;&amp;quot; intends to check if the process ASSYSTEM satisfies the LTL formula &amp;quot;&amp;lt;tt&amp;gt;GF [eats.0]&amp;lt;/tt&amp;gt;&amp;quot;. For the selected assertion above, for example, the options `Show LTL Counterexample` and `Show LTL Counterexample in State Space` are enabled as a counterexample was found for the check. On the other hand, the options `Check Assertion` and `Interrupt Assertion` are disabled as the assertion check was completed.&lt;br /&gt;
&lt;br /&gt;
The contextual menu has in general the following options:&lt;br /&gt;
&lt;br /&gt;
The following options affect only the assertion being selected.&lt;br /&gt;
*	&#039;&#039;&#039;Debug or Show LTL/CTL Counterexample…&#039;&#039;&#039;: Opens the graphical viewer for exploring the counterexample that was found for the respective LTL assertion check. Option is enabled if the assertion is not negated and its status is cross (✘), or if the assertion is negated and its status is tick (✔). Option appears if the assertion type is an LTL assertion or a CTL assertion.&lt;br /&gt;
*	&#039;&#039;&#039;Debug Assertion&#039;&#039;&#039;: Opens a trace-failure debugger window showing the reason why the corresponding assertion check failed. Option is enabled if the assertion is not negated and its status is cross (✘), or if the assertion is negated and its status is tick (✔). Option available for all types of assertions except for LTL and CTL assertions.&lt;br /&gt;
*	&#039;&#039;&#039;Check Assertion&#039;&#039;&#039;: Starts immediately the check of the assertion being selected before right clicking on it.&lt;br /&gt;
*	&#039;&#039;&#039;Interrupt Assertion Check&#039;&#039;&#039;: Interrupts the current assertion check.&lt;br /&gt;
*	&#039;&#039;&#039;Uncheck Assertion&#039;&#039;&#039;: If the assertion was checked and the result of the check is different from question mark (?), then the status of the assertion will be reset to question mark. Option is enabled only if the assertion result is different from question mark.&lt;br /&gt;
*	&#039;&#039;&#039;Delete Assertion&#039;&#039;&#039;: Removes the selected item from the assertion list.&lt;br /&gt;
*	&#039;&#039;&#039;Negate Assertion&#039;&#039;&#039;: Negates the respective assertion. If the result of the (proper) assertion check is cross (✘), then the result of the negated assertion becomes tick (✔). Otherwise, if the result of the (proper) assertion is tick (✔), the negated assertion becomes cross (✘).&lt;br /&gt;
*	&#039;&#039;&#039;Swap Processes&#039;&#039;&#039;: Option available only for refinement assertions. Performing the command causes the attachment of a new refinement assertion in which the process expressions on both sides of the refinement operator `[m=` are swapped. If, for example, we execute ‘’Swap Processes’’ on the assertion &amp;quot;&amp;lt;tt&amp;gt;P [T= Q&amp;lt;/tt&amp;gt;&amp;quot;, the command adds to the list of assertions the assertion &amp;quot;&amp;lt;tt&amp;gt;Q [T= P&amp;lt;/tt&amp;gt;&amp;quot;.&lt;br /&gt;
The following options affect all assertions in the list box.&lt;br /&gt;
*	&#039;&#039;&#039;Check All Assertions&#039;&#039;&#039;: The command causes the check of all assertions in the list box. The assertions that are already checked would not be checked again.&lt;br /&gt;
*	&#039;&#039;&#039;Uncheck All Assertions&#039;&#039;&#039;: The status of all assertions in the list box is reset to question mark.&lt;br /&gt;
*	&#039;&#039;&#039;Delete All Assertions&#039;&#039;&#039;: All entries in the list box are removed. As a result the message “No assertions were added.” appears in the list box.&lt;br /&gt;
Other options. The following options have no impact on the assertions in the list box.&lt;br /&gt;
*	&#039;&#039;&#039;Summary of the CSP Syntax&#039;&#039;&#039;: Opens a window in which the summary of the CSP-M syntax and features supported by the ProB tool is given.&lt;br /&gt;
*	&#039;&#039;&#039;Evaluate CSP Expressions&#039;&#039;&#039;: Opens the Eval console in which CSP expressions can be evaluated.&lt;br /&gt;
*	&#039;&#039;&#039;Open Specification with FDR&#039;&#039;&#039;: Opens the currently loaded CSP-M specification in FDR2. The FDR2 tool is launched with the currently loaded specification if FDR2 is installed and the correct path to the `fdr2` command is set for the respective preference `Path to the FDR2 tool`. The value of the `Path to the FDR2 tool` preference can be changed from the “CSP Preferences…” window which can be opened by selecting the `CSP Preferences…` command in `Preferences` menu of the main window.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The Tab Pane&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The tab pane is placed at the bottom of the window and enables the user to construct and check properties of processes of the currently loaded CSP-M file without adding explicitly assertions to the file.&lt;br /&gt;
&lt;br /&gt;
There are overall six tab pages. Each tab page is used to build up new assertion statements. The tab pages provide selectors, entries and command buttons for assembling, adding and checking new assertions. In each of the selectors all possible processes of the loaded CSP-M file are accessible. It is also possible to specify new process expressions by entering these in the respective entry of the process selector. The tab pages for creating LTL and CTL assertions provide additionally an appropriate entry for specifying the according LTL and CTL formula intended to be checked on the specified process, respectively.&lt;br /&gt;
&lt;br /&gt;
Each tab page is equipped with the following command buttons: &lt;br /&gt;
&lt;br /&gt;
*	&#039;&#039;&#039;Add&#039;&#039;&#039;: Attaching a new assertion to the list of assertions in the list box. If the entry in one of the selectors is empty no assertion will be added to list box and a warning message will appear informing the user that some of the entries were not specified. If the entered assertion in the tab page is already in the list box, then a warning box appears informing the user that the assertion is already in the list box. If the assertion is present in the list box it will not be added.&lt;br /&gt;
*	&#039;&#039;&#039;Check&#039;&#039;&#039;: Attaching a new assertion to the list of assertions in the list box and immediately starting checking the assertion. If the assertion is already in the list box, then the user will be informed that the assertion is already in the list box and in case it is not checked yet its check will be started.&lt;br /&gt;
*	&#039;&#039;&#039;Cancel/Interrupt&#039;&#039;&#039;: Closes the window or interrupts an assertion check. In case the “Cancel” command is executed all checks and new assertions will get lost. If an assertion is currently checked, then the button command “Cancel” is replaced by another button command ‘’Interrupt’’, which causes the interruption of the current assertion check when the button is clicked on.&lt;br /&gt;
&lt;br /&gt;
== Debugging Non-satisfied Assertions ==&lt;br /&gt;
&lt;br /&gt;
In case an assertion check has failed the user can explore the reason for the assertion violation. If the corresponding assertion is not negated and after finishing the assertion check is marked by cross, then this is an indication that ProB has found a counterexample for the check. The counterexample can be explored by a second double-click with the ‘Mouse-1’ button or by selecting the assertion and then pressing the ‘Enter’ button. Depending on the type of the assertion and the type of the counterexample a corresponding debugging window is opened.&lt;br /&gt;
&lt;br /&gt;
If a CSP process violates an LTL formula or a universally quantified CTL formula, then by performing a second double-click on the respective assertion one can explore the provided counterexample by means of the graphical viewer ([http://stups.hhu.de/ProB/w/Graphical_Viewer Graphical Viewer]).&lt;br /&gt;
&lt;br /&gt;
In the following we give an overview of the features for debugging counterexamples being found for different refinement checks. Consider the following CSP processes:&lt;br /&gt;
&lt;br /&gt;
P = a -&amp;gt; b -&amp;gt; c -&amp;gt; STOP&lt;br /&gt;
&lt;br /&gt;
Q = a -&amp;gt; (b -&amp;gt; Q [] c -&amp;gt; Q)&lt;br /&gt;
&lt;br /&gt;
R = a -&amp;gt; b -&amp;gt; R&lt;br /&gt;
&lt;br /&gt;
If we intend to check whether P is deadlock free, then we can state the assertion &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;assert P :[deadlock free [F]]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
The check of the assertion will finish by marking the assertion in the list box with a cross symbol (✘). The cross symbol indicates that a counterexample was found for the assertion check. The counterexample is basically given by the trace &amp;lt;math&amp;gt;\langle a,b,c \rangle&amp;lt;/math&amp;gt; as obviously `P` reaches a deadlock state after performing the trace &amp;lt;math&amp;gt;\langle a,b,c \rangle&amp;lt;/math&amp;gt;. Providing a second double-click on the assertion will open the following debugging window:&lt;br /&gt;
&lt;br /&gt;
[[file: CSP_Deadlock_Trace.png]]&lt;br /&gt;
&lt;br /&gt;
Considering the CSP processes `Q` and `R` one can see or check that `R` is a trace refinement of `Q` since `R` performs the same set of traces as `Q`. Thus, the assertion check for `Q [T= R` will mark the assertion statement in the list box by a tick symbol (✔). On the other hand, checking the assertion `R [T= Q` will find a counterexample for the refinement check. Performing a second double-click on the item `R [T= Q` will open the following trace debugger window with the counterexample displayed in it:&lt;br /&gt;
&lt;br /&gt;
[[file: CSP_Trace_Debugger.png]]&lt;br /&gt;
&lt;br /&gt;
A counterexample of a trace-refinement assertion is a trace leading to a state in which the implementation process performs an event that the specification process cannot perform. In the example above both processes `P` and `Q` perform the trace &amp;lt;math&amp;gt;\langle a \rangle&amp;lt;/math&amp;gt; and reach states in which the implementation process can perform an event that is not offered by the specification process &#039;&#039;R&#039;&#039;. One can easily deduce from the picture above that `Q` performs after `a` the event `c` which is not offered by `R` as `R` can perform only `b` after `a`. In the left most column `Accept` the debugger window lists all possible events that are offered by the specification process after performing the trace given in the `Trace` column next to `Accepts`.&lt;br /&gt;
&lt;br /&gt;
As we already mentioned above `R` is a trace-refinement of `Q`. On the other hand, checking whether `R` is a failures-refinement of `Q` will produce a counterexample since `R` refuses the event `c` that is offered by Q after executing `a`. Accordingly, the counterexample will be illustrated within the following trace debugger window:&lt;br /&gt;
&lt;br /&gt;
[[file: CSP_Failures_Debugger.png]]&lt;br /&gt;
&lt;br /&gt;
These are basically the three types of debugging windows that will appear when debugging a counterexample for an assertion check in case the respective assertion is not an LTL or a CTL assertion. When a counterexample for an LTL assertion is found it will be explored in the graphical viewer, the same graphical viewer that is used for visualizing the state space models in ProB. &lt;br /&gt;
&lt;br /&gt;
Let us observe again the CSP process `Q` and suppose we want to check whether `Q` satisfies the LTL formula `F [c]`. Then, the respective LTL assertion is declared as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;assert Q |= LTL: “F [c]”&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The assertion check will produce a counterexample as `Q` obviously reaches a cycle “(b -&amp;gt; a)+” that violates the property “F [c]”. Performing a second double-click on the assertion will display the following state space graph in the graphical viewer:&lt;br /&gt;
&lt;br /&gt;
[[file: CE_LTL_assertion.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above, the nodes and the transitions of the respective counterexample  &amp;quot;a -&amp;gt; (b -&amp;gt; a)+&amp;quot; are colored in red.&lt;br /&gt;
&lt;br /&gt;
== Checking CSP Assertions with `probcli` ==&lt;br /&gt;
It is also possible to check CSP assertions with the command line version of ProB. The command has the following syntax:&lt;br /&gt;
 probcli -csp_assertion &amp;quot;A&amp;quot; File&lt;br /&gt;
&lt;br /&gt;
where &#039;&#039;A&#039;&#039; is a CSP assertion and &#039;&#039;File&#039;&#039; the path to the CSP file. For example, if we want to check the refinement assertion `&amp;lt;tt&amp;gt;P [T= Q&amp;lt;/tt&amp;gt;` on some CSP specification `example.csp`, then we can do this by running the ProB command line version with the following options:&lt;br /&gt;
 probcli -csp_assertion &amp;quot;P [T= Q&amp;quot; example.csp&lt;br /&gt;
&lt;br /&gt;
Note that the assertion should be placed between quotes. In addition, when an assertion is checked with the &#039;-csp_assertion&#039; option the keyword &#039;&#039;&#039;assert&#039;&#039;&#039; should be omitted.&lt;br /&gt;
&lt;br /&gt;
Notice that for checking LTL and CTL assertions from the command line you need to escape the double quotes (&amp;quot;) wrapping the respective LTL/CTL formula by means of a backslash \.&lt;br /&gt;
 probcli -csp_assertion &amp;quot;Q |= LTL: \&amp;quot;F [c]\&amp;quot;&amp;quot; example.csp&lt;br /&gt;
&lt;br /&gt;
== References and Notes ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=The_ProB_Animator_and_Model_Checker&amp;diff=3511</id>
		<title>The ProB Animator and Model Checker</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=The_ProB_Animator_and_Model_Checker&amp;diff=3511"/>
		<updated>2016-02-22T15:53:22Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Features */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60%&amp;quot; style=&amp;quot;padding-right:20px;&amp;quot; |ProB is an animator, constraint solver and model checker for the [http://en.wikipedia.org/wiki/B-Method B-Method] (see the [http://www.clearsy.com/en/our-specific-know-how/b-method/?lang=en B-Method site of Clearsy]). It allows fully automatic animation of B specifications, and can be used to systematically check a specification for a wide range of errors. The constraint-solving capabilities of ProB can also be used for model finding, deadlock checking and test-case generation.&lt;br /&gt;
&lt;br /&gt;
In addition to the B language, ProB also supports [http://www.event-b.org/ Event-B], [http://en.wikipedia.org/wiki/Communicating_sequential_processes CSP-M],&lt;br /&gt;
[http://research.microsoft.com/en-us/um/people/lamport/tla/tla.html TLA+], and [http://en.wikipedia.org/wiki/Z_notation Z]. ProB can be installed within [http://sourceforge.net/projects/rodin-b-sharp/ Rodin], where it comes with [http://www.stups.uni-duesseldorf.de/BMotionStudio/ BMotionStudio] to easily generate domain specific graphical visualizations.&lt;br /&gt;
&lt;br /&gt;
ProB is being used within Siemens, Alstom, and several other companies for [http://www.data-validation.fr data validation] of complicated properties for safety critical systems. Commercial support is provided by the spin-off company [http://www.formalmind.com Formal Mind].&lt;br /&gt;
&lt;br /&gt;
Part of the research and development was conducted within various research projects, such as the [http://www.epsrc.ac.uk/default.htm EPSRC] funded projects [http://users.ecs.soton.ac.uk/phh/abcd/ ABCD] and [http://users.ecs.soton.ac.uk/mal/ISM.html iMoc], the EU funded projects [http://rodin.cs.ncl.ac.uk/ Rodin], [http://www.deploy-project.eu/ Deploy] and [http://www.advance-ict.eu/ Advance] as well as the [http://www.dfg.de/ DFG] project [http://www.gepavas.de/ Gepavas]. &lt;br /&gt;
&lt;br /&gt;
Automatically generated test [http://nightly.cobra.cs.uni-duesseldorf.de/coverage/html/ coverage reports are available].&lt;br /&gt;
&lt;br /&gt;
|width=&amp;quot;40%&amp;quot; style=&amp;quot;background:#EDF2F2;padding:15px;&amp;quot; | &#039;&#039;&#039;News&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;19/2/2015&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.5.0]] is available. Highlights: improved random enumeration, MACE/SEM style static symmetry reduction for deferred set elements, MC/DC coverage analysis for guards and invariants, improved TLC interface, bug fixes and improvements including but not limited to the constraint solver.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3/6/2014&#039;&#039;&#039;&lt;br /&gt;
ProB supports [[Event-B Theories]]. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;30/03/2012&#039;&#039;&#039;&lt;br /&gt;
A first version of the online [[ProB_Logic_Calculator|ProB Logic Calculator]] is available.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; &#039;&#039;&#039;&lt;br /&gt;
[[Download#Short Release History|More in Release History]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
The core of ProB is implemented in [http://www.sics.se/isl/sicstuswww/site/index.html SICStus Prolog] (but can be run without a SICStus Prolog license). The ProB constraint solver is implemented using co-routining and the CLP(FD) finite domain library of SICStus. An alternate [[Using_ProB_with_KODKOD | constraint solver based on Kodkod (and thus SAT)]] is also available within ProB, as is an alternate [[TLC|model checking engine (TLC)]] for low-level B specifications. The [[ProBLicence | ProB Licence can be found here]].&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
ProB covers a [[Summary of B Syntax|large part of B]], and we are striving towards full coverage of Atelier B and B4Free constructs. ProB supports B features such as non-deterministic operations, ANY statements, operations with complex arguments, sets, sequences, functions, lambda abstractions, set comprehensions, records, constants and properties, and many more. Not supported are the Atelier B tree operations and there are restrictions on DEFINITIONS. ProB does support multiple machines, refinements, and implementations. ProB can also be used for automated [[Refinement Checking|refinement checking]] and [[LTL Model Checking|LTL model checking]]. It also [[CSP-M|supports almost full CSP-M]] process descriptions (as of version 1.2.7), to be used on their own or to guide B machines for specification and property validation. The state space of the specifications can be [[Graphical Viewer|graphically visualized]]. &lt;br /&gt;
ProB also supports Z specifications (ProB in this context is sometimes called [[ProZ]]) as well as [[TLA|TLA+ specifications]]. We now also have an online [[ProB Logic Calculator]].&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Checking_CSP_Assertions&amp;diff=3510</id>
		<title>Checking CSP Assertions</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Checking_CSP_Assertions&amp;diff=3510"/>
		<updated>2016-02-22T13:28:10Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Debugging Non-satisfied Assertions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;As of version 1.3.4, ProB provides support for refinement checking and various other assertions (deadlock, divergence, determinism, and LTL/CTL assertions) of CSP-M specifications. In this tutorial we give a short overview of the ProB’s implementations and features for checking CSP assertions. In the Tcl/Tk interface of ProB, CSP assertions can be assembled and checked in the &#039;&#039;CSP Assertions Viewer&#039;&#039;. A description of the &#039;&#039;CSP Assertions Viewer&#039;&#039; is also given.&lt;br /&gt;
&lt;br /&gt;
== Supported CSP Assertions in ProB ==&lt;br /&gt;
&lt;br /&gt;
ProB provides support for checking almost all types of CSP-M assertions that can be checked within FDR2. Besides the assertion types that can be checked in FDR2, in ProB one also can check temporal properties on processes expressed by means of LTL and CTL formulae.&amp;lt;ref&amp;gt;ProB provides support for LTL and CTL model checking (citations needed).&amp;lt;/ref&amp;gt; The following types of assertions are supported in ProB:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Refinement&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Refinement is one of the fundamental notions for construction and verification of systems specified in CSP. Given two CSP processes &#039;&#039;P&#039;&#039; and &#039;&#039;Q&#039;&#039; one can state in ProB the property that process &#039;&#039;Q&#039;&#039; is an ‘m’ refinement of &#039;&#039;P&#039;&#039; by the following assertion declaration:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;assert P [m= Q&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ‘m’ indicates one of the following types of comparison: ‘T’ for traces, ‘F’ for failures, ‘FD’ for failures-divergence, ‘R’ for refusals, and ‘RD’ for ‘refusals-divergence’. Note that the refinement types ‘V’ (revivals) and ‘VD’ (revivals-divergence) that are part of the refinement assertions supported by FDR2 are yet not supported by ProB.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Deadlock&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Stating assertions about CSP processes to be deadlock-free is possible by the following assertion declaration:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;assert P :[deadlock free [m]]&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &#039;&#039;P&#039;&#039; is a process expression and ‘m’ indicates one of the following models: ‘F’ (failures) and ‘FD’ (failures-divergence).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Determinism&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Stating assertions about CSP processes to be deterministic is possible by the following assertion declaration:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;assert P :[deterministic [m]]&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &#039;&#039;P&#039;&#039; is a process expression and ‘m’ one of the following models: ‘F’ (failures) and ‘FD’ (failures-divergence).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Livelock&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Stating assertions about CSP processes to be livelock-free is possible by the following assertion declaration:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;assert P :[livelock free]&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &#039;&#039;P&#039;&#039; is a process expression.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Temporal Properties&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
In ProB it is also possible to make assertions about temporal properties of CSP processes both in LTL and CTL. Basically, one wants to check whether some process &#039;&#039;P&#039;&#039; satisfies a formula &#039;&#039;f&#039;&#039; expressed in a temporal logic (denoted by &amp;lt;tt&amp;gt;P |= f&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
To check whether a process &#039;&#039;P&#039;&#039; satisfies an LTL formula &#039;&#039;f&#039;&#039; write the following declaration:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;assert P |= LTL: “f”&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that &#039;&#039;f&#039;&#039; must be placed between quotes and that the satisfaction relation |= is immediately followed by `LTL:`. ProB supports LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt;, an extended version of LTL which provides additionally support for making propositions on transitions. The following LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; syntax for CSP-M specifications can be outlined by the following rules:&lt;br /&gt;
&lt;br /&gt;
*	Atomic propositions:&lt;br /&gt;
**	To check if an event `evt` is enabled in a state use `e(evt)`&lt;br /&gt;
*	Transition propositions:&lt;br /&gt;
**	To check whether an event `evt` is executed use `[evt]`&lt;br /&gt;
*	 Logical operators&lt;br /&gt;
**	`true` and `false`&lt;br /&gt;
**	`not`: negation&lt;br /&gt;
**	`&amp;amp;`,`or` and `=&amp;gt;`: conjunction, disjunction and implication&lt;br /&gt;
*	Temporal operators:&lt;br /&gt;
**	`G f`: globally&lt;br /&gt;
**	`F f`: finally&lt;br /&gt;
**	`X f`: next&lt;br /&gt;
**	`f U g`: until&lt;br /&gt;
**	`f W g`: weak-until&lt;br /&gt;
**	`f R g`: release&lt;br /&gt;
*	Fairness operators:&lt;br /&gt;
**	`WF(evt)` or `wf(evt)`: weak fairness, where `evt` is an event&lt;br /&gt;
**	`SF(evt)` or `sf(evt)`: strong fairness, where `evt` is an event&lt;br /&gt;
**	`WEF` and `SEF` for checking LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formulae on executions that are strongly and weakly fair with respect to all events, respectively&lt;br /&gt;
&lt;br /&gt;
An LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula &#039;&#039;f&#039;&#039; is satisfied by some CSP process &#039;&#039;P&#039;&#039; if all executions of &#039;&#039;P&#039;&#039; satisfy &#039;&#039;f&#039;&#039;. If there is an execution of &#039;&#039;P&#039;&#039; which violates the property &#039;&#039;f&#039;&#039;, then the test &amp;lt;tt&amp;gt;P |= f&amp;lt;/tt&amp;gt; fails by providing a counterexample. Depending on whether &#039;&#039;f&#039;&#039; expresses, a safety or liveness property, a finite path or a path in a lasso-form (, i.e. a path leading to a cycle) is returned as a counterexample, respectively.&lt;br /&gt;
&lt;br /&gt;
Note that ProB supports also Past-LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt;. Past-LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt;, however, may be considered to be inappropriate for LTL assertions since the goal of this type of assertions is usually to check whether all executions starting at the initial states of the process satisfy the respective LTL&amp;lt;sup&amp;gt;[e]&amp;lt;/sup&amp;gt; formula.&lt;br /&gt;
&lt;br /&gt;
To check whether a process &#039;&#039;P&#039;&#039; satisfies a CTL formula &#039;&#039;f&#039;&#039; the following assertion should be made:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tt&amp;gt;assert P |= CTL: “f”&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As for LTL, CTL formulae should be put in between quotes. The CTL syntax for CSP-M specifications could be summarised as follows:&lt;br /&gt;
*	Atomic propositions:&lt;br /&gt;
**	To check if an event `evt` is enabled in a state use `e(evt)`&lt;br /&gt;
*	Transition propositions:&lt;br /&gt;
**	To check whether an event `evt` is executed use `[evt]`&lt;br /&gt;
*	State formulae, where f, f1 and f2 are path formulae:&lt;br /&gt;
**	true | false | `not` f | f1 `&amp;amp;` f2 | f1 `or` f2 | f1 `=&amp;gt;` f2,&lt;br /&gt;
**	E f : path quantifier `&amp;lt;math&amp;gt;\exists&amp;lt;/math&amp;gt;`, pronounced `for some path`&lt;br /&gt;
**	A f : path quantifier `&amp;lt;math&amp;gt;\forall&amp;lt;/math&amp;gt;`, pronounced `for all paths`&lt;br /&gt;
*	Path formulae, where g, g1 and g2 are state formulae:&lt;br /&gt;
**	`X g`: next&lt;br /&gt;
**	`g1 U g2`: until&lt;br /&gt;
**	`G g`: globally&lt;br /&gt;
**	`F g`: finally&lt;br /&gt;
*	Next executed event:&lt;br /&gt;
**	`EX [e] true`: &lt;br /&gt;
&lt;br /&gt;
Note that these two types of assertions, the LTL and CTL assertions, are not part of the CSP-M language supported by FDR2. Loading a CSP-M file in FDR2 having assertion declarations of this form will exit with a syntax error. Bear in mind to remove or comment out such LTL/CTL assertions in the CSP-M file before loading it in FDR2.&lt;br /&gt;
&lt;br /&gt;
== CSP Assertions Viewer ==&lt;br /&gt;
&lt;br /&gt;
When a CSP-M specification is loaded one can open the &#039;&#039;CSP Assertion Viewer&#039;&#039; either from the menu bar of the main window by selecting the `Check CSP-M Assertions` command in the `Verify` menu or from the Refinement button in the ‘’State Properties’’ pane. The viewer looks as follows:&lt;br /&gt;
&lt;br /&gt;
[[file:CSPAssertionsViewer.png]]&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;CSP Assertion Viewer&#039;&#039; of ProB has a similar design to the graphical user interface of FDR2. It consists basically of three main components: a menu bar, a list box and a tab pane. In the following each of the components and their corresponding functionalities are thoroughly described.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The Menu Bar&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
The menu bar is placed at the top of the window. On OS X, it is placed at the top of the screen. The menu bar includes several menus providing commands for adjusting, executing and changing the items in the list box, as well as some (standard) options for re-loading the model, saving the items to an external file or the loaded file, and launching some external tools related with the domain in which the list items are checked. Each menu can be popped up by a click with Mouse-1 (usually the left mouse button). The menu bar consists of the following menus and menu commands:&lt;br /&gt;
&lt;br /&gt;
*	&#039;&#039;&#039;File&#039;&#039;&#039;&lt;br /&gt;
**	&#039;&#039;Reopen File&#039;&#039;: Reopening (re-reading and re-loading) the currently loaded file, incorporating any changes that may have been made since the file was last loaded.&lt;br /&gt;
**	&#039;&#039;Copy new Assertions to File&#039;&#039;: All assertions that have been added to the list box since the currently loaded file was last read will be written to the file, i.e. all assertions that are yet not in the file are appended to it.&lt;br /&gt;
**	&#039;&#039;Save Assertions to External File&#039;&#039;: Selecting the option opens a standard Tk dialog box requesting a name of a file in which the assertions and their results in the list box could be saved.&lt;br /&gt;
**	&#039;&#039;Exit&#039;&#039;: Closing the CSP Assertion Viewer. Any assertion check results and any recently added assertions from the Tab Pane will get lost. The user will not be prompted to save these to the source file or an external file.&lt;br /&gt;
* &#039;&#039;&#039;Font&#039;&#039;&#039;&amp;lt;br/&amp;gt;Changing the font settings of the elements in the list box. Each of the items of this menu is a cascading menu that provides a number of options to be selected. The currently selected option in the cascading menu is marked by a tick symbol (✓).&lt;br /&gt;
**	&#039;&#039;Family-Name&#039;&#039;: Change the font family of the text in the list box. There are currently four font families that could be chosen: Arial, Curier, Helvetica, and Times. Default font is Curier. &lt;br /&gt;
**	&#039;&#039;Size&#039;&#039;: Change the font size of the text in the list box. Default font size is 10.&lt;br /&gt;
**	&#039;&#039;Background&#039;&#039;: Change the background color of the list box. Default background color is Gray90.&lt;br /&gt;
*	&#039;&#039;&#039;Assertions&#039;&#039;&#039;&amp;lt;br/&amp;gt;The menu provides a list of commands for checking different types of assertions. In case a particular type of assertions is checked the respective command checks only these assertions that are not checked yet.&lt;br /&gt;
**	&#039;&#039;Uncheck All Assertions&#039;&#039;: Set the status of all assertions in the list box to non-checked (`?`). &lt;br /&gt;
**	&#039;&#039;Delete All Assertions&#039;&#039;: Delete all assertions in the list box.&lt;br /&gt;
**	&#039;&#039;Check All Refinement…&#039;&#039;: The item is a cascading menu and provides commands to check all assertions of one of the following supported refinement types: Traces, Failures, Failures-Divergence, Refusals, and Refusals-Divergence.&lt;br /&gt;
**	&#039;&#039;Check Processes for…&#039;&#039;: The item is a cascading menu and provides commands to check all assertions of the following supported types of checks: Deadlock, Determinism and Livelock.&lt;br /&gt;
**	&#039;&#039;Check All LTL Assertions&#039;&#039;: Selecting this command causes ProB to check all LTL assertions in the list box that are not checked yet.&lt;br /&gt;
**	&#039;&#039;Check All CTL Assertions&#039;&#039;: Selecting this command causes ProB to check all CTL assertions in the list box that are not checked yet.&lt;br /&gt;
**	&#039;&#039;Check All Assertions&#039;&#039;: Selecting this command causes ProB to check of all assertions in the list box that are not checked yet.&lt;br /&gt;
*	&#039;&#039;&#039;External Tools&#039;&#039;&#039;&lt;br /&gt;
**	&#039;&#039;Open Specification with FDR&#039;&#039;: Open the currently loaded CSP-M specification in FDR2. The FDR2 tool is launched with the currently loaded specification in case the FDR2 is installed and the correct path to the `fdr2` command is set for the respective preference `Path to the FDR2 tool`. The value of the `Path to the FDR2 tool` preference can be changed from the “CSP Preferences…” window which can be opened by selecting the `CSP Preferences…` command in `Preferences` menu of the main window.&lt;br /&gt;
**	&#039;&#039;Evaluate with CSPM-Interpreter&#039;&#039;: Selecting this command opens a console in which one can evaluate CSP-M expressions using the CSP-M interpreter. The CSP-M interpreter is an external tool implemented independently from ProB. CSP-M expression can be evaluated if the `cspm` tool is installed and the path to the cspm-command is set for the respective preference `Path to CSPM tool`. The command is obsolete and its removal is considered in future.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The Assertion List Box&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
This part of the viewer lists all assertions stated in the currently loaded CSP-M specification and provides a set of features for checking, manipulating, and debugging of CSP assertions in the list. To each statement in the assertion list box a symbol is assigned, placed on the left side of it, that reveals the current status of the statement in the viewer:&lt;br /&gt;
&lt;br /&gt;
*	?    -  Assertion not checked yet.&lt;br /&gt;
*	✔ - Assertion check completed successfully.&lt;br /&gt;
*	✘ - Assertion check completed, but a counterexample was found to the stated property. The debugger can be used to explore the reason why the property does not hold.&lt;br /&gt;
*	⌚ - Assertion is currently checked.&lt;br /&gt;
*	! -  The check of the assertion not completed for some reason. Possible causes for the interruption may be: &lt;br /&gt;
**	Syntax error in the property was detected;&lt;br /&gt;
**	Assertion check failed because of missing implementation;&lt;br /&gt;
**	Assertion check interrupted by user. &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt; Note that in case of an LTL and a CTL assertion the check could fail to complete because of a syntax error in the respective formula. If an assertion check fails to complete an error box is popped up displaying an error message, which indicates why the assertion check could not be completed.&lt;br /&gt;
&lt;br /&gt;
An assertion can be selected by clicking on it with Mouse-1 and checked by double-clicking on it with Mouse-1. Alternatively, selecting an assertion and then pressing the Enter key can start the respective assertion check.  When an assertion check is in progress, the assertion will be marked by the clock symbol (⌚). If the assertion check is completed without interrupting it, a new status is assigned to the assertion: tick symbol (✔) indicating that the assertion was completed successfully or cross symbol (✘) indicating that a counterexample was found to the stated property. In case that the status is cross the counterexample can be explored by (second) double-click with Mouse-1 on the assertion or by selecting the assertion and then pressing the Enter key. If the respective assertion is negated, i.e. there is `not` in front of the assertion property, and marked with a cross, then no counterexample can be explored as the proper statement holds.&lt;br /&gt;
&lt;br /&gt;
The list box is equipped with a contextual menu (or a pop-up menu), which appears when you right-click on an assertion in the list. Depending on the type and the status of the assertion the contextual menu provides options for checking, debugging, modifying the respective assertion, as well as various other options. Take, for example, the selected assertion on which the contextual menu is popped up in the picture below.&lt;br /&gt;
&lt;br /&gt;
[[file: CSPAssertionsViewer_ctxmenu.png]]&lt;br /&gt;
&lt;br /&gt;
The assertion &amp;quot;&amp;lt;tt&amp;gt;ASSYSTEM |= LTL: “GF [eats.0]”&amp;lt;/tt&amp;gt;&amp;quot; intends to check if the process ASSYSTEM satisfies the LTL formula &amp;quot;&amp;lt;tt&amp;gt;GF [eats.0]&amp;lt;/tt&amp;gt;&amp;quot;. For the selected assertion above, for example, the options `Show LTL Counterexample` and `Show LTL Counterexample in State Space` are enabled as a counterexample was found for the check. On the other hand, the options `Check Assertion` and `Interrupt Assertion` are disabled as the assertion check was completed.&lt;br /&gt;
&lt;br /&gt;
The contextual menu has in general the following options:&lt;br /&gt;
&lt;br /&gt;
The following options affect only the assertion being selected.&lt;br /&gt;
*	&#039;&#039;&#039;Debug or Show LTL/CTL Counterexample…&#039;&#039;&#039;: Opens the graphical viewer for exploring the counterexample that was found for the respective LTL assertion check. Option is enabled if the assertion is not negated and its status is cross (✘), or if the assertion is negated and its status is tick (✔). Option appears if the assertion type is an LTL assertion or a CTL assertion.&lt;br /&gt;
*	&#039;&#039;&#039;Debug Assertion&#039;&#039;&#039;: Opens a trace-failure debugger window showing the reason why the corresponding assertion check failed. Option is enabled if the assertion is not negated and its status is cross (✘), or if the assertion is negated and its status is tick (✔). Option available for all types of assertions except for LTL and CTL assertions.&lt;br /&gt;
*	&#039;&#039;&#039;Check Assertion&#039;&#039;&#039;: Starts immediately the check of the assertion being selected before right clicking on it.&lt;br /&gt;
*	&#039;&#039;&#039;Interrupt Assertion Check&#039;&#039;&#039;: Interrupts the current assertion check.&lt;br /&gt;
*	&#039;&#039;&#039;Uncheck Assertion&#039;&#039;&#039;: If the assertion was checked and the result of the check is different from question mark (?), then the status of the assertion will be reset to question mark. Option is enabled only if the assertion result is different from question mark.&lt;br /&gt;
*	&#039;&#039;&#039;Delete Assertion&#039;&#039;&#039;: Removes the selected item from the assertion list.&lt;br /&gt;
*	&#039;&#039;&#039;Negate Assertion&#039;&#039;&#039;: Negates the respective assertion. If the result of the (proper) assertion check is cross (✘), then the result of the negated assertion becomes tick (✔). Otherwise, if the result of the (proper) assertion is tick (✔), the negated assertion becomes cross (✘).&lt;br /&gt;
*	&#039;&#039;&#039;Swap Processes&#039;&#039;&#039;: Option available only for refinement assertions. Performing the command causes the attachment of a new refinement assertion in which the process expressions on both sides of the refinement operator `[m=` are swapped. If, for example, we execute ‘’Swap Processes’’ on the assertion &amp;quot;&amp;lt;tt&amp;gt;P [T= Q&amp;lt;/tt&amp;gt;&amp;quot;, the command adds to the list of assertions the assertion &amp;quot;&amp;lt;tt&amp;gt;Q [T= P&amp;lt;/tt&amp;gt;&amp;quot;.&lt;br /&gt;
The following options affect all assertions in the list box.&lt;br /&gt;
*	&#039;&#039;&#039;Check All Assertions&#039;&#039;&#039;: The command causes the check of all assertions in the list box. The assertions that are already checked would not be checked again.&lt;br /&gt;
*	&#039;&#039;&#039;Uncheck All Assertions&#039;&#039;&#039;: The status of all assertions in the list box is reset to question mark.&lt;br /&gt;
*	&#039;&#039;&#039;Delete All Assertions&#039;&#039;&#039;: All entries in the list box are removed. As a result the message “No assertions were added.” appears in the list box.&lt;br /&gt;
Other options. The following options have no impact on the assertions in the list box.&lt;br /&gt;
*	&#039;&#039;&#039;Summary of the CSP Syntax&#039;&#039;&#039;: Opens a window in which the summary of the CSP-M syntax and features supported by the ProB tool is given.&lt;br /&gt;
*	&#039;&#039;&#039;Evaluate CSP Expressions&#039;&#039;&#039;: Opens the Eval console in which CSP expressions can be evaluated.&lt;br /&gt;
*	&#039;&#039;&#039;Open Specification with FDR&#039;&#039;&#039;: Opens the currently loaded CSP-M specification in FDR2. The FDR2 tool is launched with the currently loaded specification if FDR2 is installed and the correct path to the `fdr2` command is set for the respective preference `Path to the FDR2 tool`. The value of the `Path to the FDR2 tool` preference can be changed from the “CSP Preferences…” window which can be opened by selecting the `CSP Preferences…` command in `Preferences` menu of the main window.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The Tab Pane&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The tab pane is placed at the bottom of the window and enables the user to construct and check properties of processes of the currently loaded CSP-M file without adding explicitly assertions to the file.&lt;br /&gt;
&lt;br /&gt;
There are overall six tab pages. Each tab page is used to build up new assertion statements. The tab pages provide selectors, entries and command buttons for assembling, adding and checking new assertions. In each of the selectors all possible processes of the loaded CSP-M file are accessible. It is also possible to specify new process expressions by entering these in the respective entry of the process selector. The tab pages for creating LTL and CTL assertions provide additionally an appropriate entry for specifying the according LTL and CTL formula intended to be checked on the specified process, respectively.&lt;br /&gt;
&lt;br /&gt;
Each tab page is equipped with the following command buttons: &lt;br /&gt;
&lt;br /&gt;
*	&#039;&#039;&#039;Add&#039;&#039;&#039;: Attaching a new assertion to the list of assertions in the list box. If the entry in one of the selectors is empty no assertion will be added to list box and a warning message will appear informing the user that some of the entries were not specified. If the entered assertion in the tab page is already in the list box, then a warning box appears informing the user that the assertion is already in the list box. If the assertion is present in the list box it will not be added.&lt;br /&gt;
*	&#039;&#039;&#039;Check&#039;&#039;&#039;: Attaching a new assertion to the list of assertions in the list box and immediately starting checking the assertion. If the assertion is already in the list box, then the user will be informed that the assertion is already in the list box and in case it is not checked yet its check will be started.&lt;br /&gt;
*	&#039;&#039;&#039;Cancel/Interrupt&#039;&#039;&#039;: Closes the window or interrupts an assertion check. In case the “Cancel” command is executed all checks and new assertions will get lost. If an assertion is currently checked, then the button command “Cancel” is replaced by another button command ‘’Interrupt’’, which causes the interruption of the current assertion check when the button is clicked on.&lt;br /&gt;
&lt;br /&gt;
== Debugging Non-satisfied Assertions ==&lt;br /&gt;
&lt;br /&gt;
In case an assertion check has failed the user can explore the reason for the assertion violation. If the corresponding assertion is not negated and after finishing the assertion check is marked by cross, then this is an indication that ProB has found a counterexample for the check. The counterexample can be explored by a second double-click with the ‘Mouse-1’ button or by selecting the assertion and then pressing the ‘Enter’ button. Depending on the type of the assertion and the type of the counterexample a corresponding debugging window is opened.&lt;br /&gt;
&lt;br /&gt;
If a CSP process violates an LTL formula or a universally quantified CTL formula, then by performing a second double-click on the respective assertion one can explore the provided counterexample by means of the graphical viewer ([http://stups.hhu.de/ProB/w/Graphical_Viewer Graphical Viewer]).&lt;br /&gt;
&lt;br /&gt;
In the following we give an overview of the features for debugging counterexamples being found for different refinement checks. Consider the following CSP processes:&lt;br /&gt;
&lt;br /&gt;
P = a -&amp;gt; b -&amp;gt; c -&amp;gt; STOP&lt;br /&gt;
&lt;br /&gt;
Q = a -&amp;gt; (b -&amp;gt; Q [] c -&amp;gt; Q)&lt;br /&gt;
&lt;br /&gt;
R = a -&amp;gt; b -&amp;gt; R&lt;br /&gt;
&lt;br /&gt;
If we intend to check whether P is deadlock free, then we can state the assertion &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;assert P :[deadlock free [F]]&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
The check of the assertion will finish by marking the assertion in the list box with a cross symbol (✘). The cross symbol indicates that a counterexample was found for the assertion check. The counterexample is basically given by the trace &amp;lt;math&amp;gt;\langle a,b,c \rangle&amp;lt;/math&amp;gt; as obviously `P` reaches a deadlock state after performing the trace &amp;lt;math&amp;gt;\langle a,b,c \rangle&amp;lt;/math&amp;gt;. Providing a second double-click on the assertion will open the following debugging window:&lt;br /&gt;
&lt;br /&gt;
[[file: CSP_Deadlock_Trace.png]]&lt;br /&gt;
&lt;br /&gt;
Considering the CSP processes `Q` and `R` one can see or check that `R` is a trace refinement of `Q` since `R` performs the same set of traces as `Q`. Thus, the assertion check for `Q [T= R` will mark the assertion statement in the list box by a tick symbol (✔). On the other hand, checking the assertion `R [T= Q` will find a counterexample for the refinement check. Performing a second double-click on the item `R [T= Q` will open the following trace debugger window with the counterexample displayed in it:&lt;br /&gt;
&lt;br /&gt;
[[file: CSP_Trace_Debugger.png]]&lt;br /&gt;
&lt;br /&gt;
A counterexample of a trace-refinement assertion is a trace leading to a state in which the implementation process performs an event that the specification process cannot perform. In the example above both processes `P` and `Q` perform the trace &amp;lt;math&amp;gt;\langle a \rangle&amp;lt;/math&amp;gt; and reach states in which the implementation process can perform an event that is not offered by the specification process &#039;&#039;R&#039;&#039;. One can easily deduce from the picture above that `Q` performs after `a` the event `c` which is not offered by `R` as `R` can perform only `b` after `a`. In the left most column `Accept` the debugger window lists all possible events that are offered by the specification process after performing the trace given in the `Trace` column next to `Accepts`.&lt;br /&gt;
&lt;br /&gt;
As we already mentioned above `R` is a trace-refinement of `Q`. On the other hand, checking whether `R` is a failures-refinement of `Q` will produce a counterexample since `R` refuses the event `c` that is offered by Q after executing `a`. Accordingly, the counterexample will be illustrated within the following trace debugger window:&lt;br /&gt;
&lt;br /&gt;
[[file: CSP_Failures_Debugger.png]]&lt;br /&gt;
&lt;br /&gt;
These are basically the three types of debugging windows that will appear when debugging a counterexample for an assertion check in case the respective assertion is not an LTL or a CTL assertion. When a counterexample for an LTL assertion is found it will be explored in the graphical viewer, the same graphical viewer that is used for visualizing the state space models in ProB. &lt;br /&gt;
&lt;br /&gt;
Let us observe again the CSP process `Q` and suppose we want to check whether `Q` satisfies the LTL formula `F [c]`. Then, the respective LTL assertion is declared as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;assert Q |= LTL: “F [c]”&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The assertion check will produce a counterexample as `Q` obviously reaches a cycle “(b -&amp;gt; a)+” that violates the property “F [c]”. Performing a second double-click on the assertion will display the following state space graph in the graphical viewer:&lt;br /&gt;
&lt;br /&gt;
[[file: CE_LTL_assertion.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above, the nodes and the transitions of the respective counterexample  &amp;quot;a -&amp;gt; (b -&amp;gt; a)+&amp;quot; are colored in red.&lt;br /&gt;
&lt;br /&gt;
== Checking CSP Assertions with `probcli` ==&lt;br /&gt;
It is also possible to check CSP assertions with the command line version of ProB. The command has the following syntax:&lt;br /&gt;
 probcli -csp_assertion &amp;quot;A&amp;quot; File&lt;br /&gt;
&lt;br /&gt;
where &#039;&#039;A&#039;&#039; is a CSP assertion and &#039;&#039;File&#039;&#039; the path to the CSP file. For example, if we want to check the refinement assertion `&amp;lt;tt&amp;gt;P [T= Q&amp;lt;/tt&amp;gt;` on some CSP specification `example.csp`, then we can do this by running the ProB command line version with the following options:&lt;br /&gt;
 probcli -csp_assertion &amp;quot;P [T= Q&amp;quot; example.csp&lt;br /&gt;
&lt;br /&gt;
Note that the assertion should be placed between quotes. In addition, when an assertion is checked with the &#039;-csp_assertion&#039; option the keyword &#039;&#039;&#039;assert&#039;&#039;&#039; should be omitted.&lt;br /&gt;
== References and Notes ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3509</id>
		<title>Tutorial Enabling Analysis</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3509"/>
		<updated>2016-02-22T12:56:08Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Enabling Relations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The B-method and in particular its successor Event-B are methodologies for formal development and verification of systems. In Event-B, a machine is usually viewed as a reactive system executing continuously enabled (atomic) events in an interleaved fashion. Thus, parallel events of the system are easily modeled as an interleaving of operation executions. On the other hand, the introduction of abstract counters is required when events are supposed to be executed in some (sequential) order. This, however, can in some cases slow the work of understanding and verifying a model since identifying the sequential ordering of events in an Event-B model is not that obvious. Thus, using methods for determining the control flow can be sometimes very beneficial for understanding the model, as well as for techniques for automatic verification such as model checking.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we present a static analysis for B and Event-B that can be used to reveal the control flow of a machine and to optimize model checking of models written in B and Event-B (see also [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Guard_Evaluation Tutorial on Partial Guard Evaluation ]). The results of the analysis, designated also as ‘’enabling analysis’’, can be presented as relations by means of a table or by means of a graph. For simplicity, we will concentrate mainly on B and use the terminology of the formalism.&lt;br /&gt;
&lt;br /&gt;
== Enabling Relations ==&lt;br /&gt;
What we want to find out is how the operations influence each other within a B model. In other words, for each pair (op1,op2) of operations we try to determine as precise as possible how op1 can affect the guard condition of op2 with regard to enabledness. To determine the enabling relations between operations we use syntactic analyses, as well as the constraint-based abilities of ProB.&lt;br /&gt;
&lt;br /&gt;
Consider the following B machine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE Example&lt;br /&gt;
VARIABLES x, y, z&lt;br /&gt;
INVARIANT&lt;br /&gt;
    x:NATURAL&lt;br /&gt;
  &amp;amp; y:INTEGER&lt;br /&gt;
  &amp;amp; z:INTEGER&lt;br /&gt;
INITIALISATION &lt;br /&gt;
  x:=6 || y:=-2 || z:=0&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Op1 = PRE x + y&amp;gt;=4  THEN x:=x+2 || y:=2 END;&lt;br /&gt;
  Op2 = PRE x mod 2=1 THEN x:=x+1 || y:=2 END;&lt;br /&gt;
  Op3 = PRE x mod 2=0 THEN x:=x+2 END;&lt;br /&gt;
  Op4 = PRE x&amp;lt;0 THEN y:=y-1 END;&lt;br /&gt;
  Op5 = PRE y/=2 THEN z:=3 END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The machine has three variables x,y,z, where x ranges over the domain of natural numbers and y and z over the domain of all integers. For this machine we have 25 pairs of operations for which we want to determine the respective enabling relations. Additionally, we identify 5 further pairs that show the influence of the INITIALISATION on the guard conditions of all other operations. Consider, for example, the pair (Op2,Op1) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op1 is enabled in each state of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; where the predicate ‘x+y&amp;gt;=4’ is fulfilled. Since the effect of Op2 assigns 2 to y and increments x by one upon condition that x is a positive odd number in the before-state of Op2, we can assume that Op1 is always enabled after the execution of Op2. In other words, in all after-states of Op2 the operation Op1 is guaranteed to be enabled. This relation between Op2 and Op1 we can illustrate as follows: &lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above the green boxes denote that the evaluation of the guard of Op1 is true, whereas the red boxes denote that the evaluation of the guard of Op1 is false. &lt;br /&gt;
&lt;br /&gt;
Another pair of interest is (Op2,Op5) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op5 is enabled only in those states in which y is not equal to 2. Obviously, in each after-state of Op2 y is equal to 2 and thus we can conclude that Op5 is impossible to be enabled after each execution of Op2. Such a relation between two operations we denote as ‘’impossible’’ and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
Both arrows in the illustration of the ‘’impossible’’ relation indicate that whether the guard condition of Op5 is fulfilled or not in a before-state of Op2 operation Op5 will be disabled in the respective after-state of Op2. In order to recognize a tuple (op1,op2) as ‘’impossible’’ we require that op2 is always disabled after op1 without further considering whether op2 is always enabled or always disabled in the before-states of op1. &lt;br /&gt;
&lt;br /&gt;
Consider, for instance, the pair (Op2, Op2) in the machine above. We can easily conclude that Op2 becomes disabled after it is executed and clearly, the second case (\false -&amp;gt; \false) of the impossible relation is not possible for (Op2, Op2). This gives rise of introducing another (more precise) impossible relation:&lt;br /&gt;
 &lt;br /&gt;
[[File:ImpossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Accordingly, we can derive another relation from ‘’impossible’’ for which only the second case of the ‘’impossible’’ relation is fulfilled:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
As an example for a pair of operations that fulfills the ‘’impossible_keep’’ requirement you can take, for example, the pair (Op3,Op2) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Since Op2 and Op3 cannot be both enabled in a state and the execution of Op3 cannot enable Op2, then we can easily conclude that Op2 remains always disabled after Op3.&lt;br /&gt;
&lt;br /&gt;
Similarly as for ‘’impossible’’, one could derive two further enabling relations from ‘’guaranteed’’:&lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedEnableKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Another interesting class of enabling relations that could be helpful for better understanding and analyzing B and Event-B models is that of the ‘’keep’’ relations. We say that an operation op1 ‘’keeps’’ another operation op2 if op1 cannot change the status of the enabling condition of op2, i.e. op1 keeps op2 enabled respectively disabled. This relationship could be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:KeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
We can take (Op1,Op2) and (Op1,Op3) as examples of pairs in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; that are elements of the keep relation. ‘’keep’’ relations can sometimes be easily determined by analyzing just the syntactic structure of both operations, or more precisely the “read” and “write” sets of both operations.&amp;lt;ref&amp;gt;For an operation op the set read(op) denotes the set of variables that are read by op. Accordingly, by write(op) we denote the set of variables that are written by op.&amp;lt;/ref&amp;gt; If, for example, an operation op1 does not write any variable of the machine that is read in the guard condition of op2, then we can infer that op1 ‘’keeps’’ op2. In that case we also say that op1 does not change op2 syntactically. In the class of the ‘’keep’’ relations are included also relations such as independence. Two operations op1 and op2 are called independent if each of them cannot disable the other operation and the both orders of execution &amp;lt;op1,op2&amp;gt; and &amp;lt;op2,op1&amp;gt; have the same effect.&amp;lt;ref&amp;gt;See the [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Order_Reduction Tutorial on Partial Order Reduction] for more information on independence between operations.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three classes (‘’guaranteed’’, ‘’impossible’’ and ‘’keep’’) of enabling relations presented so far represent definite relations. That is, if a pair of operations (op1,op2) is confirmed to be a relation of one of this three classes, then we can certainly say what effect on the enabling condition of op2 would the execution of op1 have. However, for some pairs of operations we cannot certainly say what effect an operation would have on the enabling condition of another operation. This is due to the fact that the enabling status of an operation does not only depend on the effect of the executed operations, but also on the current variables’ evaluation. Take, for instance, the tuple (Op3,Op1) from the B machine above. Considering the action part of Op3 and the guard condition of Op1 we can assume that Op3 can enable Op1. Since the guard of Op1 depends not only on the current value of x, but also on y, there could be transitions s -&amp;gt; s&#039; of Op3 in the state space of the machine where Op1 is disabled in both states s and s’. Though, what we could definitely say is that Op3 cannot disable Op1. This relationship we can illustrate as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleEnableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
The opposite relation of “possible_enable” is the relation where an operation op2 can disable another operation op1. Formally, we say that op2 can disable op1 if op2 may disable op1 and op2 cannot enable op1. This relationship is denoted as “possible_disable” and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
In order to determine how operations influence each other we need to assure first that these are feasible. An operation ‘’op’’ is said to be feasible if there is a state of the machine that satisfies the invariant of the machine and in which ‘’op’’ is enabled. In the B machine above the operation Op4, for example, is not feasible. Obviously, Op4 is enabled only in states where x is a negative number and states in which x is a negative number are visibly not consistent with the invariant since &amp;quot;x : NATURAL&amp;quot;. Such incompatibilities are sometimes of great importance for the modeler and therefore they should be revealed in the process of computing the enabling relations. In our case for each pair of operations (Op4,-) and (-,Op4) the status “infeasible” will be returned.&lt;br /&gt;
&lt;br /&gt;
We can now list all possible enabling relations for the machine &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; by means of a table. For each entry in the table the operation in the row is the operation whose effect is studied on the status of the guard of the operation in the column.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingResults.png]]&lt;br /&gt;
&lt;br /&gt;
Rather than showing the enabling information for each pair of operations of the machine, one can display the enabling relations by means of a graph. The graph contains the operations as nodes and the above enabling relations as edges between the nodes, with the exception that relations marked as impossible, independent or infeasible are not shown in the graph. We denote such graphs as enable graphs. The enable graph of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; looks as follows.&lt;br /&gt;
&lt;br /&gt;
[[File: EnableGraph_Example.png]]&lt;br /&gt;
&lt;br /&gt;
From the enable graph one can recognize the control flow of the model and deduce some properties. For example, we can clearly see that &amp;lt;tt&amp;gt;Op4&amp;lt;/tt&amp;gt; cannot occur after the execution of another operation.&lt;br /&gt;
&lt;br /&gt;
== Summary of the Enabling Relations ==&lt;br /&gt;
&lt;br /&gt;
In the following, we summarize most of the enabling relations that we think can provide a useful feedback to the user. For each of the enabling relations we have given an appropriate example. In the examples below we compute the effect of executing ‘op1’ on the status of the guard of ‘op2’. The relation identifiers are the same as they appear as results in ProB.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;guaranteed&#039;&#039;: op2 guaranteed to be executable after op1.&lt;br /&gt;
[[File: GuaranteedExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_enable&#039;&#039;: op2 is guaranteed to become enabled after op1.&lt;br /&gt;
[[File: GuaranteedEnableExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_keep&#039;&#039;: op2 is guaranteed to stay enabled after op1.&lt;br /&gt;
[[File: GuaranteedKeepExample.png]]&lt;br /&gt;
* &#039;&#039;impossible&#039;&#039;: op2 is impossible to be executed after op1.&lt;br /&gt;
[[File: ImpossibleExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_disable&#039;&#039;: op2 is guaranteed to become disabled after op1.&lt;br /&gt;
[[File: ImpossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_keep&#039;&#039;: op2 is impossible to become enabled after op1.&lt;br /&gt;
[[File: ImpossibleKeepExample.png]]&lt;br /&gt;
* &#039;&#039;keep&#039;&#039;: op2 always stays enabled resp. disabled after op1.&lt;br /&gt;
[[File: KeepExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_unchanged&#039;&#039;: op1 does not write any variable read in the guard of op2, i.e. write(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticUnchangedExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_independent&#039;&#039;: op1 and op2 are syntactically independent, i.e. read(op1) /\ write(op2) = {} &amp;amp; write(op1) /\ read(op2) = {} &amp;amp; write(op1) /\ write(op2) = {}&lt;br /&gt;
[[File: SyntacticIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;syntactically_fully_independent&#039;&#039;: op1 and op2 are syntactically independent and additionally, read(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticFullyIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;possible_enable&#039;&#039;: op2 possible after op1, but op2 cannot be disabled by op1.&lt;br /&gt;
[[File: PossibleEnableExample.png]]&lt;br /&gt;
* &#039;&#039;possible_disable&#039;&#039;: op2 possible after iop1, but op2 cannot be enabled by op1.&lt;br /&gt;
[[File: PossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;infeasible&#039;&#039;: op1 is not feasible and thus cannot influence op2.&lt;br /&gt;
[[File: InfeasibleExample.png]]&lt;br /&gt;
&lt;br /&gt;
== Performing Enabling Analysis within ProB  ==&lt;br /&gt;
&lt;br /&gt;
The enabling analysis has been implemented in the ProB toolset.  The computation of the enabling relations is based on syntactic and constraint-based techniques. The identification of relations such as ‘’syntactic_independent’’ and ‘’syntactic_unchanged’’ requires just a thorough study of the syntactic structure of the operations, i.e. no calls to the constraint solver have to be made. However, to confirm, for example, that an operation is guaranteed or impossible to be executed after another operation the use of the ProB’s constraint solver is unavoidable. For instance, consider the pair (Op2,Op1) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. As we have seen, in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; the operation Op1 is guaranteed to be enabled after each execution of Op2. In ProB this could be computed by feeding the (before-after) predicate “ (x mod 2 = 1) =&amp;gt; [x:=x+1 || y:=2] (x+y&amp;lt;4)” into the constraint solver. As a result, the constraint solver will not find a solution for the predicate, i.e. the constraint solver will not find a state ‘’s’’ satisfying “x mod 2 = 1” from which after executing Op2 at ‘’s’’ a solution state s’ will be found that fulfills “x+y&amp;lt;4”; note that “x+y&amp;lt;4” is the negation of the guard of Op1. Since there is no after-state of Op2 at which Op1 is disabled we can conclude that Op1 is guaranteed to be executed after Op2. When constraints are getting more complex the constraint solver may need more time for solving and determining the enabling relations may become a very time-expensive task. Therefore, a time-out for each constraint solver call is set. In other words, if the constraint solver does not find a solution in the given time by the user, then the respective relation will be denoted as time-outed. By default, in ProB the time-out for each constraint solver call is set to 300 ms.&lt;br /&gt;
&lt;br /&gt;
Within &amp;lt;tt&amp;gt;ProB Tcl/Tk&amp;lt;/tt&amp;gt; you can find the menu &amp;quot;Enabling Analysis&amp;quot; in the &amp;quot;Analysis&amp;quot; menu of the menu bar.&lt;br /&gt;
[[File: EnablingAnalysisMenu.png]]&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;Enabling Analysis&amp;quot; menu provides multiple commands:&lt;br /&gt;
* &amp;quot;Enabling Analysis (Table)&amp;quot;: this command performs a (fast) enabling analysis on the respective B model using a time-out of 300 ms for the constraint-solver calls. The result of the enabling analysis is shown in a table. The table lists all enabling relations between the operations of the loaded B model. These can be exported to a CSV file. The table for &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; at the end of the &#039;&#039;&#039; Enabling Relations&#039;&#039;&#039; section was constructed this way.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Precise, Table)&amp;quot;: this command performs an enabling analysis using a time-out of 2800 ms for each of the constraint-solver calls. As for the command above, the result of the analysis is shown in a table that can be exported to a CSV file.&lt;br /&gt;
* &amp;quot;Enabling Relations After...&amp;quot;: this command computes all the enabling relations involving an operation chosen by the user.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Graph)&amp;quot;: this command performs the fast enabling analysis but displays the results as a graph. In case the preference &amp;quot;DOT_SHOW_OP_READ_WRITES&amp;quot; is set for each operation the read/write information is displayed.&lt;br /&gt;
* &amp;quot;Enabling Analysis (POR)...&amp;quot;: this menu provides further commands for another form of enabling analysis the results of which are used for the partial guard evaluation optimisation in ProB.&lt;br /&gt;
* &amp;quot;Read/Write Matrix (Table)&amp;quot;: this command performs syntactic analysis on the model. The analysis determines the read and write sets for each operation of the machine.&lt;br /&gt;
* &amp;quot;Dependence Analysis (Table)&amp;quot;: this command performs a dependency analysis for each pair of operations. More specifically, the analysis determines which operations are dependent or independent to each other.&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB (probcli) one can perform an enabling analysis on a B or Event-B model by means of the &amp;lt;tt&amp;gt;-enabling_analysis&amp;lt;/tt&amp;gt; option. The results of the analysis, as well as intermediate data and some statistics are printed out on the console:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli Example.mch -enabling_analysis&lt;br /&gt;
CHECKING ENABLING AFTER INITIALISATION&lt;br /&gt;
INITIALISATION ---&amp;gt; Op1  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op2  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op3  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op4  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op5  :: ok : guaranteed&lt;br /&gt;
.....&lt;br /&gt;
CHECKING ENABLING AFTER: Op5 r:[y] / w:[z]&lt;br /&gt;
Op5 ---&amp;gt; Op1  :: Enable=syntactic_independent&lt;br /&gt;
Op5 ---&amp;gt; Op2  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op3  :: Enable=syntactic_fully_independent&lt;br /&gt;
Op5 ---&amp;gt; Op4  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op5  :: Enable=syntactic_unchanged&lt;br /&gt;
% Finished CBC Enabling Analysis 810 ms walltime (770 ms runtime), since start: 1650 ms&lt;br /&gt;
% CBC Enabling Stats:&lt;br /&gt;
% Nr of events: 5&lt;br /&gt;
% Nr of cbc calls: 30, Timeout results: 2&lt;br /&gt;
Origin,Op1,Op2,Op3,Op4,Op5&lt;br /&gt;
INITIALISATION,guaranteed,impossible,guaranteed,impossible,guaranteed&lt;br /&gt;
Op1,timeout_possible_disable,keep,keep,impossible_keep,syntactic_independent&lt;br /&gt;
Op2,guaranteed,impossible,guaranteed,impossible_keep,impossible&lt;br /&gt;
Op3,timeout_possible,impossible_keep,guaranteed,impossible_keep,syntactic_fully_independent&lt;br /&gt;
Op4,impossible_keep,syntactic_unchanged,syntactic_unchanged,syntactic_keep,impossible_keep&lt;br /&gt;
Op5,syntactic_independent,syntactic_unchanged,syntactic_fully_independent,syntactic_unchanged,syntactic_unchanged&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To perform enabling analysis from the command line and save the results to a CSV-file use the following commando:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli file.mch -enabling_analysis_csv FILE &amp;lt;/pre&amp;gt;&lt;br /&gt;
where FILE is the name of the CSV-file in which the results of the analysis are stored.&lt;br /&gt;
&lt;br /&gt;
== References and Footnotes ==&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=File:EnableGraph_Example.png&amp;diff=3508</id>
		<title>File:EnableGraph Example.png</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=File:EnableGraph_Example.png&amp;diff=3508"/>
		<updated>2016-02-22T12:48:57Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3496</id>
		<title>Tutorial Enabling Analysis</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3496"/>
		<updated>2016-02-16T14:51:34Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Performing Enabling Analysis within ProB */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The B-method and in particular its successor Event-B are methodologies for formal development and verification of systems. In Event-B, a machine is usually viewed as a reactive system executing continuously enabled (atomic) events in an interleaved fashion. Thus, parallel events of the system are easily modeled as an interleaving of operation executions. On the other hand, the introduction of abstract counters is required when events are supposed to be executed in some (sequential) order. This, however, can in some cases slow the work of understanding and verifying a model since identifying the sequential ordering of events in an Event-B model is not that obvious. Thus, using methods for determining the control flow can be sometimes very beneficial for understanding the model, as well as for techniques for automatic verification such as model checking.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we present a static analysis for B and Event-B that can be used to reveal the control flow of a machine and to optimize model checking of models written in B and Event-B (see also [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Guard_Evaluation Tutorial on Partial Guard Evaluation ]). The results of the analysis, designated also as ‘’enabling analysis’’, can be presented as relations by means of a table or by means of a graph. For simplicity, we will concentrate mainly on B and use the terminology of the formalism.&lt;br /&gt;
&lt;br /&gt;
== Enabling Relations ==&lt;br /&gt;
What we want to find out is how the operations influence each other within a B model. In other words, for each pair (op1,op2) of operations we try to determine as precise as possible how op1 can affect the guard condition of op2 with regard to enabledness. To determine the enabling relations between operations we use syntactic analyses, as well as the constraint-based abilities of ProB.&lt;br /&gt;
&lt;br /&gt;
Consider the following B machine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE Example&lt;br /&gt;
VARIABLES x, y, z&lt;br /&gt;
INVARIANT&lt;br /&gt;
    x:NATURAL&lt;br /&gt;
  &amp;amp; y:INTEGER&lt;br /&gt;
  &amp;amp; z:INTEGER&lt;br /&gt;
INITIALISATION &lt;br /&gt;
  x:=6 || y:=-2 || z:=0&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Op1 = PRE x + y&amp;gt;=4  THEN x:=x+2 || y:=2 END;&lt;br /&gt;
  Op2 = PRE x mod 2=1 THEN x:=x+1 || y:=2 END;&lt;br /&gt;
  Op3 = PRE x mod 2=0 THEN x:=x+2 END;&lt;br /&gt;
  Op4 = PRE x&amp;lt;0 THEN y:=y-1 END;&lt;br /&gt;
  Op5 = PRE y/=2 THEN z:=3 END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The machine has three variables x,y,z, where x ranges over the domain of natural numbers and y and z over the domain of all integers. For this machine we have 25 pairs of operations for which we want to determine the respective enabling relations. Additionally, we identify 5 further pairs that show the influence of the INITIALISATION on the guard conditions of all other operations. Consider, for example, the pair (Op2,Op1) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op1 is enabled in each state of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; where the predicate ‘x+y&amp;gt;=4’ is fulfilled. Since the effect of Op2 assigns 2 to y and increments x by one upon condition that x is a positive odd number in the before-state of Op2, we can assume that Op1 is always enabled after the execution of Op2. In other words, in all after-states of Op2 the operation Op1 is guaranteed to be enabled. This relation between Op2 and Op1 we can illustrate as follows: &lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above the green boxes denote that the evaluation of the guard of Op1 is true, whereas the red boxes denote that the evaluation of the guard of Op1 is false. &lt;br /&gt;
&lt;br /&gt;
Another pair of interest is (Op2,Op5) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op5 is enabled only in those states in which y is not equal to 2. Obviously, in each after-state of Op2 y is equal to 2 and thus we can conclude that Op5 is impossible to be enabled after each execution of Op2. Such a relation between two operations we denote as ‘’impossible’’ and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
Both arrows in the illustration of the ‘’impossible’’ relation indicate that whether the guard condition of Op5 is fulfilled or not in a before-state of Op2 operation Op5 will be disabled in the respective after-state of Op2. In order to recognize a tuple (op1,op2) as ‘’impossible’’ we require that op2 is always disabled after op1 without further considering whether op2 is always enabled or always disabled in the before-states of op1. &lt;br /&gt;
&lt;br /&gt;
Consider, for instance, the pair (Op2, Op2) in the machine above. We can easily conclude that Op2 becomes disabled after it is executed and clearly, the second case (\false -&amp;gt; \false) of the impossible relation is not possible for (Op2, Op2). This gives rise of introducing another (more precise) impossible relation:&lt;br /&gt;
 &lt;br /&gt;
[[File:ImpossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Accordingly, we can derive another relation from ‘’impossible’’ for which only the second case of the ‘’impossible’’ relation is fulfilled:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
As an example for a pair of operations that fulfills the ‘’impossible_keep’’ requirement you can take, for example, the pair (Op3,Op2) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Since Op2 and Op3 cannot be both enabled in a state and the execution of Op3 cannot enable Op2, then we can easily conclude that Op2 remains always disabled after Op3.&lt;br /&gt;
&lt;br /&gt;
Similarly as for ‘’impossible’’, one could derive two further enabling relations from ‘’guaranteed’’:&lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedEnableKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Another interesting class of enabling relations that could be helpful for better understanding and analyzing B and Event-B models is that of the ‘’keep’’ relations. We say that an operation op1 ‘’keeps’’ another operation op2 if op1 cannot change the status of the enabling condition of op2, i.e. op1 keeps op2 enabled respectively disabled. This relationship could be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:KeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
We can take (Op1,Op2) and (Op1,Op3) as examples of pairs in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; that are elements of the keep relation. ‘’keep’’ relations can sometimes be easily determined by analyzing just the syntactic structure of both operations, or more precisely the “read” and “write” sets of both operations.&amp;lt;ref&amp;gt;For an operation op the set read(op) denotes the set of variables that are read by op. Accordingly, by write(op) we denote the set of variables that are written by op.&amp;lt;/ref&amp;gt; If, for example, an operation op1 does not write any variable of the machine that is read in the guard condition of op2, then we can infer that op1 ‘’keeps’’ op2. In that case we also say that op1 does not change op2 syntactically. In the class of the ‘’keep’’ relations are included also relations such as independence. Two operations op1 and op2 are called independent if each of them cannot disable the other operation and the both orders of execution &amp;lt;op1,op2&amp;gt; and &amp;lt;op2,op1&amp;gt; have the same effect.&amp;lt;ref&amp;gt;See the [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Order_Reduction Tutorial on Partial Order Reduction] for more information on independence between operations.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three classes (‘’guaranteed’’, ‘’impossible’’ and ‘’keep’’) of enabling relations presented so far represent definite relations. That is, if a pair of operations (op1,op2) is confirmed to be a relation of one of this three classes, then we can certainly say what effect on the enabling condition of op2 would the execution of op1 have. However, for some pairs of operations we cannot certainly say what effect an operation would have on the enabling condition of another operation. This is due to the fact that the enabling status of an operation does not only depend on the effect of the executed operations, but also on the current variables’ evaluation. Take, for instance, the tuple (Op3,Op1) from the B machine above. Considering the action part of Op3 and the guard condition of Op1 we can assume that Op3 can enable Op1. Since the guard of Op1 depends not only on the current value of x, but also on y, there could be transitions s -&amp;gt; s&#039; of Op3 in the state space of the machine where Op1 is disabled in both states s and s’. Though, what we could definitely say is that Op3 cannot disable Op1. This relationship we can illustrate as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleEnableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
The opposite relation of “possible_enable” is the relation where an operation op2 can disable another operation op1. Formally, we say that op2 can disable op1 if op2 may disable op1 and op2 cannot enable op1. This relationship is denoted as “possible_disable” and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
In order to determine how operations influence each other we need to assure first that these are feasible. An operation ‘’op’’ is said to be feasible if there is a state of the machine that satisfies the invariant of the machine and in which ‘’op’’ is enabled. In the B machine above the operation Op4, for example, is not feasible. Obviously, Op4 is enabled only in states where x is a negative number and states in which x is a negative number are visibly not consistent with the invariant since &amp;quot;x : NATURAL&amp;quot;. Such incompatibilities are sometimes of great importance for the modeler and therefore they should be revealed in the process of computing the enabling relations. In our case for each pair of operations (Op4,-) and (-,Op4) the status “infeasible” will be returned.&lt;br /&gt;
&lt;br /&gt;
We can now list all possible enabling relations for the machine &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; by means of a table. For each entry in the table the operation in the row is the operation whose effect is studied on the status of the guard of the operation in the column.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingResults.png]]&lt;br /&gt;
&lt;br /&gt;
== Summary of the Enabling Relations ==&lt;br /&gt;
&lt;br /&gt;
In the following, we summarize most of the enabling relations that we think can provide a useful feedback to the user. For each of the enabling relations we have given an appropriate example. In the examples below we compute the effect of executing ‘op1’ on the status of the guard of ‘op2’. The relation identifiers are the same as they appear as results in ProB.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;guaranteed&#039;&#039;: op2 guaranteed to be executable after op1.&lt;br /&gt;
[[File: GuaranteedExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_enable&#039;&#039;: op2 is guaranteed to become enabled after op1.&lt;br /&gt;
[[File: GuaranteedEnableExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_keep&#039;&#039;: op2 is guaranteed to stay enabled after op1.&lt;br /&gt;
[[File: GuaranteedKeepExample.png]]&lt;br /&gt;
* &#039;&#039;impossible&#039;&#039;: op2 is impossible to be executed after op1.&lt;br /&gt;
[[File: ImpossibleExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_disable&#039;&#039;: op2 is guaranteed to become disabled after op1.&lt;br /&gt;
[[File: ImpossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_keep&#039;&#039;: op2 is impossible to become enabled after op1.&lt;br /&gt;
[[File: ImpossibleKeepExample.png]]&lt;br /&gt;
* &#039;&#039;keep&#039;&#039;: op2 always stays enabled resp. disabled after op1.&lt;br /&gt;
[[File: KeepExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_unchanged&#039;&#039;: op1 does not write any variable read in the guard of op2, i.e. write(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticUnchangedExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_independent&#039;&#039;: op1 and op2 are syntactically independent, i.e. read(op1) /\ write(op2) = {} &amp;amp; write(op1) /\ read(op2) = {} &amp;amp; write(op1) /\ write(op2) = {}&lt;br /&gt;
[[File: SyntacticIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;syntactically_fully_independent&#039;&#039;: op1 and op2 are syntactically independent and additionally, read(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticFullyIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;possible_enable&#039;&#039;: op2 possible after op1, but op2 cannot be disabled by op1.&lt;br /&gt;
[[File: PossibleEnableExample.png]]&lt;br /&gt;
* &#039;&#039;possible_disable&#039;&#039;: op2 possible after iop1, but op2 cannot be enabled by op1.&lt;br /&gt;
[[File: PossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;infeasible&#039;&#039;: op1 is not feasible and thus cannot influence op2.&lt;br /&gt;
[[File: InfeasibleExample.png]]&lt;br /&gt;
&lt;br /&gt;
== Performing Enabling Analysis within ProB  ==&lt;br /&gt;
&lt;br /&gt;
The enabling analysis has been implemented in the ProB toolset.  The computation of the enabling relations is based on syntactic and constraint-based techniques. The identification of relations such as ‘’syntactic_independent’’ and ‘’syntactic_unchanged’’ requires just a thorough study of the syntactic structure of the operations, i.e. no calls to the constraint solver have to be made. However, to confirm, for example, that an operation is guaranteed or impossible to be executed after another operation the use of the ProB’s constraint solver is unavoidable. For instance, consider the pair (Op2,Op1) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. As we have seen, in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; the operation Op1 is guaranteed to be enabled after each execution of Op2. In ProB this could be computed by feeding the (before-after) predicate “ (x mod 2 = 1) =&amp;gt; [x:=x+1 || y:=2] (x+y&amp;lt;4)” into the constraint solver. As a result, the constraint solver will not find a solution for the predicate, i.e. the constraint solver will not find a state ‘’s’’ satisfying “x mod 2 = 1” from which after executing Op2 at ‘’s’’ a solution state s’ will be found that fulfills “x+y&amp;lt;4”; note that “x+y&amp;lt;4” is the negation of the guard of Op1. Since there is no after-state of Op2 at which Op1 is disabled we can conclude that Op1 is guaranteed to be executed after Op2. When constraints are getting more complex the constraint solver may need more time for solving and determining the enabling relations may become a very time-expensive task. Therefore, a time-out for each constraint solver call is set. In other words, if the constraint solver does not find a solution in the given time by the user, then the respective relation will be denoted as time-outed. By default, in ProB the time-out for each constraint solver call is set to 300 ms.&lt;br /&gt;
&lt;br /&gt;
Within &amp;lt;tt&amp;gt;ProB Tcl/Tk&amp;lt;/tt&amp;gt; you can find the menu &amp;quot;Enabling Analysis&amp;quot; in the &amp;quot;Analysis&amp;quot; menu of the menu bar.&lt;br /&gt;
[[File: EnablingAnalysisMenu.png]]&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;Enabling Analysis&amp;quot; menu provides multiple commands:&lt;br /&gt;
* &amp;quot;Enabling Analysis (Table)&amp;quot;: this command performs a (fast) enabling analysis on the respective B model using a time-out of 300 ms for the constraint-solver calls. The result of the enabling analysis is shown in a table. The table lists all enabling relations between the operations of the loaded B model. These can be exported to a CSV file. The table for &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; at the end of the &#039;&#039;&#039; Enabling Relations&#039;&#039;&#039; section was constructed this way.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Precise, Table)&amp;quot;: this command performs an enabling analysis using a time-out of 2800 ms for each of the constraint-solver calls. As for the command above, the result of the analysis is shown in a table that can be exported to a CSV file.&lt;br /&gt;
* &amp;quot;Enabling Relations After...&amp;quot;: this command computes all the enabling relations involving an operation chosen by the user.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Graph)&amp;quot;: this command performs the fast enabling analysis but displays the results as a graph. In case the preference &amp;quot;DOT_SHOW_OP_READ_WRITES&amp;quot; is set for each operation the read/write information is displayed.&lt;br /&gt;
* &amp;quot;Enabling Analysis (POR)...&amp;quot;: this menu provides further commands for another form of enabling analysis the results of which are used for the partial guard evaluation optimisation in ProB.&lt;br /&gt;
* &amp;quot;Read/Write Matrix (Table)&amp;quot;: this command performs syntactic analysis on the model. The analysis determines the read and write sets for each operation of the machine.&lt;br /&gt;
* &amp;quot;Dependence Analysis (Table)&amp;quot;: this command performs a dependency analysis for each pair of operations. More specifically, the analysis determines which operations are dependent or independent to each other.&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB (probcli) one can perform an enabling analysis on a B or Event-B model by means of the &amp;lt;tt&amp;gt;-enabling_analysis&amp;lt;/tt&amp;gt; option. The results of the analysis, as well as intermediate data and some statistics are printed out on the console:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli Example.mch -enabling_analysis&lt;br /&gt;
CHECKING ENABLING AFTER INITIALISATION&lt;br /&gt;
INITIALISATION ---&amp;gt; Op1  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op2  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op3  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op4  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op5  :: ok : guaranteed&lt;br /&gt;
.....&lt;br /&gt;
CHECKING ENABLING AFTER: Op5 r:[y] / w:[z]&lt;br /&gt;
Op5 ---&amp;gt; Op1  :: Enable=syntactic_independent&lt;br /&gt;
Op5 ---&amp;gt; Op2  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op3  :: Enable=syntactic_fully_independent&lt;br /&gt;
Op5 ---&amp;gt; Op4  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op5  :: Enable=syntactic_unchanged&lt;br /&gt;
% Finished CBC Enabling Analysis 810 ms walltime (770 ms runtime), since start: 1650 ms&lt;br /&gt;
% CBC Enabling Stats:&lt;br /&gt;
% Nr of events: 5&lt;br /&gt;
% Nr of cbc calls: 30, Timeout results: 2&lt;br /&gt;
Origin,Op1,Op2,Op3,Op4,Op5&lt;br /&gt;
INITIALISATION,guaranteed,impossible,guaranteed,impossible,guaranteed&lt;br /&gt;
Op1,timeout_possible_disable,keep,keep,impossible_keep,syntactic_independent&lt;br /&gt;
Op2,guaranteed,impossible,guaranteed,impossible_keep,impossible&lt;br /&gt;
Op3,timeout_possible,impossible_keep,guaranteed,impossible_keep,syntactic_fully_independent&lt;br /&gt;
Op4,impossible_keep,syntactic_unchanged,syntactic_unchanged,syntactic_keep,impossible_keep&lt;br /&gt;
Op5,syntactic_independent,syntactic_unchanged,syntactic_fully_independent,syntactic_unchanged,syntactic_unchanged&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To perform enabling analysis from the command line and save the results to a CSV-file use the following commando:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli file.mch -enabling_analysis_csv FILE &amp;lt;/pre&amp;gt;&lt;br /&gt;
where FILE is the name of the CSV-file in which the results of the analysis are stored.&lt;br /&gt;
&lt;br /&gt;
== References and Footnotes ==&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3495</id>
		<title>Tutorial Enabling Analysis</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3495"/>
		<updated>2016-02-16T14:51:21Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Performing Enabling Analysis within ProB */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The B-method and in particular its successor Event-B are methodologies for formal development and verification of systems. In Event-B, a machine is usually viewed as a reactive system executing continuously enabled (atomic) events in an interleaved fashion. Thus, parallel events of the system are easily modeled as an interleaving of operation executions. On the other hand, the introduction of abstract counters is required when events are supposed to be executed in some (sequential) order. This, however, can in some cases slow the work of understanding and verifying a model since identifying the sequential ordering of events in an Event-B model is not that obvious. Thus, using methods for determining the control flow can be sometimes very beneficial for understanding the model, as well as for techniques for automatic verification such as model checking.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we present a static analysis for B and Event-B that can be used to reveal the control flow of a machine and to optimize model checking of models written in B and Event-B (see also [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Guard_Evaluation Tutorial on Partial Guard Evaluation ]). The results of the analysis, designated also as ‘’enabling analysis’’, can be presented as relations by means of a table or by means of a graph. For simplicity, we will concentrate mainly on B and use the terminology of the formalism.&lt;br /&gt;
&lt;br /&gt;
== Enabling Relations ==&lt;br /&gt;
What we want to find out is how the operations influence each other within a B model. In other words, for each pair (op1,op2) of operations we try to determine as precise as possible how op1 can affect the guard condition of op2 with regard to enabledness. To determine the enabling relations between operations we use syntactic analyses, as well as the constraint-based abilities of ProB.&lt;br /&gt;
&lt;br /&gt;
Consider the following B machine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE Example&lt;br /&gt;
VARIABLES x, y, z&lt;br /&gt;
INVARIANT&lt;br /&gt;
    x:NATURAL&lt;br /&gt;
  &amp;amp; y:INTEGER&lt;br /&gt;
  &amp;amp; z:INTEGER&lt;br /&gt;
INITIALISATION &lt;br /&gt;
  x:=6 || y:=-2 || z:=0&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Op1 = PRE x + y&amp;gt;=4  THEN x:=x+2 || y:=2 END;&lt;br /&gt;
  Op2 = PRE x mod 2=1 THEN x:=x+1 || y:=2 END;&lt;br /&gt;
  Op3 = PRE x mod 2=0 THEN x:=x+2 END;&lt;br /&gt;
  Op4 = PRE x&amp;lt;0 THEN y:=y-1 END;&lt;br /&gt;
  Op5 = PRE y/=2 THEN z:=3 END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The machine has three variables x,y,z, where x ranges over the domain of natural numbers and y and z over the domain of all integers. For this machine we have 25 pairs of operations for which we want to determine the respective enabling relations. Additionally, we identify 5 further pairs that show the influence of the INITIALISATION on the guard conditions of all other operations. Consider, for example, the pair (Op2,Op1) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op1 is enabled in each state of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; where the predicate ‘x+y&amp;gt;=4’ is fulfilled. Since the effect of Op2 assigns 2 to y and increments x by one upon condition that x is a positive odd number in the before-state of Op2, we can assume that Op1 is always enabled after the execution of Op2. In other words, in all after-states of Op2 the operation Op1 is guaranteed to be enabled. This relation between Op2 and Op1 we can illustrate as follows: &lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above the green boxes denote that the evaluation of the guard of Op1 is true, whereas the red boxes denote that the evaluation of the guard of Op1 is false. &lt;br /&gt;
&lt;br /&gt;
Another pair of interest is (Op2,Op5) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op5 is enabled only in those states in which y is not equal to 2. Obviously, in each after-state of Op2 y is equal to 2 and thus we can conclude that Op5 is impossible to be enabled after each execution of Op2. Such a relation between two operations we denote as ‘’impossible’’ and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
Both arrows in the illustration of the ‘’impossible’’ relation indicate that whether the guard condition of Op5 is fulfilled or not in a before-state of Op2 operation Op5 will be disabled in the respective after-state of Op2. In order to recognize a tuple (op1,op2) as ‘’impossible’’ we require that op2 is always disabled after op1 without further considering whether op2 is always enabled or always disabled in the before-states of op1. &lt;br /&gt;
&lt;br /&gt;
Consider, for instance, the pair (Op2, Op2) in the machine above. We can easily conclude that Op2 becomes disabled after it is executed and clearly, the second case (\false -&amp;gt; \false) of the impossible relation is not possible for (Op2, Op2). This gives rise of introducing another (more precise) impossible relation:&lt;br /&gt;
 &lt;br /&gt;
[[File:ImpossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Accordingly, we can derive another relation from ‘’impossible’’ for which only the second case of the ‘’impossible’’ relation is fulfilled:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
As an example for a pair of operations that fulfills the ‘’impossible_keep’’ requirement you can take, for example, the pair (Op3,Op2) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Since Op2 and Op3 cannot be both enabled in a state and the execution of Op3 cannot enable Op2, then we can easily conclude that Op2 remains always disabled after Op3.&lt;br /&gt;
&lt;br /&gt;
Similarly as for ‘’impossible’’, one could derive two further enabling relations from ‘’guaranteed’’:&lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedEnableKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Another interesting class of enabling relations that could be helpful for better understanding and analyzing B and Event-B models is that of the ‘’keep’’ relations. We say that an operation op1 ‘’keeps’’ another operation op2 if op1 cannot change the status of the enabling condition of op2, i.e. op1 keeps op2 enabled respectively disabled. This relationship could be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:KeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
We can take (Op1,Op2) and (Op1,Op3) as examples of pairs in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; that are elements of the keep relation. ‘’keep’’ relations can sometimes be easily determined by analyzing just the syntactic structure of both operations, or more precisely the “read” and “write” sets of both operations.&amp;lt;ref&amp;gt;For an operation op the set read(op) denotes the set of variables that are read by op. Accordingly, by write(op) we denote the set of variables that are written by op.&amp;lt;/ref&amp;gt; If, for example, an operation op1 does not write any variable of the machine that is read in the guard condition of op2, then we can infer that op1 ‘’keeps’’ op2. In that case we also say that op1 does not change op2 syntactically. In the class of the ‘’keep’’ relations are included also relations such as independence. Two operations op1 and op2 are called independent if each of them cannot disable the other operation and the both orders of execution &amp;lt;op1,op2&amp;gt; and &amp;lt;op2,op1&amp;gt; have the same effect.&amp;lt;ref&amp;gt;See the [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Order_Reduction Tutorial on Partial Order Reduction] for more information on independence between operations.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three classes (‘’guaranteed’’, ‘’impossible’’ and ‘’keep’’) of enabling relations presented so far represent definite relations. That is, if a pair of operations (op1,op2) is confirmed to be a relation of one of this three classes, then we can certainly say what effect on the enabling condition of op2 would the execution of op1 have. However, for some pairs of operations we cannot certainly say what effect an operation would have on the enabling condition of another operation. This is due to the fact that the enabling status of an operation does not only depend on the effect of the executed operations, but also on the current variables’ evaluation. Take, for instance, the tuple (Op3,Op1) from the B machine above. Considering the action part of Op3 and the guard condition of Op1 we can assume that Op3 can enable Op1. Since the guard of Op1 depends not only on the current value of x, but also on y, there could be transitions s -&amp;gt; s&#039; of Op3 in the state space of the machine where Op1 is disabled in both states s and s’. Though, what we could definitely say is that Op3 cannot disable Op1. This relationship we can illustrate as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleEnableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
The opposite relation of “possible_enable” is the relation where an operation op2 can disable another operation op1. Formally, we say that op2 can disable op1 if op2 may disable op1 and op2 cannot enable op1. This relationship is denoted as “possible_disable” and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
In order to determine how operations influence each other we need to assure first that these are feasible. An operation ‘’op’’ is said to be feasible if there is a state of the machine that satisfies the invariant of the machine and in which ‘’op’’ is enabled. In the B machine above the operation Op4, for example, is not feasible. Obviously, Op4 is enabled only in states where x is a negative number and states in which x is a negative number are visibly not consistent with the invariant since &amp;quot;x : NATURAL&amp;quot;. Such incompatibilities are sometimes of great importance for the modeler and therefore they should be revealed in the process of computing the enabling relations. In our case for each pair of operations (Op4,-) and (-,Op4) the status “infeasible” will be returned.&lt;br /&gt;
&lt;br /&gt;
We can now list all possible enabling relations for the machine &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; by means of a table. For each entry in the table the operation in the row is the operation whose effect is studied on the status of the guard of the operation in the column.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingResults.png]]&lt;br /&gt;
&lt;br /&gt;
== Summary of the Enabling Relations ==&lt;br /&gt;
&lt;br /&gt;
In the following, we summarize most of the enabling relations that we think can provide a useful feedback to the user. For each of the enabling relations we have given an appropriate example. In the examples below we compute the effect of executing ‘op1’ on the status of the guard of ‘op2’. The relation identifiers are the same as they appear as results in ProB.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;guaranteed&#039;&#039;: op2 guaranteed to be executable after op1.&lt;br /&gt;
[[File: GuaranteedExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_enable&#039;&#039;: op2 is guaranteed to become enabled after op1.&lt;br /&gt;
[[File: GuaranteedEnableExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_keep&#039;&#039;: op2 is guaranteed to stay enabled after op1.&lt;br /&gt;
[[File: GuaranteedKeepExample.png]]&lt;br /&gt;
* &#039;&#039;impossible&#039;&#039;: op2 is impossible to be executed after op1.&lt;br /&gt;
[[File: ImpossibleExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_disable&#039;&#039;: op2 is guaranteed to become disabled after op1.&lt;br /&gt;
[[File: ImpossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_keep&#039;&#039;: op2 is impossible to become enabled after op1.&lt;br /&gt;
[[File: ImpossibleKeepExample.png]]&lt;br /&gt;
* &#039;&#039;keep&#039;&#039;: op2 always stays enabled resp. disabled after op1.&lt;br /&gt;
[[File: KeepExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_unchanged&#039;&#039;: op1 does not write any variable read in the guard of op2, i.e. write(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticUnchangedExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_independent&#039;&#039;: op1 and op2 are syntactically independent, i.e. read(op1) /\ write(op2) = {} &amp;amp; write(op1) /\ read(op2) = {} &amp;amp; write(op1) /\ write(op2) = {}&lt;br /&gt;
[[File: SyntacticIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;syntactically_fully_independent&#039;&#039;: op1 and op2 are syntactically independent and additionally, read(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticFullyIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;possible_enable&#039;&#039;: op2 possible after op1, but op2 cannot be disabled by op1.&lt;br /&gt;
[[File: PossibleEnableExample.png]]&lt;br /&gt;
* &#039;&#039;possible_disable&#039;&#039;: op2 possible after iop1, but op2 cannot be enabled by op1.&lt;br /&gt;
[[File: PossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;infeasible&#039;&#039;: op1 is not feasible and thus cannot influence op2.&lt;br /&gt;
[[File: InfeasibleExample.png]]&lt;br /&gt;
&lt;br /&gt;
== Performing Enabling Analysis within ProB  ==&lt;br /&gt;
&lt;br /&gt;
The enabling analysis has been implemented in the ProB toolset.  The computation of the enabling relations is based on syntactic and constraint-based techniques. The identification of relations such as ‘’syntactic_independent’’ and ‘’syntactic_unchanged’’ requires just a thorough study of the syntactic structure of the operations, i.e. no calls to the constraint solver have to be made. However, to confirm, for example, that an operation is guaranteed or impossible to be executed after another operation the use of the ProB’s constraint solver is unavoidable. For instance, consider the pair (Op2,Op1) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. As we have seen, in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; the operation Op1 is guaranteed to be enabled after each execution of Op2. In ProB this could be computed by feeding the (before-after) predicate “ (x mod 2 = 1) =&amp;gt; [x:=x+1 || y:=2] (x+y&amp;lt;4)” into the constraint solver. As a result, the constraint solver will not find a solution for the predicate, i.e. the constraint solver will not find a state ‘’s’’ satisfying “x mod 2 = 1” from which after executing Op2 at ‘’s’’ a solution state s’ will be found that fulfills “x+y&amp;lt;4”; note that “x+y&amp;lt;4” is the negation of the guard of Op1. Since there is no after-state of Op2 at which Op1 is disabled we can conclude that Op1 is guaranteed to be executed after Op2. When constraints are getting more complex the constraint solver may need more time for solving and determining the enabling relations may become a very time-expensive task. Therefore, a time-out for each constraint solver call is set. In other words, if the constraint solver does not find a solution in the given time by the user, then the respective relation will be denoted as time-outed. By default, in ProB the time-out for each constraint solver call is set to 300 ms.&lt;br /&gt;
&lt;br /&gt;
Within &amp;lt;tt&amp;gt;ProB Tcl/Tk&amp;lt;/tt&amp;gt; you can find the menu &amp;quot;Enabling Analysis&amp;quot; in the &amp;quot;Analysis&amp;quot; menu of the menu bar.&lt;br /&gt;
[[File: EnablingAnalysisMenu.png]]&lt;br /&gt;
The &amp;quot;Enabling Analysis&amp;quot; menu provides multiple commands:&lt;br /&gt;
* &amp;quot;Enabling Analysis (Table)&amp;quot;: this command performs a (fast) enabling analysis on the respective B model using a time-out of 300 ms for the constraint-solver calls. The result of the enabling analysis is shown in a table. The table lists all enabling relations between the operations of the loaded B model. These can be exported to a CSV file. The table for &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; at the end of the &#039;&#039;&#039; Enabling Relations&#039;&#039;&#039; section was constructed this way.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Precise, Table)&amp;quot;: this command performs an enabling analysis using a time-out of 2800 ms for each of the constraint-solver calls. As for the command above, the result of the analysis is shown in a table that can be exported to a CSV file.&lt;br /&gt;
* &amp;quot;Enabling Relations After...&amp;quot;: this command computes all the enabling relations involving an operation chosen by the user.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Graph)&amp;quot;: this command performs the fast enabling analysis but displays the results as a graph. In case the preference &amp;quot;DOT_SHOW_OP_READ_WRITES&amp;quot; is set for each operation the read/write information is displayed.&lt;br /&gt;
* &amp;quot;Enabling Analysis (POR)...&amp;quot;: this menu provides further commands for another form of enabling analysis the results of which are used for the partial guard evaluation optimisation in ProB.&lt;br /&gt;
* &amp;quot;Read/Write Matrix (Table)&amp;quot;: this command performs syntactic analysis on the model. The analysis determines the read and write sets for each operation of the machine.&lt;br /&gt;
* &amp;quot;Dependence Analysis (Table)&amp;quot;: this command performs a dependency analysis for each pair of operations. More specifically, the analysis determines which operations are dependent or independent to each other.&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB (probcli) one can perform an enabling analysis on a B or Event-B model by means of the &amp;lt;tt&amp;gt;-enabling_analysis&amp;lt;/tt&amp;gt; option. The results of the analysis, as well as intermediate data and some statistics are printed out on the console:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli Example.mch -enabling_analysis&lt;br /&gt;
CHECKING ENABLING AFTER INITIALISATION&lt;br /&gt;
INITIALISATION ---&amp;gt; Op1  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op2  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op3  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op4  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op5  :: ok : guaranteed&lt;br /&gt;
.....&lt;br /&gt;
CHECKING ENABLING AFTER: Op5 r:[y] / w:[z]&lt;br /&gt;
Op5 ---&amp;gt; Op1  :: Enable=syntactic_independent&lt;br /&gt;
Op5 ---&amp;gt; Op2  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op3  :: Enable=syntactic_fully_independent&lt;br /&gt;
Op5 ---&amp;gt; Op4  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op5  :: Enable=syntactic_unchanged&lt;br /&gt;
% Finished CBC Enabling Analysis 810 ms walltime (770 ms runtime), since start: 1650 ms&lt;br /&gt;
% CBC Enabling Stats:&lt;br /&gt;
% Nr of events: 5&lt;br /&gt;
% Nr of cbc calls: 30, Timeout results: 2&lt;br /&gt;
Origin,Op1,Op2,Op3,Op4,Op5&lt;br /&gt;
INITIALISATION,guaranteed,impossible,guaranteed,impossible,guaranteed&lt;br /&gt;
Op1,timeout_possible_disable,keep,keep,impossible_keep,syntactic_independent&lt;br /&gt;
Op2,guaranteed,impossible,guaranteed,impossible_keep,impossible&lt;br /&gt;
Op3,timeout_possible,impossible_keep,guaranteed,impossible_keep,syntactic_fully_independent&lt;br /&gt;
Op4,impossible_keep,syntactic_unchanged,syntactic_unchanged,syntactic_keep,impossible_keep&lt;br /&gt;
Op5,syntactic_independent,syntactic_unchanged,syntactic_fully_independent,syntactic_unchanged,syntactic_unchanged&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To perform enabling analysis from the command line and save the results to a CSV-file use the following commando:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli file.mch -enabling_analysis_csv FILE &amp;lt;/pre&amp;gt;&lt;br /&gt;
where FILE is the name of the CSV-file in which the results of the analysis are stored.&lt;br /&gt;
&lt;br /&gt;
== References and Footnotes ==&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3494</id>
		<title>Tutorial Enabling Analysis</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3494"/>
		<updated>2016-02-16T14:50:58Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Performing Enabling Analysis within ProB */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The B-method and in particular its successor Event-B are methodologies for formal development and verification of systems. In Event-B, a machine is usually viewed as a reactive system executing continuously enabled (atomic) events in an interleaved fashion. Thus, parallel events of the system are easily modeled as an interleaving of operation executions. On the other hand, the introduction of abstract counters is required when events are supposed to be executed in some (sequential) order. This, however, can in some cases slow the work of understanding and verifying a model since identifying the sequential ordering of events in an Event-B model is not that obvious. Thus, using methods for determining the control flow can be sometimes very beneficial for understanding the model, as well as for techniques for automatic verification such as model checking.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we present a static analysis for B and Event-B that can be used to reveal the control flow of a machine and to optimize model checking of models written in B and Event-B (see also [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Guard_Evaluation Tutorial on Partial Guard Evaluation ]). The results of the analysis, designated also as ‘’enabling analysis’’, can be presented as relations by means of a table or by means of a graph. For simplicity, we will concentrate mainly on B and use the terminology of the formalism.&lt;br /&gt;
&lt;br /&gt;
== Enabling Relations ==&lt;br /&gt;
What we want to find out is how the operations influence each other within a B model. In other words, for each pair (op1,op2) of operations we try to determine as precise as possible how op1 can affect the guard condition of op2 with regard to enabledness. To determine the enabling relations between operations we use syntactic analyses, as well as the constraint-based abilities of ProB.&lt;br /&gt;
&lt;br /&gt;
Consider the following B machine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE Example&lt;br /&gt;
VARIABLES x, y, z&lt;br /&gt;
INVARIANT&lt;br /&gt;
    x:NATURAL&lt;br /&gt;
  &amp;amp; y:INTEGER&lt;br /&gt;
  &amp;amp; z:INTEGER&lt;br /&gt;
INITIALISATION &lt;br /&gt;
  x:=6 || y:=-2 || z:=0&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Op1 = PRE x + y&amp;gt;=4  THEN x:=x+2 || y:=2 END;&lt;br /&gt;
  Op2 = PRE x mod 2=1 THEN x:=x+1 || y:=2 END;&lt;br /&gt;
  Op3 = PRE x mod 2=0 THEN x:=x+2 END;&lt;br /&gt;
  Op4 = PRE x&amp;lt;0 THEN y:=y-1 END;&lt;br /&gt;
  Op5 = PRE y/=2 THEN z:=3 END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The machine has three variables x,y,z, where x ranges over the domain of natural numbers and y and z over the domain of all integers. For this machine we have 25 pairs of operations for which we want to determine the respective enabling relations. Additionally, we identify 5 further pairs that show the influence of the INITIALISATION on the guard conditions of all other operations. Consider, for example, the pair (Op2,Op1) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op1 is enabled in each state of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; where the predicate ‘x+y&amp;gt;=4’ is fulfilled. Since the effect of Op2 assigns 2 to y and increments x by one upon condition that x is a positive odd number in the before-state of Op2, we can assume that Op1 is always enabled after the execution of Op2. In other words, in all after-states of Op2 the operation Op1 is guaranteed to be enabled. This relation between Op2 and Op1 we can illustrate as follows: &lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above the green boxes denote that the evaluation of the guard of Op1 is true, whereas the red boxes denote that the evaluation of the guard of Op1 is false. &lt;br /&gt;
&lt;br /&gt;
Another pair of interest is (Op2,Op5) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op5 is enabled only in those states in which y is not equal to 2. Obviously, in each after-state of Op2 y is equal to 2 and thus we can conclude that Op5 is impossible to be enabled after each execution of Op2. Such a relation between two operations we denote as ‘’impossible’’ and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
Both arrows in the illustration of the ‘’impossible’’ relation indicate that whether the guard condition of Op5 is fulfilled or not in a before-state of Op2 operation Op5 will be disabled in the respective after-state of Op2. In order to recognize a tuple (op1,op2) as ‘’impossible’’ we require that op2 is always disabled after op1 without further considering whether op2 is always enabled or always disabled in the before-states of op1. &lt;br /&gt;
&lt;br /&gt;
Consider, for instance, the pair (Op2, Op2) in the machine above. We can easily conclude that Op2 becomes disabled after it is executed and clearly, the second case (\false -&amp;gt; \false) of the impossible relation is not possible for (Op2, Op2). This gives rise of introducing another (more precise) impossible relation:&lt;br /&gt;
 &lt;br /&gt;
[[File:ImpossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Accordingly, we can derive another relation from ‘’impossible’’ for which only the second case of the ‘’impossible’’ relation is fulfilled:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
As an example for a pair of operations that fulfills the ‘’impossible_keep’’ requirement you can take, for example, the pair (Op3,Op2) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Since Op2 and Op3 cannot be both enabled in a state and the execution of Op3 cannot enable Op2, then we can easily conclude that Op2 remains always disabled after Op3.&lt;br /&gt;
&lt;br /&gt;
Similarly as for ‘’impossible’’, one could derive two further enabling relations from ‘’guaranteed’’:&lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedEnableKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Another interesting class of enabling relations that could be helpful for better understanding and analyzing B and Event-B models is that of the ‘’keep’’ relations. We say that an operation op1 ‘’keeps’’ another operation op2 if op1 cannot change the status of the enabling condition of op2, i.e. op1 keeps op2 enabled respectively disabled. This relationship could be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:KeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
We can take (Op1,Op2) and (Op1,Op3) as examples of pairs in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; that are elements of the keep relation. ‘’keep’’ relations can sometimes be easily determined by analyzing just the syntactic structure of both operations, or more precisely the “read” and “write” sets of both operations.&amp;lt;ref&amp;gt;For an operation op the set read(op) denotes the set of variables that are read by op. Accordingly, by write(op) we denote the set of variables that are written by op.&amp;lt;/ref&amp;gt; If, for example, an operation op1 does not write any variable of the machine that is read in the guard condition of op2, then we can infer that op1 ‘’keeps’’ op2. In that case we also say that op1 does not change op2 syntactically. In the class of the ‘’keep’’ relations are included also relations such as independence. Two operations op1 and op2 are called independent if each of them cannot disable the other operation and the both orders of execution &amp;lt;op1,op2&amp;gt; and &amp;lt;op2,op1&amp;gt; have the same effect.&amp;lt;ref&amp;gt;See the [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Order_Reduction Tutorial on Partial Order Reduction] for more information on independence between operations.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three classes (‘’guaranteed’’, ‘’impossible’’ and ‘’keep’’) of enabling relations presented so far represent definite relations. That is, if a pair of operations (op1,op2) is confirmed to be a relation of one of this three classes, then we can certainly say what effect on the enabling condition of op2 would the execution of op1 have. However, for some pairs of operations we cannot certainly say what effect an operation would have on the enabling condition of another operation. This is due to the fact that the enabling status of an operation does not only depend on the effect of the executed operations, but also on the current variables’ evaluation. Take, for instance, the tuple (Op3,Op1) from the B machine above. Considering the action part of Op3 and the guard condition of Op1 we can assume that Op3 can enable Op1. Since the guard of Op1 depends not only on the current value of x, but also on y, there could be transitions s -&amp;gt; s&#039; of Op3 in the state space of the machine where Op1 is disabled in both states s and s’. Though, what we could definitely say is that Op3 cannot disable Op1. This relationship we can illustrate as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleEnableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
The opposite relation of “possible_enable” is the relation where an operation op2 can disable another operation op1. Formally, we say that op2 can disable op1 if op2 may disable op1 and op2 cannot enable op1. This relationship is denoted as “possible_disable” and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
In order to determine how operations influence each other we need to assure first that these are feasible. An operation ‘’op’’ is said to be feasible if there is a state of the machine that satisfies the invariant of the machine and in which ‘’op’’ is enabled. In the B machine above the operation Op4, for example, is not feasible. Obviously, Op4 is enabled only in states where x is a negative number and states in which x is a negative number are visibly not consistent with the invariant since &amp;quot;x : NATURAL&amp;quot;. Such incompatibilities are sometimes of great importance for the modeler and therefore they should be revealed in the process of computing the enabling relations. In our case for each pair of operations (Op4,-) and (-,Op4) the status “infeasible” will be returned.&lt;br /&gt;
&lt;br /&gt;
We can now list all possible enabling relations for the machine &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; by means of a table. For each entry in the table the operation in the row is the operation whose effect is studied on the status of the guard of the operation in the column.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingResults.png]]&lt;br /&gt;
&lt;br /&gt;
== Summary of the Enabling Relations ==&lt;br /&gt;
&lt;br /&gt;
In the following, we summarize most of the enabling relations that we think can provide a useful feedback to the user. For each of the enabling relations we have given an appropriate example. In the examples below we compute the effect of executing ‘op1’ on the status of the guard of ‘op2’. The relation identifiers are the same as they appear as results in ProB.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;guaranteed&#039;&#039;: op2 guaranteed to be executable after op1.&lt;br /&gt;
[[File: GuaranteedExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_enable&#039;&#039;: op2 is guaranteed to become enabled after op1.&lt;br /&gt;
[[File: GuaranteedEnableExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_keep&#039;&#039;: op2 is guaranteed to stay enabled after op1.&lt;br /&gt;
[[File: GuaranteedKeepExample.png]]&lt;br /&gt;
* &#039;&#039;impossible&#039;&#039;: op2 is impossible to be executed after op1.&lt;br /&gt;
[[File: ImpossibleExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_disable&#039;&#039;: op2 is guaranteed to become disabled after op1.&lt;br /&gt;
[[File: ImpossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_keep&#039;&#039;: op2 is impossible to become enabled after op1.&lt;br /&gt;
[[File: ImpossibleKeepExample.png]]&lt;br /&gt;
* &#039;&#039;keep&#039;&#039;: op2 always stays enabled resp. disabled after op1.&lt;br /&gt;
[[File: KeepExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_unchanged&#039;&#039;: op1 does not write any variable read in the guard of op2, i.e. write(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticUnchangedExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_independent&#039;&#039;: op1 and op2 are syntactically independent, i.e. read(op1) /\ write(op2) = {} &amp;amp; write(op1) /\ read(op2) = {} &amp;amp; write(op1) /\ write(op2) = {}&lt;br /&gt;
[[File: SyntacticIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;syntactically_fully_independent&#039;&#039;: op1 and op2 are syntactically independent and additionally, read(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticFullyIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;possible_enable&#039;&#039;: op2 possible after op1, but op2 cannot be disabled by op1.&lt;br /&gt;
[[File: PossibleEnableExample.png]]&lt;br /&gt;
* &#039;&#039;possible_disable&#039;&#039;: op2 possible after iop1, but op2 cannot be enabled by op1.&lt;br /&gt;
[[File: PossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;infeasible&#039;&#039;: op1 is not feasible and thus cannot influence op2.&lt;br /&gt;
[[File: InfeasibleExample.png]]&lt;br /&gt;
&lt;br /&gt;
== Performing Enabling Analysis within ProB  ==&lt;br /&gt;
&lt;br /&gt;
The enabling analysis has been implemented in the ProB toolset.  The computation of the enabling relations is based on syntactic and constraint-based techniques. The identification of relations such as ‘’syntactic_independent’’ and ‘’syntactic_unchanged’’ requires just a thorough study of the syntactic structure of the operations, i.e. no calls to the constraint solver have to be made. However, to confirm, for example, that an operation is guaranteed or impossible to be executed after another operation the use of the ProB’s constraint solver is unavoidable. For instance, consider the pair (Op2,Op1) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. As we have seen, in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; the operation Op1 is guaranteed to be enabled after each execution of Op2. In ProB this could be computed by feeding the (before-after) predicate “ (x mod 2 = 1) =&amp;gt; [x:=x+1 || y:=2] (x+y&amp;lt;4)” into the constraint solver. As a result, the constraint solver will not find a solution for the predicate, i.e. the constraint solver will not find a state ‘’s’’ satisfying “x mod 2 = 1” from which after executing Op2 at ‘’s’’ a solution state s’ will be found that fulfills “x+y&amp;lt;4”; note that “x+y&amp;lt;4” is the negation of the guard of Op1. Since there is no after-state of Op2 at which Op1 is disabled we can conclude that Op1 is guaranteed to be executed after Op2. When constraints are getting more complex the constraint solver may need more time for solving and determining the enabling relations may become a very time-expensive task. Therefore, a time-out for each constraint solver call is set. In other words, if the constraint solver does not find a solution in the given time by the user, then the respective relation will be denoted as time-outed. By default, in ProB the time-out for each constraint solver call is set to 300 ms.&lt;br /&gt;
&lt;br /&gt;
Within &amp;lt;tt&amp;gt;ProB Tcl/Tk&amp;lt;/tt&amp;gt; you can find the menu &amp;quot;Enabling Analysis&amp;quot; in the &amp;quot;Analysis&amp;quot; menu of the menu bar.&lt;br /&gt;
[[File: EnablingAnalysisMenu.png]]&lt;br /&gt;
 The &amp;quot;Enabling Analysis&amp;quot; menu provides multiple commands:&lt;br /&gt;
* &amp;quot;Enabling Analysis (Table)&amp;quot;: this command performs a (fast) enabling analysis on the respective B model using a time-out of 300 ms for the constraint-solver calls. The result of the enabling analysis is shown in a table. The table lists all enabling relations between the operations of the loaded B model. These can be exported to a CSV file. The table for &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; at the end of the &#039;&#039;&#039; Enabling Relations&#039;&#039;&#039; section was constructed this way.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Precise, Table)&amp;quot;: this command performs an enabling analysis using a time-out of 2800 ms for each of the constraint-solver calls. As for the command above, the result of the analysis is shown in a table that can be exported to a CSV file.&lt;br /&gt;
* &amp;quot;Enabling Relations After...&amp;quot;: this command computes all the enabling relations involving an operation chosen by the user.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Graph)&amp;quot;: this command performs the fast enabling analysis but displays the results as a graph. In case the preference &amp;quot;DOT_SHOW_OP_READ_WRITES&amp;quot; is set for each operation the read/write information is displayed.&lt;br /&gt;
* &amp;quot;Enabling Analysis (POR)...&amp;quot;: this menu provides further commands for another form of enabling analysis the results of which are used for the partial guard evaluation optimisation in ProB.&lt;br /&gt;
* &amp;quot;Read/Write Matrix (Table)&amp;quot;: this command performs syntactic analysis on the model. The analysis determines the read and write sets for each operation of the machine.&lt;br /&gt;
* &amp;quot;Dependence Analysis (Table)&amp;quot;: this command performs a dependency analysis for each pair of operations. More specifically, the analysis determines which operations are dependent or independent to each other.&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB (probcli) one can perform an enabling analysis on a B or Event-B model by means of the &amp;lt;tt&amp;gt;-enabling_analysis&amp;lt;/tt&amp;gt; option. The results of the analysis, as well as intermediate data and some statistics are printed out on the console:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli Example.mch -enabling_analysis&lt;br /&gt;
CHECKING ENABLING AFTER INITIALISATION&lt;br /&gt;
INITIALISATION ---&amp;gt; Op1  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op2  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op3  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op4  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op5  :: ok : guaranteed&lt;br /&gt;
.....&lt;br /&gt;
CHECKING ENABLING AFTER: Op5 r:[y] / w:[z]&lt;br /&gt;
Op5 ---&amp;gt; Op1  :: Enable=syntactic_independent&lt;br /&gt;
Op5 ---&amp;gt; Op2  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op3  :: Enable=syntactic_fully_independent&lt;br /&gt;
Op5 ---&amp;gt; Op4  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op5  :: Enable=syntactic_unchanged&lt;br /&gt;
% Finished CBC Enabling Analysis 810 ms walltime (770 ms runtime), since start: 1650 ms&lt;br /&gt;
% CBC Enabling Stats:&lt;br /&gt;
% Nr of events: 5&lt;br /&gt;
% Nr of cbc calls: 30, Timeout results: 2&lt;br /&gt;
Origin,Op1,Op2,Op3,Op4,Op5&lt;br /&gt;
INITIALISATION,guaranteed,impossible,guaranteed,impossible,guaranteed&lt;br /&gt;
Op1,timeout_possible_disable,keep,keep,impossible_keep,syntactic_independent&lt;br /&gt;
Op2,guaranteed,impossible,guaranteed,impossible_keep,impossible&lt;br /&gt;
Op3,timeout_possible,impossible_keep,guaranteed,impossible_keep,syntactic_fully_independent&lt;br /&gt;
Op4,impossible_keep,syntactic_unchanged,syntactic_unchanged,syntactic_keep,impossible_keep&lt;br /&gt;
Op5,syntactic_independent,syntactic_unchanged,syntactic_fully_independent,syntactic_unchanged,syntactic_unchanged&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To perform enabling analysis from the command line and save the results to a CSV-file use the following commando:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli file.mch -enabling_analysis_csv FILE &amp;lt;/pre&amp;gt;&lt;br /&gt;
where FILE is the name of the CSV-file in which the results of the analysis are stored.&lt;br /&gt;
&lt;br /&gt;
== References and Footnotes ==&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=File:EnablingAnalysisMenu.png&amp;diff=3493</id>
		<title>File:EnablingAnalysisMenu.png</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=File:EnablingAnalysisMenu.png&amp;diff=3493"/>
		<updated>2016-02-16T14:50:32Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: Ivaylo Dobrikov uploaded a new version of File:EnablingAnalysisMenu.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=File:EnablingAnalysisMenu.png&amp;diff=3492</id>
		<title>File:EnablingAnalysisMenu.png</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=File:EnablingAnalysisMenu.png&amp;diff=3492"/>
		<updated>2016-02-16T14:49:22Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: Ivaylo Dobrikov uploaded a new version of File:EnablingAnalysisMenu.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=File:EnablingAnalysisMenu.png&amp;diff=3491</id>
		<title>File:EnablingAnalysisMenu.png</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=File:EnablingAnalysisMenu.png&amp;diff=3491"/>
		<updated>2016-02-16T14:44:55Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3490</id>
		<title>Tutorial Enabling Analysis</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3490"/>
		<updated>2016-02-16T14:44:27Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Performing Enabling Analysis within ProB */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The B-method and in particular its successor Event-B are methodologies for formal development and verification of systems. In Event-B, a machine is usually viewed as a reactive system executing continuously enabled (atomic) events in an interleaved fashion. Thus, parallel events of the system are easily modeled as an interleaving of operation executions. On the other hand, the introduction of abstract counters is required when events are supposed to be executed in some (sequential) order. This, however, can in some cases slow the work of understanding and verifying a model since identifying the sequential ordering of events in an Event-B model is not that obvious. Thus, using methods for determining the control flow can be sometimes very beneficial for understanding the model, as well as for techniques for automatic verification such as model checking.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we present a static analysis for B and Event-B that can be used to reveal the control flow of a machine and to optimize model checking of models written in B and Event-B (see also [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Guard_Evaluation Tutorial on Partial Guard Evaluation ]). The results of the analysis, designated also as ‘’enabling analysis’’, can be presented as relations by means of a table or by means of a graph. For simplicity, we will concentrate mainly on B and use the terminology of the formalism.&lt;br /&gt;
&lt;br /&gt;
== Enabling Relations ==&lt;br /&gt;
What we want to find out is how the operations influence each other within a B model. In other words, for each pair (op1,op2) of operations we try to determine as precise as possible how op1 can affect the guard condition of op2 with regard to enabledness. To determine the enabling relations between operations we use syntactic analyses, as well as the constraint-based abilities of ProB.&lt;br /&gt;
&lt;br /&gt;
Consider the following B machine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE Example&lt;br /&gt;
VARIABLES x, y, z&lt;br /&gt;
INVARIANT&lt;br /&gt;
    x:NATURAL&lt;br /&gt;
  &amp;amp; y:INTEGER&lt;br /&gt;
  &amp;amp; z:INTEGER&lt;br /&gt;
INITIALISATION &lt;br /&gt;
  x:=6 || y:=-2 || z:=0&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Op1 = PRE x + y&amp;gt;=4  THEN x:=x+2 || y:=2 END;&lt;br /&gt;
  Op2 = PRE x mod 2=1 THEN x:=x+1 || y:=2 END;&lt;br /&gt;
  Op3 = PRE x mod 2=0 THEN x:=x+2 END;&lt;br /&gt;
  Op4 = PRE x&amp;lt;0 THEN y:=y-1 END;&lt;br /&gt;
  Op5 = PRE y/=2 THEN z:=3 END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The machine has three variables x,y,z, where x ranges over the domain of natural numbers and y and z over the domain of all integers. For this machine we have 25 pairs of operations for which we want to determine the respective enabling relations. Additionally, we identify 5 further pairs that show the influence of the INITIALISATION on the guard conditions of all other operations. Consider, for example, the pair (Op2,Op1) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op1 is enabled in each state of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; where the predicate ‘x+y&amp;gt;=4’ is fulfilled. Since the effect of Op2 assigns 2 to y and increments x by one upon condition that x is a positive odd number in the before-state of Op2, we can assume that Op1 is always enabled after the execution of Op2. In other words, in all after-states of Op2 the operation Op1 is guaranteed to be enabled. This relation between Op2 and Op1 we can illustrate as follows: &lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above the green boxes denote that the evaluation of the guard of Op1 is true, whereas the red boxes denote that the evaluation of the guard of Op1 is false. &lt;br /&gt;
&lt;br /&gt;
Another pair of interest is (Op2,Op5) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op5 is enabled only in those states in which y is not equal to 2. Obviously, in each after-state of Op2 y is equal to 2 and thus we can conclude that Op5 is impossible to be enabled after each execution of Op2. Such a relation between two operations we denote as ‘’impossible’’ and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
Both arrows in the illustration of the ‘’impossible’’ relation indicate that whether the guard condition of Op5 is fulfilled or not in a before-state of Op2 operation Op5 will be disabled in the respective after-state of Op2. In order to recognize a tuple (op1,op2) as ‘’impossible’’ we require that op2 is always disabled after op1 without further considering whether op2 is always enabled or always disabled in the before-states of op1. &lt;br /&gt;
&lt;br /&gt;
Consider, for instance, the pair (Op2, Op2) in the machine above. We can easily conclude that Op2 becomes disabled after it is executed and clearly, the second case (\false -&amp;gt; \false) of the impossible relation is not possible for (Op2, Op2). This gives rise of introducing another (more precise) impossible relation:&lt;br /&gt;
 &lt;br /&gt;
[[File:ImpossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Accordingly, we can derive another relation from ‘’impossible’’ for which only the second case of the ‘’impossible’’ relation is fulfilled:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
As an example for a pair of operations that fulfills the ‘’impossible_keep’’ requirement you can take, for example, the pair (Op3,Op2) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Since Op2 and Op3 cannot be both enabled in a state and the execution of Op3 cannot enable Op2, then we can easily conclude that Op2 remains always disabled after Op3.&lt;br /&gt;
&lt;br /&gt;
Similarly as for ‘’impossible’’, one could derive two further enabling relations from ‘’guaranteed’’:&lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedEnableKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Another interesting class of enabling relations that could be helpful for better understanding and analyzing B and Event-B models is that of the ‘’keep’’ relations. We say that an operation op1 ‘’keeps’’ another operation op2 if op1 cannot change the status of the enabling condition of op2, i.e. op1 keeps op2 enabled respectively disabled. This relationship could be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:KeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
We can take (Op1,Op2) and (Op1,Op3) as examples of pairs in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; that are elements of the keep relation. ‘’keep’’ relations can sometimes be easily determined by analyzing just the syntactic structure of both operations, or more precisely the “read” and “write” sets of both operations.&amp;lt;ref&amp;gt;For an operation op the set read(op) denotes the set of variables that are read by op. Accordingly, by write(op) we denote the set of variables that are written by op.&amp;lt;/ref&amp;gt; If, for example, an operation op1 does not write any variable of the machine that is read in the guard condition of op2, then we can infer that op1 ‘’keeps’’ op2. In that case we also say that op1 does not change op2 syntactically. In the class of the ‘’keep’’ relations are included also relations such as independence. Two operations op1 and op2 are called independent if each of them cannot disable the other operation and the both orders of execution &amp;lt;op1,op2&amp;gt; and &amp;lt;op2,op1&amp;gt; have the same effect.&amp;lt;ref&amp;gt;See the [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Order_Reduction Tutorial on Partial Order Reduction] for more information on independence between operations.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three classes (‘’guaranteed’’, ‘’impossible’’ and ‘’keep’’) of enabling relations presented so far represent definite relations. That is, if a pair of operations (op1,op2) is confirmed to be a relation of one of this three classes, then we can certainly say what effect on the enabling condition of op2 would the execution of op1 have. However, for some pairs of operations we cannot certainly say what effect an operation would have on the enabling condition of another operation. This is due to the fact that the enabling status of an operation does not only depend on the effect of the executed operations, but also on the current variables’ evaluation. Take, for instance, the tuple (Op3,Op1) from the B machine above. Considering the action part of Op3 and the guard condition of Op1 we can assume that Op3 can enable Op1. Since the guard of Op1 depends not only on the current value of x, but also on y, there could be transitions s -&amp;gt; s&#039; of Op3 in the state space of the machine where Op1 is disabled in both states s and s’. Though, what we could definitely say is that Op3 cannot disable Op1. This relationship we can illustrate as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleEnableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
The opposite relation of “possible_enable” is the relation where an operation op2 can disable another operation op1. Formally, we say that op2 can disable op1 if op2 may disable op1 and op2 cannot enable op1. This relationship is denoted as “possible_disable” and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
In order to determine how operations influence each other we need to assure first that these are feasible. An operation ‘’op’’ is said to be feasible if there is a state of the machine that satisfies the invariant of the machine and in which ‘’op’’ is enabled. In the B machine above the operation Op4, for example, is not feasible. Obviously, Op4 is enabled only in states where x is a negative number and states in which x is a negative number are visibly not consistent with the invariant since &amp;quot;x : NATURAL&amp;quot;. Such incompatibilities are sometimes of great importance for the modeler and therefore they should be revealed in the process of computing the enabling relations. In our case for each pair of operations (Op4,-) and (-,Op4) the status “infeasible” will be returned.&lt;br /&gt;
&lt;br /&gt;
We can now list all possible enabling relations for the machine &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; by means of a table. For each entry in the table the operation in the row is the operation whose effect is studied on the status of the guard of the operation in the column.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingResults.png]]&lt;br /&gt;
&lt;br /&gt;
== Summary of the Enabling Relations ==&lt;br /&gt;
&lt;br /&gt;
In the following, we summarize most of the enabling relations that we think can provide a useful feedback to the user. For each of the enabling relations we have given an appropriate example. In the examples below we compute the effect of executing ‘op1’ on the status of the guard of ‘op2’. The relation identifiers are the same as they appear as results in ProB.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;guaranteed&#039;&#039;: op2 guaranteed to be executable after op1.&lt;br /&gt;
[[File: GuaranteedExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_enable&#039;&#039;: op2 is guaranteed to become enabled after op1.&lt;br /&gt;
[[File: GuaranteedEnableExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_keep&#039;&#039;: op2 is guaranteed to stay enabled after op1.&lt;br /&gt;
[[File: GuaranteedKeepExample.png]]&lt;br /&gt;
* &#039;&#039;impossible&#039;&#039;: op2 is impossible to be executed after op1.&lt;br /&gt;
[[File: ImpossibleExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_disable&#039;&#039;: op2 is guaranteed to become disabled after op1.&lt;br /&gt;
[[File: ImpossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_keep&#039;&#039;: op2 is impossible to become enabled after op1.&lt;br /&gt;
[[File: ImpossibleKeepExample.png]]&lt;br /&gt;
* &#039;&#039;keep&#039;&#039;: op2 always stays enabled resp. disabled after op1.&lt;br /&gt;
[[File: KeepExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_unchanged&#039;&#039;: op1 does not write any variable read in the guard of op2, i.e. write(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticUnchangedExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_independent&#039;&#039;: op1 and op2 are syntactically independent, i.e. read(op1) /\ write(op2) = {} &amp;amp; write(op1) /\ read(op2) = {} &amp;amp; write(op1) /\ write(op2) = {}&lt;br /&gt;
[[File: SyntacticIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;syntactically_fully_independent&#039;&#039;: op1 and op2 are syntactically independent and additionally, read(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticFullyIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;possible_enable&#039;&#039;: op2 possible after op1, but op2 cannot be disabled by op1.&lt;br /&gt;
[[File: PossibleEnableExample.png]]&lt;br /&gt;
* &#039;&#039;possible_disable&#039;&#039;: op2 possible after iop1, but op2 cannot be enabled by op1.&lt;br /&gt;
[[File: PossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;infeasible&#039;&#039;: op1 is not feasible and thus cannot influence op2.&lt;br /&gt;
[[File: InfeasibleExample.png]]&lt;br /&gt;
&lt;br /&gt;
== Performing Enabling Analysis within ProB  ==&lt;br /&gt;
&lt;br /&gt;
The enabling analysis has been implemented in the ProB toolset.  The computation of the enabling relations is based on syntactic and constraint-based techniques. The identification of relations such as ‘’syntactic_independent’’ and ‘’syntactic_unchanged’’ requires just a thorough study of the syntactic structure of the operations, i.e. no calls to the constraint solver have to be made. However, to confirm, for example, that an operation is guaranteed or impossible to be executed after another operation the use of the ProB’s constraint solver is unavoidable. For instance, consider the pair (Op2,Op1) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. As we have seen, in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; the operation Op1 is guaranteed to be enabled after each execution of Op2. In ProB this could be computed by feeding the (before-after) predicate “ (x mod 2 = 1) =&amp;gt; [x:=x+1 || y:=2] (x+y&amp;lt;4)” into the constraint solver. As a result, the constraint solver will not find a solution for the predicate, i.e. the constraint solver will not find a state ‘’s’’ satisfying “x mod 2 = 1” from which after executing Op2 at ‘’s’’ a solution state s’ will be found that fulfills “x+y&amp;lt;4”; note that “x+y&amp;lt;4” is the negation of the guard of Op1. Since there is no after-state of Op2 at which Op1 is disabled we can conclude that Op1 is guaranteed to be executed after Op2. When constraints are getting more complex the constraint solver may need more time for solving and determining the enabling relations may become a very time-expensive task. Therefore, a time-out for each constraint solver call is set. In other words, if the constraint solver does not find a solution in the given time by the user, then the respective relation will be denoted as time-outed. By default, in ProB the time-out for each constraint solver call is set to 300 ms.&lt;br /&gt;
&lt;br /&gt;
Within &amp;lt;tt&amp;gt;ProB Tcl/Tk&amp;lt;/tt&amp;gt; you can find the menu &amp;quot;Enabling Analysis&amp;quot; in the &amp;quot;Analysis&amp;quot; menu of the menu bar.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingAnalysisMenu.png]]&lt;br /&gt;
&lt;br /&gt;
 The &amp;quot;Enabling Analysis&amp;quot; menu provides multiple commands:&lt;br /&gt;
* &amp;quot;Enabling Analysis (Table)&amp;quot;: this command performs a (fast) enabling analysis on the respective B model using a time-out of 300 ms for the constraint-solver calls. The result of the enabling analysis is shown in a table. The table lists all enabling relations between the operations of the loaded B model. These can be exported to a CSV file. The table for &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; at the end of the &#039;&#039;&#039; Enabling Relations&#039;&#039;&#039; section was constructed this way.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Precise, Table)&amp;quot;: this command performs an enabling analysis using a time-out of 2800 ms for each of the constraint-solver calls. As for the command above, the result of the analysis is shown in a table that can be exported to a CSV file.&lt;br /&gt;
* &amp;quot;Enabling Relations After...&amp;quot;: this command computes all the enabling relations involving an operation chosen by the user.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Graph)&amp;quot;: this command performs the fast enabling analysis but displays the results as a graph. In case the preference &amp;quot;DOT_SHOW_OP_READ_WRITES&amp;quot; is set for each operation the read/write information is displayed.&lt;br /&gt;
* &amp;quot;Enabling Analysis (POR)...&amp;quot;: this menu provides further commands for another form of enabling analysis the results of which are used for the partial guard evaluation optimisation in ProB.&lt;br /&gt;
* &amp;quot;Read/Write Matrix (Table)&amp;quot;: this command performs syntactic analysis on the model. The analysis determines the read and write sets for each operation of the machine.&lt;br /&gt;
* &amp;quot;Dependence Analysis (Table)&amp;quot;: this command performs a dependency analysis for each pair of operations. More specifically, the analysis determines which operations are dependent or independent to each other.&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB (probcli) one can perform an enabling analysis on a B or Event-B model by means of the &amp;lt;tt&amp;gt;-enabling_analysis&amp;lt;/tt&amp;gt; option. The results of the analysis, as well as intermediate data and some statistics are printed out on the console:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli Example.mch -enabling_analysis&lt;br /&gt;
CHECKING ENABLING AFTER INITIALISATION&lt;br /&gt;
INITIALISATION ---&amp;gt; Op1  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op2  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op3  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op4  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op5  :: ok : guaranteed&lt;br /&gt;
.....&lt;br /&gt;
CHECKING ENABLING AFTER: Op5 r:[y] / w:[z]&lt;br /&gt;
Op5 ---&amp;gt; Op1  :: Enable=syntactic_independent&lt;br /&gt;
Op5 ---&amp;gt; Op2  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op3  :: Enable=syntactic_fully_independent&lt;br /&gt;
Op5 ---&amp;gt; Op4  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op5  :: Enable=syntactic_unchanged&lt;br /&gt;
% Finished CBC Enabling Analysis 810 ms walltime (770 ms runtime), since start: 1650 ms&lt;br /&gt;
% CBC Enabling Stats:&lt;br /&gt;
% Nr of events: 5&lt;br /&gt;
% Nr of cbc calls: 30, Timeout results: 2&lt;br /&gt;
Origin,Op1,Op2,Op3,Op4,Op5&lt;br /&gt;
INITIALISATION,guaranteed,impossible,guaranteed,impossible,guaranteed&lt;br /&gt;
Op1,timeout_possible_disable,keep,keep,impossible_keep,syntactic_independent&lt;br /&gt;
Op2,guaranteed,impossible,guaranteed,impossible_keep,impossible&lt;br /&gt;
Op3,timeout_possible,impossible_keep,guaranteed,impossible_keep,syntactic_fully_independent&lt;br /&gt;
Op4,impossible_keep,syntactic_unchanged,syntactic_unchanged,syntactic_keep,impossible_keep&lt;br /&gt;
Op5,syntactic_independent,syntactic_unchanged,syntactic_fully_independent,syntactic_unchanged,syntactic_unchanged&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To perform enabling analysis from the command line and save the results to a CSV-file use the following commando:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli file.mch -enabling_analysis_csv FILE &amp;lt;/pre&amp;gt;&lt;br /&gt;
where FILE is the name of the CSV-file in which the results of the analysis are stored.&lt;br /&gt;
&lt;br /&gt;
== References and Footnotes ==&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3489</id>
		<title>Tutorial Enabling Analysis</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3489"/>
		<updated>2016-02-16T09:44:47Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Enabling Relations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The B-method and in particular its successor Event-B are methodologies for formal development and verification of systems. In Event-B, a machine is usually viewed as a reactive system executing continuously enabled (atomic) events in an interleaved fashion. Thus, parallel events of the system are easily modeled as an interleaving of operation executions. On the other hand, the introduction of abstract counters is required when events are supposed to be executed in some (sequential) order. This, however, can in some cases slow the work of understanding and verifying a model since identifying the sequential ordering of events in an Event-B model is not that obvious. Thus, using methods for determining the control flow can be sometimes very beneficial for understanding the model, as well as for techniques for automatic verification such as model checking.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we present a static analysis for B and Event-B that can be used to reveal the control flow of a machine and to optimize model checking of models written in B and Event-B (see also [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Guard_Evaluation Tutorial on Partial Guard Evaluation ]). The results of the analysis, designated also as ‘’enabling analysis’’, can be presented as relations by means of a table or by means of a graph. For simplicity, we will concentrate mainly on B and use the terminology of the formalism.&lt;br /&gt;
&lt;br /&gt;
== Enabling Relations ==&lt;br /&gt;
What we want to find out is how the operations influence each other within a B model. In other words, for each pair (op1,op2) of operations we try to determine as precise as possible how op1 can affect the guard condition of op2 with regard to enabledness. To determine the enabling relations between operations we use syntactic analyses, as well as the constraint-based abilities of ProB.&lt;br /&gt;
&lt;br /&gt;
Consider the following B machine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE Example&lt;br /&gt;
VARIABLES x, y, z&lt;br /&gt;
INVARIANT&lt;br /&gt;
    x:NATURAL&lt;br /&gt;
  &amp;amp; y:INTEGER&lt;br /&gt;
  &amp;amp; z:INTEGER&lt;br /&gt;
INITIALISATION &lt;br /&gt;
  x:=6 || y:=-2 || z:=0&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Op1 = PRE x + y&amp;gt;=4  THEN x:=x+2 || y:=2 END;&lt;br /&gt;
  Op2 = PRE x mod 2=1 THEN x:=x+1 || y:=2 END;&lt;br /&gt;
  Op3 = PRE x mod 2=0 THEN x:=x+2 END;&lt;br /&gt;
  Op4 = PRE x&amp;lt;0 THEN y:=y-1 END;&lt;br /&gt;
  Op5 = PRE y/=2 THEN z:=3 END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The machine has three variables x,y,z, where x ranges over the domain of natural numbers and y and z over the domain of all integers. For this machine we have 25 pairs of operations for which we want to determine the respective enabling relations. Additionally, we identify 5 further pairs that show the influence of the INITIALISATION on the guard conditions of all other operations. Consider, for example, the pair (Op2,Op1) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op1 is enabled in each state of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; where the predicate ‘x+y&amp;gt;=4’ is fulfilled. Since the effect of Op2 assigns 2 to y and increments x by one upon condition that x is a positive odd number in the before-state of Op2, we can assume that Op1 is always enabled after the execution of Op2. In other words, in all after-states of Op2 the operation Op1 is guaranteed to be enabled. This relation between Op2 and Op1 we can illustrate as follows: &lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above the green boxes denote that the evaluation of the guard of Op1 is true, whereas the red boxes denote that the evaluation of the guard of Op1 is false. &lt;br /&gt;
&lt;br /&gt;
Another pair of interest is (Op2,Op5) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op5 is enabled only in those states in which y is not equal to 2. Obviously, in each after-state of Op2 y is equal to 2 and thus we can conclude that Op5 is impossible to be enabled after each execution of Op2. Such a relation between two operations we denote as ‘’impossible’’ and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
Both arrows in the illustration of the ‘’impossible’’ relation indicate that whether the guard condition of Op5 is fulfilled or not in a before-state of Op2 operation Op5 will be disabled in the respective after-state of Op2. In order to recognize a tuple (op1,op2) as ‘’impossible’’ we require that op2 is always disabled after op1 without further considering whether op2 is always enabled or always disabled in the before-states of op1. &lt;br /&gt;
&lt;br /&gt;
Consider, for instance, the pair (Op2, Op2) in the machine above. We can easily conclude that Op2 becomes disabled after it is executed and clearly, the second case (\false -&amp;gt; \false) of the impossible relation is not possible for (Op2, Op2). This gives rise of introducing another (more precise) impossible relation:&lt;br /&gt;
 &lt;br /&gt;
[[File:ImpossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Accordingly, we can derive another relation from ‘’impossible’’ for which only the second case of the ‘’impossible’’ relation is fulfilled:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
As an example for a pair of operations that fulfills the ‘’impossible_keep’’ requirement you can take, for example, the pair (Op3,Op2) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Since Op2 and Op3 cannot be both enabled in a state and the execution of Op3 cannot enable Op2, then we can easily conclude that Op2 remains always disabled after Op3.&lt;br /&gt;
&lt;br /&gt;
Similarly as for ‘’impossible’’, one could derive two further enabling relations from ‘’guaranteed’’:&lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedEnableKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Another interesting class of enabling relations that could be helpful for better understanding and analyzing B and Event-B models is that of the ‘’keep’’ relations. We say that an operation op1 ‘’keeps’’ another operation op2 if op1 cannot change the status of the enabling condition of op2, i.e. op1 keeps op2 enabled respectively disabled. This relationship could be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:KeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
We can take (Op1,Op2) and (Op1,Op3) as examples of pairs in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; that are elements of the keep relation. ‘’keep’’ relations can sometimes be easily determined by analyzing just the syntactic structure of both operations, or more precisely the “read” and “write” sets of both operations.&amp;lt;ref&amp;gt;For an operation op the set read(op) denotes the set of variables that are read by op. Accordingly, by write(op) we denote the set of variables that are written by op.&amp;lt;/ref&amp;gt; If, for example, an operation op1 does not write any variable of the machine that is read in the guard condition of op2, then we can infer that op1 ‘’keeps’’ op2. In that case we also say that op1 does not change op2 syntactically. In the class of the ‘’keep’’ relations are included also relations such as independence. Two operations op1 and op2 are called independent if each of them cannot disable the other operation and the both orders of execution &amp;lt;op1,op2&amp;gt; and &amp;lt;op2,op1&amp;gt; have the same effect.&amp;lt;ref&amp;gt;See the [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Order_Reduction Tutorial on Partial Order Reduction] for more information on independence between operations.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three classes (‘’guaranteed’’, ‘’impossible’’ and ‘’keep’’) of enabling relations presented so far represent definite relations. That is, if a pair of operations (op1,op2) is confirmed to be a relation of one of this three classes, then we can certainly say what effect on the enabling condition of op2 would the execution of op1 have. However, for some pairs of operations we cannot certainly say what effect an operation would have on the enabling condition of another operation. This is due to the fact that the enabling status of an operation does not only depend on the effect of the executed operations, but also on the current variables’ evaluation. Take, for instance, the tuple (Op3,Op1) from the B machine above. Considering the action part of Op3 and the guard condition of Op1 we can assume that Op3 can enable Op1. Since the guard of Op1 depends not only on the current value of x, but also on y, there could be transitions s -&amp;gt; s&#039; of Op3 in the state space of the machine where Op1 is disabled in both states s and s’. Though, what we could definitely say is that Op3 cannot disable Op1. This relationship we can illustrate as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleEnableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
The opposite relation of “possible_enable” is the relation where an operation op2 can disable another operation op1. Formally, we say that op2 can disable op1 if op2 may disable op1 and op2 cannot enable op1. This relationship is denoted as “possible_disable” and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
In order to determine how operations influence each other we need to assure first that these are feasible. An operation ‘’op’’ is said to be feasible if there is a state of the machine that satisfies the invariant of the machine and in which ‘’op’’ is enabled. In the B machine above the operation Op4, for example, is not feasible. Obviously, Op4 is enabled only in states where x is a negative number and states in which x is a negative number are visibly not consistent with the invariant since &amp;quot;x : NATURAL&amp;quot;. Such incompatibilities are sometimes of great importance for the modeler and therefore they should be revealed in the process of computing the enabling relations. In our case for each pair of operations (Op4,-) and (-,Op4) the status “infeasible” will be returned.&lt;br /&gt;
&lt;br /&gt;
We can now list all possible enabling relations for the machine &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; by means of a table. For each entry in the table the operation in the row is the operation whose effect is studied on the status of the guard of the operation in the column.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingResults.png]]&lt;br /&gt;
&lt;br /&gt;
== Summary of the Enabling Relations ==&lt;br /&gt;
&lt;br /&gt;
In the following, we summarize most of the enabling relations that we think can provide a useful feedback to the user. For each of the enabling relations we have given an appropriate example. In the examples below we compute the effect of executing ‘op1’ on the status of the guard of ‘op2’. The relation identifiers are the same as they appear as results in ProB.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;guaranteed&#039;&#039;: op2 guaranteed to be executable after op1.&lt;br /&gt;
[[File: GuaranteedExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_enable&#039;&#039;: op2 is guaranteed to become enabled after op1.&lt;br /&gt;
[[File: GuaranteedEnableExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_keep&#039;&#039;: op2 is guaranteed to stay enabled after op1.&lt;br /&gt;
[[File: GuaranteedKeepExample.png]]&lt;br /&gt;
* &#039;&#039;impossible&#039;&#039;: op2 is impossible to be executed after op1.&lt;br /&gt;
[[File: ImpossibleExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_disable&#039;&#039;: op2 is guaranteed to become disabled after op1.&lt;br /&gt;
[[File: ImpossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_keep&#039;&#039;: op2 is impossible to become enabled after op1.&lt;br /&gt;
[[File: ImpossibleKeepExample.png]]&lt;br /&gt;
* &#039;&#039;keep&#039;&#039;: op2 always stays enabled resp. disabled after op1.&lt;br /&gt;
[[File: KeepExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_unchanged&#039;&#039;: op1 does not write any variable read in the guard of op2, i.e. write(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticUnchangedExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_independent&#039;&#039;: op1 and op2 are syntactically independent, i.e. read(op1) /\ write(op2) = {} &amp;amp; write(op1) /\ read(op2) = {} &amp;amp; write(op1) /\ write(op2) = {}&lt;br /&gt;
[[File: SyntacticIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;syntactically_fully_independent&#039;&#039;: op1 and op2 are syntactically independent and additionally, read(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticFullyIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;possible_enable&#039;&#039;: op2 possible after op1, but op2 cannot be disabled by op1.&lt;br /&gt;
[[File: PossibleEnableExample.png]]&lt;br /&gt;
* &#039;&#039;possible_disable&#039;&#039;: op2 possible after iop1, but op2 cannot be enabled by op1.&lt;br /&gt;
[[File: PossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;infeasible&#039;&#039;: op1 is not feasible and thus cannot influence op2.&lt;br /&gt;
[[File: InfeasibleExample.png]]&lt;br /&gt;
&lt;br /&gt;
== Performing Enabling Analysis within ProB  ==&lt;br /&gt;
&lt;br /&gt;
The enabling analysis has been implemented in the ProB toolset.  The computation of the enabling relations is based on syntactic and constraint-based techniques. The identification of relations such as ‘’syntactic_independent’’ and ‘’syntactic_unchanged’’ requires just a thorough study of the syntactic structure of the operations, i.e. no calls to the constraint solver have to be made. However, to confirm, for example, that an operation is guaranteed or impossible to be executed after another operation the use of the ProB’s constraint solver is unavoidable. For instance, consider the pair (Op2,Op1) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. As we have seen, in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; the operation Op1 is guaranteed to be enabled after each execution of Op2. In ProB this could be computed by feeding the (before-after) predicate “ (x mod 2 = 1) =&amp;gt; [x:=x+1 || y:=2] (x+y&amp;lt;4)” into the constraint solver. As a result, the constraint solver will not find a solution for the predicate, i.e. the constraint solver will not find a state ‘’s’’ satisfying “x mod 2 = 1” from which after executing Op2 at ‘’s’’ a solution state s’ will be found that fulfills “x+y&amp;lt;4”; note that “x+y&amp;lt;4” is the negation of the guard of Op1. Since there is no after-state of Op2 at which Op1 is disabled we can conclude that Op1 is guaranteed to be executed after Op2. When constraints are getting more complex the constraint solver may need more time for solving and determining the enabling relations may become a very time-expensive task. Therefore, a time-out for each constraint solver call is set. In other words, if the constraint solver does not find a solution in the given time by the user, then the respective relation will be denoted as time-outed. By default, in ProB the time-out for each constraint solver call is set to 300 ms.&lt;br /&gt;
&lt;br /&gt;
Within &amp;lt;tt&amp;gt;ProB Tcl/Tk&amp;lt;/tt&amp;gt; you can find the menu &amp;quot;Enabling Analysis&amp;quot; in the &amp;quot;Analysis&amp;quot; menu of the menu bar.  The &amp;quot;Enabling Analysis&amp;quot; menu provides multiple commands:&lt;br /&gt;
* &amp;quot;Enabling Analysis (Table)&amp;quot;: this command performs a (fast) enabling analysis on the respective B model using a time-out of 300 ms for the constraint-solver calls. The result of the enabling analysis is shown in a table. The table lists all enabling relations between the operations of the loaded B model. These can be exported to a CSV file. The table for &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; at the end of the &#039;&#039;&#039; Enabling Relations&#039;&#039;&#039; section was constructed this way.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Precise, Table)&amp;quot;: this command performs an enabling analysis using a time-out of 2800 ms for each of the constraint-solver calls. As for the command above, the result of the analysis is shown in a table that can be exported to a CSV file.&lt;br /&gt;
* &amp;quot;Enabling Relations After...&amp;quot;: this command computes all the enabling relations involving an operation chosen by the user.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Graph)&amp;quot;: this command performs the fast enabling analysis but displays the results as a graph. In case the preference &amp;quot;DOT_SHOW_OP_READ_WRITES&amp;quot; is set for each operation the read/write information is displayed.&lt;br /&gt;
* &amp;quot;Enabling Analysis (POR)...&amp;quot;: this menu provides further commands for another form of enabling analysis the results of which are used for the partial guard evaluation optimisation in ProB.&lt;br /&gt;
* &amp;quot;Read/Write Matrix (Table)&amp;quot;: this command performs syntactic analysis on the model. The analysis determines the read and write sets for each operation of the machine.&lt;br /&gt;
* &amp;quot;Dependence Analysis (Table)&amp;quot;: this command performs a dependency analysis for each pair of operations. More specifically, the analysis determines which operations are dependent or independent to each other.&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB (probcli) one can perform an enabling analysis on a B or Event-B model by means of the &amp;lt;tt&amp;gt;-enabling_analysis&amp;lt;/tt&amp;gt; option. The results of the analysis, as well as intermediate data and some statistics are printed out on the console:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli Example.mch -enabling_analysis&lt;br /&gt;
CHECKING ENABLING AFTER INITIALISATION&lt;br /&gt;
INITIALISATION ---&amp;gt; Op1  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op2  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op3  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op4  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op5  :: ok : guaranteed&lt;br /&gt;
.....&lt;br /&gt;
CHECKING ENABLING AFTER: Op5 r:[y] / w:[z]&lt;br /&gt;
Op5 ---&amp;gt; Op1  :: Enable=syntactic_independent&lt;br /&gt;
Op5 ---&amp;gt; Op2  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op3  :: Enable=syntactic_fully_independent&lt;br /&gt;
Op5 ---&amp;gt; Op4  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op5  :: Enable=syntactic_unchanged&lt;br /&gt;
% Finished CBC Enabling Analysis 810 ms walltime (770 ms runtime), since start: 1650 ms&lt;br /&gt;
% CBC Enabling Stats:&lt;br /&gt;
% Nr of events: 5&lt;br /&gt;
% Nr of cbc calls: 30, Timeout results: 2&lt;br /&gt;
Origin,Op1,Op2,Op3,Op4,Op5&lt;br /&gt;
INITIALISATION,guaranteed,impossible,guaranteed,impossible,guaranteed&lt;br /&gt;
Op1,timeout_possible_disable,keep,keep,impossible_keep,syntactic_independent&lt;br /&gt;
Op2,guaranteed,impossible,guaranteed,impossible_keep,impossible&lt;br /&gt;
Op3,timeout_possible,impossible_keep,guaranteed,impossible_keep,syntactic_fully_independent&lt;br /&gt;
Op4,impossible_keep,syntactic_unchanged,syntactic_unchanged,syntactic_keep,impossible_keep&lt;br /&gt;
Op5,syntactic_independent,syntactic_unchanged,syntactic_fully_independent,syntactic_unchanged,syntactic_unchanged&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To perform enabling analysis from the command line and save the results to a CSV-file use the following commando:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli file.mch -enabling_analysis_csv FILE &amp;lt;/pre&amp;gt;&lt;br /&gt;
where FILE is the name of the CSV-file in which the results of the analysis are stored.&lt;br /&gt;
&lt;br /&gt;
== References and Footnotes ==&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3488</id>
		<title>Tutorial Enabling Analysis</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3488"/>
		<updated>2016-02-15T17:12:48Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Enabling Relations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The B-method and in particular its successor Event-B are methodologies for formal development and verification of systems. In Event-B, a machine is usually viewed as a reactive system executing continuously enabled (atomic) events in an interleaved fashion. Thus, parallel events of the system are easily modeled as an interleaving of operation executions. On the other hand, the introduction of abstract counters is required when events are supposed to be executed in some (sequential) order. This, however, can in some cases slow the work of understanding and verifying a model since identifying the sequential ordering of events in an Event-B model is not that obvious. Thus, using methods for determining the control flow can be sometimes very beneficial for understanding the model, as well as for techniques for automatic verification such as model checking.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we present a static analysis for B and Event-B that can be used to reveal the control flow of a machine and to optimize model checking of models written in B and Event-B (see also [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Guard_Evaluation Tutorial on Partial Guard Evaluation ]). The results of the analysis, designated also as ‘’enabling analysis’’, can be presented as relations by means of a table or by means of a graph. For simplicity, we will concentrate mainly on B and use the terminology of the formalism.&lt;br /&gt;
&lt;br /&gt;
== Enabling Relations ==&lt;br /&gt;
What we want to find out is how the operations influence each other within a B model. In other words, for each pair (op1,op2) of operations we try to determine as precise as possible how op1 can affect the guard condition of op2 with regard to enabledness. To determine the enabling relations between operations we use syntactic analyses, as well as the constraint-based abilities of ProB.&lt;br /&gt;
&lt;br /&gt;
Consider the following B machine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE Example&lt;br /&gt;
VARIABLES x, y, z&lt;br /&gt;
INVARIANT&lt;br /&gt;
    x:NATURAL&lt;br /&gt;
  &amp;amp; y:INTEGER&lt;br /&gt;
  &amp;amp; z:INTEGER&lt;br /&gt;
INITIALISATION &lt;br /&gt;
  x:=6 || y:=-2 || z:=0&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Op1 = PRE x + y&amp;gt;=4  THEN x:=x+2 || y:=2 END;&lt;br /&gt;
  Op2 = PRE x mod 2=1 THEN x:=x+1 || y:=2 END;&lt;br /&gt;
  Op3 = PRE x mod 2=0 THEN x:=x+2 END;&lt;br /&gt;
  Op4 = PRE x&amp;lt;0 THEN y:=y-1 END;&lt;br /&gt;
  Op5 = PRE y/=2 THEN z:=3 END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The machine has three variables x,y,z, where x ranges over the domain of natural numbers and y and z over the domain of all integers. For this machine we have 25 pairs of operations for which we want to determine the respective enabling relations. Additionally, we identify 5 further pairs that show the influence of the INITIALISATION on the guard conditions of all other operations. Consider, for example, the pair (Op2,Op1) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op1 is enabled in each state of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; where the predicate ‘x+y&amp;gt;=4’ is fulfilled. Since the effect of Op2 assigns 2 to y and increments x by one upon condition that x is a positive odd number in the before-state of Op2, we can assume that Op1 is always enabled after the execution of Op2. In other words, in all after-states of Op2 the operation Op1 is guaranteed to be enabled. This relation between Op2 and Op1 we can illustrate as follows: &lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above the green boxes denote that the evaluation of the guard of Op1 is true, whereas the red boxes denote that the evaluation of the guard of Op1 is false. &lt;br /&gt;
&lt;br /&gt;
Another pair of interest is (Op2,Op5) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op5 is enabled only in those states in which y is not equal to 2. Obviously, in each after-state of Op2 y is equal to 2 and thus we can conclude that Op5 is impossible to be enabled after each execution of Op2. Such a relation between two operations we denote as ‘’impossible’’ and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
Both arrows in the illustration of the ‘’impossible’’ relation indicate that whether the guard condition of Op5 is fulfilled or not in a before-state of Op2 operation Op5 will be disabled in the respective after-state of Op2. In order to recognize a tuple (op1,op2) as ‘’impossible’’ we require that op2 is always disabled after op1 without further considering whether op2 is always enabled or always disabled in the before-states of op1. &lt;br /&gt;
&lt;br /&gt;
Consider, for instance, the pair (Op2, Op2) in the machine above. We can easily conclude that Op2 becomes disabled after it is executed and clearly, the second case (\false -&amp;gt; \false) of the impossible relation is not possible for (Op2, Op2). This gives rise of introducing another (more precise) impossible relation:&lt;br /&gt;
 &lt;br /&gt;
[[File:ImpossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Accordingly, we can derive another relation from ‘’impossible’’ for which only the second case of the ‘’impossible’’ relation is fulfilled:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
As an example for a pair of operations that fulfills the ‘’impossible_keep’’ requirement you can take, for example, the pair (Op3,Op2) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Since Op2 and Op3 cannot be both enabled in a state and the execution of Op3 cannot enable Op2, then we can easily conclude that Op2 remains always disabled after Op3.&lt;br /&gt;
&lt;br /&gt;
Similarly as for ‘’impossible’’, one could derive two further enabling relations from ‘’guaranteed’’:&lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedEnableKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Another interesting class of enabling relations that could be helpful for better understanding and analyzing B and Event-B models is that of the ‘’keep’’ relations. We say that an operation op1 ‘’keeps’’ another operation op2 if op1 cannot change the status of the enabling condition of op2, i.e. op1 keeps op2 enabled respectively disabled. This relationship could be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:KeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
We can take (Op1,Op2) and (Op1,Op3) as examples of pairs in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; that are elements of the keep relation. ‘’keep’’ relations can sometimes be easily determined by analyzing just the syntactic structure of both operations, or more precisely the “read” and “write” sets of both operations.&amp;lt;ref&amp;gt;For an operation op the set read(op) denotes the set of variables that are read by op. Accordingly, by write(op) we denote the set of variables that are written by op.&amp;lt;/ref&amp;gt; If, for example, an operation op1 does not write any variable of the machine that is read in the guard condition of op2, then we can infer that op1 ‘’keeps’’ op2. In that case we also say that op1 does not change op2 syntactically. In the class of the ‘’keep’’ relations are included also relations such as independence. Two operations op1 and op2 are called independent if each of them cannot disable the other operation and the both orders of execution &amp;lt;op1,op2&amp;gt; and &amp;lt;op2,op1&amp;gt; have the same effect.&amp;lt;ref&amp;gt;See the [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Order_Reduction Tutorial on Partial Order Reduction] for more information on independence between operations.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three classes (‘’guaranteed’’, ‘’impossible’’ and ‘’keep’’) of enabling relations presented so far represent definite relations. That is, if a pair of operations (op1,op2) is confirmed to be a relation of one of this three classes, then we can certainly say what effect on the enabling condition of op2 would the execution of op1 have. However, for some pairs of operations we cannot certainly say what effect an operation would have on the enabling condition of another operation. This is due to the fact that the enabling status of an operation does not only depend on the effect of the executed operations, but also on the current variables’ evaluation. Take, for instance, the tuple (Op3,Op1) from the B machine above. Considering the action part of Op3 and the guard condition of Op1 we can assume that Op3 can enable Op1. Since the guard of Op1 depends not only on the current value of x, but also on y, there could be transitions s -&amp;gt; s&#039; of Op3 in the state space of the machine where Op1 is disabled in both states ‘’s’’ and ‘’s’’’. Though, what we could definitely say is that Op3 cannot disable Op1. This relationship we can illustrate as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleEnableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
The opposite relation of “possible_enable” is the relation where an operation op2 can disable another operation op1. Formally, we say that op2 can disable op1 if op2 may disable op1 and op2 cannot enable op1. This relationship is denoted as “possible_disable” and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
In order to determine how operations influence each other we need to assure first that these are feasible. An operation ‘’op’’ is said to be feasible if there is a state of the machine that satisfies the invariant of the machine and in which ‘’op’’ is enabled. In the B machine above the operation Op4, for example, is not feasible. Obviously, Op4 is enabled only in states where x is a negative number and states in which x is a negative number are visibly not consistent with the invariant since &amp;quot;x : NATURAL&amp;quot;. Such incompatibilities are sometimes of great importance for the modeler and therefore they should be revealed in the process of computing the enabling relations. In our case for each pair of operations (Op4,-) and (-,Op4) the status “infeasible” will be returned.&lt;br /&gt;
&lt;br /&gt;
We can now list all possible enabling relations for the machine &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; by means of a table. For each entry in the table the operation in the row is the operation whose effect is studied on the status of the guard of the operation in the column.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingResults.png]]&lt;br /&gt;
&lt;br /&gt;
== Summary of the Enabling Relations ==&lt;br /&gt;
&lt;br /&gt;
In the following, we summarize most of the enabling relations that we think can provide a useful feedback to the user. For each of the enabling relations we have given an appropriate example. In the examples below we compute the effect of executing ‘op1’ on the status of the guard of ‘op2’. The relation identifiers are the same as they appear as results in ProB.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;guaranteed&#039;&#039;: op2 guaranteed to be executable after op1.&lt;br /&gt;
[[File: GuaranteedExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_enable&#039;&#039;: op2 is guaranteed to become enabled after op1.&lt;br /&gt;
[[File: GuaranteedEnableExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_keep&#039;&#039;: op2 is guaranteed to stay enabled after op1.&lt;br /&gt;
[[File: GuaranteedKeepExample.png]]&lt;br /&gt;
* &#039;&#039;impossible&#039;&#039;: op2 is impossible to be executed after op1.&lt;br /&gt;
[[File: ImpossibleExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_disable&#039;&#039;: op2 is guaranteed to become disabled after op1.&lt;br /&gt;
[[File: ImpossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_keep&#039;&#039;: op2 is impossible to become enabled after op1.&lt;br /&gt;
[[File: ImpossibleKeepExample.png]]&lt;br /&gt;
* &#039;&#039;keep&#039;&#039;: op2 always stays enabled resp. disabled after op1.&lt;br /&gt;
[[File: KeepExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_unchanged&#039;&#039;: op1 does not write any variable read in the guard of op2, i.e. write(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticUnchangedExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_independent&#039;&#039;: op1 and op2 are syntactically independent, i.e. read(op1) /\ write(op2) = {} &amp;amp; write(op1) /\ read(op2) = {} &amp;amp; write(op1) /\ write(op2) = {}&lt;br /&gt;
[[File: SyntacticIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;syntactically_fully_independent&#039;&#039;: op1 and op2 are syntactically independent and additionally, read(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticFullyIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;possible_enable&#039;&#039;: op2 possible after op1, but op2 cannot be disabled by op1.&lt;br /&gt;
[[File: PossibleEnableExample.png]]&lt;br /&gt;
* &#039;&#039;possible_disable&#039;&#039;: op2 possible after iop1, but op2 cannot be enabled by op1.&lt;br /&gt;
[[File: PossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;infeasible&#039;&#039;: op1 is not feasible and thus cannot influence op2.&lt;br /&gt;
[[File: InfeasibleExample.png]]&lt;br /&gt;
&lt;br /&gt;
== Performing Enabling Analysis within ProB  ==&lt;br /&gt;
&lt;br /&gt;
The enabling analysis has been implemented in the ProB toolset.  The computation of the enabling relations is based on syntactic and constraint-based techniques. The identification of relations such as ‘’syntactic_independent’’ and ‘’syntactic_unchanged’’ requires just a thorough study of the syntactic structure of the operations, i.e. no calls to the constraint solver have to be made. However, to confirm, for example, that an operation is guaranteed or impossible to be executed after another operation the use of the ProB’s constraint solver is unavoidable. For instance, consider the pair (Op2,Op1) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. As we have seen, in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; the operation Op1 is guaranteed to be enabled after each execution of Op2. In ProB this could be computed by feeding the (before-after) predicate “ (x mod 2 = 1) =&amp;gt; [x:=x+1 || y:=2] (x+y&amp;lt;4)” into the constraint solver. As a result, the constraint solver will not find a solution for the predicate, i.e. the constraint solver will not find a state ‘’s’’ satisfying “x mod 2 = 1” from which after executing Op2 at ‘’s’’ a solution state s’ will be found that fulfills “x+y&amp;lt;4”; note that “x+y&amp;lt;4” is the negation of the guard of Op1. Since there is no after-state of Op2 at which Op1 is disabled we can conclude that Op1 is guaranteed to be executed after Op2. When constraints are getting more complex the constraint solver may need more time for solving and determining the enabling relations may become a very time-expensive task. Therefore, a time-out for each constraint solver call is set. In other words, if the constraint solver does not find a solution in the given time by the user, then the respective relation will be denoted as time-outed. By default, in ProB the time-out for each constraint solver call is set to 300 ms.&lt;br /&gt;
&lt;br /&gt;
Within &amp;lt;tt&amp;gt;ProB Tcl/Tk&amp;lt;/tt&amp;gt; you can find the menu &amp;quot;Enabling Analysis&amp;quot; in the &amp;quot;Analysis&amp;quot; menu of the menu bar.  The &amp;quot;Enabling Analysis&amp;quot; menu provides multiple commands:&lt;br /&gt;
* &amp;quot;Enabling Analysis (Table)&amp;quot;: this command performs a (fast) enabling analysis on the respective B model using a time-out of 300 ms for the constraint-solver calls. The result of the enabling analysis is shown in a table. The table lists all enabling relations between the operations of the loaded B model. These can be exported to a CSV file. The table for &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; at the end of the &#039;&#039;&#039; Enabling Relations&#039;&#039;&#039; section was constructed this way.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Precise, Table)&amp;quot;: this command performs an enabling analysis using a time-out of 2800 ms for each of the constraint-solver calls. As for the command above, the result of the analysis is shown in a table that can be exported to a CSV file.&lt;br /&gt;
* &amp;quot;Enabling Relations After...&amp;quot;: this command computes all the enabling relations involving an operation chosen by the user.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Graph)&amp;quot;: this command performs the fast enabling analysis but displays the results as a graph. In case the preference &amp;quot;DOT_SHOW_OP_READ_WRITES&amp;quot; is set for each operation the read/write information is displayed.&lt;br /&gt;
* &amp;quot;Enabling Analysis (POR)...&amp;quot;: this menu provides further commands for another form of enabling analysis the results of which are used for the partial guard evaluation optimisation in ProB.&lt;br /&gt;
* &amp;quot;Read/Write Matrix (Table)&amp;quot;: this command performs syntactic analysis on the model. The analysis determines the read and write sets for each operation of the machine.&lt;br /&gt;
* &amp;quot;Dependence Analysis (Table)&amp;quot;: this command performs a dependency analysis for each pair of operations. More specifically, the analysis determines which operations are dependent or independent to each other.&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB (probcli) one can perform an enabling analysis on a B or Event-B model by means of the &amp;lt;tt&amp;gt;-enabling_analysis&amp;lt;/tt&amp;gt; option. The results of the analysis, as well as intermediate data and some statistics are printed out on the console:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli Example.mch -enabling_analysis&lt;br /&gt;
CHECKING ENABLING AFTER INITIALISATION&lt;br /&gt;
INITIALISATION ---&amp;gt; Op1  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op2  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op3  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op4  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op5  :: ok : guaranteed&lt;br /&gt;
.....&lt;br /&gt;
CHECKING ENABLING AFTER: Op5 r:[y] / w:[z]&lt;br /&gt;
Op5 ---&amp;gt; Op1  :: Enable=syntactic_independent&lt;br /&gt;
Op5 ---&amp;gt; Op2  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op3  :: Enable=syntactic_fully_independent&lt;br /&gt;
Op5 ---&amp;gt; Op4  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op5  :: Enable=syntactic_unchanged&lt;br /&gt;
% Finished CBC Enabling Analysis 810 ms walltime (770 ms runtime), since start: 1650 ms&lt;br /&gt;
% CBC Enabling Stats:&lt;br /&gt;
% Nr of events: 5&lt;br /&gt;
% Nr of cbc calls: 30, Timeout results: 2&lt;br /&gt;
Origin,Op1,Op2,Op3,Op4,Op5&lt;br /&gt;
INITIALISATION,guaranteed,impossible,guaranteed,impossible,guaranteed&lt;br /&gt;
Op1,timeout_possible_disable,keep,keep,impossible_keep,syntactic_independent&lt;br /&gt;
Op2,guaranteed,impossible,guaranteed,impossible_keep,impossible&lt;br /&gt;
Op3,timeout_possible,impossible_keep,guaranteed,impossible_keep,syntactic_fully_independent&lt;br /&gt;
Op4,impossible_keep,syntactic_unchanged,syntactic_unchanged,syntactic_keep,impossible_keep&lt;br /&gt;
Op5,syntactic_independent,syntactic_unchanged,syntactic_fully_independent,syntactic_unchanged,syntactic_unchanged&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To perform enabling analysis from the command line and save the results to a CSV-file use the following commando:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli file.mch -enabling_analysis_csv FILE &amp;lt;/pre&amp;gt;&lt;br /&gt;
where FILE is the name of the CSV-file in which the results of the analysis are stored.&lt;br /&gt;
&lt;br /&gt;
== References and Footnotes ==&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3487</id>
		<title>Tutorial Enabling Analysis</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3487"/>
		<updated>2016-02-12T15:59:14Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Summary of the Enabling Relations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The B-method and in particular its successor Event-B are methodologies for formal development and verification of systems. In Event-B, a machine is usually viewed as a reactive system executing continuously enabled (atomic) events in an interleaved fashion. Thus, parallel events of the system are easily modeled as an interleaving of operation executions. On the other hand, the introduction of abstract counters is required when events are supposed to be executed in some (sequential) order. This, however, can in some cases slow the work of understanding and verifying a model since identifying the sequential ordering of events in an Event-B model is not that obvious. Thus, using methods for determining the control flow can be sometimes very beneficial for understanding the model, as well as for techniques for automatic verification such as model checking.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we present a static analysis for B and Event-B that can be used to reveal the control flow of a machine and to optimize model checking of models written in B and Event-B (see also [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Guard_Evaluation Tutorial on Partial Guard Evaluation ]). The results of the analysis, designated also as ‘’enabling analysis’’, can be presented as relations by means of a table or by means of a graph. For simplicity, we will concentrate mainly on B and use the terminology of the formalism.&lt;br /&gt;
&lt;br /&gt;
== Enabling Relations ==&lt;br /&gt;
What we want to find out is how the operations influence each other within a B model. In other words, for each pair (op1,op2) of operations we try to determine as precise as possible how op1 can affect the guard condition of op2 with regard to enabledness. To determine the enabling relations between operations we use syntactic analyses, as well as the constraint-based abilities of ProB.&lt;br /&gt;
&lt;br /&gt;
Consider the following B machine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE Example&lt;br /&gt;
VARIABLES x, y, z&lt;br /&gt;
INVARIANT&lt;br /&gt;
    x:NATURAL&lt;br /&gt;
  &amp;amp; y:INTEGER&lt;br /&gt;
  &amp;amp; z:INTEGER&lt;br /&gt;
INITIALISATION &lt;br /&gt;
  x:=6 || y:=-2 || z:=0&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Op1 = PRE x + y&amp;gt;=4  THEN x:=x+2 || y:=2 END;&lt;br /&gt;
  Op2 = PRE x mod 2=1 THEN x:=x+1 || y:=2 END;&lt;br /&gt;
  Op3 = PRE x mod 2=0 THEN x:=x+2 END;&lt;br /&gt;
  Op4 = PRE x&amp;lt;0 THEN y:=y-1 END;&lt;br /&gt;
  Op5 = PRE y/=2 THEN z:=3 END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The machine has three variables x,y,z, where x ranges over the domain of natural numbers and y and z over the domain of all integers. For this machine we have 25 pairs of operations for which we want to determine the respective enabling relations. Additionally, we identify 5 further pairs that show the influence of the INITIALISATION on the guard conditions of all other operations. Consider, for example, the pair (Op2,Op1) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op1 is enabled in each state of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; where the predicate ‘x+y&amp;gt;=4’ is fulfilled. Since the effect of Op2 assigns 2 to y and increments x by one upon condition that x is a positive odd number in the before-state of Op2, we can assume that Op1 is always enabled after the execution of Op2. In other words, in all after-states of Op2 the operation Op1 is guaranteed to be enabled. This relation between Op2 and Op1 we can illustrate as follows: &lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above the green boxes denote that the evaluation of the guard of Op1 is true, whereas the red boxes denote that the evaluation of the guard of Op1 is false. &lt;br /&gt;
&lt;br /&gt;
Another pair of interest is (Op2,Op5) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op5 is enabled only in those states in which y is not equal to 2. Obviously, in each after-state of Op2 y is equal to 2 and thus we can conclude that Op5 is impossible to be enabled after each execution of Op2. Such a relation between two operations we denote as ‘’impossible’’ and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
Both arrows in the illustration of the ‘’impossible’’ relation indicate that whether the guard condition of Op5 is fulfilled or not in a before-state of Op2 operation Op5 will be disabled in the respective after-state of Op2. In order to recognize a tuple (op1,op2) as ‘’impossible’’ we require that op2 is always disabled after op1 without further considering whether op2 is always enabled or always disabled in the before-states of op1. &lt;br /&gt;
&lt;br /&gt;
Consider, for instance, the pair (Op2, Op2) in the machine above. We can easily conclude that Op2 becomes disabled after it is executed and clearly, the second case (\false -&amp;gt; \false) of the impossible relation is not possible for (Op2, Op2). This gives rise of introducing another (more precise) impossible relation:&lt;br /&gt;
 &lt;br /&gt;
[[File:ImpossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Accordingly, we can derive another relation from ‘’impossible’’ for which only the second case of the ‘’impossible’’ relation is fulfilled:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
As an example for a pair of operations that fulfills the ‘’impossible_keep’’ requirement you can take, for example, the pair (Op3,Op2) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Since Op2 and Op3 cannot be both enabled in a state and the execution of Op3 cannot enable Op2, then we can easily conclude that Op2 remains always disabled after Op3.&lt;br /&gt;
&lt;br /&gt;
Similarly as for ‘’impossible’’, one could derive two further enabling relations from ‘’guaranteed’’:&lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedEnableKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Another interesting class of enabling relations that could be helpful for better understanding and analyzing B and Event-B models is that of the ‘’keep’’ relations. We say that an operation op1 ‘’keeps’’ another operation op2 if op1 cannot change the status of the enabling condition of op2, i.e. op1 keeps op2 enabled respectively disabled. This relationship could be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:KeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
We can take (Op1,Op2) and (Op1,Op3) as examples of pairs in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; that are elements of the keep relation. ‘’keep’’ relations can sometimes be easily determined by analyzing just the syntactic structure of both operations, or more precisely the “read” and “write” sets of both operations.&amp;lt;ref&amp;gt;For an operation op the set read(op) denotes the set of variables that are read by op. Accordingly, by write(op) we denote the set of variables that are written by op.&amp;lt;/ref&amp;gt; If, for example, an operation op1 does not write any variable of the machine that is read in the guard condition of op2, then we can infer that op1 ‘’keeps’’ op2. In that case we also say that op1 does not change op2 syntactically. In the class of the ‘’keep’’ relations are included also relations such as independence. Two operations op1 and op2 are called independent if each of them cannot disable the other operation and the both orders of execution &amp;lt;op1,op2&amp;gt; and &amp;lt;op2,op1&amp;gt; have the same effect.&amp;lt;ref&amp;gt;See the [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Order_Reduction Tutorial on Partial Order Reduction] for more information on independence between operations.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three classes (‘’guaranteed’’, ‘’impossible’’ and ‘’keep’’) of enabling relations presented so far represent definite relations. That is, if a pair of operations (op1,op2) is confirmed to be a relation of one of this three classes, then we can certainly say what effect on the enabling condition of op2 would the execution of op1 have. However, for some pairs of operations we cannot certainly say what effect an operation would have on the enabling condition of another operation. This is due to the fact that the enabling status of an operation does not only depend on the effect of the executed operations, but also on the current variables’ evaluation. Take, for instance, the tuple (Op3,Op1) from the B machine above. Considering the action part of Op3 and the guard condition of Op1 we can assume that Op3 can enable Op1. Since the guard of Op1 depends not only on the current value of x, but also on y, there could be transitions s&amp;lt;math&amp;gt;\overset{Op_3}{\rightarrow}&amp;lt;/math&amp;gt;s&#039; in the state space of the machine where Op1 is disabled in both states ‘’s’’ and ‘’s’’’. Though, what we could definitely say is that Op3 cannot disable Op1. This relationship we can illustrate as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleEnableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
The opposite relation of “possible_enable” is the relation where an operation op2 can disable another operation op1. Formally, we say that op2 can disable op1 if op2 may disable op1 and op2 cannot enable op1. This relationship is denoted as “possible_disable” and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
In order to determine how operations influence each other we need to assure first that these are feasible. An operation ‘’op’’ is said to be feasible if there is a state of the machine that satisfies the invariant of the machine and in which ‘’op’’ is enabled. In the B machine above the operation Op4, for example, is not feasible. Obviously, Op4 is enabled only in states where x is a negative number and states in which x is a negative number are visibly not consistent with the invariant since &amp;quot;x : NATURAL&amp;quot;. Such incompatibilities are sometimes of great importance for the modeler and therefore they should be revealed in the process of computing the enabling relations. In our case for each pair of operations (Op4,-) and (-,Op4) the status “infeasible” will be returned.&lt;br /&gt;
&lt;br /&gt;
We can now list all possible enabling relations for the machine &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; by means of a table. For each entry in the table the operation in the row is the operation whose effect is studied on the status of the guard of the operation in the column.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingResults.png]]&lt;br /&gt;
&lt;br /&gt;
== Summary of the Enabling Relations ==&lt;br /&gt;
&lt;br /&gt;
In the following, we summarize most of the enabling relations that we think can provide a useful feedback to the user. For each of the enabling relations we have given an appropriate example. In the examples below we compute the effect of executing ‘op1’ on the status of the guard of ‘op2’. The relation identifiers are the same as they appear as results in ProB.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;guaranteed&#039;&#039;: op2 guaranteed to be executable after op1.&lt;br /&gt;
[[File: GuaranteedExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_enable&#039;&#039;: op2 is guaranteed to become enabled after op1.&lt;br /&gt;
[[File: GuaranteedEnableExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_keep&#039;&#039;: op2 is guaranteed to stay enabled after op1.&lt;br /&gt;
[[File: GuaranteedKeepExample.png]]&lt;br /&gt;
* &#039;&#039;impossible&#039;&#039;: op2 is impossible to be executed after op1.&lt;br /&gt;
[[File: ImpossibleExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_disable&#039;&#039;: op2 is guaranteed to become disabled after op1.&lt;br /&gt;
[[File: ImpossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_keep&#039;&#039;: op2 is impossible to become enabled after op1.&lt;br /&gt;
[[File: ImpossibleKeepExample.png]]&lt;br /&gt;
* &#039;&#039;keep&#039;&#039;: op2 always stays enabled resp. disabled after op1.&lt;br /&gt;
[[File: KeepExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_unchanged&#039;&#039;: op1 does not write any variable read in the guard of op2, i.e. write(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticUnchangedExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_independent&#039;&#039;: op1 and op2 are syntactically independent, i.e. read(op1) /\ write(op2) = {} &amp;amp; write(op1) /\ read(op2) = {} &amp;amp; write(op1) /\ write(op2) = {}&lt;br /&gt;
[[File: SyntacticIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;syntactically_fully_independent&#039;&#039;: op1 and op2 are syntactically independent and additionally, read(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticFullyIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;possible_enable&#039;&#039;: op2 possible after op1, but op2 cannot be disabled by op1.&lt;br /&gt;
[[File: PossibleEnableExample.png]]&lt;br /&gt;
* &#039;&#039;possible_disable&#039;&#039;: op2 possible after iop1, but op2 cannot be enabled by op1.&lt;br /&gt;
[[File: PossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;infeasible&#039;&#039;: op1 is not feasible and thus cannot influence op2.&lt;br /&gt;
[[File: InfeasibleExample.png]]&lt;br /&gt;
&lt;br /&gt;
== Performing Enabling Analysis within ProB  ==&lt;br /&gt;
&lt;br /&gt;
The enabling analysis has been implemented in the ProB toolset.  The computation of the enabling relations is based on syntactic and constraint-based techniques. The identification of relations such as ‘’syntactic_independent’’ and ‘’syntactic_unchanged’’ requires just a thorough study of the syntactic structure of the operations, i.e. no calls to the constraint solver have to be made. However, to confirm, for example, that an operation is guaranteed or impossible to be executed after another operation the use of the ProB’s constraint solver is unavoidable. For instance, consider the pair (Op2,Op1) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. As we have seen, in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; the operation Op1 is guaranteed to be enabled after each execution of Op2. In ProB this could be computed by feeding the (before-after) predicate “ (x mod 2 = 1) =&amp;gt; [x:=x+1 || y:=2] (x+y&amp;lt;4)” into the constraint solver. As a result, the constraint solver will not find a solution for the predicate, i.e. the constraint solver will not find a state ‘’s’’ satisfying “x mod 2 = 1” from which after executing Op2 at ‘’s’’ a solution state s’ will be found that fulfills “x+y&amp;lt;4”; note that “x+y&amp;lt;4” is the negation of the guard of Op1. Since there is no after-state of Op2 at which Op1 is disabled we can conclude that Op1 is guaranteed to be executed after Op2. When constraints are getting more complex the constraint solver may need more time for solving and determining the enabling relations may become a very time-expensive task. Therefore, a time-out for each constraint solver call is set. In other words, if the constraint solver does not find a solution in the given time by the user, then the respective relation will be denoted as time-outed. By default, in ProB the time-out for each constraint solver call is set to 300 ms.&lt;br /&gt;
&lt;br /&gt;
Within &amp;lt;tt&amp;gt;ProB Tcl/Tk&amp;lt;/tt&amp;gt; you can find the menu &amp;quot;Enabling Analysis&amp;quot; in the &amp;quot;Analysis&amp;quot; menu of the menu bar.  The &amp;quot;Enabling Analysis&amp;quot; menu provides multiple commands:&lt;br /&gt;
* &amp;quot;Enabling Analysis (Table)&amp;quot;: this command performs a (fast) enabling analysis on the respective B model using a time-out of 300 ms for the constraint-solver calls. The result of the enabling analysis is shown in a table. The table lists all enabling relations between the operations of the loaded B model. These can be exported to a CSV file. The table for &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; at the end of the &#039;&#039;&#039; Enabling Relations&#039;&#039;&#039; section was constructed this way.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Precise, Table)&amp;quot;: this command performs an enabling analysis using a time-out of 2800 ms for each of the constraint-solver calls. As for the command above, the result of the analysis is shown in a table that can be exported to a CSV file.&lt;br /&gt;
* &amp;quot;Enabling Relations After...&amp;quot;: this command computes all the enabling relations involving an operation chosen by the user.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Graph)&amp;quot;: this command performs the fast enabling analysis but displays the results as a graph. In case the preference &amp;quot;DOT_SHOW_OP_READ_WRITES&amp;quot; is set for each operation the read/write information is displayed.&lt;br /&gt;
* &amp;quot;Enabling Analysis (POR)...&amp;quot;: this menu provides further commands for another form of enabling analysis the results of which are used for the partial guard evaluation optimisation in ProB.&lt;br /&gt;
* &amp;quot;Read/Write Matrix (Table)&amp;quot;: this command performs syntactic analysis on the model. The analysis determines the read and write sets for each operation of the machine.&lt;br /&gt;
* &amp;quot;Dependence Analysis (Table)&amp;quot;: this command performs a dependency analysis for each pair of operations. More specifically, the analysis determines which operations are dependent or independent to each other.&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB (probcli) one can perform an enabling analysis on a B or Event-B model by means of the &amp;lt;tt&amp;gt;-enabling_analysis&amp;lt;/tt&amp;gt; option. The results of the analysis, as well as intermediate data and some statistics are printed out on the console:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli Example.mch -enabling_analysis&lt;br /&gt;
CHECKING ENABLING AFTER INITIALISATION&lt;br /&gt;
INITIALISATION ---&amp;gt; Op1  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op2  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op3  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op4  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op5  :: ok : guaranteed&lt;br /&gt;
.....&lt;br /&gt;
CHECKING ENABLING AFTER: Op5 r:[y] / w:[z]&lt;br /&gt;
Op5 ---&amp;gt; Op1  :: Enable=syntactic_independent&lt;br /&gt;
Op5 ---&amp;gt; Op2  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op3  :: Enable=syntactic_fully_independent&lt;br /&gt;
Op5 ---&amp;gt; Op4  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op5  :: Enable=syntactic_unchanged&lt;br /&gt;
% Finished CBC Enabling Analysis 810 ms walltime (770 ms runtime), since start: 1650 ms&lt;br /&gt;
% CBC Enabling Stats:&lt;br /&gt;
% Nr of events: 5&lt;br /&gt;
% Nr of cbc calls: 30, Timeout results: 2&lt;br /&gt;
Origin,Op1,Op2,Op3,Op4,Op5&lt;br /&gt;
INITIALISATION,guaranteed,impossible,guaranteed,impossible,guaranteed&lt;br /&gt;
Op1,timeout_possible_disable,keep,keep,impossible_keep,syntactic_independent&lt;br /&gt;
Op2,guaranteed,impossible,guaranteed,impossible_keep,impossible&lt;br /&gt;
Op3,timeout_possible,impossible_keep,guaranteed,impossible_keep,syntactic_fully_independent&lt;br /&gt;
Op4,impossible_keep,syntactic_unchanged,syntactic_unchanged,syntactic_keep,impossible_keep&lt;br /&gt;
Op5,syntactic_independent,syntactic_unchanged,syntactic_fully_independent,syntactic_unchanged,syntactic_unchanged&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To perform enabling analysis from the command line and save the results to a CSV-file use the following commando:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli file.mch -enabling_analysis_csv FILE &amp;lt;/pre&amp;gt;&lt;br /&gt;
where FILE is the name of the CSV-file in which the results of the analysis are stored.&lt;br /&gt;
&lt;br /&gt;
== References and Footnotes ==&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3486</id>
		<title>Tutorial Enabling Analysis</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3486"/>
		<updated>2016-02-12T15:55:47Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Performing Enabling Analysis within ProB */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The B-method and in particular its successor Event-B are methodologies for formal development and verification of systems. In Event-B, a machine is usually viewed as a reactive system executing continuously enabled (atomic) events in an interleaved fashion. Thus, parallel events of the system are easily modeled as an interleaving of operation executions. On the other hand, the introduction of abstract counters is required when events are supposed to be executed in some (sequential) order. This, however, can in some cases slow the work of understanding and verifying a model since identifying the sequential ordering of events in an Event-B model is not that obvious. Thus, using methods for determining the control flow can be sometimes very beneficial for understanding the model, as well as for techniques for automatic verification such as model checking.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we present a static analysis for B and Event-B that can be used to reveal the control flow of a machine and to optimize model checking of models written in B and Event-B (see also [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Guard_Evaluation Tutorial on Partial Guard Evaluation ]). The results of the analysis, designated also as ‘’enabling analysis’’, can be presented as relations by means of a table or by means of a graph. For simplicity, we will concentrate mainly on B and use the terminology of the formalism.&lt;br /&gt;
&lt;br /&gt;
== Enabling Relations ==&lt;br /&gt;
What we want to find out is how the operations influence each other within a B model. In other words, for each pair (op1,op2) of operations we try to determine as precise as possible how op1 can affect the guard condition of op2 with regard to enabledness. To determine the enabling relations between operations we use syntactic analyses, as well as the constraint-based abilities of ProB.&lt;br /&gt;
&lt;br /&gt;
Consider the following B machine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE Example&lt;br /&gt;
VARIABLES x, y, z&lt;br /&gt;
INVARIANT&lt;br /&gt;
    x:NATURAL&lt;br /&gt;
  &amp;amp; y:INTEGER&lt;br /&gt;
  &amp;amp; z:INTEGER&lt;br /&gt;
INITIALISATION &lt;br /&gt;
  x:=6 || y:=-2 || z:=0&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Op1 = PRE x + y&amp;gt;=4  THEN x:=x+2 || y:=2 END;&lt;br /&gt;
  Op2 = PRE x mod 2=1 THEN x:=x+1 || y:=2 END;&lt;br /&gt;
  Op3 = PRE x mod 2=0 THEN x:=x+2 END;&lt;br /&gt;
  Op4 = PRE x&amp;lt;0 THEN y:=y-1 END;&lt;br /&gt;
  Op5 = PRE y/=2 THEN z:=3 END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The machine has three variables x,y,z, where x ranges over the domain of natural numbers and y and z over the domain of all integers. For this machine we have 25 pairs of operations for which we want to determine the respective enabling relations. Additionally, we identify 5 further pairs that show the influence of the INITIALISATION on the guard conditions of all other operations. Consider, for example, the pair (Op2,Op1) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op1 is enabled in each state of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; where the predicate ‘x+y&amp;gt;=4’ is fulfilled. Since the effect of Op2 assigns 2 to y and increments x by one upon condition that x is a positive odd number in the before-state of Op2, we can assume that Op1 is always enabled after the execution of Op2. In other words, in all after-states of Op2 the operation Op1 is guaranteed to be enabled. This relation between Op2 and Op1 we can illustrate as follows: &lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above the green boxes denote that the evaluation of the guard of Op1 is true, whereas the red boxes denote that the evaluation of the guard of Op1 is false. &lt;br /&gt;
&lt;br /&gt;
Another pair of interest is (Op2,Op5) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op5 is enabled only in those states in which y is not equal to 2. Obviously, in each after-state of Op2 y is equal to 2 and thus we can conclude that Op5 is impossible to be enabled after each execution of Op2. Such a relation between two operations we denote as ‘’impossible’’ and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
Both arrows in the illustration of the ‘’impossible’’ relation indicate that whether the guard condition of Op5 is fulfilled or not in a before-state of Op2 operation Op5 will be disabled in the respective after-state of Op2. In order to recognize a tuple (op1,op2) as ‘’impossible’’ we require that op2 is always disabled after op1 without further considering whether op2 is always enabled or always disabled in the before-states of op1. &lt;br /&gt;
&lt;br /&gt;
Consider, for instance, the pair (Op2, Op2) in the machine above. We can easily conclude that Op2 becomes disabled after it is executed and clearly, the second case (\false -&amp;gt; \false) of the impossible relation is not possible for (Op2, Op2). This gives rise of introducing another (more precise) impossible relation:&lt;br /&gt;
 &lt;br /&gt;
[[File:ImpossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Accordingly, we can derive another relation from ‘’impossible’’ for which only the second case of the ‘’impossible’’ relation is fulfilled:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
As an example for a pair of operations that fulfills the ‘’impossible_keep’’ requirement you can take, for example, the pair (Op3,Op2) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Since Op2 and Op3 cannot be both enabled in a state and the execution of Op3 cannot enable Op2, then we can easily conclude that Op2 remains always disabled after Op3.&lt;br /&gt;
&lt;br /&gt;
Similarly as for ‘’impossible’’, one could derive two further enabling relations from ‘’guaranteed’’:&lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedEnableKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Another interesting class of enabling relations that could be helpful for better understanding and analyzing B and Event-B models is that of the ‘’keep’’ relations. We say that an operation op1 ‘’keeps’’ another operation op2 if op1 cannot change the status of the enabling condition of op2, i.e. op1 keeps op2 enabled respectively disabled. This relationship could be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:KeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
We can take (Op1,Op2) and (Op1,Op3) as examples of pairs in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; that are elements of the keep relation. ‘’keep’’ relations can sometimes be easily determined by analyzing just the syntactic structure of both operations, or more precisely the “read” and “write” sets of both operations.&amp;lt;ref&amp;gt;For an operation op the set read(op) denotes the set of variables that are read by op. Accordingly, by write(op) we denote the set of variables that are written by op.&amp;lt;/ref&amp;gt; If, for example, an operation op1 does not write any variable of the machine that is read in the guard condition of op2, then we can infer that op1 ‘’keeps’’ op2. In that case we also say that op1 does not change op2 syntactically. In the class of the ‘’keep’’ relations are included also relations such as independence. Two operations op1 and op2 are called independent if each of them cannot disable the other operation and the both orders of execution &amp;lt;op1,op2&amp;gt; and &amp;lt;op2,op1&amp;gt; have the same effect.&amp;lt;ref&amp;gt;See the [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Order_Reduction Tutorial on Partial Order Reduction] for more information on independence between operations.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three classes (‘’guaranteed’’, ‘’impossible’’ and ‘’keep’’) of enabling relations presented so far represent definite relations. That is, if a pair of operations (op1,op2) is confirmed to be a relation of one of this three classes, then we can certainly say what effect on the enabling condition of op2 would the execution of op1 have. However, for some pairs of operations we cannot certainly say what effect an operation would have on the enabling condition of another operation. This is due to the fact that the enabling status of an operation does not only depend on the effect of the executed operations, but also on the current variables’ evaluation. Take, for instance, the tuple (Op3,Op1) from the B machine above. Considering the action part of Op3 and the guard condition of Op1 we can assume that Op3 can enable Op1. Since the guard of Op1 depends not only on the current value of x, but also on y, there could be transitions s&amp;lt;math&amp;gt;\overset{Op_3}{\rightarrow}&amp;lt;/math&amp;gt;s&#039; in the state space of the machine where Op1 is disabled in both states ‘’s’’ and ‘’s’’’. Though, what we could definitely say is that Op3 cannot disable Op1. This relationship we can illustrate as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleEnableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
The opposite relation of “possible_enable” is the relation where an operation op2 can disable another operation op1. Formally, we say that op2 can disable op1 if op2 may disable op1 and op2 cannot enable op1. This relationship is denoted as “possible_disable” and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
In order to determine how operations influence each other we need to assure first that these are feasible. An operation ‘’op’’ is said to be feasible if there is a state of the machine that satisfies the invariant of the machine and in which ‘’op’’ is enabled. In the B machine above the operation Op4, for example, is not feasible. Obviously, Op4 is enabled only in states where x is a negative number and states in which x is a negative number are visibly not consistent with the invariant since &amp;quot;x : NATURAL&amp;quot;. Such incompatibilities are sometimes of great importance for the modeler and therefore they should be revealed in the process of computing the enabling relations. In our case for each pair of operations (Op4,-) and (-,Op4) the status “infeasible” will be returned.&lt;br /&gt;
&lt;br /&gt;
We can now list all possible enabling relations for the machine &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; by means of a table. For each entry in the table the operation in the row is the operation whose effect is studied on the status of the guard of the operation in the column.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingResults.png]]&lt;br /&gt;
&lt;br /&gt;
== Summary of the Enabling Relations ==&lt;br /&gt;
&lt;br /&gt;
In the following, we summarize most of the enabling relations that we could identify. For each of the enabling relations we have given an appropriate example. In the examples below we compute the effect of executing ‘op1’ on the status of the guard of ‘op2’. The relation identifiers are the same as they appear as results in ProB.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;guaranteed&#039;&#039;: op2 guaranteed to be executable after op1.&lt;br /&gt;
[[File: GuaranteedExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_enable&#039;&#039;: op2 is guaranteed to become enabled after op1.&lt;br /&gt;
[[File: GuaranteedEnableExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_keep&#039;&#039;: op2 is guaranteed to stay enabled after op1.&lt;br /&gt;
[[File: GuaranteedKeepExample.png]]&lt;br /&gt;
* &#039;&#039;impossible&#039;&#039;: op2 is impossible to be executed after op1.&lt;br /&gt;
[[File: ImpossibleExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_disable&#039;&#039;: op2 is guaranteed to become disabled after op1.&lt;br /&gt;
[[File: ImpossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_keep&#039;&#039;: op2 is impossible to become enabled after op1.&lt;br /&gt;
[[File: ImpossibleKeepExample.png]]&lt;br /&gt;
* &#039;&#039;keep&#039;&#039;: op2 always stays enabled resp. disabled after op1.&lt;br /&gt;
[[File: KeepExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_unchanged&#039;&#039;: op1 does not write any variable read in the guard of op2, i.e. write(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticUnchangedExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_independent&#039;&#039;: op1 and op2 are syntactically independent, i.e. read(op1) /\ write(op2) = {} &amp;amp; write(op1) /\ read(op2) = {} &amp;amp; write(op1) /\ write(op2) = {}&lt;br /&gt;
[[File: SyntacticIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;syntactically_fully_independent&#039;&#039;: op1 and op2 are syntactically independent and additionally, read(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticFullyIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;possible_enable&#039;&#039;: op2 possible after op1, but op2 cannot be disabled by op1.&lt;br /&gt;
[[File: PossibleEnableExample.png]]&lt;br /&gt;
* &#039;&#039;possible_disable&#039;&#039;: op2 possible after iop1, but op2 cannot be enabled by op1.&lt;br /&gt;
[[File: PossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;infeasible&#039;&#039;: op1 is not feasible and thus cannot influence op2.&lt;br /&gt;
[[File: InfeasibleExample.png]]&lt;br /&gt;
&lt;br /&gt;
== Performing Enabling Analysis within ProB  ==&lt;br /&gt;
&lt;br /&gt;
The enabling analysis has been implemented in the ProB toolset.  The computation of the enabling relations is based on syntactic and constraint-based techniques. The identification of relations such as ‘’syntactic_independent’’ and ‘’syntactic_unchanged’’ requires just a thorough study of the syntactic structure of the operations, i.e. no calls to the constraint solver have to be made. However, to confirm, for example, that an operation is guaranteed or impossible to be executed after another operation the use of the ProB’s constraint solver is unavoidable. For instance, consider the pair (Op2,Op1) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. As we have seen, in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; the operation Op1 is guaranteed to be enabled after each execution of Op2. In ProB this could be computed by feeding the (before-after) predicate “ (x mod 2 = 1) =&amp;gt; [x:=x+1 || y:=2] (x+y&amp;lt;4)” into the constraint solver. As a result, the constraint solver will not find a solution for the predicate, i.e. the constraint solver will not find a state ‘’s’’ satisfying “x mod 2 = 1” from which after executing Op2 at ‘’s’’ a solution state s’ will be found that fulfills “x+y&amp;lt;4”; note that “x+y&amp;lt;4” is the negation of the guard of Op1. Since there is no after-state of Op2 at which Op1 is disabled we can conclude that Op1 is guaranteed to be executed after Op2. When constraints are getting more complex the constraint solver may need more time for solving and determining the enabling relations may become a very time-expensive task. Therefore, a time-out for each constraint solver call is set. In other words, if the constraint solver does not find a solution in the given time by the user, then the respective relation will be denoted as time-outed. By default, in ProB the time-out for each constraint solver call is set to 300 ms.&lt;br /&gt;
&lt;br /&gt;
Within &amp;lt;tt&amp;gt;ProB Tcl/Tk&amp;lt;/tt&amp;gt; you can find the menu &amp;quot;Enabling Analysis&amp;quot; in the &amp;quot;Analysis&amp;quot; menu of the menu bar.  The &amp;quot;Enabling Analysis&amp;quot; menu provides multiple commands:&lt;br /&gt;
* &amp;quot;Enabling Analysis (Table)&amp;quot;: this command performs a (fast) enabling analysis on the respective B model using a time-out of 300 ms for the constraint-solver calls. The result of the enabling analysis is shown in a table. The table lists all enabling relations between the operations of the loaded B model. These can be exported to a CSV file. The table for &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; at the end of the &#039;&#039;&#039; Enabling Relations&#039;&#039;&#039; section was constructed this way.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Precise, Table)&amp;quot;: this command performs an enabling analysis using a time-out of 2800 ms for each of the constraint-solver calls. As for the command above, the result of the analysis is shown in a table that can be exported to a CSV file.&lt;br /&gt;
* &amp;quot;Enabling Relations After...&amp;quot;: this command computes all the enabling relations involving an operation chosen by the user.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Graph)&amp;quot;: this command performs the fast enabling analysis but displays the results as a graph. In case the preference &amp;quot;DOT_SHOW_OP_READ_WRITES&amp;quot; is set for each operation the read/write information is displayed.&lt;br /&gt;
* &amp;quot;Enabling Analysis (POR)...&amp;quot;: this menu provides further commands for another form of enabling analysis the results of which are used for the partial guard evaluation optimisation in ProB.&lt;br /&gt;
* &amp;quot;Read/Write Matrix (Table)&amp;quot;: this command performs syntactic analysis on the model. The analysis determines the read and write sets for each operation of the machine.&lt;br /&gt;
* &amp;quot;Dependence Analysis (Table)&amp;quot;: this command performs a dependency analysis for each pair of operations. More specifically, the analysis determines which operations are dependent or independent to each other.&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB (probcli) one can perform an enabling analysis on a B or Event-B model by means of the &amp;lt;tt&amp;gt;-enabling_analysis&amp;lt;/tt&amp;gt; option. The results of the analysis, as well as intermediate data and some statistics are printed out on the console:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli Example.mch -enabling_analysis&lt;br /&gt;
CHECKING ENABLING AFTER INITIALISATION&lt;br /&gt;
INITIALISATION ---&amp;gt; Op1  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op2  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op3  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op4  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op5  :: ok : guaranteed&lt;br /&gt;
.....&lt;br /&gt;
CHECKING ENABLING AFTER: Op5 r:[y] / w:[z]&lt;br /&gt;
Op5 ---&amp;gt; Op1  :: Enable=syntactic_independent&lt;br /&gt;
Op5 ---&amp;gt; Op2  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op3  :: Enable=syntactic_fully_independent&lt;br /&gt;
Op5 ---&amp;gt; Op4  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op5  :: Enable=syntactic_unchanged&lt;br /&gt;
% Finished CBC Enabling Analysis 810 ms walltime (770 ms runtime), since start: 1650 ms&lt;br /&gt;
% CBC Enabling Stats:&lt;br /&gt;
% Nr of events: 5&lt;br /&gt;
% Nr of cbc calls: 30, Timeout results: 2&lt;br /&gt;
Origin,Op1,Op2,Op3,Op4,Op5&lt;br /&gt;
INITIALISATION,guaranteed,impossible,guaranteed,impossible,guaranteed&lt;br /&gt;
Op1,timeout_possible_disable,keep,keep,impossible_keep,syntactic_independent&lt;br /&gt;
Op2,guaranteed,impossible,guaranteed,impossible_keep,impossible&lt;br /&gt;
Op3,timeout_possible,impossible_keep,guaranteed,impossible_keep,syntactic_fully_independent&lt;br /&gt;
Op4,impossible_keep,syntactic_unchanged,syntactic_unchanged,syntactic_keep,impossible_keep&lt;br /&gt;
Op5,syntactic_independent,syntactic_unchanged,syntactic_fully_independent,syntactic_unchanged,syntactic_unchanged&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To perform enabling analysis from the command line and save the results to a CSV-file use the following commando:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli file.mch -enabling_analysis_csv FILE &amp;lt;/pre&amp;gt;&lt;br /&gt;
where FILE is the name of the CSV-file in which the results of the analysis are stored.&lt;br /&gt;
&lt;br /&gt;
== References and Footnotes ==&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3485</id>
		<title>Tutorial Enabling Analysis</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3485"/>
		<updated>2016-02-12T13:38:56Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Performing Enabling Analysis within ProB */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The B-method and in particular its successor Event-B are methodologies for formal development and verification of systems. In Event-B, a machine is usually viewed as a reactive system executing continuously enabled (atomic) events in an interleaved fashion. Thus, parallel events of the system are easily modeled as an interleaving of operation executions. On the other hand, the introduction of abstract counters is required when events are supposed to be executed in some (sequential) order. This, however, can in some cases slow the work of understanding and verifying a model since identifying the sequential ordering of events in an Event-B model is not that obvious. Thus, using methods for determining the control flow can be sometimes very beneficial for understanding the model, as well as for techniques for automatic verification such as model checking.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we present a static analysis for B and Event-B that can be used to reveal the control flow of a machine and to optimize model checking of models written in B and Event-B (see also [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Guard_Evaluation Tutorial on Partial Guard Evaluation ]). The results of the analysis, designated also as ‘’enabling analysis’’, can be presented as relations by means of a table or by means of a graph. For simplicity, we will concentrate mainly on B and use the terminology of the formalism.&lt;br /&gt;
&lt;br /&gt;
== Enabling Relations ==&lt;br /&gt;
What we want to find out is how the operations influence each other within a B model. In other words, for each pair (op1,op2) of operations we try to determine as precise as possible how op1 can affect the guard condition of op2 with regard to enabledness. To determine the enabling relations between operations we use syntactic analyses, as well as the constraint-based abilities of ProB.&lt;br /&gt;
&lt;br /&gt;
Consider the following B machine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE Example&lt;br /&gt;
VARIABLES x, y, z&lt;br /&gt;
INVARIANT&lt;br /&gt;
    x:NATURAL&lt;br /&gt;
  &amp;amp; y:INTEGER&lt;br /&gt;
  &amp;amp; z:INTEGER&lt;br /&gt;
INITIALISATION &lt;br /&gt;
  x:=6 || y:=-2 || z:=0&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Op1 = PRE x + y&amp;gt;=4  THEN x:=x+2 || y:=2 END;&lt;br /&gt;
  Op2 = PRE x mod 2=1 THEN x:=x+1 || y:=2 END;&lt;br /&gt;
  Op3 = PRE x mod 2=0 THEN x:=x+2 END;&lt;br /&gt;
  Op4 = PRE x&amp;lt;0 THEN y:=y-1 END;&lt;br /&gt;
  Op5 = PRE y/=2 THEN z:=3 END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The machine has three variables x,y,z, where x ranges over the domain of natural numbers and y and z over the domain of all integers. For this machine we have 25 pairs of operations for which we want to determine the respective enabling relations. Additionally, we identify 5 further pairs that show the influence of the INITIALISATION on the guard conditions of all other operations. Consider, for example, the pair (Op2,Op1) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op1 is enabled in each state of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; where the predicate ‘x+y&amp;gt;=4’ is fulfilled. Since the effect of Op2 assigns 2 to y and increments x by one upon condition that x is a positive odd number in the before-state of Op2, we can assume that Op1 is always enabled after the execution of Op2. In other words, in all after-states of Op2 the operation Op1 is guaranteed to be enabled. This relation between Op2 and Op1 we can illustrate as follows: &lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above the green boxes denote that the evaluation of the guard of Op1 is true, whereas the red boxes denote that the evaluation of the guard of Op1 is false. &lt;br /&gt;
&lt;br /&gt;
Another pair of interest is (Op2,Op5) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op5 is enabled only in those states in which y is not equal to 2. Obviously, in each after-state of Op2 y is equal to 2 and thus we can conclude that Op5 is impossible to be enabled after each execution of Op2. Such a relation between two operations we denote as ‘’impossible’’ and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
Both arrows in the illustration of the ‘’impossible’’ relation indicate that whether the guard condition of Op5 is fulfilled or not in a before-state of Op2 operation Op5 will be disabled in the respective after-state of Op2. In order to recognize a tuple (op1,op2) as ‘’impossible’’ we require that op2 is always disabled after op1 without further considering whether op2 is always enabled or always disabled in the before-states of op1. &lt;br /&gt;
&lt;br /&gt;
Consider, for instance, the pair (Op2, Op2) in the machine above. We can easily conclude that Op2 becomes disabled after it is executed and clearly, the second case (\false -&amp;gt; \false) of the impossible relation is not possible for (Op2, Op2). This gives rise of introducing another (more precise) impossible relation:&lt;br /&gt;
 &lt;br /&gt;
[[File:ImpossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Accordingly, we can derive another relation from ‘’impossible’’ for which only the second case of the ‘’impossible’’ relation is fulfilled:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
As an example for a pair of operations that fulfills the ‘’impossible_keep’’ requirement you can take, for example, the pair (Op3,Op2) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Since Op2 and Op3 cannot be both enabled in a state and the execution of Op3 cannot enable Op2, then we can easily conclude that Op2 remains always disabled after Op3.&lt;br /&gt;
&lt;br /&gt;
Similarly as for ‘’impossible’’, one could derive two further enabling relations from ‘’guaranteed’’:&lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedEnableKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Another interesting class of enabling relations that could be helpful for better understanding and analyzing B and Event-B models is that of the ‘’keep’’ relations. We say that an operation op1 ‘’keeps’’ another operation op2 if op1 cannot change the status of the enabling condition of op2, i.e. op1 keeps op2 enabled respectively disabled. This relationship could be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:KeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
We can take (Op1,Op2) and (Op1,Op3) as examples of pairs in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; that are elements of the keep relation. ‘’keep’’ relations can sometimes be easily determined by analyzing just the syntactic structure of both operations, or more precisely the “read” and “write” sets of both operations.&amp;lt;ref&amp;gt;For an operation op the set read(op) denotes the set of variables that are read by op. Accordingly, by write(op) we denote the set of variables that are written by op.&amp;lt;/ref&amp;gt; If, for example, an operation op1 does not write any variable of the machine that is read in the guard condition of op2, then we can infer that op1 ‘’keeps’’ op2. In that case we also say that op1 does not change op2 syntactically. In the class of the ‘’keep’’ relations are included also relations such as independence. Two operations op1 and op2 are called independent if each of them cannot disable the other operation and the both orders of execution &amp;lt;op1,op2&amp;gt; and &amp;lt;op2,op1&amp;gt; have the same effect.&amp;lt;ref&amp;gt;See the [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Order_Reduction Tutorial on Partial Order Reduction] for more information on independence between operations.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three classes (‘’guaranteed’’, ‘’impossible’’ and ‘’keep’’) of enabling relations presented so far represent definite relations. That is, if a pair of operations (op1,op2) is confirmed to be a relation of one of this three classes, then we can certainly say what effect on the enabling condition of op2 would the execution of op1 have. However, for some pairs of operations we cannot certainly say what effect an operation would have on the enabling condition of another operation. This is due to the fact that the enabling status of an operation does not only depend on the effect of the executed operations, but also on the current variables’ evaluation. Take, for instance, the tuple (Op3,Op1) from the B machine above. Considering the action part of Op3 and the guard condition of Op1 we can assume that Op3 can enable Op1. Since the guard of Op1 depends not only on the current value of x, but also on y, there could be transitions s&amp;lt;math&amp;gt;\overset{Op_3}{\rightarrow}&amp;lt;/math&amp;gt;s&#039; in the state space of the machine where Op1 is disabled in both states ‘’s’’ and ‘’s’’’. Though, what we could definitely say is that Op3 cannot disable Op1. This relationship we can illustrate as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleEnableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
The opposite relation of “possible_enable” is the relation where an operation op2 can disable another operation op1. Formally, we say that op2 can disable op1 if op2 may disable op1 and op2 cannot enable op1. This relationship is denoted as “possible_disable” and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
In order to determine how operations influence each other we need to assure first that these are feasible. An operation ‘’op’’ is said to be feasible if there is a state of the machine that satisfies the invariant of the machine and in which ‘’op’’ is enabled. In the B machine above the operation Op4, for example, is not feasible. Obviously, Op4 is enabled only in states where x is a negative number and states in which x is a negative number are visibly not consistent with the invariant since &amp;quot;x : NATURAL&amp;quot;. Such incompatibilities are sometimes of great importance for the modeler and therefore they should be revealed in the process of computing the enabling relations. In our case for each pair of operations (Op4,-) and (-,Op4) the status “infeasible” will be returned.&lt;br /&gt;
&lt;br /&gt;
We can now list all possible enabling relations for the machine &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; by means of a table. For each entry in the table the operation in the row is the operation whose effect is studied on the status of the guard of the operation in the column.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingResults.png]]&lt;br /&gt;
&lt;br /&gt;
== Summary of the Enabling Relations ==&lt;br /&gt;
&lt;br /&gt;
In the following, we summarize most of the enabling relations that we could identify. For each of the enabling relations we have given an appropriate example. In the examples below we compute the effect of executing ‘op1’ on the status of the guard of ‘op2’. The relation identifiers are the same as they appear as results in ProB.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;guaranteed&#039;&#039;: op2 guaranteed to be executable after op1.&lt;br /&gt;
[[File: GuaranteedExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_enable&#039;&#039;: op2 is guaranteed to become enabled after op1.&lt;br /&gt;
[[File: GuaranteedEnableExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_keep&#039;&#039;: op2 is guaranteed to stay enabled after op1.&lt;br /&gt;
[[File: GuaranteedKeepExample.png]]&lt;br /&gt;
* &#039;&#039;impossible&#039;&#039;: op2 is impossible to be executed after op1.&lt;br /&gt;
[[File: ImpossibleExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_disable&#039;&#039;: op2 is guaranteed to become disabled after op1.&lt;br /&gt;
[[File: ImpossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_keep&#039;&#039;: op2 is impossible to become enabled after op1.&lt;br /&gt;
[[File: ImpossibleKeepExample.png]]&lt;br /&gt;
* &#039;&#039;keep&#039;&#039;: op2 always stays enabled resp. disabled after op1.&lt;br /&gt;
[[File: KeepExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_unchanged&#039;&#039;: op1 does not write any variable read in the guard of op2, i.e. write(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticUnchangedExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_independent&#039;&#039;: op1 and op2 are syntactically independent, i.e. read(op1) /\ write(op2) = {} &amp;amp; write(op1) /\ read(op2) = {} &amp;amp; write(op1) /\ write(op2) = {}&lt;br /&gt;
[[File: SyntacticIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;syntactically_fully_independent&#039;&#039;: op1 and op2 are syntactically independent and additionally, read(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticFullyIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;possible_enable&#039;&#039;: op2 possible after op1, but op2 cannot be disabled by op1.&lt;br /&gt;
[[File: PossibleEnableExample.png]]&lt;br /&gt;
* &#039;&#039;possible_disable&#039;&#039;: op2 possible after iop1, but op2 cannot be enabled by op1.&lt;br /&gt;
[[File: PossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;infeasible&#039;&#039;: op1 is not feasible and thus cannot influence op2.&lt;br /&gt;
[[File: InfeasibleExample.png]]&lt;br /&gt;
&lt;br /&gt;
== Performing Enabling Analysis within ProB  ==&lt;br /&gt;
&lt;br /&gt;
The enabling analysis has been implemented in the ProB toolset.  The computation of the enabling relations is based on syntactic and constraint-based techniques. The identification of relations such as ‘’syntactic_independent’’ and ‘’syntactic_unchanged’’ requires just a thorough study of the syntactic structure of the operations, i.e. no calls to the constraint solver should be made. However, to confirm, for example, that an operation is guaranteed or impossible to be executed after another operation the use of the ProB’s constraint solver is unavoidable. For instance, consider the pair (Op2,Op1) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. As we have seen, in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; the operation Op1 is guaranteed to be enabled after each execution of Op2. In ProB this could be computed by feeding the (before-after) predicate “ (x mod 2 = 1) =&amp;gt; [x:=x+1 || y:=2] (x+y&amp;lt;4)” into the constraint solver. As a result, the constraint solver will not find a solution for the predicate, i.e. the constraint solver will not find a state ‘’s’’ satisfying “x mod 2 = 1” from which after executing Op2 at ‘’s’’ a solution state s’ will be found that fulfils “x+y&amp;lt;4”; note that “x+y&amp;lt;4” is the negation of the guard of Op1. Since there is no after-state of Op2 at which Op1 is disabled we can conclude that Op1 is guaranteed to be executed after Op2. When constraints are getting more complex the constraint solver may need more time for solving und determining the enabling relations may become a very time-expensive task. Therefore, a time-out for each constraint solver call is set. In other words, if the constraint solver does not find a solution in the given time by the user, then the respective relation will be denoted as time-outed. By default, in ProB the time-out for each constraint solver call is set to 300 ms.&lt;br /&gt;
&lt;br /&gt;
Within &amp;lt;tt&amp;gt;ProB Tcl/Tk&amp;lt;/tt&amp;gt; you can find the menu &amp;quot;Enabling Analysis&amp;quot; in the &amp;quot;Analysis&amp;quot; menu of the menu bar.  The &amp;quot;Enabling Analysis&amp;quot; menu provides multiple commands:&lt;br /&gt;
* &amp;quot;Enabling Analysis (Table)&amp;quot;: this command performs a (fast) enabling analysis on the respective B model using a time-out of 300 ms for the constraint-solver calls. The result of the enabling analysis is shown in a table. The table lists all enabling relations between the operations of the loaded B model. These can be exported to a CSV file. The table for &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; at the end of the &#039;&#039;&#039; Enabling Relations&#039;&#039;&#039; section was constructed this way.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Precise, Table)&amp;quot;: this command performs an enabling analysis using a time-out of 2800 ms for each of the constraint-solver calls. As for the command above, the result of the analysis is shown in a table that can be exported to a CSV file.&lt;br /&gt;
* &amp;quot;Enabling Relations After...&amp;quot;: this command computes all the enabling relations involving an operation chosen by the user.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Graph)&amp;quot;: this command performs the fast enabling analysis but displays the results as a graph. In case the preference &amp;quot;DOT_SHOW_OP_READ_WRITES&amp;quot; is set for each operation the read/write information is displayed.&lt;br /&gt;
* &amp;quot;Enabling Analysis (POR)...&amp;quot;: this menu provides further commands for another form of enabling analysis the results of which are used for the partial guard evaluation optimisation in ProB.&lt;br /&gt;
* &amp;quot;Read/Write Matrix (Table)&amp;quot;: this command performs syntactic analysis on the model. The analysis determines the read and write sets for each operation of the machine.&lt;br /&gt;
* &amp;quot;Dependence Analysis (Table)&amp;quot;: this command performs a dependency analysis for each pair of operations. More specifically, the analysis determines which operations are dependent or independent to each other.&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB (probcli) one can perform an enabling analysis on a B or Event-B model by means of the &amp;lt;tt&amp;gt;-enabling_analysis&amp;lt;/tt&amp;gt; option. The results of the analysis, as well as intermediate data and some statistics are printed out on the console:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli Example.mch -enabling_analysis&lt;br /&gt;
CHECKING ENABLING AFTER INITIALISATION&lt;br /&gt;
INITIALISATION ---&amp;gt; Op1  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op2  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op3  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op4  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op5  :: ok : guaranteed&lt;br /&gt;
.....&lt;br /&gt;
CHECKING ENABLING AFTER: Op5 r:[y] / w:[z]&lt;br /&gt;
Op5 ---&amp;gt; Op1  :: Enable=syntactic_independent&lt;br /&gt;
Op5 ---&amp;gt; Op2  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op3  :: Enable=syntactic_fully_independent&lt;br /&gt;
Op5 ---&amp;gt; Op4  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op5  :: Enable=syntactic_unchanged&lt;br /&gt;
% Finished CBC Enabling Analysis 810 ms walltime (770 ms runtime), since start: 1650 ms&lt;br /&gt;
% CBC Enabling Stats:&lt;br /&gt;
% Nr of events: 5&lt;br /&gt;
% Nr of cbc calls: 30, Timeout results: 2&lt;br /&gt;
Origin,Op1,Op2,Op3,Op4,Op5&lt;br /&gt;
INITIALISATION,guaranteed,impossible,guaranteed,impossible,guaranteed&lt;br /&gt;
Op1,timeout_possible_disable,keep,keep,impossible_keep,syntactic_independent&lt;br /&gt;
Op2,guaranteed,impossible,guaranteed,impossible_keep,impossible&lt;br /&gt;
Op3,timeout_possible,impossible_keep,guaranteed,impossible_keep,syntactic_fully_independent&lt;br /&gt;
Op4,impossible_keep,syntactic_unchanged,syntactic_unchanged,syntactic_keep,impossible_keep&lt;br /&gt;
Op5,syntactic_independent,syntactic_unchanged,syntactic_fully_independent,syntactic_unchanged,syntactic_unchanged&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To perform enabling analysis from the command line and save the results to a CSV-file use the following commando:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli file.mch -enabling_analysis_csv FILE &amp;lt;/pre&amp;gt;&lt;br /&gt;
where FILE is the name of the CSV-file in which the results of the analysis are stored.&lt;br /&gt;
&lt;br /&gt;
== References and Footnotes ==&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3484</id>
		<title>Tutorial Enabling Analysis</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3484"/>
		<updated>2016-02-11T18:47:24Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Enabling Relations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The B-method and in particular its successor Event-B are methodologies for formal development and verification of systems. In Event-B, a machine is usually viewed as a reactive system executing continuously enabled (atomic) events in an interleaved fashion. Thus, parallel events of the system are easily modeled as an interleaving of operation executions. On the other hand, the introduction of abstract counters is required when events are supposed to be executed in some (sequential) order. This, however, can in some cases slow the work of understanding and verifying a model since identifying the sequential ordering of events in an Event-B model is not that obvious. Thus, using methods for determining the control flow can be sometimes very beneficial for understanding the model, as well as for techniques for automatic verification such as model checking.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we present a static analysis for B and Event-B that can be used to reveal the control flow of a machine and to optimize model checking of models written in B and Event-B (see also [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Guard_Evaluation Tutorial on Partial Guard Evaluation ]). The results of the analysis, designated also as ‘’enabling analysis’’, can be presented as relations by means of a table or by means of a graph. For simplicity, we will concentrate mainly on B and use the terminology of the formalism.&lt;br /&gt;
&lt;br /&gt;
== Enabling Relations ==&lt;br /&gt;
What we want to find out is how the operations influence each other within a B model. In other words, for each pair (op1,op2) of operations we try to determine as precise as possible how op1 can affect the guard condition of op2 with regard to enabledness. To determine the enabling relations between operations we use syntactic analyses, as well as the constraint-based abilities of ProB.&lt;br /&gt;
&lt;br /&gt;
Consider the following B machine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE Example&lt;br /&gt;
VARIABLES x, y, z&lt;br /&gt;
INVARIANT&lt;br /&gt;
    x:NATURAL&lt;br /&gt;
  &amp;amp; y:INTEGER&lt;br /&gt;
  &amp;amp; z:INTEGER&lt;br /&gt;
INITIALISATION &lt;br /&gt;
  x:=6 || y:=-2 || z:=0&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Op1 = PRE x + y&amp;gt;=4  THEN x:=x+2 || y:=2 END;&lt;br /&gt;
  Op2 = PRE x mod 2=1 THEN x:=x+1 || y:=2 END;&lt;br /&gt;
  Op3 = PRE x mod 2=0 THEN x:=x+2 END;&lt;br /&gt;
  Op4 = PRE x&amp;lt;0 THEN y:=y-1 END;&lt;br /&gt;
  Op5 = PRE y/=2 THEN z:=3 END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The machine has three variables x,y,z, where x ranges over the domain of natural numbers and y and z over the domain of all integers. For this machine we have 25 pairs of operations for which we want to determine the respective enabling relations. Additionally, we identify 5 further pairs that show the influence of the INITIALISATION on the guard conditions of all other operations. Consider, for example, the pair (Op2,Op1) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op1 is enabled in each state of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; where the predicate ‘x+y&amp;gt;=4’ is fulfilled. Since the effect of Op2 assigns 2 to y and increments x by one upon condition that x is a positive odd number in the before-state of Op2, we can assume that Op1 is always enabled after the execution of Op2. In other words, in all after-states of Op2 the operation Op1 is guaranteed to be enabled. This relation between Op2 and Op1 we can illustrate as follows: &lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above the green boxes denote that the evaluation of the guard of Op1 is true, whereas the red boxes denote that the evaluation of the guard of Op1 is false. &lt;br /&gt;
&lt;br /&gt;
Another pair of interest is (Op2,Op5) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op5 is enabled only in those states in which y is not equal to 2. Obviously, in each after-state of Op2 y is equal to 2 and thus we can conclude that Op5 is impossible to be enabled after each execution of Op2. Such a relation between two operations we denote as ‘’impossible’’ and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
Both arrows in the illustration of the ‘’impossible’’ relation indicate that whether the guard condition of Op5 is fulfilled or not in a before-state of Op2 operation Op5 will be disabled in the respective after-state of Op2. In order to recognize a tuple (op1,op2) as ‘’impossible’’ we require that op2 is always disabled after op1 without further considering whether op2 is always enabled or always disabled in the before-states of op1. &lt;br /&gt;
&lt;br /&gt;
Consider, for instance, the pair (Op2, Op2) in the machine above. We can easily conclude that Op2 becomes disabled after it is executed and clearly, the second case (\false -&amp;gt; \false) of the impossible relation is not possible for (Op2, Op2). This gives rise of introducing another (more precise) impossible relation:&lt;br /&gt;
 &lt;br /&gt;
[[File:ImpossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Accordingly, we can derive another relation from ‘’impossible’’ for which only the second case of the ‘’impossible’’ relation is fulfilled:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
As an example for a pair of operations that fulfills the ‘’impossible_keep’’ requirement you can take, for example, the pair (Op3,Op2) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Since Op2 and Op3 cannot be both enabled in a state and the execution of Op3 cannot enable Op2, then we can easily conclude that Op2 remains always disabled after Op3.&lt;br /&gt;
&lt;br /&gt;
Similarly as for ‘’impossible’’, one could derive two further enabling relations from ‘’guaranteed’’:&lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedEnableKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Another interesting class of enabling relations that could be helpful for better understanding and analyzing B and Event-B models is that of the ‘’keep’’ relations. We say that an operation op1 ‘’keeps’’ another operation op2 if op1 cannot change the status of the enabling condition of op2, i.e. op1 keeps op2 enabled respectively disabled. This relationship could be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:KeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
We can take (Op1,Op2) and (Op1,Op3) as examples of pairs in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; that are elements of the keep relation. ‘’keep’’ relations can sometimes be easily determined by analyzing just the syntactic structure of both operations, or more precisely the “read” and “write” sets of both operations.&amp;lt;ref&amp;gt;For an operation op the set read(op) denotes the set of variables that are read by op. Accordingly, by write(op) we denote the set of variables that are written by op.&amp;lt;/ref&amp;gt; If, for example, an operation op1 does not write any variable of the machine that is read in the guard condition of op2, then we can infer that op1 ‘’keeps’’ op2. In that case we also say that op1 does not change op2 syntactically. In the class of the ‘’keep’’ relations are included also relations such as independence. Two operations op1 and op2 are called independent if each of them cannot disable the other operation and the both orders of execution &amp;lt;op1,op2&amp;gt; and &amp;lt;op2,op1&amp;gt; have the same effect.&amp;lt;ref&amp;gt;See the [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Order_Reduction Tutorial on Partial Order Reduction] for more information on independence between operations.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three classes (‘’guaranteed’’, ‘’impossible’’ and ‘’keep’’) of enabling relations presented so far represent definite relations. That is, if a pair of operations (op1,op2) is confirmed to be a relation of one of this three classes, then we can certainly say what effect on the enabling condition of op2 would the execution of op1 have. However, for some pairs of operations we cannot certainly say what effect an operation would have on the enabling condition of another operation. This is due to the fact that the enabling status of an operation does not only depend on the effect of the executed operations, but also on the current variables’ evaluation. Take, for instance, the tuple (Op3,Op1) from the B machine above. Considering the action part of Op3 and the guard condition of Op1 we can assume that Op3 can enable Op1. Since the guard of Op1 depends not only on the current value of x, but also on y, there could be transitions s&amp;lt;math&amp;gt;\overset{Op_3}{\rightarrow}&amp;lt;/math&amp;gt;s&#039; in the state space of the machine where Op1 is disabled in both states ‘’s’’ and ‘’s’’’. Though, what we could definitely say is that Op3 cannot disable Op1. This relationship we can illustrate as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleEnableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
The opposite relation of “possible_enable” is the relation where an operation op2 can disable another operation op1. Formally, we say that op2 can disable op1 if op2 may disable op1 and op2 cannot enable op1. This relationship is denoted as “possible_disable” and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
In order to determine how operations influence each other we need to assure first that these are feasible. An operation ‘’op’’ is said to be feasible if there is a state of the machine that satisfies the invariant of the machine and in which ‘’op’’ is enabled. In the B machine above the operation Op4, for example, is not feasible. Obviously, Op4 is enabled only in states where x is a negative number and states in which x is a negative number are visibly not consistent with the invariant since &amp;quot;x : NATURAL&amp;quot;. Such incompatibilities are sometimes of great importance for the modeler and therefore they should be revealed in the process of computing the enabling relations. In our case for each pair of operations (Op4,-) and (-,Op4) the status “infeasible” will be returned.&lt;br /&gt;
&lt;br /&gt;
We can now list all possible enabling relations for the machine &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; by means of a table. For each entry in the table the operation in the row is the operation whose effect is studied on the status of the guard of the operation in the column.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingResults.png]]&lt;br /&gt;
&lt;br /&gt;
== Summary of the Enabling Relations ==&lt;br /&gt;
&lt;br /&gt;
In the following, we summarize most of the enabling relations that we could identify. For each of the enabling relations we have given an appropriate example. In the examples below we compute the effect of executing ‘op1’ on the status of the guard of ‘op2’. The relation identifiers are the same as they appear as results in ProB.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;guaranteed&#039;&#039;: op2 guaranteed to be executable after op1.&lt;br /&gt;
[[File: GuaranteedExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_enable&#039;&#039;: op2 is guaranteed to become enabled after op1.&lt;br /&gt;
[[File: GuaranteedEnableExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_keep&#039;&#039;: op2 is guaranteed to stay enabled after op1.&lt;br /&gt;
[[File: GuaranteedKeepExample.png]]&lt;br /&gt;
* &#039;&#039;impossible&#039;&#039;: op2 is impossible to be executed after op1.&lt;br /&gt;
[[File: ImpossibleExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_disable&#039;&#039;: op2 is guaranteed to become disabled after op1.&lt;br /&gt;
[[File: ImpossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_keep&#039;&#039;: op2 is impossible to become enabled after op1.&lt;br /&gt;
[[File: ImpossibleKeepExample.png]]&lt;br /&gt;
* &#039;&#039;keep&#039;&#039;: op2 always stays enabled resp. disabled after op1.&lt;br /&gt;
[[File: KeepExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_unchanged&#039;&#039;: op1 does not write any variable read in the guard of op2, i.e. write(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticUnchangedExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_independent&#039;&#039;: op1 and op2 are syntactically independent, i.e. read(op1) /\ write(op2) = {} &amp;amp; write(op1) /\ read(op2) = {} &amp;amp; write(op1) /\ write(op2) = {}&lt;br /&gt;
[[File: SyntacticIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;syntactically_fully_independent&#039;&#039;: op1 and op2 are syntactically independent and additionally, read(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticFullyIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;possible_enable&#039;&#039;: op2 possible after op1, but op2 cannot be disabled by op1.&lt;br /&gt;
[[File: PossibleEnableExample.png]]&lt;br /&gt;
* &#039;&#039;possible_disable&#039;&#039;: op2 possible after iop1, but op2 cannot be enabled by op1.&lt;br /&gt;
[[File: PossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;infeasible&#039;&#039;: op1 is not feasible and thus cannot influence op2.&lt;br /&gt;
[[File: InfeasibleExample.png]]&lt;br /&gt;
&lt;br /&gt;
== Performing Enabling Analysis within ProB  ==&lt;br /&gt;
&lt;br /&gt;
Within &amp;lt;tt&amp;gt;ProB Tcl/Tk&amp;lt;/tt&amp;gt; you can find the menu &amp;quot;Enabling Analysis&amp;quot; in the &amp;quot;Analysis&amp;quot; menu of the menu bar.  The &amp;quot;Enabling Analysis&amp;quot; menu provides multiple commands:&lt;br /&gt;
* &amp;quot;Enabling Analysis (Table)&amp;quot;: this command performs a (fast) enabling analysis on the respective B model using a time-out of 300 ms for the constraint-solver calls. The result of the enabling analysis is shown in a table. The table lists all enabling relations between the operations of the loaded B model. These can be exported to a CSV file. The table for &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; at the end of the &#039;&#039;&#039; Enabling Relations&#039;&#039;&#039; section was constructed this way.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Precise, Table)&amp;quot;: this command performs an enabling analysis using a time-out of 2800 ms for each of the constraint-solver calls. As for the command above, the result of the analysis is shown in a table that can be exported to a CSV file.&lt;br /&gt;
* &amp;quot;Enabling Relations After...&amp;quot;: this command computes all the enabling relations involving an operation chosen by the user.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Graph)&amp;quot;: this command performs the fast enabling analysis but displays the results as a graph. In case the preference &amp;quot;DOT_SHOW_OP_READ_WRITES&amp;quot; is set for each operation the read/write information is displayed.&lt;br /&gt;
* &amp;quot;Enabling Analysis (POR)...&amp;quot;: this menu provides further commands for another form of enabling analysis the results of which are used for the partial guard evaluation optimisation in ProB.&lt;br /&gt;
* &amp;quot;Read/Write Matrix (Table)&amp;quot;: this command performs syntactic analysis on the model. The analysis determines the read and write sets for each operation of the machine.&lt;br /&gt;
* &amp;quot;Dependence Analysis (Table)&amp;quot;: this command performs a dependency analysis for each pair of operations. More specifically, the analysis determines which operations are dependent or independent to each other.&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB (probcli) one can perform an enabling analysis on a B or Event-B model by means of the &amp;lt;tt&amp;gt;-enabling_analysis&amp;lt;/tt&amp;gt; option. The results of the analysis, as well as intermediate data and some statistics are printed out on the console:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli Example.mch -enabling_analysis&lt;br /&gt;
CHECKING ENABLING AFTER INITIALISATION&lt;br /&gt;
INITIALISATION ---&amp;gt; Op1  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op2  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op3  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op4  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op5  :: ok : guaranteed&lt;br /&gt;
.....&lt;br /&gt;
CHECKING ENABLING AFTER: Op5 r:[y] / w:[z]&lt;br /&gt;
Op5 ---&amp;gt; Op1  :: Enable=syntactic_independent&lt;br /&gt;
Op5 ---&amp;gt; Op2  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op3  :: Enable=syntactic_fully_independent&lt;br /&gt;
Op5 ---&amp;gt; Op4  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op5  :: Enable=syntactic_unchanged&lt;br /&gt;
% Finished CBC Enabling Analysis 810 ms walltime (770 ms runtime), since start: 1650 ms&lt;br /&gt;
% CBC Enabling Stats:&lt;br /&gt;
% Nr of events: 5&lt;br /&gt;
% Nr of cbc calls: 30, Timeout results: 2&lt;br /&gt;
Origin,Op1,Op2,Op3,Op4,Op5&lt;br /&gt;
INITIALISATION,guaranteed,impossible,guaranteed,impossible,guaranteed&lt;br /&gt;
Op1,timeout_possible_disable,keep,keep,impossible_keep,syntactic_independent&lt;br /&gt;
Op2,guaranteed,impossible,guaranteed,impossible_keep,impossible&lt;br /&gt;
Op3,timeout_possible,impossible_keep,guaranteed,impossible_keep,syntactic_fully_independent&lt;br /&gt;
Op4,impossible_keep,syntactic_unchanged,syntactic_unchanged,syntactic_keep,impossible_keep&lt;br /&gt;
Op5,syntactic_independent,syntactic_unchanged,syntactic_fully_independent,syntactic_unchanged,syntactic_unchanged&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To perform enabling analysis from the command line and save the results to a CSV-file use the following commando:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli file.mch -enabling_analysis_csv FILE &amp;lt;/pre&amp;gt;&lt;br /&gt;
where FILE is the name of the CSV-file in which the results of the analysis are stored.&lt;br /&gt;
&lt;br /&gt;
== References and Footnotes ==&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3483</id>
		<title>Tutorial Enabling Analysis</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3483"/>
		<updated>2016-02-11T16:07:02Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The B-method and in particular its successor Event-B are methodologies for formal development and verification of systems. In Event-B, a machine is usually viewed as a reactive system executing continuously enabled (atomic) events in an interleaved fashion. Thus, parallel events of the system are easily modeled as an interleaving of operation executions. On the other hand, the introduction of abstract counters is required when events are supposed to be executed in some (sequential) order. This, however, can in some cases slow the work of understanding and verifying a model since identifying the sequential ordering of events in an Event-B model is not that obvious. Thus, using methods for determining the control flow can be sometimes very beneficial for understanding the model, as well as for techniques for automatic verification such as model checking.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we present a static analysis for B and Event-B that can be used to reveal the control flow of a machine and to optimize model checking of models written in B and Event-B (see also [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Guard_Evaluation Tutorial on Partial Guard Evaluation ]). The results of the analysis, designated also as ‘’enabling analysis’’, can be presented as relations by means of a table or by means of a graph. For simplicity, we will concentrate mainly on B and use the terminology of the formalism.&lt;br /&gt;
&lt;br /&gt;
== Enabling Relations ==&lt;br /&gt;
What we want to find out is how the operations influence each other within a B model. In other words, for each pair (op1,op2) of operations we try to determine as precise as possible how op1 can affect the guard condition of op2 with regard to enabledness. To determine the enabling relations between operations we use syntactic analyses, as well as the constraint-based abilities of ProB.&lt;br /&gt;
&lt;br /&gt;
Consider the following B machine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE Example&lt;br /&gt;
VARIABLES x, y, z&lt;br /&gt;
INVARIANT&lt;br /&gt;
    x:NATURAL&lt;br /&gt;
  &amp;amp; y:INTEGER&lt;br /&gt;
  &amp;amp; z:INTEGER&lt;br /&gt;
INITIALISATION &lt;br /&gt;
  x:=6 || y:=-2 || z := 0&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Op1 = PRE x + y &amp;gt;= 4  THEN x:=x+2 || y:=2 END;&lt;br /&gt;
  Op2 = PRE x mod 2 = 1 THEN x:=x+1 || y:=2 END;&lt;br /&gt;
  Op3 = PRE x mod 2 = 0 THEN x:=x+2 END;&lt;br /&gt;
  Op4 = PRE x&amp;lt;0 THEN y:=y-1 END;&lt;br /&gt;
  Op5 = PRE y/=2 THEN z:=3 END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The machine has three variables x,y,z, where x ranges over the domain of natural numbers and y and z over the domain of all integers. For this machine we have 25 pairs of operations for which we want to determine the respective enabling relations. Additionally, we identify 5 further pairs that show the influence of the INITIALISATION on the guard conditions of all other operations. Consider, for example, the pair (Op2,Op1) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op1 is enabled in each state of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; where the predicate ‘x+y&amp;gt;=4’ is fulfilled. Since the effect of Op2 assigns 2 to y and increments x by one upon condition that x is a positive odd number in the before-state of Op2, we can assume that Op1 is always enabled after the execution of Op2. In other words, in all after-states of Op2 the operation Op1 is guaranteed to be enabled. This relation between Op2 and Op1 we can illustrate as follows: &lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above the green boxes denote that the evaluation of the guard of Op1 is true, whereas the red boxes denote that the evaluation of the guard of Op1 is false. &lt;br /&gt;
&lt;br /&gt;
Another pair of interest is (Op2,Op5) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op5 is enabled only in those states in which y is not equal to 2. Obviously, in each after-state of Op2 y is equal to 2 and thus we can conclude that Op5 is impossible to be enabled after each execution of Op2. Such a relation between two operations we denote as ‘’impossible’’ and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
Both arrows in the illustration of the ‘’impossible’’ relation indicate that whether the guard condition of Op5 is fulfilled or not in a before-state of Op2 operation Op5 will be disabled in the respective after-state of Op2. In order to recognize a tuple (op1,op2) as ‘’impossible’’ we require that op2 is always disabled after op1 without further considering whether op2 is always enabled or always disabled in the before-states of op1. &lt;br /&gt;
&lt;br /&gt;
Consider, for instance, the pair (Op2, Op2) in the machine above. We can easily conclude that Op2 becomes disabled after it is executed and clearly, the second case (\false -&amp;gt; \false) of the impossible relation is not possible for (Op2, Op2). This gives rise of introducing another (more precise) impossible relation:&lt;br /&gt;
 &lt;br /&gt;
[[File:ImpossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Accordingly, we can derive another relation from ‘’impossible’’ for which only the second case of the ‘’impossible’’ relation is fulfilled:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
As an example for a pair of operations that fulfills the ‘’impossible_keep’’ requirement you can take, for example, the pair (Op3,Op2) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Since Op2 and Op3 cannot be both enabled in a state and the execution of Op3 cannot enable Op2, then we can easily conclude that Op2 remains always disabled after Op3.&lt;br /&gt;
&lt;br /&gt;
Similarly as for ‘’impossible’’, one could derive two further enabling relations from ‘’guaranteed’’:&lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedEnableKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Another interesting class of enabling relations that could be helpful for better understanding and analyzing B and Event-B models is that of the ‘’keep’’ relations. We say that an operation op1 ‘’keeps’’ another operation op2 if op1 cannot change the status of the enabling condition of op2, i.e. op1 keeps op2 enabled respectively disabled. This relationship could be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:KeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
We can take (Op1,Op2) and (Op1,Op3) as examples of pairs in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; that are elements of the keep relation. ‘’keep’’ relations can sometimes be easily determined by analyzing just the syntactic structure of both operations, or more precisely the “read” and “write” sets of both operations.&amp;lt;ref&amp;gt;For an operation op the set read(op) denotes the set of variables that are read by op. Accordingly, by write(op) we denote the set of variables that are written by op.&amp;lt;/ref&amp;gt; If, for example, an operation op1 does not write any variable of the machine that is read in the guard condition of op2, then we can infer that op1 ‘’keeps’’ op2. In that case we also say that op1 does not change op2 syntactically. In the class of the ‘’keep’’ relations are included also relations such as independence. Two operations op1 and op2 are called independent if each of them cannot disable the other operation and the both orders of execution &amp;lt;op1,op2&amp;gt; and &amp;lt;op2,op1&amp;gt; have the same effect.&amp;lt;ref&amp;gt;See the [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Order_Reduction Tutorial on Partial Order Reduction] for more information on independence between operations.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three classes (‘’guaranteed’’, ‘’impossible’’ and ‘’keep’’) of enabling relations presented so far represent definite relations. That is, if a pair of operations (op1,op2) is confirmed to be a relation of one of this three classes, then we can certainly say what effect on the enabling condition of op2 would the execution of op1 have. However, for some pairs of operations we cannot certainly say what effect an operation would have on the enabling condition of another operation. This is due to the fact that the enabling status of an operation does not only depend on the effect of the executed operations, but also on the current variables’ evaluation. Take, for instance, the tuple (Op3,Op1) from the B machine above. Considering the action part of Op3 and the guard condition of Op1 we can assume that Op3 can enable Op1. Since the guard of Op1 depends not only on the current value of x, but also on y, there could be transitions s&amp;lt;math&amp;gt;\overset{Op_3}{\rightarrow}&amp;lt;/math&amp;gt;s&#039; in the state space of the machine where Op1 is disabled in both states ‘’s’’ and ‘’s’’’. Though, what we could definitely say is that Op3 cannot disable Op1. This relationship we can illustrate as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleEnableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
The opposite relation of “possible_enable” is the relation where an operation op2 can disable another operation op1. Formally, we say that op2 can disable op1 if op2 may disable op1 and op2 cannot enable op1. This relationship is denoted as “possible_disable” and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
In order to determine how operations influence each other we need to assure first that these are feasible. An operation ‘’op’’ is said to be feasible if there is a state of the machine that satisfies the invariant of the machine and in which ‘’op’’ is enabled. In the B machine above the operation Op4, for example, is not feasible. Obviously, Op4 is enabled only in states where x is a negative number and states in which x is a negative number are visibly not consistent with the invariant since &amp;quot;x : NATURAL&amp;quot;. Such incompatibilities are sometimes of great importance for the modeler and therefore they should be revealed in the process of computing the enabling relations. In our case for each pair of operations (Op4,-) and (-,Op4) the status “infeasible” will be returned.&lt;br /&gt;
&lt;br /&gt;
We can now list all possible enabling relations for the machine &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; by means of a table. For each entry in the table the operation in the row is the operation whose effect is studied on the status of the guard of the operation in the column.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingResults.png]]&lt;br /&gt;
&lt;br /&gt;
== Summary of the Enabling Relations ==&lt;br /&gt;
&lt;br /&gt;
In the following, we summarize most of the enabling relations that we could identify. For each of the enabling relations we have given an appropriate example. In the examples below we compute the effect of executing ‘op1’ on the status of the guard of ‘op2’. The relation identifiers are the same as they appear as results in ProB.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;guaranteed&#039;&#039;: op2 guaranteed to be executable after op1.&lt;br /&gt;
[[File: GuaranteedExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_enable&#039;&#039;: op2 is guaranteed to become enabled after op1.&lt;br /&gt;
[[File: GuaranteedEnableExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_keep&#039;&#039;: op2 is guaranteed to stay enabled after op1.&lt;br /&gt;
[[File: GuaranteedKeepExample.png]]&lt;br /&gt;
* &#039;&#039;impossible&#039;&#039;: op2 is impossible to be executed after op1.&lt;br /&gt;
[[File: ImpossibleExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_disable&#039;&#039;: op2 is guaranteed to become disabled after op1.&lt;br /&gt;
[[File: ImpossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_keep&#039;&#039;: op2 is impossible to become enabled after op1.&lt;br /&gt;
[[File: ImpossibleKeepExample.png]]&lt;br /&gt;
* &#039;&#039;keep&#039;&#039;: op2 always stays enabled resp. disabled after op1.&lt;br /&gt;
[[File: KeepExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_unchanged&#039;&#039;: op1 does not write any variable read in the guard of op2, i.e. write(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticUnchangedExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_independent&#039;&#039;: op1 and op2 are syntactically independent, i.e. read(op1) /\ write(op2) = {} &amp;amp; write(op1) /\ read(op2) = {} &amp;amp; write(op1) /\ write(op2) = {}&lt;br /&gt;
[[File: SyntacticIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;syntactically_fully_independent&#039;&#039;: op1 and op2 are syntactically independent and additionally, read(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticFullyIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;possible_enable&#039;&#039;: op2 possible after op1, but op2 cannot be disabled by op1.&lt;br /&gt;
[[File: PossibleEnableExample.png]]&lt;br /&gt;
* &#039;&#039;possible_disable&#039;&#039;: op2 possible after iop1, but op2 cannot be enabled by op1.&lt;br /&gt;
[[File: PossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;infeasible&#039;&#039;: op1 is not feasible and thus cannot influence op2.&lt;br /&gt;
[[File: InfeasibleExample.png]]&lt;br /&gt;
&lt;br /&gt;
== Performing Enabling Analysis within ProB  ==&lt;br /&gt;
&lt;br /&gt;
Within &amp;lt;tt&amp;gt;ProB Tcl/Tk&amp;lt;/tt&amp;gt; you can find the menu &amp;quot;Enabling Analysis&amp;quot; in the &amp;quot;Analysis&amp;quot; menu of the menu bar.  The &amp;quot;Enabling Analysis&amp;quot; menu provides multiple commands:&lt;br /&gt;
* &amp;quot;Enabling Analysis (Table)&amp;quot;: this command performs a (fast) enabling analysis on the respective B model using a time-out of 300 ms for the constraint-solver calls. The result of the enabling analysis is shown in a table. The table lists all enabling relations between the operations of the loaded B model. These can be exported to a CSV file. The table for &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; at the end of the &#039;&#039;&#039; Enabling Relations&#039;&#039;&#039; section was constructed this way.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Precise, Table)&amp;quot;: this command performs an enabling analysis using a time-out of 2800 ms for each of the constraint-solver calls. As for the command above, the result of the analysis is shown in a table that can be exported to a CSV file.&lt;br /&gt;
* &amp;quot;Enabling Relations After...&amp;quot;: this command computes all the enabling relations involving an operation chosen by the user.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Graph)&amp;quot;: this command performs the fast enabling analysis but displays the results as a graph. In case the preference &amp;quot;DOT_SHOW_OP_READ_WRITES&amp;quot; is set for each operation the read/write information is displayed.&lt;br /&gt;
* &amp;quot;Enabling Analysis (POR)...&amp;quot;: this menu provides further commands for another form of enabling analysis the results of which are used for the partial guard evaluation optimisation in ProB.&lt;br /&gt;
* &amp;quot;Read/Write Matrix (Table)&amp;quot;: this command performs syntactic analysis on the model. The analysis determines the read and write sets for each operation of the machine.&lt;br /&gt;
* &amp;quot;Dependence Analysis (Table)&amp;quot;: this command performs a dependency analysis for each pair of operations. More specifically, the analysis determines which operations are dependent or independent to each other.&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB (probcli) one can perform an enabling analysis on a B or Event-B model by means of the &amp;lt;tt&amp;gt;-enabling_analysis&amp;lt;/tt&amp;gt; option. The results of the analysis, as well as intermediate data and some statistics are printed out on the console:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli Example.mch -enabling_analysis&lt;br /&gt;
CHECKING ENABLING AFTER INITIALISATION&lt;br /&gt;
INITIALISATION ---&amp;gt; Op1  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op2  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op3  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op4  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op5  :: ok : guaranteed&lt;br /&gt;
.....&lt;br /&gt;
CHECKING ENABLING AFTER: Op5 r:[y] / w:[z]&lt;br /&gt;
Op5 ---&amp;gt; Op1  :: Enable=syntactic_independent&lt;br /&gt;
Op5 ---&amp;gt; Op2  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op3  :: Enable=syntactic_fully_independent&lt;br /&gt;
Op5 ---&amp;gt; Op4  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op5  :: Enable=syntactic_unchanged&lt;br /&gt;
% Finished CBC Enabling Analysis 810 ms walltime (770 ms runtime), since start: 1650 ms&lt;br /&gt;
% CBC Enabling Stats:&lt;br /&gt;
% Nr of events: 5&lt;br /&gt;
% Nr of cbc calls: 30, Timeout results: 2&lt;br /&gt;
Origin,Op1,Op2,Op3,Op4,Op5&lt;br /&gt;
INITIALISATION,guaranteed,impossible,guaranteed,impossible,guaranteed&lt;br /&gt;
Op1,timeout_possible_disable,keep,keep,impossible_keep,syntactic_independent&lt;br /&gt;
Op2,guaranteed,impossible,guaranteed,impossible_keep,impossible&lt;br /&gt;
Op3,timeout_possible,impossible_keep,guaranteed,impossible_keep,syntactic_fully_independent&lt;br /&gt;
Op4,impossible_keep,syntactic_unchanged,syntactic_unchanged,syntactic_keep,impossible_keep&lt;br /&gt;
Op5,syntactic_independent,syntactic_unchanged,syntactic_fully_independent,syntactic_unchanged,syntactic_unchanged&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To perform enabling analysis from the command line and save the results to a CSV-file use the following commando:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli file.mch -enabling_analysis_csv FILE &amp;lt;/pre&amp;gt;&lt;br /&gt;
where FILE is the name of the CSV-file in which the results of the analysis are stored.&lt;br /&gt;
&lt;br /&gt;
== References and Footnotes ==&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3482</id>
		<title>Tutorial Enabling Analysis</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3482"/>
		<updated>2016-02-11T15:59:35Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Performing Enabling Analysis within ProB */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The B-method and in particular its successor Event-B are methodologies for formal development and verification of systems. In Event-B, a machine is usually viewed as a reactive system executing continuously enabled (atomic) events in an interleaved fashion. Thus, parallel events of the system are easily modeled as an interleaving of operation executions. On the other hand, the introduction of abstract counters is required when events are supposed to be executed in some (sequential) order. This, however, can in some cases slow the work of understanding and verifying a model since identifying the sequential ordering of events in an Event-B model is not that obvious. Thus, using methods for determining the control flow can be sometimes very beneficial for understanding the model, as well as for techniques for automatic verification such as model checking.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we present a static analysis for B and Event-B that can be used to reveal the control flow of a machine and to optimize model checking of models written in B and Event-B (see also [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Guard_Evaluation Tutorial on Partial Guard Evaluation ]). The results of the analysis, designated also as ‘’enabling analysis’’, can be presented as relations by means of a table or by means of a graph. For simplicity, we will concentrate mainly on B and use the terminology of the formalism.&lt;br /&gt;
&lt;br /&gt;
== Enabling Relations ==&lt;br /&gt;
What we want to find out is how the operations influence each other within a B model. In other words, for each pair (op1,op2) of operations we try to determine as precise as possible how op1 can affect the guard condition of op2 with regard to enabledness. To determine the enabling relations between operations we use syntactic analyses, as well as the constraint-based abilities of ProB.&lt;br /&gt;
&lt;br /&gt;
Consider the following B machine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE Example&lt;br /&gt;
VARIABLES x, y, z&lt;br /&gt;
INVARIANT&lt;br /&gt;
    x:NATURAL&lt;br /&gt;
  &amp;amp; y:INTEGER&lt;br /&gt;
  &amp;amp; z:INTEGER&lt;br /&gt;
INITIALISATION &lt;br /&gt;
  x:=6 || y:=-2 || z := 0&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Op1 = PRE x + y &amp;gt;= 4  THEN x:=x+2 || y:=2 END;&lt;br /&gt;
  Op2 = PRE x mod 2 = 1 THEN x:=x+1 || y:=2 END;&lt;br /&gt;
  Op3 = PRE x mod 2 = 0 THEN x:=x+2 END;&lt;br /&gt;
  Op4 = PRE x&amp;lt;0 THEN y:=y-1 END;&lt;br /&gt;
  Op5 = PRE y/=2 THEN z:=3 END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The machine has three variables x,y,z, where x ranges over the domain of natural numbers and y and z over the domain of all integers. For this machine we have 25 pairs of operations for which we want to determine the respective enabling relations. Additionally, we identify 5 further pairs that show the influence of the INITIALISATION on the guard conditions of all other operations. Consider, for example, the pair (Op2,Op1) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op1 is enabled in each state of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; where the predicate ‘x+y&amp;gt;=4’ is fulfilled. Since the effect of Op2 assigns 2 to y and increments x by one upon condition that x is a positive odd number in the before-state of Op2, we can assume that Op1 is always enabled after the execution of Op2. In other words, in all after-states of Op2 the operation Op1 is guaranteed to be enabled. This relation between Op2 and Op1 we can illustrate as follows: &lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above the green boxes denote that the evaluation of the guard of Op1 is true, whereas the red boxes denote that the evaluation of the guard of Op1 is false. &lt;br /&gt;
&lt;br /&gt;
Another pair of interest is (Op2,Op5) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op5 is enabled only in those states in which y is not equal to 2. Obviously, in each after-state of Op2 y is equal to 2 and thus we can conclude that Op5 is impossible to be enabled after each execution of Op2. Such a relation between two operations we denote as ‘’impossible’’ and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
Both arrows in the illustration of the ‘’impossible’’ relation indicate that whether the guard condition of Op5 is fulfilled or not in a before-state of Op2 operation Op5 will be disabled in the respective after-state of Op2. In order to recognize a tuple (op1,op2) as ‘’impossible’’ we require that op2 is always disabled after op1 without further considering whether op2 is always enabled or always disabled in the before-states of op1. &lt;br /&gt;
&lt;br /&gt;
Consider, for instance, the pair (Op2, Op2) in the machine above. We can easily conclude that Op2 becomes disabled after it is executed and clearly, the second case (\false -&amp;gt; \false) of the impossible relation is not possible for (Op2, Op2). This gives rise of introducing another (more precise) impossible relation:&lt;br /&gt;
 &lt;br /&gt;
[[File:ImpossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Accordingly, we can derive another relation from ‘’impossible’’ for which only the second case of the ‘’impossible’’ relation is fulfilled:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
As an example for a pair of operations that fulfills the ‘’impossible_keep’’ requirement you can take, for example, the pair (Op3,Op2) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Since Op2 and Op3 cannot be both enabled in a state and the execution of Op3 cannot enable Op2, then we can easily conclude that Op2 remains always disabled after Op3.&lt;br /&gt;
&lt;br /&gt;
Similarly as for ‘’impossible’’, one could derive two further enabling relations from ‘’guaranteed’’:&lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedEnableKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Another interesting class of enabling relations that could be helpful for better understanding and analyzing B and Event-B models is that of the ‘’keep’’ relations. We say that an operation op1 ‘’keeps’’ another operation op2 if op1 cannot change the status of the enabling condition of op2, i.e. op1 keeps op2 enabled respectively disabled. This relationship could be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:KeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
We can take (Op1,Op2) and (Op1,Op3) as examples of pairs in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; that are elements of the keep relation. ‘’keep’’ relations can sometimes be easily determined by analyzing just the syntactic structure of both operations, or more precisely the “read” and “write” sets of both operations.&amp;lt;ref&amp;gt;For an operation op the set read(op) denotes the set of variables that are read by op. Accordingly, by write(op) we denote the set of variables that are written by op.&amp;lt;/ref&amp;gt; If, for example, an operation op1 does not write any variable of the machine that is read in the guard condition of op2, then we can infer that op1 ‘’keeps’’ op2. In that case we also say that op1 does not change op2 syntactically. In the class of the ‘’keep’’ relations are included also relations such as independence. Two operations op1 and op2 are called independent if each of them cannot disable the other operation and the both orders of execution &amp;lt;op1,op2&amp;gt; and &amp;lt;op2,op1&amp;gt; have the same effect.&amp;lt;ref&amp;gt;See the [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Order_Reduction Tutorial on Partial Order Reduction] for more information on independence between operations.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three classes (‘’guaranteed’’, ‘’impossible’’ and ‘’keep’’) of enabling relations presented so far represent definite relations. That is, if a pair of operations (op1,op2) is confirmed to be a relation of one of this three classes, then we can certainly say what effect on the enabling condition of op2 would the execution of op1 have. However, for some pairs of operations we cannot certainly say what effect an operation would have on the enabling condition of another operation. This is due to the fact that the enabling status of an operation does not only depend on the effect of the executed operations, but also on the current variables’ evaluation. Take, for instance, the tuple (Op3,Op1) from the B machine above. Considering the action part of Op3 and the guard condition of Op1 we can assume that Op3 can enable Op1. Since the guard of Op1 depends not only on the current value of x, but also on y, there could be transitions s&amp;lt;math&amp;gt;\overset{Op_3}{\rightarrow}&amp;lt;/math&amp;gt;s&#039; in the state space of the machine where Op1 is disabled in both states ‘’s’’ and ‘’s’’’. Though, what we could definitely say is that Op3 cannot disable Op1. This relationship we can illustrate as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleEnableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
The opposite relation of “possible_enable” is the relation where an operation op2 can disable another operation op1. Formally, we say that op2 can disable op1 if op2 may disable op1 and op2 cannot enable op1. This relationship is denoted as “possible_disable” and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
In order to determine how operations influence each other we need to assure first that these are feasible. An operation ‘’op’’ is said to be feasible if there is a state of the machine that satisfies the invariant of the machine and in which ‘’op’’ is enabled. In the B machine above the operation Op4, for example, is not feasible. Obviously, Op4 is enabled only in states where x is a negative number and states in which x is a negative number are visibly not consistent with the invariant since &amp;quot;x : NATURAL&amp;quot;. Such incompatibilities are sometimes of great importance for the modeler and therefore they should be revealed in the process of computing the enabling relations. In our case for each pair of operations (Op4,-) and (-,Op4) the status “infeasible” will be returned.&lt;br /&gt;
&lt;br /&gt;
We can now list all possible enabling relations for the machine &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; by means of a table. For each entry in the table the operation in the row is the operation whose effect is studied on the status of the guard of the operation in the column.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingResults.png]]&lt;br /&gt;
&lt;br /&gt;
== Summary of the Enabling Relations ==&lt;br /&gt;
&lt;br /&gt;
In the following, we summarize most of the enabling relations that we could identify. For each of the enabling relations we have given an appropriate example. In the examples below we compute the effect of executing ‘op1’ on the status of the guard of ‘op2’. The relation identifiers are the same as they appear as results in ProB.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;guaranteed&#039;&#039;: op2 guaranteed to be executable after op1.&lt;br /&gt;
[[File: GuaranteedExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_enable&#039;&#039;: op2 is guaranteed to become enabled after op1.&lt;br /&gt;
[[File: GuaranteedEnableExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_keep&#039;&#039;: op2 is guaranteed to stay enabled after op1.&lt;br /&gt;
[[File: GuaranteedKeepExample.png]]&lt;br /&gt;
* &#039;&#039;impossible&#039;&#039;: op2 is impossible to be executed after op1.&lt;br /&gt;
[[File: ImpossibleExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_disable&#039;&#039;: op2 is guaranteed to become disabled after op1.&lt;br /&gt;
[[File: ImpossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_keep&#039;&#039;: op2 is impossible to become enabled after op1.&lt;br /&gt;
[[File: ImpossibleKeepExample.png]]&lt;br /&gt;
* &#039;&#039;keep&#039;&#039;: op2 always stays enabled resp. disabled after op1.&lt;br /&gt;
[[File: KeepExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_unchanged&#039;&#039;: op1 does not write any variable read in the guard of op2, i.e. write(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticUnchangedExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_independent&#039;&#039;: op1 and op2 are syntactically independent, i.e. read(op1) /\ write(op2) = {} &amp;amp; write(op1) /\ read(op2) = {} &amp;amp; write(op1) /\ write(op2) = {}&lt;br /&gt;
[[File: SyntacticIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;syntactically_fully_independent&#039;&#039;: op1 and op2 are syntactically independent and additionally, read(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticFullyIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;possible_enable&#039;&#039;: op2 possible after op1, but op2 cannot be disabled by op1.&lt;br /&gt;
[[File: PossibleEnableExample.png]]&lt;br /&gt;
* &#039;&#039;possible_disable&#039;&#039;: op2 possible after iop1, but op2 cannot be enabled by op1.&lt;br /&gt;
[[File: PossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;infeasible&#039;&#039;: op1 is not feasible and thus cannot influence op2.&lt;br /&gt;
[[File: InfeasibleExample.png]]&lt;br /&gt;
&lt;br /&gt;
== Performing Enabling Analysis within ProB  ==&lt;br /&gt;
&lt;br /&gt;
Within &amp;lt;tt&amp;gt;ProB Tcl/Tk&amp;lt;/tt&amp;gt; you can find the menu &amp;quot;Enabling Analysis&amp;quot; in the &amp;quot;Analysis&amp;quot; menu of the menu bar.  The &amp;quot;Enabling Analysis&amp;quot; menu provides multiple commands:&lt;br /&gt;
* &amp;quot;Enabling Analysis (Table)&amp;quot;: this command performs a (fast) enabling analysis on the respective B model using a time-out of 300 ms for the constraint-solver calls. The result of the enabling analysis is shown in a table. The table lists all enabling relations between the operations of the loaded B model. These can be exported to a CSV file. The table for &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; at the end of the &#039;&#039;&#039; Enabling Relations&#039;&#039;&#039; section was constructed this way.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Precise, Table)&amp;quot;: this command performs an enabling analysis using a time-out of 2800 ms for each of the constraint-solver calls. As for the command above, the result of the analysis is shown in a table that can be exported to a CSV file.&lt;br /&gt;
* &amp;quot;Enabling Relations After...&amp;quot;: this command computes all the enabling relations involving an operation chosen by the user.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Graph)&amp;quot;: this command performs the fast enabling analysis but displays the results as a graph. In case the preference &amp;quot;DOT_SHOW_OP_READ_WRITES&amp;quot; is set for each operation the read/write information is displayed.&lt;br /&gt;
* &amp;quot;Enabling Analysis (POR)...&amp;quot;: this menu provides further commands for another form of enabling analysis the results of which are used for the partial guard evaluation optimisation in ProB.&lt;br /&gt;
* &amp;quot;Read/Write Matrix (Table)&amp;quot;: this command performs syntactic analysis on the model. The analysis determines the read and write sets for each operation of the machine.&lt;br /&gt;
* &amp;quot;Dependence Analysis (Table)&amp;quot;: this command performs a dependency analysis for each pair of operations. More specifically, the analysis determine which operations are dependent or independent to each other.&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB (probcli) one can perform an enabling analysis on a B or Event-B model by means of the &amp;lt;tt&amp;gt;-enabling_analysis&amp;lt;/tt&amp;gt; option. The results of the analysis, as well as intermediate data and some statistics are printed out on the console:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli Example.mch -enabling_analysis&lt;br /&gt;
CHECKING ENABLING AFTER INITIALISATION&lt;br /&gt;
INITIALISATION ---&amp;gt; Op1  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op2  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op3  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op4  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op5  :: ok : guaranteed&lt;br /&gt;
.....&lt;br /&gt;
CHECKING ENABLING AFTER: Op5 r:[y] / w:[z]&lt;br /&gt;
Op5 ---&amp;gt; Op1  :: Enable=syntactic_independent&lt;br /&gt;
Op5 ---&amp;gt; Op2  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op3  :: Enable=syntactic_fully_independent&lt;br /&gt;
Op5 ---&amp;gt; Op4  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op5  :: Enable=syntactic_unchanged&lt;br /&gt;
% Finished CBC Enabling Analysis 810 ms walltime (770 ms runtime), since start: 1650 ms&lt;br /&gt;
% CBC Enabling Stats:&lt;br /&gt;
% Nr of events: 5&lt;br /&gt;
% Nr of cbc calls: 30, Timeout results: 2&lt;br /&gt;
Origin,Op1,Op2,Op3,Op4,Op5&lt;br /&gt;
INITIALISATION,guaranteed,impossible,guaranteed,impossible,guaranteed&lt;br /&gt;
Op1,timeout_possible_disable,keep,keep,impossible_keep,syntactic_independent&lt;br /&gt;
Op2,guaranteed,impossible,guaranteed,impossible_keep,impossible&lt;br /&gt;
Op3,timeout_possible,impossible_keep,guaranteed,impossible_keep,syntactic_fully_independent&lt;br /&gt;
Op4,impossible_keep,syntactic_unchanged,syntactic_unchanged,syntactic_keep,impossible_keep&lt;br /&gt;
Op5,syntactic_independent,syntactic_unchanged,syntactic_fully_independent,syntactic_unchanged,syntactic_unchanged&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To perform enabling analysis from the command line and save the results to a CSV-file use the following commando:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli file.mch -enabling_analysis_csv FILE &amp;lt;/pre&amp;gt;&lt;br /&gt;
where FILE is the name of the CSV-file in which the results of the analysis are stored.&lt;br /&gt;
&lt;br /&gt;
== References and Footnotes ==&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3481</id>
		<title>Tutorial Enabling Analysis</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3481"/>
		<updated>2016-02-11T15:58:11Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Performing Enabling Analysis within ProB */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The B-method and in particular its successor Event-B are methodologies for formal development and verification of systems. In Event-B, a machine is usually viewed as a reactive system executing continuously enabled (atomic) events in an interleaved fashion. Thus, parallel events of the system are easily modeled as an interleaving of operation executions. On the other hand, the introduction of abstract counters is required when events are supposed to be executed in some (sequential) order. This, however, can in some cases slow the work of understanding and verifying a model since identifying the sequential ordering of events in an Event-B model is not that obvious. Thus, using methods for determining the control flow can be sometimes very beneficial for understanding the model, as well as for techniques for automatic verification such as model checking.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we present a static analysis for B and Event-B that can be used to reveal the control flow of a machine and to optimize model checking of models written in B and Event-B (see also [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Guard_Evaluation Tutorial on Partial Guard Evaluation ]). The results of the analysis, designated also as ‘’enabling analysis’’, can be presented as relations by means of a table or by means of a graph. For simplicity, we will concentrate mainly on B and use the terminology of the formalism.&lt;br /&gt;
&lt;br /&gt;
== Enabling Relations ==&lt;br /&gt;
What we want to find out is how the operations influence each other within a B model. In other words, for each pair (op1,op2) of operations we try to determine as precise as possible how op1 can affect the guard condition of op2 with regard to enabledness. To determine the enabling relations between operations we use syntactic analyses, as well as the constraint-based abilities of ProB.&lt;br /&gt;
&lt;br /&gt;
Consider the following B machine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE Example&lt;br /&gt;
VARIABLES x, y, z&lt;br /&gt;
INVARIANT&lt;br /&gt;
    x:NATURAL&lt;br /&gt;
  &amp;amp; y:INTEGER&lt;br /&gt;
  &amp;amp; z:INTEGER&lt;br /&gt;
INITIALISATION &lt;br /&gt;
  x:=6 || y:=-2 || z := 0&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Op1 = PRE x + y &amp;gt;= 4  THEN x:=x+2 || y:=2 END;&lt;br /&gt;
  Op2 = PRE x mod 2 = 1 THEN x:=x+1 || y:=2 END;&lt;br /&gt;
  Op3 = PRE x mod 2 = 0 THEN x:=x+2 END;&lt;br /&gt;
  Op4 = PRE x&amp;lt;0 THEN y:=y-1 END;&lt;br /&gt;
  Op5 = PRE y/=2 THEN z:=3 END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The machine has three variables x,y,z, where x ranges over the domain of natural numbers and y and z over the domain of all integers. For this machine we have 25 pairs of operations for which we want to determine the respective enabling relations. Additionally, we identify 5 further pairs that show the influence of the INITIALISATION on the guard conditions of all other operations. Consider, for example, the pair (Op2,Op1) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op1 is enabled in each state of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; where the predicate ‘x+y&amp;gt;=4’ is fulfilled. Since the effect of Op2 assigns 2 to y and increments x by one upon condition that x is a positive odd number in the before-state of Op2, we can assume that Op1 is always enabled after the execution of Op2. In other words, in all after-states of Op2 the operation Op1 is guaranteed to be enabled. This relation between Op2 and Op1 we can illustrate as follows: &lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above the green boxes denote that the evaluation of the guard of Op1 is true, whereas the red boxes denote that the evaluation of the guard of Op1 is false. &lt;br /&gt;
&lt;br /&gt;
Another pair of interest is (Op2,Op5) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op5 is enabled only in those states in which y is not equal to 2. Obviously, in each after-state of Op2 y is equal to 2 and thus we can conclude that Op5 is impossible to be enabled after each execution of Op2. Such a relation between two operations we denote as ‘’impossible’’ and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
Both arrows in the illustration of the ‘’impossible’’ relation indicate that whether the guard condition of Op5 is fulfilled or not in a before-state of Op2 operation Op5 will be disabled in the respective after-state of Op2. In order to recognize a tuple (op1,op2) as ‘’impossible’’ we require that op2 is always disabled after op1 without further considering whether op2 is always enabled or always disabled in the before-states of op1. &lt;br /&gt;
&lt;br /&gt;
Consider, for instance, the pair (Op2, Op2) in the machine above. We can easily conclude that Op2 becomes disabled after it is executed and clearly, the second case (\false -&amp;gt; \false) of the impossible relation is not possible for (Op2, Op2). This gives rise of introducing another (more precise) impossible relation:&lt;br /&gt;
 &lt;br /&gt;
[[File:ImpossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Accordingly, we can derive another relation from ‘’impossible’’ for which only the second case of the ‘’impossible’’ relation is fulfilled:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
As an example for a pair of operations that fulfills the ‘’impossible_keep’’ requirement you can take, for example, the pair (Op3,Op2) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Since Op2 and Op3 cannot be both enabled in a state and the execution of Op3 cannot enable Op2, then we can easily conclude that Op2 remains always disabled after Op3.&lt;br /&gt;
&lt;br /&gt;
Similarly as for ‘’impossible’’, one could derive two further enabling relations from ‘’guaranteed’’:&lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedEnableKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Another interesting class of enabling relations that could be helpful for better understanding and analyzing B and Event-B models is that of the ‘’keep’’ relations. We say that an operation op1 ‘’keeps’’ another operation op2 if op1 cannot change the status of the enabling condition of op2, i.e. op1 keeps op2 enabled respectively disabled. This relationship could be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:KeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
We can take (Op1,Op2) and (Op1,Op3) as examples of pairs in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; that are elements of the keep relation. ‘’keep’’ relations can sometimes be easily determined by analyzing just the syntactic structure of both operations, or more precisely the “read” and “write” sets of both operations.&amp;lt;ref&amp;gt;For an operation op the set read(op) denotes the set of variables that are read by op. Accordingly, by write(op) we denote the set of variables that are written by op.&amp;lt;/ref&amp;gt; If, for example, an operation op1 does not write any variable of the machine that is read in the guard condition of op2, then we can infer that op1 ‘’keeps’’ op2. In that case we also say that op1 does not change op2 syntactically. In the class of the ‘’keep’’ relations are included also relations such as independence. Two operations op1 and op2 are called independent if each of them cannot disable the other operation and the both orders of execution &amp;lt;op1,op2&amp;gt; and &amp;lt;op2,op1&amp;gt; have the same effect.&amp;lt;ref&amp;gt;See the [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Order_Reduction Tutorial on Partial Order Reduction] for more information on independence between operations.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three classes (‘’guaranteed’’, ‘’impossible’’ and ‘’keep’’) of enabling relations presented so far represent definite relations. That is, if a pair of operations (op1,op2) is confirmed to be a relation of one of this three classes, then we can certainly say what effect on the enabling condition of op2 would the execution of op1 have. However, for some pairs of operations we cannot certainly say what effect an operation would have on the enabling condition of another operation. This is due to the fact that the enabling status of an operation does not only depend on the effect of the executed operations, but also on the current variables’ evaluation. Take, for instance, the tuple (Op3,Op1) from the B machine above. Considering the action part of Op3 and the guard condition of Op1 we can assume that Op3 can enable Op1. Since the guard of Op1 depends not only on the current value of x, but also on y, there could be transitions s&amp;lt;math&amp;gt;\overset{Op_3}{\rightarrow}&amp;lt;/math&amp;gt;s&#039; in the state space of the machine where Op1 is disabled in both states ‘’s’’ and ‘’s’’’. Though, what we could definitely say is that Op3 cannot disable Op1. This relationship we can illustrate as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleEnableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
The opposite relation of “possible_enable” is the relation where an operation op2 can disable another operation op1. Formally, we say that op2 can disable op1 if op2 may disable op1 and op2 cannot enable op1. This relationship is denoted as “possible_disable” and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
In order to determine how operations influence each other we need to assure first that these are feasible. An operation ‘’op’’ is said to be feasible if there is a state of the machine that satisfies the invariant of the machine and in which ‘’op’’ is enabled. In the B machine above the operation Op4, for example, is not feasible. Obviously, Op4 is enabled only in states where x is a negative number and states in which x is a negative number are visibly not consistent with the invariant since &amp;quot;x : NATURAL&amp;quot;. Such incompatibilities are sometimes of great importance for the modeler and therefore they should be revealed in the process of computing the enabling relations. In our case for each pair of operations (Op4,-) and (-,Op4) the status “infeasible” will be returned.&lt;br /&gt;
&lt;br /&gt;
We can now list all possible enabling relations for the machine &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; by means of a table. For each entry in the table the operation in the row is the operation whose effect is studied on the status of the guard of the operation in the column.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingResults.png]]&lt;br /&gt;
&lt;br /&gt;
== Summary of the Enabling Relations ==&lt;br /&gt;
&lt;br /&gt;
In the following, we summarize most of the enabling relations that we could identify. For each of the enabling relations we have given an appropriate example. In the examples below we compute the effect of executing ‘op1’ on the status of the guard of ‘op2’. The relation identifiers are the same as they appear as results in ProB.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;guaranteed&#039;&#039;: op2 guaranteed to be executable after op1.&lt;br /&gt;
[[File: GuaranteedExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_enable&#039;&#039;: op2 is guaranteed to become enabled after op1.&lt;br /&gt;
[[File: GuaranteedEnableExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_keep&#039;&#039;: op2 is guaranteed to stay enabled after op1.&lt;br /&gt;
[[File: GuaranteedKeepExample.png]]&lt;br /&gt;
* &#039;&#039;impossible&#039;&#039;: op2 is impossible to be executed after op1.&lt;br /&gt;
[[File: ImpossibleExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_disable&#039;&#039;: op2 is guaranteed to become disabled after op1.&lt;br /&gt;
[[File: ImpossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_keep&#039;&#039;: op2 is impossible to become enabled after op1.&lt;br /&gt;
[[File: ImpossibleKeepExample.png]]&lt;br /&gt;
* &#039;&#039;keep&#039;&#039;: op2 always stays enabled resp. disabled after op1.&lt;br /&gt;
[[File: KeepExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_unchanged&#039;&#039;: op1 does not write any variable read in the guard of op2, i.e. write(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticUnchangedExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_independent&#039;&#039;: op1 and op2 are syntactically independent, i.e. read(op1) /\ write(op2) = {} &amp;amp; write(op1) /\ read(op2) = {} &amp;amp; write(op1) /\ write(op2) = {}&lt;br /&gt;
[[File: SyntacticIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;syntactically_fully_independent&#039;&#039;: op1 and op2 are syntactically independent and additionally, read(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticFullyIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;possible_enable&#039;&#039;: op2 possible after op1, but op2 cannot be disabled by op1.&lt;br /&gt;
[[File: PossibleEnableExample.png]]&lt;br /&gt;
* &#039;&#039;possible_disable&#039;&#039;: op2 possible after iop1, but op2 cannot be enabled by op1.&lt;br /&gt;
[[File: PossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;infeasible&#039;&#039;: op1 is not feasible and thus cannot influence op2.&lt;br /&gt;
[[File: InfeasibleExample.png]]&lt;br /&gt;
&lt;br /&gt;
== Performing Enabling Analysis within ProB  ==&lt;br /&gt;
&lt;br /&gt;
Within &amp;lt;tt&amp;gt;ProB Tcl/Tk&amp;lt;/tt&amp;gt; you can find the menu &amp;quot;Enabling Analysis&amp;quot; in the &amp;quot;Analysis&amp;quot; menu of the menu bar.  The &amp;quot;Enabling Analysis&amp;quot; menu provides multiple commands:&lt;br /&gt;
* &amp;quot;Enabling Analysis (Table)&amp;quot;: this command performs a (fast) enabling analysis on the respective B model using a time-out of 300 ms for the constraint-solver calls. The result of the enabling analysis is shown in a table. The table lists all enabling relations between the operations of the loaded B model. These can be exported to a CSV file. The table for &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; at the end of the &#039;&#039;&#039; Enabling Relations&#039;&#039;&#039; section was constructed this way.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Precise, Table)&amp;quot;: this command performs an enabling analysis using a time-out of 2800 ms for each of the constraint-solver calls. As for the command above, the result of the analysis is shown in a table that can be exported to a CSV file.&lt;br /&gt;
* &amp;quot;Enabling Relations After...&amp;quot;: this command computes all the enabling relations involving an operation chosen by the user.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Graph)&amp;quot;: this command performs the fast enabling analysis but displays the results as a graph. In case the preference &amp;quot;DOT_SHOW_OP_READ_WRITES&amp;quot; is set for each operation the read/write information is displayed.&lt;br /&gt;
* &amp;quot;Enabling Analysis (POR)...&amp;quot;: this menu provides further commands for another form of enabling analysis the results of which are used for the partial guard evaluation optimisation in ProB.&lt;br /&gt;
* &amp;quot;Read/Write Matrix (Table)&amp;quot;: this command performs syntactic analysis on the model. The analysis determines the read and write sets for each operation of the machine.&lt;br /&gt;
* &amp;quot;Dependence Analysis (Table)&amp;quot;: this command performs a dependency analysis for each pair of operations. More specifically, the analysis determine which operations are dependent or independent to each other.&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB (probcli) one can perform an enabling analysis on a B or Event-B model by means of the &amp;lt;tt&amp;gt;-enabling_analysis&amp;lt;/tt&amp;gt; option. The results of the analysis, as well as other intermediate data is printed out on the console:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli Example.mch -enabling_analysis&lt;br /&gt;
CHECKING ENABLING AFTER INITIALISATION&lt;br /&gt;
INITIALISATION ---&amp;gt; Op1  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op2  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op3  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op4  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op5  :: ok : guaranteed&lt;br /&gt;
.....&lt;br /&gt;
CHECKING ENABLING AFTER: Op5 r:[y] / w:[z]&lt;br /&gt;
Op5 ---&amp;gt; Op1  :: Enable=syntactic_independent&lt;br /&gt;
Op5 ---&amp;gt; Op2  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op3  :: Enable=syntactic_fully_independent&lt;br /&gt;
Op5 ---&amp;gt; Op4  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op5  :: Enable=syntactic_unchanged&lt;br /&gt;
% Finished CBC Enabling Analysis 810 ms walltime (770 ms runtime), since start: 1650 ms&lt;br /&gt;
% CBC Enabling Stats:&lt;br /&gt;
% Nr of events: 5&lt;br /&gt;
% Nr of cbc calls: 30, Timeout results: 2&lt;br /&gt;
Origin,Op1,Op2,Op3,Op4,Op5&lt;br /&gt;
INITIALISATION,guaranteed,impossible,guaranteed,impossible,guaranteed&lt;br /&gt;
Op1,timeout_possible_disable,keep,keep,impossible_keep,syntactic_independent&lt;br /&gt;
Op2,guaranteed,impossible,guaranteed,impossible_keep,impossible&lt;br /&gt;
Op3,timeout_possible,impossible_keep,guaranteed,impossible_keep,syntactic_fully_independent&lt;br /&gt;
Op4,impossible_keep,syntactic_unchanged,syntactic_unchanged,syntactic_keep,impossible_keep&lt;br /&gt;
Op5,syntactic_independent,syntactic_unchanged,syntactic_fully_independent,syntactic_unchanged,syntactic_unchanged&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To perform enabling analysis from the command line and save the results to a CSV-file use the following commando:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli file.mch -enabling_analysis_csv FILE &amp;lt;/pre&amp;gt;&lt;br /&gt;
where FILE is the name of the CSV-file in which the results of the analysis are stored.&lt;br /&gt;
&lt;br /&gt;
== References and Footnotes ==&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3480</id>
		<title>Tutorial Enabling Analysis</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3480"/>
		<updated>2016-02-11T15:48:41Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Performing Enabling Analysis within ProB */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The B-method and in particular its successor Event-B are methodologies for formal development and verification of systems. In Event-B, a machine is usually viewed as a reactive system executing continuously enabled (atomic) events in an interleaved fashion. Thus, parallel events of the system are easily modeled as an interleaving of operation executions. On the other hand, the introduction of abstract counters is required when events are supposed to be executed in some (sequential) order. This, however, can in some cases slow the work of understanding and verifying a model since identifying the sequential ordering of events in an Event-B model is not that obvious. Thus, using methods for determining the control flow can be sometimes very beneficial for understanding the model, as well as for techniques for automatic verification such as model checking.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we present a static analysis for B and Event-B that can be used to reveal the control flow of a machine and to optimize model checking of models written in B and Event-B (see also [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Guard_Evaluation Tutorial on Partial Guard Evaluation ]). The results of the analysis, designated also as ‘’enabling analysis’’, can be presented as relations by means of a table or by means of a graph. For simplicity, we will concentrate mainly on B and use the terminology of the formalism.&lt;br /&gt;
&lt;br /&gt;
== Enabling Relations ==&lt;br /&gt;
What we want to find out is how the operations influence each other within a B model. In other words, for each pair (op1,op2) of operations we try to determine as precise as possible how op1 can affect the guard condition of op2 with regard to enabledness. To determine the enabling relations between operations we use syntactic analyses, as well as the constraint-based abilities of ProB.&lt;br /&gt;
&lt;br /&gt;
Consider the following B machine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE Example&lt;br /&gt;
VARIABLES x, y, z&lt;br /&gt;
INVARIANT&lt;br /&gt;
    x:NATURAL&lt;br /&gt;
  &amp;amp; y:INTEGER&lt;br /&gt;
  &amp;amp; z:INTEGER&lt;br /&gt;
INITIALISATION &lt;br /&gt;
  x:=6 || y:=-2 || z := 0&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Op1 = PRE x + y &amp;gt;= 4  THEN x:=x+2 || y:=2 END;&lt;br /&gt;
  Op2 = PRE x mod 2 = 1 THEN x:=x+1 || y:=2 END;&lt;br /&gt;
  Op3 = PRE x mod 2 = 0 THEN x:=x+2 END;&lt;br /&gt;
  Op4 = PRE x&amp;lt;0 THEN y:=y-1 END;&lt;br /&gt;
  Op5 = PRE y/=2 THEN z:=3 END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The machine has three variables x,y,z, where x ranges over the domain of natural numbers and y and z over the domain of all integers. For this machine we have 25 pairs of operations for which we want to determine the respective enabling relations. Additionally, we identify 5 further pairs that show the influence of the INITIALISATION on the guard conditions of all other operations. Consider, for example, the pair (Op2,Op1) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op1 is enabled in each state of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; where the predicate ‘x+y&amp;gt;=4’ is fulfilled. Since the effect of Op2 assigns 2 to y and increments x by one upon condition that x is a positive odd number in the before-state of Op2, we can assume that Op1 is always enabled after the execution of Op2. In other words, in all after-states of Op2 the operation Op1 is guaranteed to be enabled. This relation between Op2 and Op1 we can illustrate as follows: &lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above the green boxes denote that the evaluation of the guard of Op1 is true, whereas the red boxes denote that the evaluation of the guard of Op1 is false. &lt;br /&gt;
&lt;br /&gt;
Another pair of interest is (Op2,Op5) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op5 is enabled only in those states in which y is not equal to 2. Obviously, in each after-state of Op2 y is equal to 2 and thus we can conclude that Op5 is impossible to be enabled after each execution of Op2. Such a relation between two operations we denote as ‘’impossible’’ and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
Both arrows in the illustration of the ‘’impossible’’ relation indicate that whether the guard condition of Op5 is fulfilled or not in a before-state of Op2 operation Op5 will be disabled in the respective after-state of Op2. In order to recognize a tuple (op1,op2) as ‘’impossible’’ we require that op2 is always disabled after op1 without further considering whether op2 is always enabled or always disabled in the before-states of op1. &lt;br /&gt;
&lt;br /&gt;
Consider, for instance, the pair (Op2, Op2) in the machine above. We can easily conclude that Op2 becomes disabled after it is executed and clearly, the second case (\false -&amp;gt; \false) of the impossible relation is not possible for (Op2, Op2). This gives rise of introducing another (more precise) impossible relation:&lt;br /&gt;
 &lt;br /&gt;
[[File:ImpossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Accordingly, we can derive another relation from ‘’impossible’’ for which only the second case of the ‘’impossible’’ relation is fulfilled:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
As an example for a pair of operations that fulfills the ‘’impossible_keep’’ requirement you can take, for example, the pair (Op3,Op2) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Since Op2 and Op3 cannot be both enabled in a state and the execution of Op3 cannot enable Op2, then we can easily conclude that Op2 remains always disabled after Op3.&lt;br /&gt;
&lt;br /&gt;
Similarly as for ‘’impossible’’, one could derive two further enabling relations from ‘’guaranteed’’:&lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedEnableKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Another interesting class of enabling relations that could be helpful for better understanding and analyzing B and Event-B models is that of the ‘’keep’’ relations. We say that an operation op1 ‘’keeps’’ another operation op2 if op1 cannot change the status of the enabling condition of op2, i.e. op1 keeps op2 enabled respectively disabled. This relationship could be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:KeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
We can take (Op1,Op2) and (Op1,Op3) as examples of pairs in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; that are elements of the keep relation. ‘’keep’’ relations can sometimes be easily determined by analyzing just the syntactic structure of both operations, or more precisely the “read” and “write” sets of both operations.&amp;lt;ref&amp;gt;For an operation op the set read(op) denotes the set of variables that are read by op. Accordingly, by write(op) we denote the set of variables that are written by op.&amp;lt;/ref&amp;gt; If, for example, an operation op1 does not write any variable of the machine that is read in the guard condition of op2, then we can infer that op1 ‘’keeps’’ op2. In that case we also say that op1 does not change op2 syntactically. In the class of the ‘’keep’’ relations are included also relations such as independence. Two operations op1 and op2 are called independent if each of them cannot disable the other operation and the both orders of execution &amp;lt;op1,op2&amp;gt; and &amp;lt;op2,op1&amp;gt; have the same effect.&amp;lt;ref&amp;gt;See the [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Order_Reduction Tutorial on Partial Order Reduction] for more information on independence between operations.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three classes (‘’guaranteed’’, ‘’impossible’’ and ‘’keep’’) of enabling relations presented so far represent definite relations. That is, if a pair of operations (op1,op2) is confirmed to be a relation of one of this three classes, then we can certainly say what effect on the enabling condition of op2 would the execution of op1 have. However, for some pairs of operations we cannot certainly say what effect an operation would have on the enabling condition of another operation. This is due to the fact that the enabling status of an operation does not only depend on the effect of the executed operations, but also on the current variables’ evaluation. Take, for instance, the tuple (Op3,Op1) from the B machine above. Considering the action part of Op3 and the guard condition of Op1 we can assume that Op3 can enable Op1. Since the guard of Op1 depends not only on the current value of x, but also on y, there could be transitions s&amp;lt;math&amp;gt;\overset{Op_3}{\rightarrow}&amp;lt;/math&amp;gt;s&#039; in the state space of the machine where Op1 is disabled in both states ‘’s’’ and ‘’s’’’. Though, what we could definitely say is that Op3 cannot disable Op1. This relationship we can illustrate as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleEnableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
The opposite relation of “possible_enable” is the relation where an operation op2 can disable another operation op1. Formally, we say that op2 can disable op1 if op2 may disable op1 and op2 cannot enable op1. This relationship is denoted as “possible_disable” and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
In order to determine how operations influence each other we need to assure first that these are feasible. An operation ‘’op’’ is said to be feasible if there is a state of the machine that satisfies the invariant of the machine and in which ‘’op’’ is enabled. In the B machine above the operation Op4, for example, is not feasible. Obviously, Op4 is enabled only in states where x is a negative number and states in which x is a negative number are visibly not consistent with the invariant since &amp;quot;x : NATURAL&amp;quot;. Such incompatibilities are sometimes of great importance for the modeler and therefore they should be revealed in the process of computing the enabling relations. In our case for each pair of operations (Op4,-) and (-,Op4) the status “infeasible” will be returned.&lt;br /&gt;
&lt;br /&gt;
We can now list all possible enabling relations for the machine &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; by means of a table. For each entry in the table the operation in the row is the operation whose effect is studied on the status of the guard of the operation in the column.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingResults.png]]&lt;br /&gt;
&lt;br /&gt;
== Summary of the Enabling Relations ==&lt;br /&gt;
&lt;br /&gt;
In the following, we summarize most of the enabling relations that we could identify. For each of the enabling relations we have given an appropriate example. In the examples below we compute the effect of executing ‘op1’ on the status of the guard of ‘op2’. The relation identifiers are the same as they appear as results in ProB.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;guaranteed&#039;&#039;: op2 guaranteed to be executable after op1.&lt;br /&gt;
[[File: GuaranteedExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_enable&#039;&#039;: op2 is guaranteed to become enabled after op1.&lt;br /&gt;
[[File: GuaranteedEnableExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_keep&#039;&#039;: op2 is guaranteed to stay enabled after op1.&lt;br /&gt;
[[File: GuaranteedKeepExample.png]]&lt;br /&gt;
* &#039;&#039;impossible&#039;&#039;: op2 is impossible to be executed after op1.&lt;br /&gt;
[[File: ImpossibleExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_disable&#039;&#039;: op2 is guaranteed to become disabled after op1.&lt;br /&gt;
[[File: ImpossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_keep&#039;&#039;: op2 is impossible to become enabled after op1.&lt;br /&gt;
[[File: ImpossibleKeepExample.png]]&lt;br /&gt;
* &#039;&#039;keep&#039;&#039;: op2 always stays enabled resp. disabled after op1.&lt;br /&gt;
[[File: KeepExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_unchanged&#039;&#039;: op1 does not write any variable read in the guard of op2, i.e. write(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticUnchangedExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_independent&#039;&#039;: op1 and op2 are syntactically independent, i.e. read(op1) /\ write(op2) = {} &amp;amp; write(op1) /\ read(op2) = {} &amp;amp; write(op1) /\ write(op2) = {}&lt;br /&gt;
[[File: SyntacticIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;syntactically_fully_independent&#039;&#039;: op1 and op2 are syntactically independent and additionally, read(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticFullyIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;possible_enable&#039;&#039;: op2 possible after op1, but op2 cannot be disabled by op1.&lt;br /&gt;
[[File: PossibleEnableExample.png]]&lt;br /&gt;
* &#039;&#039;possible_disable&#039;&#039;: op2 possible after iop1, but op2 cannot be enabled by op1.&lt;br /&gt;
[[File: PossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;infeasible&#039;&#039;: op1 is not feasible and thus cannot influence op2.&lt;br /&gt;
[[File: InfeasibleExample.png]]&lt;br /&gt;
&lt;br /&gt;
== Performing Enabling Analysis within ProB  ==&lt;br /&gt;
&lt;br /&gt;
Within &amp;lt;tt&amp;gt;ProB Tcl/Tk&amp;lt;/tt&amp;gt; you can find the menu &amp;quot;Enabling Analysis&amp;quot; in the &amp;quot;Analysis&amp;quot; menu of the menu bar.  The &amp;quot;Enabling Analysis&amp;quot; menu provides multiple commands:&lt;br /&gt;
* &amp;quot;Enabling Analysis (Table)&amp;quot;: this command performs a (fast) enabling analysis on the respective B model using a time-out of 300 ms for the constraint-solver calls. The result of the enabling analysis is shown in a table. The table lists all enabling relations between the operations of the loaded B model. These can be exported to a CSV file. The table for &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; at the end of the &#039;&#039;&#039; Enabling Relations&#039;&#039;&#039; section was constructed this way.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Precise, Table)&amp;quot;: this command performs an enabling analysis using a time-out of 2800 ms for each of the constraint-solver calls. As for the command above, the result of the analysis is shown in a table that can be exported to a CSV file.&lt;br /&gt;
* &amp;quot;Enabling Relations After...&amp;quot;: this command computes all the enabling relations involving an operation chosen by the user.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Graph)&amp;quot;: this command performs the fast enabling analysis but displays the results as a graph. In case the preference &amp;quot;DOT_SHOW_OP_READ_WRITES&amp;quot; is set for each operation the read/write information is displayed.&lt;br /&gt;
* &amp;quot;Enabling Analysis (POR)...&amp;quot;: this menu provides further commands for another form of enabling analysis the results of which are used for the partial guard evaluation optimisation in ProB.&lt;br /&gt;
* &amp;quot;Read/Write Matrix (Table)&amp;quot;: this command performs syntactic analysis on the model. The analysis determines the read and write sets for each operation of the machine.&lt;br /&gt;
* &amp;quot;Dependence Analysis (Table)&amp;quot;: this command performs a dependency analysis for each pair of operations. More specifically, the analysis determine which operations are dependent or independent to each other.&lt;br /&gt;
&lt;br /&gt;
With the command line version of ProB (probcli) one can perform an enabling analysis on a B or Event-B model by means of the &amp;lt;tt&amp;gt;-enabling_analysis&amp;lt;/tt&amp;gt; option. The results of the analysis, as well as other intermediate data is printed out on the console:&lt;br /&gt;
&amp;lt;pre&amp;gt;$ probcli Example.mch -enabling_analysis&lt;br /&gt;
CHECKING ENABLING AFTER INITIALISATION&lt;br /&gt;
INITIALISATION ---&amp;gt; Op1  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op2  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op3  :: ok : guaranteed&lt;br /&gt;
INITIALISATION ---&amp;gt; Op4  :: impossible&lt;br /&gt;
INITIALISATION ---&amp;gt; Op5  :: ok : guaranteed&lt;br /&gt;
.....&lt;br /&gt;
CHECKING ENABLING AFTER: Op5 r:[y] / w:[z]&lt;br /&gt;
Op5 ---&amp;gt; Op1  :: Enable=syntactic_independent&lt;br /&gt;
Op5 ---&amp;gt; Op2  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op3  :: Enable=syntactic_fully_independent&lt;br /&gt;
Op5 ---&amp;gt; Op4  :: Enable=syntactic_unchanged&lt;br /&gt;
Op5 ---&amp;gt; Op5  :: Enable=syntactic_unchanged&lt;br /&gt;
% Finished CBC Enabling Analysis 810 ms walltime (770 ms runtime), since start: 1650 ms&lt;br /&gt;
% CBC Enabling Stats:&lt;br /&gt;
% Nr of events: 5&lt;br /&gt;
% Nr of cbc calls: 30, Timeout results: 2&lt;br /&gt;
Origin,Op1,Op2,Op3,Op4,Op5&lt;br /&gt;
INITIALISATION,guaranteed,impossible,guaranteed,impossible,guaranteed&lt;br /&gt;
Op1,timeout_possible_disable,keep,keep,impossible_keep,syntactic_independent&lt;br /&gt;
Op2,guaranteed,impossible,guaranteed,impossible_keep,impossible&lt;br /&gt;
Op3,timeout_possible,impossible_keep,guaranteed,impossible_keep,syntactic_fully_independent&lt;br /&gt;
Op4,impossible_keep,syntactic_unchanged,syntactic_unchanged,syntactic_keep,impossible_keep&lt;br /&gt;
Op5,syntactic_independent,syntactic_unchanged,syntactic_fully_independent,syntactic_unchanged,syntactic_unchanged&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References and Footnotes ==&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3479</id>
		<title>Tutorial Enabling Analysis</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3479"/>
		<updated>2016-02-11T15:36:54Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: /* Computing Enabling Relations with ProB */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The B-method and in particular its successor Event-B are methodologies for formal development and verification of systems. In Event-B, a machine is usually viewed as a reactive system executing continuously enabled (atomic) events in an interleaved fashion. Thus, parallel events of the system are easily modeled as an interleaving of operation executions. On the other hand, the introduction of abstract counters is required when events are supposed to be executed in some (sequential) order. This, however, can in some cases slow the work of understanding and verifying a model since identifying the sequential ordering of events in an Event-B model is not that obvious. Thus, using methods for determining the control flow can be sometimes very beneficial for understanding the model, as well as for techniques for automatic verification such as model checking.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we present a static analysis for B and Event-B that can be used to reveal the control flow of a machine and to optimize model checking of models written in B and Event-B (see also [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Guard_Evaluation Tutorial on Partial Guard Evaluation ]). The results of the analysis, designated also as ‘’enabling analysis’’, can be presented as relations by means of a table or by means of a graph. For simplicity, we will concentrate mainly on B and use the terminology of the formalism.&lt;br /&gt;
&lt;br /&gt;
== Enabling Relations ==&lt;br /&gt;
What we want to find out is how the operations influence each other within a B model. In other words, for each pair (op1,op2) of operations we try to determine as precise as possible how op1 can affect the guard condition of op2 with regard to enabledness. To determine the enabling relations between operations we use syntactic analyses, as well as the constraint-based abilities of ProB.&lt;br /&gt;
&lt;br /&gt;
Consider the following B machine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE Example&lt;br /&gt;
VARIABLES x, y, z&lt;br /&gt;
INVARIANT&lt;br /&gt;
    x:NATURAL&lt;br /&gt;
  &amp;amp; y:INTEGER&lt;br /&gt;
  &amp;amp; z:INTEGER&lt;br /&gt;
INITIALISATION &lt;br /&gt;
  x:=6 || y:=-2 || z := 0&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Op1 = PRE x + y &amp;gt;= 4  THEN x:=x+2 || y:=2 END;&lt;br /&gt;
  Op2 = PRE x mod 2 = 1 THEN x:=x+1 || y:=2 END;&lt;br /&gt;
  Op3 = PRE x mod 2 = 0 THEN x:=x+2 END;&lt;br /&gt;
  Op4 = PRE x&amp;lt;0 THEN y:=y-1 END;&lt;br /&gt;
  Op5 = PRE y/=2 THEN z:=3 END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The machine has three variables x,y,z, where x ranges over the domain of natural numbers and y and z over the domain of all integers. For this machine we have 25 pairs of operations for which we want to determine the respective enabling relations. Additionally, we identify 5 further pairs that show the influence of the INITIALISATION on the guard conditions of all other operations. Consider, for example, the pair (Op2,Op1) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op1 is enabled in each state of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; where the predicate ‘x+y&amp;gt;=4’ is fulfilled. Since the effect of Op2 assigns 2 to y and increments x by one upon condition that x is a positive odd number in the before-state of Op2, we can assume that Op1 is always enabled after the execution of Op2. In other words, in all after-states of Op2 the operation Op1 is guaranteed to be enabled. This relation between Op2 and Op1 we can illustrate as follows: &lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above the green boxes denote that the evaluation of the guard of Op1 is true, whereas the red boxes denote that the evaluation of the guard of Op1 is false. &lt;br /&gt;
&lt;br /&gt;
Another pair of interest is (Op2,Op5) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op5 is enabled only in those states in which y is not equal to 2. Obviously, in each after-state of Op2 y is equal to 2 and thus we can conclude that Op5 is impossible to be enabled after each execution of Op2. Such a relation between two operations we denote as ‘’impossible’’ and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
Both arrows in the illustration of the ‘’impossible’’ relation indicate that whether the guard condition of Op5 is fulfilled or not in a before-state of Op2 operation Op5 will be disabled in the respective after-state of Op2. In order to recognize a tuple (op1,op2) as ‘’impossible’’ we require that op2 is always disabled after op1 without further considering whether op2 is always enabled or always disabled in the before-states of op1. &lt;br /&gt;
&lt;br /&gt;
Consider, for instance, the pair (Op2, Op2) in the machine above. We can easily conclude that Op2 becomes disabled after it is executed and clearly, the second case (\false -&amp;gt; \false) of the impossible relation is not possible for (Op2, Op2). This gives rise of introducing another (more precise) impossible relation:&lt;br /&gt;
 &lt;br /&gt;
[[File:ImpossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Accordingly, we can derive another relation from ‘’impossible’’ for which only the second case of the ‘’impossible’’ relation is fulfilled:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
As an example for a pair of operations that fulfills the ‘’impossible_keep’’ requirement you can take, for example, the pair (Op3,Op2) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Since Op2 and Op3 cannot be both enabled in a state and the execution of Op3 cannot enable Op2, then we can easily conclude that Op2 remains always disabled after Op3.&lt;br /&gt;
&lt;br /&gt;
Similarly as for ‘’impossible’’, one could derive two further enabling relations from ‘’guaranteed’’:&lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedEnableKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Another interesting class of enabling relations that could be helpful for better understanding and analyzing B and Event-B models is that of the ‘’keep’’ relations. We say that an operation op1 ‘’keeps’’ another operation op2 if op1 cannot change the status of the enabling condition of op2, i.e. op1 keeps op2 enabled respectively disabled. This relationship could be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:KeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
We can take (Op1,Op2) and (Op1,Op3) as examples of pairs in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; that are elements of the keep relation. ‘’keep’’ relations can sometimes be easily determined by analyzing just the syntactic structure of both operations, or more precisely the “read” and “write” sets of both operations.&amp;lt;ref&amp;gt;For an operation op the set read(op) denotes the set of variables that are read by op. Accordingly, by write(op) we denote the set of variables that are written by op.&amp;lt;/ref&amp;gt; If, for example, an operation op1 does not write any variable of the machine that is read in the guard condition of op2, then we can infer that op1 ‘’keeps’’ op2. In that case we also say that op1 does not change op2 syntactically. In the class of the ‘’keep’’ relations are included also relations such as independence. Two operations op1 and op2 are called independent if each of them cannot disable the other operation and the both orders of execution &amp;lt;op1,op2&amp;gt; and &amp;lt;op2,op1&amp;gt; have the same effect.&amp;lt;ref&amp;gt;See the [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Order_Reduction Tutorial on Partial Order Reduction] for more information on independence between operations.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three classes (‘’guaranteed’’, ‘’impossible’’ and ‘’keep’’) of enabling relations presented so far represent definite relations. That is, if a pair of operations (op1,op2) is confirmed to be a relation of one of this three classes, then we can certainly say what effect on the enabling condition of op2 would the execution of op1 have. However, for some pairs of operations we cannot certainly say what effect an operation would have on the enabling condition of another operation. This is due to the fact that the enabling status of an operation does not only depend on the effect of the executed operations, but also on the current variables’ evaluation. Take, for instance, the tuple (Op3,Op1) from the B machine above. Considering the action part of Op3 and the guard condition of Op1 we can assume that Op3 can enable Op1. Since the guard of Op1 depends not only on the current value of x, but also on y, there could be transitions s&amp;lt;math&amp;gt;\overset{Op_3}{\rightarrow}&amp;lt;/math&amp;gt;s&#039; in the state space of the machine where Op1 is disabled in both states ‘’s’’ and ‘’s’’’. Though, what we could definitely say is that Op3 cannot disable Op1. This relationship we can illustrate as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleEnableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
The opposite relation of “possible_enable” is the relation where an operation op2 can disable another operation op1. Formally, we say that op2 can disable op1 if op2 may disable op1 and op2 cannot enable op1. This relationship is denoted as “possible_disable” and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
In order to determine how operations influence each other we need to assure first that these are feasible. An operation ‘’op’’ is said to be feasible if there is a state of the machine that satisfies the invariant of the machine and in which ‘’op’’ is enabled. In the B machine above the operation Op4, for example, is not feasible. Obviously, Op4 is enabled only in states where x is a negative number and states in which x is a negative number are visibly not consistent with the invariant since &amp;quot;x : NATURAL&amp;quot;. Such incompatibilities are sometimes of great importance for the modeler and therefore they should be revealed in the process of computing the enabling relations. In our case for each pair of operations (Op4,-) and (-,Op4) the status “infeasible” will be returned.&lt;br /&gt;
&lt;br /&gt;
We can now list all possible enabling relations for the machine &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; by means of a table. For each entry in the table the operation in the row is the operation whose effect is studied on the status of the guard of the operation in the column.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingResults.png]]&lt;br /&gt;
&lt;br /&gt;
== Summary of the Enabling Relations ==&lt;br /&gt;
&lt;br /&gt;
In the following, we summarize most of the enabling relations that we could identify. For each of the enabling relations we have given an appropriate example. In the examples below we compute the effect of executing ‘op1’ on the status of the guard of ‘op2’. The relation identifiers are the same as they appear as results in ProB.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;guaranteed&#039;&#039;: op2 guaranteed to be executable after op1.&lt;br /&gt;
[[File: GuaranteedExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_enable&#039;&#039;: op2 is guaranteed to become enabled after op1.&lt;br /&gt;
[[File: GuaranteedEnableExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_keep&#039;&#039;: op2 is guaranteed to stay enabled after op1.&lt;br /&gt;
[[File: GuaranteedKeepExample.png]]&lt;br /&gt;
* &#039;&#039;impossible&#039;&#039;: op2 is impossible to be executed after op1.&lt;br /&gt;
[[File: ImpossibleExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_disable&#039;&#039;: op2 is guaranteed to become disabled after op1.&lt;br /&gt;
[[File: ImpossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_keep&#039;&#039;: op2 is impossible to become enabled after op1.&lt;br /&gt;
[[File: ImpossibleKeepExample.png]]&lt;br /&gt;
* &#039;&#039;keep&#039;&#039;: op2 always stays enabled resp. disabled after op1.&lt;br /&gt;
[[File: KeepExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_unchanged&#039;&#039;: op1 does not write any variable read in the guard of op2, i.e. write(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticUnchangedExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_independent&#039;&#039;: op1 and op2 are syntactically independent, i.e. read(op1) /\ write(op2) = {} &amp;amp; write(op1) /\ read(op2) = {} &amp;amp; write(op1) /\ write(op2) = {}&lt;br /&gt;
[[File: SyntacticIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;syntactically_fully_independent&#039;&#039;: op1 and op2 are syntactically independent and additionally, read(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticFullyIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;possible_enable&#039;&#039;: op2 possible after op1, but op2 cannot be disabled by op1.&lt;br /&gt;
[[File: PossibleEnableExample.png]]&lt;br /&gt;
* &#039;&#039;possible_disable&#039;&#039;: op2 possible after iop1, but op2 cannot be enabled by op1.&lt;br /&gt;
[[File: PossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;infeasible&#039;&#039;: op1 is not feasible and thus cannot influence op2.&lt;br /&gt;
[[File: InfeasibleExample.png]]&lt;br /&gt;
&lt;br /&gt;
== Performing Enabling Analysis within ProB  ==&lt;br /&gt;
&lt;br /&gt;
Within &amp;lt;tt&amp;gt;ProB Tcl/Tk&amp;lt;/tt&amp;gt; you can find the menu &amp;quot;Enabling Analysis&amp;quot; in the &amp;quot;Analysis&amp;quot; menu of the menu bar.  The &amp;quot;Enabling Analysis&amp;quot; menu provides multiple commands:&lt;br /&gt;
* &amp;quot;Enabling Analysis (Table)&amp;quot;: this command performs a (fast) enabling analysis on the respective B model using a time-out of 300 ms for the constraint-solver calls. The result of the enabling analysis is shown in a table. The table lists all enabling relations between the operations of the loaded B model. These can be exported to a CSV file. The table for &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; at the end of the &#039;&#039;&#039; Enabling Relations&#039;&#039;&#039; section was constructed this way.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Precise, Table)&amp;quot;: this command performs an enabling analysis using a time-out of 2800 ms for each of the constraint-solver calls. As for the command above, the result of the analysis is shown in a table that can be exported to a CSV file.&lt;br /&gt;
* &amp;quot;Enabling Relations After...&amp;quot;: this command computes all the enabling relations involving an operation chosen by the user.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Graph)&amp;quot;: this command performs the fast enabling analysis but displays the results as a graph. In case the preference &amp;quot;DOT_SHOW_OP_READ_WRITES&amp;quot; is set for each operation the read/write information is displayed.&lt;br /&gt;
* &amp;quot;Enabling Analysis (POR)...&amp;quot;: this menu provides further commands for another form of enabling analysis the results of which are used for the partial guard evaluation optimisation in ProB.&lt;br /&gt;
* &amp;quot;Read/Write Matrix (Table)&amp;quot;: this command performs syntactic analysis on the model. The analysis determines the read and write sets for each operation of the machine.&lt;br /&gt;
* &amp;quot;Dependence Analysis (Table)&amp;quot;: this command performs a dependency analysis for each pair of operations. More specifically, the analysis determine which operations are dependent or independent to each other.&lt;br /&gt;
&lt;br /&gt;
== References and Footnotes ==&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3478</id>
		<title>Tutorial Enabling Analysis</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3478"/>
		<updated>2016-02-11T15:36:22Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The B-method and in particular its successor Event-B are methodologies for formal development and verification of systems. In Event-B, a machine is usually viewed as a reactive system executing continuously enabled (atomic) events in an interleaved fashion. Thus, parallel events of the system are easily modeled as an interleaving of operation executions. On the other hand, the introduction of abstract counters is required when events are supposed to be executed in some (sequential) order. This, however, can in some cases slow the work of understanding and verifying a model since identifying the sequential ordering of events in an Event-B model is not that obvious. Thus, using methods for determining the control flow can be sometimes very beneficial for understanding the model, as well as for techniques for automatic verification such as model checking.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we present a static analysis for B and Event-B that can be used to reveal the control flow of a machine and to optimize model checking of models written in B and Event-B (see also [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Guard_Evaluation Tutorial on Partial Guard Evaluation ]). The results of the analysis, designated also as ‘’enabling analysis’’, can be presented as relations by means of a table or by means of a graph. For simplicity, we will concentrate mainly on B and use the terminology of the formalism.&lt;br /&gt;
&lt;br /&gt;
== Enabling Relations ==&lt;br /&gt;
What we want to find out is how the operations influence each other within a B model. In other words, for each pair (op1,op2) of operations we try to determine as precise as possible how op1 can affect the guard condition of op2 with regard to enabledness. To determine the enabling relations between operations we use syntactic analyses, as well as the constraint-based abilities of ProB.&lt;br /&gt;
&lt;br /&gt;
Consider the following B machine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE Example&lt;br /&gt;
VARIABLES x, y, z&lt;br /&gt;
INVARIANT&lt;br /&gt;
    x:NATURAL&lt;br /&gt;
  &amp;amp; y:INTEGER&lt;br /&gt;
  &amp;amp; z:INTEGER&lt;br /&gt;
INITIALISATION &lt;br /&gt;
  x:=6 || y:=-2 || z := 0&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Op1 = PRE x + y &amp;gt;= 4  THEN x:=x+2 || y:=2 END;&lt;br /&gt;
  Op2 = PRE x mod 2 = 1 THEN x:=x+1 || y:=2 END;&lt;br /&gt;
  Op3 = PRE x mod 2 = 0 THEN x:=x+2 END;&lt;br /&gt;
  Op4 = PRE x&amp;lt;0 THEN y:=y-1 END;&lt;br /&gt;
  Op5 = PRE y/=2 THEN z:=3 END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The machine has three variables x,y,z, where x ranges over the domain of natural numbers and y and z over the domain of all integers. For this machine we have 25 pairs of operations for which we want to determine the respective enabling relations. Additionally, we identify 5 further pairs that show the influence of the INITIALISATION on the guard conditions of all other operations. Consider, for example, the pair (Op2,Op1) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op1 is enabled in each state of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; where the predicate ‘x+y&amp;gt;=4’ is fulfilled. Since the effect of Op2 assigns 2 to y and increments x by one upon condition that x is a positive odd number in the before-state of Op2, we can assume that Op1 is always enabled after the execution of Op2. In other words, in all after-states of Op2 the operation Op1 is guaranteed to be enabled. This relation between Op2 and Op1 we can illustrate as follows: &lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above the green boxes denote that the evaluation of the guard of Op1 is true, whereas the red boxes denote that the evaluation of the guard of Op1 is false. &lt;br /&gt;
&lt;br /&gt;
Another pair of interest is (Op2,Op5) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op5 is enabled only in those states in which y is not equal to 2. Obviously, in each after-state of Op2 y is equal to 2 and thus we can conclude that Op5 is impossible to be enabled after each execution of Op2. Such a relation between two operations we denote as ‘’impossible’’ and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
Both arrows in the illustration of the ‘’impossible’’ relation indicate that whether the guard condition of Op5 is fulfilled or not in a before-state of Op2 operation Op5 will be disabled in the respective after-state of Op2. In order to recognize a tuple (op1,op2) as ‘’impossible’’ we require that op2 is always disabled after op1 without further considering whether op2 is always enabled or always disabled in the before-states of op1. &lt;br /&gt;
&lt;br /&gt;
Consider, for instance, the pair (Op2, Op2) in the machine above. We can easily conclude that Op2 becomes disabled after it is executed and clearly, the second case (\false -&amp;gt; \false) of the impossible relation is not possible for (Op2, Op2). This gives rise of introducing another (more precise) impossible relation:&lt;br /&gt;
 &lt;br /&gt;
[[File:ImpossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Accordingly, we can derive another relation from ‘’impossible’’ for which only the second case of the ‘’impossible’’ relation is fulfilled:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
As an example for a pair of operations that fulfills the ‘’impossible_keep’’ requirement you can take, for example, the pair (Op3,Op2) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Since Op2 and Op3 cannot be both enabled in a state and the execution of Op3 cannot enable Op2, then we can easily conclude that Op2 remains always disabled after Op3.&lt;br /&gt;
&lt;br /&gt;
Similarly as for ‘’impossible’’, one could derive two further enabling relations from ‘’guaranteed’’:&lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedEnableKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Another interesting class of enabling relations that could be helpful for better understanding and analyzing B and Event-B models is that of the ‘’keep’’ relations. We say that an operation op1 ‘’keeps’’ another operation op2 if op1 cannot change the status of the enabling condition of op2, i.e. op1 keeps op2 enabled respectively disabled. This relationship could be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:KeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
We can take (Op1,Op2) and (Op1,Op3) as examples of pairs in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; that are elements of the keep relation. ‘’keep’’ relations can sometimes be easily determined by analyzing just the syntactic structure of both operations, or more precisely the “read” and “write” sets of both operations.&amp;lt;ref&amp;gt;For an operation op the set read(op) denotes the set of variables that are read by op. Accordingly, by write(op) we denote the set of variables that are written by op.&amp;lt;/ref&amp;gt; If, for example, an operation op1 does not write any variable of the machine that is read in the guard condition of op2, then we can infer that op1 ‘’keeps’’ op2. In that case we also say that op1 does not change op2 syntactically. In the class of the ‘’keep’’ relations are included also relations such as independence. Two operations op1 and op2 are called independent if each of them cannot disable the other operation and the both orders of execution &amp;lt;op1,op2&amp;gt; and &amp;lt;op2,op1&amp;gt; have the same effect.&amp;lt;ref&amp;gt;See the [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Order_Reduction Tutorial on Partial Order Reduction] for more information on independence between operations.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three classes (‘’guaranteed’’, ‘’impossible’’ and ‘’keep’’) of enabling relations presented so far represent definite relations. That is, if a pair of operations (op1,op2) is confirmed to be a relation of one of this three classes, then we can certainly say what effect on the enabling condition of op2 would the execution of op1 have. However, for some pairs of operations we cannot certainly say what effect an operation would have on the enabling condition of another operation. This is due to the fact that the enabling status of an operation does not only depend on the effect of the executed operations, but also on the current variables’ evaluation. Take, for instance, the tuple (Op3,Op1) from the B machine above. Considering the action part of Op3 and the guard condition of Op1 we can assume that Op3 can enable Op1. Since the guard of Op1 depends not only on the current value of x, but also on y, there could be transitions s&amp;lt;math&amp;gt;\overset{Op_3}{\rightarrow}&amp;lt;/math&amp;gt;s&#039; in the state space of the machine where Op1 is disabled in both states ‘’s’’ and ‘’s’’’. Though, what we could definitely say is that Op3 cannot disable Op1. This relationship we can illustrate as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleEnableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
The opposite relation of “possible_enable” is the relation where an operation op2 can disable another operation op1. Formally, we say that op2 can disable op1 if op2 may disable op1 and op2 cannot enable op1. This relationship is denoted as “possible_disable” and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
In order to determine how operations influence each other we need to assure first that these are feasible. An operation ‘’op’’ is said to be feasible if there is a state of the machine that satisfies the invariant of the machine and in which ‘’op’’ is enabled. In the B machine above the operation Op4, for example, is not feasible. Obviously, Op4 is enabled only in states where x is a negative number and states in which x is a negative number are visibly not consistent with the invariant since &amp;quot;x : NATURAL&amp;quot;. Such incompatibilities are sometimes of great importance for the modeler and therefore they should be revealed in the process of computing the enabling relations. In our case for each pair of operations (Op4,-) and (-,Op4) the status “infeasible” will be returned.&lt;br /&gt;
&lt;br /&gt;
We can now list all possible enabling relations for the machine &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; by means of a table. For each entry in the table the operation in the row is the operation whose effect is studied on the status of the guard of the operation in the column.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingResults.png]]&lt;br /&gt;
&lt;br /&gt;
== Summary of the Enabling Relations ==&lt;br /&gt;
&lt;br /&gt;
In the following, we summarize most of the enabling relations that we could identify. For each of the enabling relations we have given an appropriate example. In the examples below we compute the effect of executing ‘op1’ on the status of the guard of ‘op2’. The relation identifiers are the same as they appear as results in ProB.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;guaranteed&#039;&#039;: op2 guaranteed to be executable after op1.&lt;br /&gt;
[[File: GuaranteedExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_enable&#039;&#039;: op2 is guaranteed to become enabled after op1.&lt;br /&gt;
[[File: GuaranteedEnableExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_keep&#039;&#039;: op2 is guaranteed to stay enabled after op1.&lt;br /&gt;
[[File: GuaranteedKeepExample.png]]&lt;br /&gt;
* &#039;&#039;impossible&#039;&#039;: op2 is impossible to be executed after op1.&lt;br /&gt;
[[File: ImpossibleExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_disable&#039;&#039;: op2 is guaranteed to become disabled after op1.&lt;br /&gt;
[[File: ImpossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_keep&#039;&#039;: op2 is impossible to become enabled after op1.&lt;br /&gt;
[[File: ImpossibleKeepExample.png]]&lt;br /&gt;
* &#039;&#039;keep&#039;&#039;: op2 always stays enabled resp. disabled after op1.&lt;br /&gt;
[[File: KeepExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_unchanged&#039;&#039;: op1 does not write any variable read in the guard of op2, i.e. write(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticUnchangedExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_independent&#039;&#039;: op1 and op2 are syntactically independent, i.e. read(op1) /\ write(op2) = {} &amp;amp; write(op1) /\ read(op2) = {} &amp;amp; write(op1) /\ write(op2) = {}&lt;br /&gt;
[[File: SyntacticIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;syntactically_fully_independent&#039;&#039;: op1 and op2 are syntactically independent and additionally, read(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticFullyIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;possible_enable&#039;&#039;: op2 possible after op1, but op2 cannot be disabled by op1.&lt;br /&gt;
[[File: PossibleEnableExample.png]]&lt;br /&gt;
* &#039;&#039;possible_disable&#039;&#039;: op2 possible after iop1, but op2 cannot be enabled by op1.&lt;br /&gt;
[[File: PossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;infeasible&#039;&#039;: op1 is not feasible and thus cannot influence op2.&lt;br /&gt;
[[File: InfeasibleExample.png]]&lt;br /&gt;
&lt;br /&gt;
== Computing Enabling Relations with ProB  ==&lt;br /&gt;
&lt;br /&gt;
Within &amp;lt;tt&amp;gt;ProB Tcl/Tk&amp;lt;/tt&amp;gt; you can find the menu &amp;quot;Enabling Analysis&amp;quot; in the &amp;quot;Analysis&amp;quot; menu of the menu bar.  The &amp;quot;Enabling Analysis&amp;quot; menu provides multiple commands:&lt;br /&gt;
* &amp;quot;Enabling Analysis (Table)&amp;quot;: this command performs a (fast) enabling analysis on the respective B model using a time-out of 300 ms for the constraint-solver calls. The result of the enabling analysis is shown in a table. The table lists all enabling relations between the operations of the loaded B model. These can be exported to a CSV file. The table for &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; at the end of the &#039;&#039;&#039; Enabling Relations&#039;&#039;&#039; section was constructed this way.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Precise, Table)&amp;quot;: this command performs an enabling analysis using a time-out of 2800 ms for each of the constraint-solver calls. As for the command above, the result of the analysis is shown in a table that can be exported to a CSV file.&lt;br /&gt;
* &amp;quot;Enabling Relations After...&amp;quot;: this command computes all the enabling relations involving an operation chosen by the user.&lt;br /&gt;
* &amp;quot;Enabling Analysis (Graph)&amp;quot;: this command performs the fast enabling analysis but displays the results as a graph. In case the preference &amp;quot;DOT_SHOW_OP_READ_WRITES&amp;quot; is set for each operation the read/write information is displayed.&lt;br /&gt;
* &amp;quot;Enabling Analysis (POR)...&amp;quot;: this menu provides further commands for another form of enabling analysis the results of which are used for the partial guard evaluation optimisation in ProB.&lt;br /&gt;
* &amp;quot;Read/Write Matrix (Table)&amp;quot;: this command performs syntactic analysis on the model. The analysis determines the read and write sets for each operation of the machine.&lt;br /&gt;
* &amp;quot;Dependence Analysis (Table)&amp;quot;: this command performs a dependency analysis for each pair of operations. More specifically, the analysis determine which operations are dependent or independent to each other.&lt;br /&gt;
&lt;br /&gt;
== References and Footnotes ==&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3477</id>
		<title>Tutorial Enabling Analysis</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Tutorial_Enabling_Analysis&amp;diff=3477"/>
		<updated>2016-02-11T14:55:14Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The B-method and in particular its successor Event-B are methodologies for formal development and verification of systems. In Event-B, a machine is usually viewed as a reactive system executing continuously enabled (atomic) events in an interleaved fashion. Thus, parallel events of the system are easily modeled as an interleaving of operation executions. On the other hand, the introduction of abstract counters is required when events are supposed to be executed in some (sequential) order. This, however, can in some cases slow the work of understanding and verifying a model since identifying the sequential ordering of events in an Event-B model is not that obvious. Thus, using methods for determining the control flow can be sometimes very beneficial for understanding the model, as well as for techniques for automatic verification such as model checking.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we present a static analysis for B and Event-B that can be used to reveal the control flow of a machine and to optimize model checking of models written in B and Event-B (see also [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Guard_Evaluation Tutorial on Partial Guard Evaluation ]). The results of the analysis, designated also as ‘’enabling analysis’’, can be presented as relations by means of a table or by means of a graph. For simplicity, we will concentrate mainly on B and use the terminology of the formalism.&lt;br /&gt;
&lt;br /&gt;
== Enabling Relation ==&lt;br /&gt;
What we want to find out is how the operations influence each other within a B model. In other words, for each pair (op1,op2) of operations we try to determine as precise as possible how op1 can affect the guard condition of op2 with regard to enabledness. To determine the enabling relations between operations we use syntactic analyses, as well as the constraint-based abilities of ProB.&lt;br /&gt;
&lt;br /&gt;
Consider the following B machine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE Example&lt;br /&gt;
VARIABLES x, y, z&lt;br /&gt;
INVARIANT&lt;br /&gt;
    x:NATURAL&lt;br /&gt;
  &amp;amp; y:INTEGER&lt;br /&gt;
  &amp;amp; z:INTEGER&lt;br /&gt;
INITIALISATION &lt;br /&gt;
  x:=6 || y:=-2 || z := 0&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Op1 = PRE x + y &amp;gt;= 4  THEN x:=x+2 || y:=2 END;&lt;br /&gt;
  Op2 = PRE x mod 2 = 1 THEN x:=x+1 || y:=2 END;&lt;br /&gt;
  Op3 = PRE x mod 2 = 0 THEN x:=x+2 END;&lt;br /&gt;
  Op4 = PRE x&amp;lt;0 THEN y:=y-1 END;&lt;br /&gt;
  Op5 = PRE y/=2 THEN z:=3 END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The machine has three variables x,y,z, where x ranges over the domain of natural numbers and y and z over the domain of all integers. For this machine we have 25 pairs of operations for which we want to determine the respective enabling relations. Additionally, we identify 5 further pairs that show the influence of the INITIALISATION on the guard conditions of all other operations. Consider, for example, the pair (Op2,Op1) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op1 is enabled in each state of &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; where the predicate ‘x+y&amp;gt;=4’ is fulfilled. Since the effect of Op2 assigns 2 to y and increments x by one upon condition that x is a positive odd number in the before-state of Op2, we can assume that Op1 is always enabled after the execution of Op2. In other words, in all after-states of Op2 the operation Op1 is guaranteed to be enabled. This relation between Op2 and Op1 we can illustrate as follows: &lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
In the figure above the green boxes denote that the evaluation of the guard of Op1 is true, whereas the red boxes denote that the evaluation of the guard of Op1 is false. &lt;br /&gt;
&lt;br /&gt;
Another pair of interest is (Op2,Op5) in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Clearly, Op5 is enabled only in those states in which y is not equal to 2. Obviously, in each after-state of Op2 y is equal to 2 and thus we can conclude that Op5 is impossible to be enabled after each execution of Op2. Such a relation between two operations we denote as ‘’impossible’’ and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleRelationEn.png]]&lt;br /&gt;
&lt;br /&gt;
Both arrows in the illustration of the ‘’impossible’’ relation indicate that whether the guard condition of Op5 is fulfilled or not in a before-state of Op2 operation Op5 will be disabled in the respective after-state of Op2. In order to recognize a tuple (op1,op2) as ‘’impossible’’ we require that op2 is always disabled after op1 without further considering whether op2 is always enabled or always disabled in the before-states of op1. &lt;br /&gt;
&lt;br /&gt;
Consider, for instance, the pair (Op2, Op2) in the machine above. We can easily conclude that Op2 becomes disabled after it is executed and clearly, the second case (\false -&amp;gt; \false) of the impossible relation is not possible for (Op2, Op2). This gives rise of introducing another (more precise) impossible relation:&lt;br /&gt;
 &lt;br /&gt;
[[File:ImpossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Accordingly, we can derive another relation from ‘’impossible’’ for which only the second case of the ‘’impossible’’ relation is fulfilled:&lt;br /&gt;
&lt;br /&gt;
[[File:ImpossibleKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
As an example for a pair of operations that fulfills the ‘’impossible_keep’’ requirement you can take, for example, the pair (Op3,Op2) from &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt;. Since Op2 and Op3 cannot be both enabled in a state and the execution of Op3 cannot enable Op2, then we can easily conclude that Op2 remains always disabled after Op3.&lt;br /&gt;
&lt;br /&gt;
Similarly as for ‘’impossible’’, one could derive two further enabling relations from ‘’guaranteed’’:&lt;br /&gt;
&lt;br /&gt;
[[File:GuaranteedEnableKeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
Another interesting class of enabling relations that could be helpful for better understanding and analyzing B and Event-B models is that of the ‘’keep’’ relations. We say that an operation op1 ‘’keeps’’ another operation op2 if op1 cannot change the status of the enabling condition of op2, i.e. op1 keeps op2 enabled respectively disabled. This relationship could be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:KeepRelation.png]]&lt;br /&gt;
&lt;br /&gt;
We can take (Op1,Op2) and (Op1,Op3) as examples of pairs in &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; that are elements of the keep relation. ‘’keep’’ relations can sometimes be easily determined by analyzing just the syntactic structure of both operations, or more precisely the “read” and “write” sets of both operations.&amp;lt;ref&amp;gt;For an operation op the set read(op) denotes the set of variables that are read by op. Accordingly, by write(op) we denote the set of variables that are written by op.&amp;lt;/ref&amp;gt; If, for example, an operation op1 does not write any variable of the machine that is read in the guard condition of op2, then we can infer that op1 ‘’keeps’’ op2. In that case we also say that op1 does not change op2 syntactically. In the class of the ‘’keep’’ relations are included also relations such as independence. Two operations op1 and op2 are called independent if each of them cannot disable the other operation and the both orders of execution &amp;lt;op1,op2&amp;gt; and &amp;lt;op2,op1&amp;gt; have the same effect.&amp;lt;ref&amp;gt;See the [https://www3.hhu.de/stups/prob/index.php/Tutorial_Various_Optimizations#Partial_Order_Reduction Tutorial on Partial Order Reduction] for more information on independence between operations.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All three classes (‘’guaranteed’’, ‘’impossible’’ and ‘’keep’’) of enabling relations presented so far represent definite relations. That is, if a pair of operations (op1,op2) is confirmed to be a relation of one of this three classes, then we can certainly say what effect on the enabling condition of op2 would the execution of op1 have. However, for some pairs of operations we cannot certainly say what effect an operation would have on the enabling condition of another operation. This is due to the fact that the enabling status of an operation does not only depend on the effect of the executed operations, but also on the current variables’ evaluation. Take, for instance, the tuple (Op3,Op1) from the B machine above. Considering the action part of Op3 and the guard condition of Op1 we can assume that Op3 can enable Op1. Since the guard of Op1 depends not only on the current value of x, but also on y, there could be transitions s&amp;lt;math&amp;gt;\overset{Op_3}{\rightarrow}&amp;lt;/math&amp;gt;s&#039; in the state space of the machine where Op1 is disabled in both states ‘’s’’ and ‘’s’’’. Though, what we could definitely say is that Op3 cannot disable Op1. This relationship we can illustrate as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleEnableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
The opposite relation of “possible_enable” is the relation where an operation op2 can disable another operation op1. Formally, we say that op2 can disable op1 if op2 may disable op1 and op2 cannot enable op1. This relationship is denoted as “possible_disable” and can be illustrated as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:PossibleDisableRelation.png]]&lt;br /&gt;
&lt;br /&gt;
In order to determine how operations influence each other we need to assure first that these are feasible. An operation ‘’op’’ is said to be feasible if there is a state of the machine that satisfies the invariant of the machine and in which ‘’op’’ is enabled. In the B machine above the operation Op4, for example, is not feasible. Obviously, Op4 is enabled only in states where x is a negative number and states in which x is a negative number are visibly not consistent with the invariant since &amp;quot;x : NATURAL&amp;quot;. Such incompatibilities are sometimes of great importance for the modeler and therefore they should be revealed in the process of computing the enabling relations. In our case for each pair of operations (Op4,-) and (-,Op4) the status “infeasible” will be returned.&lt;br /&gt;
&lt;br /&gt;
We can now list all possible enabling relations for the machine &amp;lt;tt&amp;gt;Example.mch&amp;lt;/tt&amp;gt; by means of a table. For each entry in the table the operation in the row is the operation whose effect is studied on the status of the guard of the operation in the column.&lt;br /&gt;
&lt;br /&gt;
[[File: EnablingResults.png]]&lt;br /&gt;
&lt;br /&gt;
== Summary of the Enabling Relations ==&lt;br /&gt;
&lt;br /&gt;
In the following, we summarize most of the enabling relations that we could identify. For each of the enabling relations we have given an appropriate example. In the examples below we compute the effect of executing ‘op1’ on the status of the guard of ‘op2’. The relation identifiers are the same as they appear as results in ProB.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;guaranteed&#039;&#039;: op2 guaranteed to be executable after op1.&lt;br /&gt;
[[File: GuaranteedExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_enable&#039;&#039;: op2 is guaranteed to become enabled after op1.&lt;br /&gt;
[[File: GuaranteedEnableExample.png]]&lt;br /&gt;
* &#039;&#039;guaranteed_keep&#039;&#039;: op2 is guaranteed to stay enabled after op1.&lt;br /&gt;
[[File: GuaranteedKeepExample.png]]&lt;br /&gt;
* &#039;&#039;impossible&#039;&#039;: op2 is impossible to be executed after op1.&lt;br /&gt;
[[File: ImpossibleExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_disable&#039;&#039;: op2 is guaranteed to become disabled after op1.&lt;br /&gt;
[[File: ImpossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;impossible_keep&#039;&#039;: op2 is impossible to become enabled after op1.&lt;br /&gt;
[[File: ImpossibleKeepExample.png]]&lt;br /&gt;
* &#039;&#039;keep&#039;&#039;: op2 always stays enabled resp. disabled after op1.&lt;br /&gt;
[[File: KeepExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_unchanged&#039;&#039;: op1 does not write any variable read in the guard of op2, i.e. write(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticUnchangedExample.png]]&lt;br /&gt;
* &#039;&#039;syntactic_independent&#039;&#039;: op1 and op2 are syntactically independent, i.e. read(op1) /\ write(op2) = {} &amp;amp; write(op1) /\ read(op2) = {} &amp;amp; write(op1) /\ write(op2) = {}&lt;br /&gt;
[[File: SyntacticIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;syntactically_fully_independent&#039;&#039;: op1 and op2 are syntactically independent and additionally, read(op1) /\ read(op2) = {}&lt;br /&gt;
[[File: SyntacticFullyIndependentExample.png]]&lt;br /&gt;
* &#039;&#039;possible_enable&#039;&#039;: op2 possible after op1, but op2 cannot be disabled by op1.&lt;br /&gt;
[[File: PossibleEnableExample.png]]&lt;br /&gt;
* &#039;&#039;possible_disable&#039;&#039;: op2 possible after iop1, but op2 cannot be enabled by op1.&lt;br /&gt;
[[File: PossibleDisableExample.png]]&lt;br /&gt;
* &#039;&#039;infeasible&#039;&#039;: op1 is not feasible and thus cannot influence op2.&lt;br /&gt;
[[File: InfeasibleExample.png]]&lt;br /&gt;
&lt;br /&gt;
== References and Footnotes ==&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=File:EnablingResults.png&amp;diff=3476</id>
		<title>File:EnablingResults.png</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=File:EnablingResults.png&amp;diff=3476"/>
		<updated>2016-02-11T14:54:15Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=File:ImpossibleDisableExample.png&amp;diff=3474</id>
		<title>File:ImpossibleDisableExample.png</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=File:ImpossibleDisableExample.png&amp;diff=3474"/>
		<updated>2016-02-11T14:40:17Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=File:ToggleExample.png&amp;diff=3473</id>
		<title>File:ToggleExample.png</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=File:ToggleExample.png&amp;diff=3473"/>
		<updated>2016-02-11T14:38:44Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=File:SyntacticUnchangedExample.png&amp;diff=3472</id>
		<title>File:SyntacticUnchangedExample.png</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=File:SyntacticUnchangedExample.png&amp;diff=3472"/>
		<updated>2016-02-11T14:38:32Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=File:SyntacticIndependentExample.png&amp;diff=3471</id>
		<title>File:SyntacticIndependentExample.png</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=File:SyntacticIndependentExample.png&amp;diff=3471"/>
		<updated>2016-02-11T14:38:19Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=File:SyntacticFullyIndependentExample.png&amp;diff=3470</id>
		<title>File:SyntacticFullyIndependentExample.png</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=File:SyntacticFullyIndependentExample.png&amp;diff=3470"/>
		<updated>2016-02-11T14:38:05Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=File:PossibleExample.png&amp;diff=3469</id>
		<title>File:PossibleExample.png</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=File:PossibleExample.png&amp;diff=3469"/>
		<updated>2016-02-11T14:37:28Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=File:PossibleEnableExample.png&amp;diff=3468</id>
		<title>File:PossibleEnableExample.png</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=File:PossibleEnableExample.png&amp;diff=3468"/>
		<updated>2016-02-11T14:37:12Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=File:PossibleDisableExample.png&amp;diff=3467</id>
		<title>File:PossibleDisableExample.png</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=File:PossibleDisableExample.png&amp;diff=3467"/>
		<updated>2016-02-11T14:36:58Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=File:KeepExample.png&amp;diff=3466</id>
		<title>File:KeepExample.png</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=File:KeepExample.png&amp;diff=3466"/>
		<updated>2016-02-11T14:36:35Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=File:InfeasibleExample.png&amp;diff=3465</id>
		<title>File:InfeasibleExample.png</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=File:InfeasibleExample.png&amp;diff=3465"/>
		<updated>2016-02-11T14:36:22Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=File:ImpossibleKeepExample.png&amp;diff=3464</id>
		<title>File:ImpossibleKeepExample.png</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=File:ImpossibleKeepExample.png&amp;diff=3464"/>
		<updated>2016-02-11T14:35:36Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=File:ImpossibleExample.png&amp;diff=3463</id>
		<title>File:ImpossibleExample.png</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=File:ImpossibleExample.png&amp;diff=3463"/>
		<updated>2016-02-11T14:35:20Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=File:GuaranteedKeepExample.png&amp;diff=3461</id>
		<title>File:GuaranteedKeepExample.png</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=File:GuaranteedKeepExample.png&amp;diff=3461"/>
		<updated>2016-02-11T14:34:48Z</updated>

		<summary type="html">&lt;p&gt;Ivaylo Dobrikov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ivaylo Dobrikov</name></author>
	</entry>
</feed>