<?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=Jan+Gruteser</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=Jan+Gruteser"/>
	<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Special:Contributions/Jan_Gruteser"/>
	<updated>2026-05-27T06:50:56Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Sequent_Prover&amp;diff=6145</id>
		<title>Sequent Prover</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Sequent_Prover&amp;diff=6145"/>
		<updated>2026-05-15T13:50:35Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Using ProB, sequents can be proven interactively. &lt;br /&gt;
For the construction of a formal proof, rules for rewriting expressions or decomposing proof goals into simpler subgoals are applied.&lt;br /&gt;
To discharge a proof obligation one has to prove one or more sequents, consisting of hypotheses and a goal that must be derived from the hypotheses.&lt;br /&gt;
&lt;br /&gt;
Currently, &amp;lt;tt&amp;gt;.pl&amp;lt;/tt&amp;gt; files with proof obligations can be loaded which are exported from Rodin. To generate these files, an Event-B component must be selected in Rodin and the option &amp;lt;tt&amp;gt;ProB Standalone &amp;gt; Export POs for ProB&amp;lt;/tt&amp;gt; must be invoked.&lt;br /&gt;
&lt;br /&gt;
All rules that are applicable to the current sequent are displayed in the Operations View.&lt;br /&gt;
The implemented rules include the inference and rewrite rules available in Rodin:&lt;br /&gt;
* https://wiki.event-b.org/index.php/Inference_Rules&lt;br /&gt;
* https://wiki.event-b.org/index.php/All_Rewrite_Rules&lt;br /&gt;
&lt;br /&gt;
The State View shows the current sequent, including its hypotheses and goal, as well as important state properties. Furthermore, the State Visualisation presents both the current state and the preceding state, allowing a comparison between consecutive steps. By right-clicking on a predicate within this visualisation, the user can see rules that are applicable to that selected element.&lt;br /&gt;
&lt;br /&gt;
(Overview img)&lt;br /&gt;
&lt;br /&gt;
==== Transitions ====&lt;br /&gt;
&lt;br /&gt;
Some rules require additional user input, i.e. an expression or a predicate. This is necessary, for example when it is necessary to add a new hypothesis to advance the proof, to instantiate quantifiers like the existential quantifier or perform a case distinction.&lt;br /&gt;
&lt;br /&gt;
Transitions for these rules are displayed in orange / with a question mark. This indicates that the subsequent state is not computed in advance, either because the execution depends on user input, so they cannot be precomputed or it is a transition for an external provers (where no parameters are expected). &lt;br /&gt;
&lt;br /&gt;
[[File:Sequent prover transitions.png|800px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;skip_to_cont&amp;lt;/tt&amp;gt; is a transition that allows you to skip the current sequent and prove it later. If it is selected here, arr &amp;amp;isin; &amp;amp;integers; &amp;amp;#8696; &amp;amp;integers; will be the next goal. &amp;lt;tt&amp;gt;CONTINUATION&amp;lt;/tt&amp;gt; denotes the number of additional sequents in the proof, so now there are four sequents in total, including the current sequent.&lt;br /&gt;
&lt;br /&gt;
==== Input Syntax ====&lt;br /&gt;
&lt;br /&gt;
User input has to be provided in [[Summary_of_B_Syntax|B Syntax]]. Due to syntactic differences between B and Event-B, certain operators must be adapted accordingly. For instance, a cartesian product is written as &#039;&#039;&#039;S ** T&#039;&#039;&#039;, exponentiation as &#039;&#039;&#039;a^b&#039;&#039;&#039; and set difference as &#039;&#039;&#039;S \\ T&#039;&#039;&#039; (note that it is written as &amp;lt;tt&amp;gt;\\&amp;lt;/tt&amp;gt; in the input because of the escape character &amp;lt;tt&amp;gt;\&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&amp;lt;tt&amp;gt;finite(S)&amp;lt;/tt&amp;gt; is an Event-B operator and is entered as &amp;lt;tt&amp;gt;S:FIN(S)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To illustrate a valid input, this is an example predicate for a hypothesis to be added (x &amp;amp;ne; 0 &amp;amp;and; s &amp;amp;cup; t &amp;amp;sub; &amp;amp;naturals;):&lt;br /&gt;
&lt;br /&gt;
[[File:Sequent prover add hyp.png|700px]]&lt;br /&gt;
&lt;br /&gt;
==== Saving Proofs ====&lt;br /&gt;
&lt;br /&gt;
To save a proof, the proof trace can be stored as a &amp;lt;tt&amp;gt;.prob2trace&amp;lt;/tt&amp;gt; file (1a), which can later be reloaded and reused (1b). This option allows proofs to be revised, for example by interactively replaying the trace and modifying some steps. Alternatively, proofs can be exported as HTML documents (2):&lt;br /&gt;
&lt;br /&gt;
[[File:Sequent prover proof saving.png|800px]]&lt;br /&gt;
&lt;br /&gt;
==== Automatic Provers ====&lt;br /&gt;
&lt;br /&gt;
In addition to interactive proving, ProB allows the invocation of external automatic provers. This can be useful for determining whether a given sequent is provable at all. The following provers can be called:&lt;br /&gt;
&lt;br /&gt;
* [[Tutorial Disprover|the ProB (Dis-)Prover]] which searches for counterexamples and can invalidate and prove sequents&lt;br /&gt;
* ProB&#039;s well-definedness prover for discharging well-definedness proof obligations&lt;br /&gt;
* Atelier B&#039;s mono-lemma (ml) prover and predicate prover (pp)&lt;br /&gt;
&lt;br /&gt;
To use the Atelier B provers, the path to the &amp;lt;tt&amp;gt;krt&amp;lt;/tt&amp;gt; tool must be set via &amp;lt;tt&amp;gt;File &amp;gt; Preferences &amp;gt; ATELIERB_KRT_PATH&amp;lt;/tt&amp;gt;. If the provers from Atelier B were installed in Rodin, the &amp;lt;tt&amp;gt;krt&amp;lt;/tt&amp;gt; executable might be found within Rodin&#039;s configuration directory (path is possibly &amp;lt;tt&amp;gt;/Users/.../rodin/configuration/org.eclipse.osgi/.../krt&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
The question mark shown on transitions for external provers also indicates that they may not be executable. It is the case if too many or unsuitable hypotheses are selected for proving the goal.&lt;br /&gt;
&lt;br /&gt;
==== Examples ====&lt;br /&gt;
A few export examples can be found here: https://stups.hhu-hosting.de/models/sequent_prover.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6098</id>
		<title>Other languages</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6098"/>
		<updated>2026-03-05T14:08:33Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* Using VisB in XTL mode */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]&lt;br /&gt;
[[Category:Developer Manual]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== XTL Prolog Format for Transition Systems ==&lt;br /&gt;
&lt;br /&gt;
You can also use ProB to animate and model check other specification languages by writing your own Prolog interpreter. To do this you should create a Prolog file with the .P extension and which defines three predicates:&lt;br /&gt;
* &amp;lt;tt&amp;gt;trans/3&amp;lt;/tt&amp;gt;: this predicate should compute for every state (second argument), the outgoing transitions (first argument), and the resulting new states (third argument)&lt;br /&gt;
* &amp;lt;tt&amp;gt;prop/2&amp;lt;/tt&amp;gt;: this predicate should compute the properties for the states of your system&lt;br /&gt;
* &amp;lt;tt&amp;gt;start/1&amp;lt;/tt&amp;gt;: this defines the initial states of your system&lt;br /&gt;
&lt;br /&gt;
For example, the following defines a system with two states (a and b) and two transitions (lock and unlock):&lt;br /&gt;
&lt;br /&gt;
 start(a).&lt;br /&gt;
 trans(lock,a,b).&lt;br /&gt;
 trans(unlock,b,a).&lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
These Prolog files can be loaded with ProB&#039;s open command (be sure to use the .P extension and to either choose &amp;quot;All files&amp;quot; or &amp;quot;Other Formalisms&amp;quot; in the file filtering menu).&lt;br /&gt;
&lt;br /&gt;
=== All recognised Prolog Predicates ===&lt;br /&gt;
&lt;br /&gt;
As of ProB 1.15.0, it is possible to specify symbolic transitions using the predicate &amp;lt;tt&amp;gt;symb_trans/3&amp;lt;/tt&amp;gt;. Such transitions are only available via the execute by predicate dialog and are intended for transitions that require user input or have side effects.&lt;br /&gt;
&amp;lt;tt&amp;gt;symb_trans_enabled(Name,State)&amp;lt;/tt&amp;gt; can be optionally used to mark states in which a symbolic transition is potentially enabled (not guaranteed).&lt;br /&gt;
&lt;br /&gt;
To provide dynamic transition properties, such as descriptions, the two predicates &amp;lt;tt&amp;gt;trans/4&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;start/2&amp;lt;/tt&amp;gt; can be used, where the last parameter is a list of properties, e.g.&lt;br /&gt;
 trans(toggle_button,button(A),button(B),[description(toggle_from_to(A,B))]) :- toggle(A,B).&lt;br /&gt;
Static properties, such as parameter names, can be provided using &amp;lt;tt&amp;gt;trans_prop(TransName,Prop)&amp;lt;/tt&amp;gt;, e.g.&lt;br /&gt;
 trans_prop(set_button,param_names([&#039;ButtonState&#039;])).&lt;br /&gt;
For symbolic transitions it is required to provide parameter names.&lt;br /&gt;
&lt;br /&gt;
The following can be used to set up an animation image matrix with corresponding actions:&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image(Nr,Path)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_function_result(State,List)&amp;lt;/tt&amp;gt; where List is a list of terms of the form ((Row,Col),Img) where Img is either a declared animation_image number or another Prolog term&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_right_click_transition(Row,Col,TransitionTemplate)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_click_transition(FromRow,FromCol,ToRow,ToCol,ListOfTransitionTemplates,ImageNr)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example for visualisation can be found at [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]].&lt;br /&gt;
&lt;br /&gt;
Further recognised predicates are:&lt;br /&gt;
* &amp;lt;tt&amp;gt;prob_pragma_string(DefinionName,Value)&amp;lt;/tt&amp;gt;: a way to mimic B DEFINITION Strings in XTL mode&lt;br /&gt;
* &amp;lt;tt&amp;gt;nr_state_properties(Nr)&amp;lt;/tt&amp;gt;: number of state properties displayed in the state view&lt;br /&gt;
* &amp;lt;tt&amp;gt;heuristic_function_active&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;heuristic_function_result(State,Res)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
The following predicates specify a simple button:&lt;br /&gt;
&lt;br /&gt;
 start(button(on)).&lt;br /&gt;
 trans(toggle_button,button(X),button(Y)) :- toggle(X,Y).&lt;br /&gt;
 trans(set_button(X),_,button(X)) :- X=on ; X=off.&lt;br /&gt;
 prop(button(X),&#039;=&#039;(button,X)).&lt;br /&gt;
 toggle(on,off).&lt;br /&gt;
 toggle(off,on).&lt;br /&gt;
&lt;br /&gt;
Another simple example for a very basic process algebra is as follows:&lt;br /&gt;
&lt;br /&gt;
 % start(PossibleInitialState)&lt;br /&gt;
 start(choice(pref(a,stop),intl(pref(b,pref(c,stop)),pref(d,stop)))).&lt;br /&gt;
 &lt;br /&gt;
 % trans(Event, StateBefore, StateAfter)&lt;br /&gt;
 trans(A,pref(A,P),P). % action prefix&lt;br /&gt;
 trans(A,intl(P,Q),intl(P2,Q)) :- trans(A,P,P2). % interleave&lt;br /&gt;
 trans(A,intl(P,Q),intl(P,Q2)) :- trans(A,Q,Q2).&lt;br /&gt;
 trans(A,par(P,Q),par(P2,Q2)) :- trans(A,P,P2), trans(A,Q,Q2). % parallel composition&lt;br /&gt;
 trans(A,choice(P,Q),P2) :- trans(A,P,P2). % choice&lt;br /&gt;
 trans(A,choice(P,Q),Q2) :- trans(A,Q,Q2).&lt;br /&gt;
 &lt;br /&gt;
 % prop(State, PropertyOfState)&lt;br /&gt;
 prop(pref(A,P),prefix).&lt;br /&gt;
 prop(intl(P,Q),interleave).&lt;br /&gt;
 prop(A,A).&lt;br /&gt;
 &lt;br /&gt;
If you have a working interpreter, you can also contact the ProB developers in order for your interpreter to be included in the standard ProB distribution (in the style of the CSP-M or Promela interpreters).&lt;br /&gt;
With this you can add syntax highlighting, error highlighting in the source code, highlighting during animation, support for new LTL properties,...&lt;br /&gt;
&lt;br /&gt;
Another, slightly more elaborate example, is the following interpreter for regular expressions:&lt;br /&gt;
&lt;br /&gt;
 /* A simple animator for regular expressions */&lt;br /&gt;
 &lt;br /&gt;
 start(&#039;|&#039;(&#039;.&#039;(&#039;*&#039;(a),b) ,  &#039;.&#039;(&#039;*&#039;(b),a))). &lt;br /&gt;
 &lt;br /&gt;
 trans(_,[],_) :- !,fail.&lt;br /&gt;
 trans(X,X,[]) :- atomic(X),!.&lt;br /&gt;
 trans(X,&#039;|&#039;(R1,R2),R) :- &lt;br /&gt;
  trans(X,R1,R) ; trans(X,R2,R).&lt;br /&gt;
 trans(X,&#039;.&#039;(R1,B),R) :- trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,B,R).&lt;br /&gt;
 trans(X,&#039;?&#039;(R1),R) :-&lt;br /&gt;
  trans(X,R1,R) ; (X=epsilon,R=[]).&lt;br /&gt;
 trans(epsilon,&#039;*&#039;(_R1),[]). &lt;br /&gt;
 trans(X,&#039;*&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 trans(X,&#039;+&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 &lt;br /&gt;
 gen_concat(R1,R2,R) :- &lt;br /&gt;
  (R1=[] -&amp;gt; R = R2 ; R = &#039;.&#039;(R1,R2)).&lt;br /&gt;
 &lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
Finally, a more complex example is [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]] which also includes a graphical visualisation (using the &amp;lt;tt&amp;gt;animation_function_result&amp;lt;/tt&amp;gt; predicate recognised by ProB as of version 1.4.0-rc3).&lt;br /&gt;
&lt;br /&gt;
=== Using VisB in XTL mode ===&lt;br /&gt;
&lt;br /&gt;
Since ProB 1.15.0, it is possible to use [[VisB|VisB]] with XTL specifications. For this, a B (!) definition file (&amp;lt;tt&amp;gt;.def&amp;lt;/tt&amp;gt;) must be used, as with B models, which enables the use of VisB DEFINITIONS. The B definition file can the be linked to the specification using&lt;br /&gt;
 prob_pragma_string(&#039;VISB_DEFINITIONS_FILE&#039;,PathToFile).&lt;br /&gt;
(or via the VisB view in ProB2-UI).&lt;br /&gt;
To access the value of state properties in the current state, e.g. for VisB updates, the external function &amp;lt;tt&amp;gt;STATE_PROPERTY(NameOfProp)&amp;lt;/tt&amp;gt; can be used, where &amp;lt;tt&amp;gt;NameOfProp&amp;lt;/tt&amp;gt; corresponds to a property of the special style &amp;lt;tt&amp;gt;&#039;=&#039;(Name,Value)&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;prop/2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
A simple example can be found [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples/-/tree/master/TrafficLight/XTL?ref_type=heads here].&lt;br /&gt;
&lt;br /&gt;
Note that for event predicates the parameter values must be wrapped in &amp;lt;tt&amp;gt;STRING_TO_TERM&amp;lt;/tt&amp;gt;, e.g.&lt;br /&gt;
 rec(event: &amp;quot;set_button&amp;quot;, predicate: &amp;quot;buttonState = STRING_TO_TERM(\&amp;quot;on\&amp;quot;)&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
== Promela ==&lt;br /&gt;
&lt;br /&gt;
Version 1.2.7 of ProB  (July 2008) was able to open Promela files. This mode provided source-level highlighting during animation. The main purpose was to debug and animate Promela specifications in a user-friendly way. We do not plan to compete in terms of model checking speed with Spin (Spin compiles Promela to C code, ProB uses a Prolog interpreter). To animate a Promela model, simply open the file with the .pml or .prom extension with the &amp;quot;File-&amp;gt;Open...&amp;quot; command. You will have to choose &amp;quot;Other Formalisms&amp;quot; or &amp;quot;All Files&amp;quot; in the filter pop-up-menu to be able to select the file.&lt;br /&gt;
&lt;br /&gt;
This direct support of Promela files has been discontinued, but the Promela interpreter is still available as an XTL Prolog specification (see above) and can thus be used to animate Promela specifications with ProB.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Rodin_POs_and_ProB&amp;diff=6079</id>
		<title>Rodin POs and ProB</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Rodin_POs_and_ProB&amp;diff=6079"/>
		<updated>2026-01-23T12:35:21Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
What is the relationship between Rodin proof obligations (POs) and ProB.&lt;br /&gt;
In short, ProB can be made to check individual proof obligations.&lt;br /&gt;
During animation and model checking, ProB will compute its own&lt;br /&gt;
verification conditions for invariants, theorems, etc.&lt;br /&gt;
However, if the PROOF_INFO preference is set to true (which it is by default)&lt;br /&gt;
it will make use of the information about which POs are discharged to simplify&lt;br /&gt;
the invariant checking for Event-B models.&lt;br /&gt;
&lt;br /&gt;
== ProB Prover Disprover ==&lt;br /&gt;
&lt;br /&gt;
ProB can be applied to individual POs by clicking the ProB button in the &amp;lt;em&amp;gt;Proof Control&amp;lt;/em&amp;gt; view of Rodin.&lt;br /&gt;
&lt;br /&gt;
[[File:disprover_proof_control.png]]&lt;br /&gt;
&lt;br /&gt;
See [[Tutorial_Disprover| the tutorial on the ProB Prover/Disprover]] for more details.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
One can also export the POs of a particular Event-B machine for use with the  [[Using_the_Command-Line_Version_of_ProB|command-line version of ProB]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:rodin_export_pos.png]]&lt;br /&gt;
&lt;br /&gt;
This will generate a Prolog file (with .pl ending) which can be read by probcli. It will then check the individual proof obligations.&lt;br /&gt;
Here is an example run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
probcli GearDoor1_mch.pl&lt;br /&gt;
...&lt;br /&gt;
Disprover Run Summary: [true-9]&lt;br /&gt;
Project LandingGearNew&lt;br /&gt;
Machine GearDoor1 (exported Sun Feb 08 10:38:51 CET 2015)&lt;br /&gt;
Number of  POs: 9 ([INITIALISATION/safety_inv1/INV,env_start_retracting/safety_inv1/INV,env_retract_gear/safety_inv1/INV,env_start_extending/safety_inv1/INV,env_extend_gear/safety_inv1/INV,env_start_open_door/safety_inv1/INV,env_open_door/safety_inv1/INV,env_start_close_door/safety_inv1/INV,env_close_door/safety_inv1/INV])&lt;br /&gt;
Number of proven (within Rodin) POs: 9 ([INITIALISATION/safety_inv1/INV,env_start_retracting/safety_inv1/INV,env_retract_gear/safety_inv1/INV,env_start_extending/safety_inv1/INV,env_extend_gear/safety_inv1/INV,env_start_open_door/safety_inv1/INV,env_open_door/safety_inv1/INV,env_start_close_door/safety_inv1/INV,env_close_door/safety_inv1/INV])&lt;br /&gt;
ProB Disprover Analysis with timeout 300 ms&lt;br /&gt;
Number of proven     (by ProB) POs: 9 ([INITIALISATION/safety_inv1/INV,env_start_retracting/safety_inv1/INV,env_retract_gear/safety_inv1/INV,env_start_extending/safety_inv1/INV,env_extend_gear/safety_inv1/INV,env_start_open_door/safety_inv1/INV,env_open_door/safety_inv1/INV,env_start_close_door/safety_inv1/INV,env_close_door/safety_inv1/INV])&lt;br /&gt;
Number of disproven  (by ProB) POs: 0 ([])&lt;br /&gt;
Number of unproven   (by ProB) POs: 0 ([])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ProB Model Checker ==&lt;br /&gt;
&lt;br /&gt;
During animation and model checking, ProB will compute its own&lt;br /&gt;
verification conditions for invariants, theorems, etc.&lt;br /&gt;
However, if the PROOF_INFO preference is set to true (which it is by default)&lt;br /&gt;
it will make use of the information about which POs are discharged to simplify&lt;br /&gt;
the invariant checking for Event-B models.&lt;br /&gt;
&lt;br /&gt;
The information about discharged proof obligations is automatically obtained by ProB from Rodin. It is also saved in the [[Tutorial_Rodin_Exporting|.eventb export files]].&lt;br /&gt;
&lt;br /&gt;
In ProB Tcl/Tk (aka ProB Classic) you can inspect the so obtained specialized (simplified) invariants for each operation, by choosing one of the commands in the Debug menu:&lt;br /&gt;
&lt;br /&gt;
[[File:prob_show_specialized_invariants_menu.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:prob_show_specialized_invariants_result.png]]&lt;br /&gt;
&lt;br /&gt;
== ProB Sequent Prover ==&lt;br /&gt;
&lt;br /&gt;
Since ProB 1.15.1, ProB includes a [[Sequent_Prover|Sequent Prover]] based on the inference and rewrite rules implemented in Rodin.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Download&amp;diff=6067</id>
		<title>Download</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Download&amp;diff=6067"/>
		<updated>2026-01-03T17:55:12Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* macOS issues */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Latest Release ==&lt;br /&gt;
&lt;br /&gt;
Below are links for downloading the latest stable release of probcli (the command line version of ProB) and ProB Tcl/Tk (ProB with a graphical user interface written in Tcl/Tk).&lt;br /&gt;
Note: please use the provided start scripts (StartProB.sh or StartProBWin.bat) to start ProB.&lt;br /&gt;
The list of changes can be found in the [[ProB_Release_History | ProB release history]].&lt;br /&gt;
&lt;br /&gt;
Details of the [[ProBLicence| ProB Licence can be found here]].&lt;br /&gt;
ProB is free to use and open source. For commercial support contact  [https://www.stups.uni-duesseldorf.de/~leuschel/ Michael Leuschel]. In particular, we can provide access to the validation report for using ProB as a tool of class T2 or T3 within the European norm [https://de.wikipedia.org/wiki/EN_50128 EN50128].&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;table table-bordered wikitable&amp;quot; &amp;lt;!-- table and table-bordered for Bootstrap (ProB skin), wikitable for MediaWiki (Vector, MonoBook, etc. skins) --&amp;gt;&lt;br /&gt;
! Platform&lt;br /&gt;
! Release Date&lt;br /&gt;
! Download&lt;br /&gt;
! Dependencies&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; style=&amp;quot;background-color:lightgrey;&amp;quot; | 1.15.1&lt;br /&gt;
|-&lt;br /&gt;
| Linux &lt;br /&gt;
| 21.12.2025 &lt;br /&gt;
| [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/1.15.1/ProB.linux64.tar.gz Tarball]&amp;lt;br/&amp;gt;&lt;br /&gt;
| Java 8 or newer ([[#Java Requirements for B parser|see below]]), Tcl/Tk 8.5 or 8.6 ([[#Tcl/Tk on Linux|see below]]), [https://www.graphviz.org/download/ GraphViz]&lt;br /&gt;
|-&lt;br /&gt;
| Windows&lt;br /&gt;
| 21.12.2025  &lt;br /&gt;
| [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/1.15.1/ProB.windows64.zip Zipfile] (Tcl/Tk 8.6), &amp;lt;br/&amp;gt; [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/1.15.1/ProB.windows64-tcltk-85.zip Zipfile] (Tcl/Tk 8.5)&lt;br /&gt;
| Tcl/Tk 8.5 or 8.6 ([[#Tcl/Tk on Windows|see below]]), Java 8 or newer ([[#Java Requirements for B parser|see below]]), [https://www.graphviz.org/download/ GraphViz], [[Windows Installation Instructions]]&lt;br /&gt;
|-&lt;br /&gt;
| macOS&lt;br /&gt;
| 21.12.2025  &lt;br /&gt;
| [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/1.15.1/ProB.macos.zip Zipfile] (Universal ARM/Intel notarized)&amp;lt;br/&amp;gt; &lt;br /&gt;
[https://github.com/hhu-stups/homebrew-prob Homebrew Tap]&lt;br /&gt;
| macOS 10.14 (Mojave) or newer, Tcl/Tk 8.6 ([[#Tcl/Tk on macOS|see below]]), Java 8 or newer ([[#Java Requirements for B parser|see below]]), [https://www.graphviz.org/download/ Graphviz] ([[#Graphviz_Requirements|see below]])&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The B parser of ProB requires Java 8 or newer. More details [[#Java Requirements for B parser|are available below]].&lt;br /&gt;
&lt;br /&gt;
The Graphical User Interface of ProB Tcl/Tk requires Tcl/Tk 8.5 or 8.6. More details [[#Tcl/Tk Requirements for ProB Tcl/Tk|are available below]].&lt;br /&gt;
The default Tcl/Tk on macOS is broken and will result in &amp;lt;b&amp;gt;black windows&amp;lt;/b&amp;gt;, and you have to [[#Tcl/Tk Requirements for ProB Tcl/Tk|install another version of Tcl/Tk]]. (Note: Tcl/Tk 9 is not binary compatible and cannot yet be used.)&lt;br /&gt;
All releases include the command-line version &amp;lt;b&amp;gt;probcli&amp;lt;/b&amp;gt; which does &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; require Tcl/Tk.&lt;br /&gt;
&lt;br /&gt;
Releases are compiled for the &#039;&#039;&#039;x86_64&#039;&#039;&#039; architecture (64-bit Intel).&lt;br /&gt;
macOS releases of ProB 1.12.0 and later also support &#039;&#039;&#039;aarch64&#039;&#039;&#039; (64-bit ARM/Apple Silicon).&lt;br /&gt;
The last version built for x86 (32-bit Intel) is ProB 1.8.0 (see [[DownloadPriorVersions|prior versions]]).&lt;br /&gt;
If you are using an unsupported architecture or system, you may still be able to [[Running ProB from source|run ProB from source]].&lt;br /&gt;
&lt;br /&gt;
Note that: on &amp;lt;b&amp;gt;macOS&amp;lt;/b&amp;gt; you  still have to right-click on the application and use &amp;quot;Open&amp;quot;, even though ProB Tcl/Tk (and probcli and all libraries) are signed and notarized. &lt;br /&gt;
 &lt;br /&gt;
=== Latest Beta Release ===&lt;br /&gt;
&lt;br /&gt;
The latest beta release is [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/1.13.1-beta1 1.13.1-beta1].&lt;br /&gt;
It may be older than the latest final release.&lt;br /&gt;
An official beta release always passes all of ProB&#039;s tests.&lt;br /&gt;
However, we do not follow the stringent checklist for final releases&lt;br /&gt;
(e.g., checking SICStus Prolog Spider warnings, checking coverage and additional manual&lt;br /&gt;
UI tests).&lt;br /&gt;
Also, we do not store coverage reports and other information necessary for T2 certification.&lt;br /&gt;
&lt;br /&gt;
=== Nightly Builds ===&lt;br /&gt;
&lt;br /&gt;
More current [https://stups.hhu-hosting.de/downloads/prob/tcltk/nightly/ nightly integration builds] are also available.&lt;br /&gt;
These releases are usually updated every night and old versions are not stored.&lt;br /&gt;
&lt;br /&gt;
Note for macOS users: Nightly builds of ProB are not signed or notarized, so macOS 10.15 and later (Catalina, Big Sur or Monterey, Ventura) will refuse to run them.&lt;br /&gt;
As a workaround, you will need to run &amp;lt;code&amp;gt;xattr -r -d com.apple.quarantine *&amp;lt;/code&amp;gt; inside the ProB directory before launching ProB.&lt;br /&gt;
The stable and beta releases listed above are signed and notarized, so they will run without extra steps.&lt;br /&gt;
&lt;br /&gt;
Automatically generated test [https://stups.hhu-hosting.de/internal/coverage/html/ coverage reports are also available].&lt;br /&gt;
They are usually updated once per week.&lt;br /&gt;
&lt;br /&gt;
=== Sourcecode ===&lt;br /&gt;
&lt;br /&gt;
You can download the latest Prolog sourcecode snapshot from: https://stups.hhu-hosting.de/downloads/prob/source/&lt;br /&gt;
&lt;br /&gt;
The source code for the ProB parsers (B, LTL, ...) can be obtained from: https://github.com/hhu-stups/probparsers&lt;br /&gt;
&lt;br /&gt;
=== Prior Versions ===&lt;br /&gt;
&lt;br /&gt;
Prior Versions of ProB going back to 1.3.1 [[DownloadPriorVersions|are available for download here]]. &lt;br /&gt;
If you are interested in still earlier releases, please have a look at the [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/ Download directory].&lt;br /&gt;
&lt;br /&gt;
== Other ProB tools ==&lt;br /&gt;
&lt;br /&gt;
=== ProB Jupyter Kernel ===&lt;br /&gt;
&lt;br /&gt;
You can now create Jupyter Notebooks in B using the ProB Jupyter kernel.&lt;br /&gt;
Downloads, instructions, and source code can be found on [https://gitlab.cs.uni-duesseldorf.de/general/stups/prob2-jupyter-kernel its own page].&lt;br /&gt;
&lt;br /&gt;
You can [https://mybinder.org/v2/git/https%3A%2F%2Fgitlab.cs.uni-duesseldorf.de%2Fgeneral%2Fstups%2Fprob2-jupyter-kernel.git/master?filepath=notebooks try out the ProB Jupyter kernel in your browser] without installing it first.&lt;br /&gt;
Note that &#039;&#039;&#039;notebooks are not saved permanently in this online version!&#039;&#039;&#039;&lt;br /&gt;
To keep your notebooks, you &#039;&#039;must&#039;&#039; download them before closing the page.&lt;br /&gt;
&lt;br /&gt;
=== ProB for Rodin ===&lt;br /&gt;
To install ProB for Rodin, first download a current version of Rodin (e.g., [https://sourceforge.net/projects/rodin-b-sharp/files/Core_Rodin_Platform/3.9/ Rodin 3.9]). Inside Rodin, choose Help -&amp;gt; Install New Software and choose the pre-configured ProB update site.&lt;br /&gt;
&lt;br /&gt;
More [[Tutorial Rodin First Step|detailed installation instructions and a brief tutorial]] are available.&lt;br /&gt;
&lt;br /&gt;
* Nightly builds of ProB for Rodin 3 can be obtained from within Rodin by using the update site https://stups.hhu-hosting.de/rodin/prob1/nightly.&lt;br /&gt;
&lt;br /&gt;
=== ProB2-UI (based on JavaFX)===&lt;br /&gt;
&lt;br /&gt;
Version 1.3.0 of the new JavaFX-based [[ProB2-UI]] is available.&lt;br /&gt;
See the [https://github.com/hhu-stups/prob2_ui/blob/develop/doc/prob2ui_release_history.md release history] for what&#039;s new.&lt;br /&gt;
You can use these stand-alone versions which come bundled with the right Java runtime environment:&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/1.3.0/ProB%202%20UI-1.3.0.exe Windows (x86_64) installer] - requires Windows 10 or later&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/1.3.0/ProB%202%20UI-aarch64-1.3.0.dmg macOS (Apple Silicon) application DMG] (not signed/notarized yet! [[#macOS issues|see below]]) - requires macOS 11 (Big Sur) or later&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/1.3.0/ProB%202%20UI-x86_64-1.3.0.dmg macOS (Intel) application DMG] (not signed/notarized yet! [[#macOS issues|see below]]) - requires macOS 11 (Big Sur) or later&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/1.3.0/prob2-ui_1.3.0_amd64.deb Debian (x86_64) package]&lt;br /&gt;
&lt;br /&gt;
You can also download a [https://stups.hhu-hosting.de/downloads/prob2/1.3.0/prob2-ui-1.3.0-multi.jar multi-platform jar], which works with Java 21 or later on all supported platforms (except macOS on arm64 - we recommend using the native macOS application instead).&lt;br /&gt;
&lt;br /&gt;
Details about new features and improvements can be found in the [https://github.com/hhu-stups/prob2_ui/blob/develop/doc/prob2ui_release_history.md release history], along with download links for older versions.&lt;br /&gt;
&lt;br /&gt;
Snapshot builds of the current &#039;&#039;development&#039;&#039; version of ProB2-UI (1.3.1-SNAPSHOT) are also available:&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/snapshot/ProB2-UI-1.3.1.exe Windows installer snapshot]&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/snapshot/ProB2-UI-aarch64-1.3.1.dmg macOS (Apple Silicon) application DMG snapshot] (not signed/notarized! [[#macOS issues|see below]])&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/snapshot/ProB2-UI-x86_64-1.3.1.dmg macOS (Intel) application DMG snapshot] (not signed/notarized! [[#macOS issues|see below]])&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/snapshot/prob2-ui_1.3.1_amd64.deb Debian package snapshot]&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/snapshot/prob2-ui-1.3.1-SNAPSHOT-multi.jar Multi-platform jar snapshot]&lt;br /&gt;
&lt;br /&gt;
The source code for ProB2-UI is available at https://github.com/hhu-stups/prob2_ui and can be built by following [https://github.com/hhu-stups/prob2_ui#running-from-source these instructions].&lt;br /&gt;
&lt;br /&gt;
The underlying [[ProB Java API]] of ProB2-UI (aka the ProB 2 kernel) is available to Java developers via [https://central.sonatype.com/artifact/de.hhu.stups/de.prob2.kernel Maven Central].&lt;br /&gt;
Its source code can be obtained from: https://github.com/hhu-stups/prob2_kernel.&lt;br /&gt;
&lt;br /&gt;
==== macOS issues ====&lt;br /&gt;
&lt;br /&gt;
When you run the macOS app for the first time, you might have to open the app &#039;&#039;twice&#039;&#039; for ProB2-UI to start properly.&lt;br /&gt;
This should only happen once.&lt;br /&gt;
&lt;br /&gt;
The ProB2-UI macOS app releases are signed and notarized, so they should run without issues.&lt;br /&gt;
However, the multi-platform jar and snapshot app builds are &#039;&#039;not&#039;&#039; signed or notarized, so macOS will refuse to run them or say that the application is damaged.&lt;br /&gt;
As a workaround, right-click the app, select &amp;quot;Open&amp;quot;, and confirm the security dialog.&lt;br /&gt;
If the dialog still doesn&#039;t give you an option to open the app, click &amp;quot;Cancel&amp;quot; and do the same thing again.&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
As a workaround, run this command in the folder where &#039;&#039;ProB2-UI.app&#039;&#039; is located:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
xattr -r -d com.apple.quarantine &amp;quot;ProB2-UI.app&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The multi-platform jar can also be started from the command line, which bypasses the signing/notarization check:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
java -jar prob2-ui-1.3.0-multi.jar&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Editor Support ===&lt;br /&gt;
&lt;br /&gt;
==== VSCODE ====&lt;br /&gt;
There is a [https://github.com/hhu-stups/b-language-extension B/ProB Language Support] extension for the Visual Studio Code (VS Code) editor. It integrates with [[Using the Command-Line Version of ProB|command line tool probcli]] to obtain error markers for syntax and type errors. It can also be used for [[Well-Definedness Checking#VSCode|well-definedness checking]].&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/vscode_plugin Download for manual installation]&lt;br /&gt;
&lt;br /&gt;
==== VIM ====&lt;br /&gt;
A [https://github.com/bivab/prob.vim VIM plugin for ProB is available]. It shows a quick fix list of parse and type errors for classical B machines (.mch) using the [[Using_the_Command-Line_Version_of_ProB|command line tool probcli]]. VIM has builtin syntax highlighting support for [https://github.com/vim/vim/blob/master/runtime/syntax/b.vim B].&lt;br /&gt;
&lt;br /&gt;
==== BBedit ====&lt;br /&gt;
Some [https://github.com/leuschel/bbedit-prob BBedit Language modules for B, TLA+, CSP and Prolog] are available; these do not use [[Using_the_Command-Line_Version_of_ProB|command line tool probcli]].&lt;br /&gt;
&lt;br /&gt;
== Java Requirements for B Parser ==&lt;br /&gt;
The B parser of ProB requires Java 8 or newer. Java 11, 17, etc. are also fully supported.&lt;br /&gt;
ProB 1.9.3 is the last version to support Java 7. ProB 1.5.0 is the last version to support Java 6.&lt;br /&gt;
&lt;br /&gt;
You can install a Java Runtime Environment (JRE) from various sources, such as [https://adoptium.net/ Eclipse Adoptium], [https://www.azul.com/downloads/?version=java-8-lts&amp;amp;package=jre-fx Azul Zulu], or your system package manager.&lt;br /&gt;
&lt;br /&gt;
Note: on some systems (macOS) you may have to install the full Java Development Kit (JDK), and not just the JRE, so that Java 8 becomes available to the command-line tools.&lt;br /&gt;
Type &amp;lt;code&amp;gt;java -version&amp;lt;/code&amp;gt; to check which version is used by default for command-line tools; see also [http://stackoverflow.com/questions/21964709/how-to-set-or-change-the-default-java-jdk-version-on-os-x this discussion on StackOverflow].&lt;br /&gt;
In case you have trouble starting the Java parser you can now set the &amp;lt;code&amp;gt;JAVA_PATH&amp;lt;/code&amp;gt; preference of ProB to point to the &amp;lt;code&amp;gt;java&amp;lt;/code&amp;gt; tool (or java.exe on Windows).&lt;br /&gt;
&lt;br /&gt;
To check whether ProB can correctly use its Java parser you can type the following (using probcli.exe on Windows):&lt;br /&gt;
 probcli -version -v&lt;br /&gt;
This will try and start the parser and obtain the parser version.&lt;br /&gt;
In case Java is not correctly installed you should get an error message.&lt;br /&gt;
If you see the error message&lt;br /&gt;
 &amp;lt;tt&amp;gt;Unsupported major.minor version 52.0&amp;lt;/tt&amp;gt;&lt;br /&gt;
this means you do not have Java 8 or newer installed. You can try setting the path to the correct java version by setting the JAVA_PATH preference as follows:&lt;br /&gt;
 probcli -p JAVA_PATH path/to/java -version -v&lt;br /&gt;
&lt;br /&gt;
== Tcl/Tk Requirements for ProB Tcl/Tk ==&lt;br /&gt;
&lt;br /&gt;
ProB Tcl/Tk requires an installation of Tcl/Tk 8.5 or Tcl/Tk 8.6. The command-line tool probcli does &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; require this.&lt;br /&gt;
&lt;br /&gt;
=== Tcl/Tk on macOS ===&lt;br /&gt;
Important note: macOS comes pre-installed with a version of Tcl/Tk which is broken.&lt;br /&gt;
This may result in the display of unreadable &amp;lt;b&amp;gt;black windows&amp;lt;/b&amp;gt; or crashes in the standard file dialogs.&lt;br /&gt;
There are various options to install Tcl/Tk:&lt;br /&gt;
* with Homebrew using the [https://formulae.brew.sh/formula/tcl-tk tcl-tk formula]&lt;br /&gt;
* with [https://ports.macports.org/port/tcl/ MacPorts]&lt;br /&gt;
* use the  [http://www.activestate.com/activetcl/downloads/ ActiveTcl version of Tcl/Tk]&lt;br /&gt;
You should probably start ProB using the &amp;lt;tt&amp;gt;StartProB.sh&amp;lt;/tt&amp;gt; script: it will auto-detect Tcl/Tk versions and set the SP_TCL_DSO environment variable.&lt;br /&gt;
Below are more details:&lt;br /&gt;
&lt;br /&gt;
==== Tcl/Tk from Homebrew or MacPorts ====&lt;br /&gt;
&lt;br /&gt;
You can install a newer Tcl/Tk (e.g., 8.6.13) using [https://brew.sh &amp;lt;b&amp;gt;Homebrew&amp;lt;/b&amp;gt;] or [https://www.macports.org &amp;lt;b&amp;gt;MacPorts&amp;lt;/b&amp;gt;].&lt;br /&gt;
Note: In the earlier release 8.6.11 [https://bugs.python.org/issue44828 file open and file save dialogs will not work].&lt;br /&gt;
For Homebrew the command to install the[https://formulae.brew.sh/formula/tcl-tk tcl-tk formula] is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 brew install tcl-tk&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The latest versions of Homebrew now install Tcl/Tk 9.0 which does not work yet with ProB.&lt;br /&gt;
In this case install&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 brew install tcl-tk@8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, as the location of the libraries is not standard, you have to define the variable &amp;lt;tt&amp;gt;SP_TCL_DSO&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The &amp;lt;tt&amp;gt;StartProB.sh&amp;lt;/tt&amp;gt; script should set SP_TCL_DSO automatically.&lt;br /&gt;
You can also define and export this variable yourself before starting ProB from the Terminal by typing this (you may have to adapt the link if you are using another version of Tcl/Tk):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
export SP_TCL_DSO=/opt/homebrew/Cellar/tcl-tk@8/8.6.16/lib/libtcl8.6.dylib&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you have uses MacPorts the path is probably &amp;lt;tt&amp;gt;/opt/local/lib/libtcl.dylib&amp;lt;/tt&amp;gt;.&lt;br /&gt;
You can also set the variable by adding &amp;lt;tt&amp;gt;-DSP_TCL_DSO=/usr/local/Cellar/tcl-tk/8.6.12/lib/libtcl8.6.dylib&amp;lt;/tt&amp;gt; to the command starting ProB. You may also have to install &amp;lt;tt&amp;gt;tk-table&amp;lt;/tt&amp;gt; package yourself (it is bundled with Active Tcl).&lt;br /&gt;
&lt;br /&gt;
==== Active Tcl ====&lt;br /&gt;
&lt;br /&gt;
The [http://www.activestate.com/activetcl/downloads/ the ActiveTcl version of Tcl/Tk] is automatically recognised by ProB and you do not have to set &amp;lt;tt&amp;gt;SP_TCL_DSO&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
However, in Active Tcl/Tk 8.6 on macOS the double click in the &amp;quot;Operations View&amp;quot; or other views  is not working correctly.&lt;br /&gt;
You have to hit the RETURN key in the &amp;quot;Operations View&amp;quot; or right-click on an operation and select &amp;quot;Perform ...&amp;quot;  to execute an operation until this is fixed.&lt;br /&gt;
The older ersion [http://bugs.python.org/issue15853 8.5.12 has a bug related to copying text], see also [http://sourceforge.net/tracker/?func=detail&amp;amp;aid=3555211&amp;amp;group_id=12997&amp;amp;atid=112997_type here]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Other Notes ====&lt;br /&gt;
Note: on macOS Catalina or later the Tcl/Tk menu bar is sometimes not working. Switching to another application and then back to ProB seems to solve the problem.&lt;br /&gt;
If you see the message &amp;quot;&amp;lt;tt&amp;gt;macOS 11 or later required !&amp;lt;/tt&amp;gt;&amp;quot;  in the terminal when launching &amp;lt;tt&amp;gt;prob&amp;lt;/tt&amp;gt; you should re-install Tcl/Tk as described above.&lt;br /&gt;
&lt;br /&gt;
=== Tcl/Tk on Windows ===&lt;br /&gt;
We currently provide two downloads of ProB, one for Tcl/Tk 8.6 (which we recommend)&lt;br /&gt;
and a version for Tcl/Tk 8.5.&lt;br /&gt;
You can use for example the  [https://www.activestate.com/products/tcl/ ActiveTcl releases].&lt;br /&gt;
Note: For the 64 bit version of ProB for Windows, you have to install the 64 bit Tcl/Tk 8.5 version!&lt;br /&gt;
ProB 1.12 (currently available as nightly build) works with both Tcl/Tk 8.5 and 8.6.&lt;br /&gt;
You may have to point the environment variable SP_TCL_DSO to the correct DLL before starting ProB. For Tcl/Tk 8.5 this is typically&lt;br /&gt;
base-tcl8.5-thread-win32-x86_64.dll.&lt;br /&gt;
You can either go to System -&amp;gt; Settings -&amp;gt; Advanced -&amp;gt; Environment Variables&lt;br /&gt;
or use the setx command for this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
setx SP_TCL_DSO C:\Tcl\bin\base-tcl8.5-thread-win32-x86_64.dll&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tcl/Tk on Linux ===&lt;br /&gt;
On Linux you can typically install Tcl/Tk using &amp;lt;tt&amp;gt;sudo apt-get install tcl8.5 tk8.5&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
On very recent Linux systems (such as Ubuntu 20.04) you may want to download (and compile) [https://www.tcl.tk/software/tcltk/downloadnow85.html Tcl/Tk 8.5] or use [https://ubuntu.pkgs.org/18.04/ubuntu-universe-amd64/tcl8.5_8.5.19-4_amd64.deb.html packages from earlier releases].&lt;br /&gt;
&lt;br /&gt;
On Linux OpenSuse (12.3) you may have to perform the following for ProB to work:&lt;br /&gt;
 ln -s /usr/lib/libtk8.5.so /usr/lib/libtk8.5.so.0&lt;br /&gt;
 ln -s /usr/lib/libtcl8.5.so /usr/lib/libtcl8.5.so.0&lt;br /&gt;
&lt;br /&gt;
Also, some of the feature require the table extension, which can be installed like this:&lt;br /&gt;
 sudo apt install tk-table&lt;br /&gt;
Finally, support for .png ANIMATION_IMG declarations requires the Img package:&lt;br /&gt;
 sudo apt install libtk-img&lt;br /&gt;
&lt;br /&gt;
== Graphviz Requirements ==&lt;br /&gt;
&lt;br /&gt;
If you wish to view various visualizations generated by ProB Tcl/Tk or probcli you will need [http://www.graphviz.org/ GraphViz].&lt;br /&gt;
ProB generates various graphs (state space, custom graph, machine hierarchy,...) as .dot files and then  uses the command-line tool &amp;lt;tt&amp;gt;dot&amp;lt;/tt&amp;gt; to layout the graph and convert it to PDF.&lt;br /&gt;
&lt;br /&gt;
ProB Tcl/Tk can also use dot-file viewer such as the &amp;lt;tt&amp;gt;dotty&amp;lt;/tt&amp;gt; program from GraphViz in Linux.&lt;br /&gt;
On macOS and Windows  it is more difficult to obtain a good viewer application for dot files. VS Code with the [https://marketplace.visualstudio.com/items?itemName=tintinweb.graphviz-interactive-preview Graphviz Interactive Preview] extension is a candidate.&lt;br /&gt;
The commercial OmniGraffle macOS application can import .dot files.  A free alternative on macOS may be [https://ports.macports.org/port/graphviz-gui/ graphviz-gui] by [https://www.macports.org MacPorts]. To install the application do this&lt;br /&gt;
* &amp;lt;tt&amp;gt;sudo port install graphviz-gui&amp;lt;/tt&amp;gt;&lt;br /&gt;
The viewer can now be found in /Applications/MacPorts/Graphviz.app (you may have to set the ProB graphical viewer preference &amp;lt;tt&amp;gt;dot_viewer&amp;lt;/tt&amp;gt; to this path).&lt;br /&gt;
If you do not manage to install a viewer, you should select Preferences -&amp;gt; Graphical Viewer -&amp;gt; PDF within ProB Tcl/Tk.&lt;br /&gt;
Indeed, many ProB commands work directly with the command-line tool &amp;lt;tt&amp;gt;dot&amp;lt;/tt&amp;gt; which you can install on macOS with MacPorts like this:&lt;br /&gt;
* &amp;lt;tt&amp;gt;sudo port install graphviz&amp;lt;/tt&amp;gt;&lt;br /&gt;
On Mac you can now install the latest version of Graphviz using [https://brew.sh HomeBrew]:&lt;br /&gt;
&lt;br /&gt;
 1. &amp;lt;tt&amp;gt;brew uninstall graphviz&amp;lt;/tt&amp;gt;&lt;br /&gt;
 2. &amp;lt;tt&amp;gt;brew install graphviz --with-gts&amp;lt;/tt&amp;gt;&lt;br /&gt;
 3. &amp;lt;tt&amp;gt;brew link --overwrite graphviz&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Step 1. is optional; you only need to use it if you have a prior version of Graphviz installed.&lt;br /&gt;
Step3 links the binaries to /usr/local/bin.&lt;br /&gt;
This is probably better than using the [http://www.pixelglow.com/graphviz/ older version from Pixelglow].&lt;br /&gt;
&lt;br /&gt;
You can also manually set the DOT (path_to_dot) preference if ProB cannot find the Graphviz dot binary you have installed.&lt;br /&gt;
&lt;br /&gt;
== Short Release History ==&lt;br /&gt;
&lt;br /&gt;
The full  [[ProB_Release_History | ProB release history can be found here]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2025-12-21&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.15.1]] is available. Automatic use of operation reuse and compression for model checking. STORE_DETAILED_TRANSITION_INFOS preference and calls LTL property. Interactive proof via animator interface for Rodin PO files.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2025-06-26&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.15.0]] is available. Interactive trace replay. Many [[VisB#VisB_DEFINITIONS |VisB]] improvements (use definition files for all models, grouping of VISB objects in a single definition, VISB_CLICK_META_INFOS, ...). Profiling can be turned on via PROFILING_INFO preference. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2024-02-20&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.13.0]] is available. Better Rodin theory support. Template strings. Unicode improvements. READ_JSON and other new external functions. VisB support for groups and &amp;quot;use&amp;quot; element. [[Monte_Carlo_Tree_Search_Game_Play|MCTS game play]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2024-02-03&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.12.2-fix1]] is available.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2023-08-10&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.12.2]] is available. [[VisB#VisB_DEFINITIONS_2 |VisB]] improvements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2023-04-04&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.12.0]] is available. Call stack infos, performance improvements in parser and solver,  new [[LTL_Model_Checking#Supported_Syntax |LTL]] operators, [[VisB#VisB_Additional_SVG_Objects|VisB]] improvements, reals/floats for [[Event-B_Theories|Rodin theories]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2021-12-29&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.11.1]] is available. Highlights: identifiers between backquotes, flexible JSON trace replay, DPLLT solving command, improvements to Z3 backend.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2021-10-06&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.11.0]] is available. Highlights: improved support for infinite sets, operation caching (OPERATION_REUSE), faster LTL checking for safety formulas, more compact .prob files, VisB HTML export, constructive Z3 translation.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2020-12-15&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.10.0]] is available. Highlights: well-definedness prover, REAL datatype, -lint comand for VSCode and Atom, improved unsat core and error messages.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2020-02-19&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.9.3]] is available. Highlights: performance improvements, new external functions, performance monitoring.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2019-11-11&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.9.2]] is available. Minor bugfix release.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2019-11-08&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.9.1]] is available. Maintenance release.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2019-07-12&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.9.0]] is available. Highlights: improved error feedback, improved Unicode support, regular expression library, memoization.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2018-10-01&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.8.2]] is available. Highlights: improved error feedback, support [https://gitlab.cs.uni-duesseldorf.de/general/stups/prob2-jupyter-kernel Jupyter kernel], first [[Alloy|support for Alloy models]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2018-03-20&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.8.0]] is available. Highlights: terminal colour support, performance improvements for displaying very large values, improved symmetry breaking and constraint solving.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2017-10-05&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.7.1]] is available. Highlights: performance, non-deterministic assigned variables shown, Z improvements, export history to HTML.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2017-07-11&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.7.0]] is available. Highlights: improved [[Generating_Documents_with_ProB_and_Latex |Latex document generation]], improved XML/CSV data import and export, RULE DSL language, many improvements in constraint solver.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2016-10-20&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.6.1]] is available. Highlights: [[Generating_Documents_with_ProB_and_Latex |Latex document generation]], LET and IF-THEN-ELSE for expressions and predicates, XML logging, XML data import, performance improvements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2016-04-22&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.6.0]] is available. Highlights: [[Tutorial_Directed_Model_Checking|directed model checking]], [[Using_ProB_with_Z3|Z3 available as backend]], B line comments and unicode symbols, improved error messages, performance improvements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2015-02-19&#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, [[State_Space_Coverage_Analyses|MC/DC coverage]] analysis for guards and invariants, [[TLC|improved TLC interface]], bug fixes and improvements including but not limited to the constraint solver.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2014-08-29&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.4.1]], a small bugfix-only release is available. For a list of new features in 1.4.0 see below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2014-08-18&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.4.0]] is available. Highlights: CLP(FD)-based constraint solver enabled by default, kernel can handle more operations symbolically, [[TLC|integration of the TLC model checker]], bug fixes and performance improvements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2013-03-04&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.3.6]] is available. Highlights: improved constraint propagation for division, modulo, intervals, model checking progress bar, performance improvements, [[Using_ProB_with_KODKOD | improved Kodkod backend]] and use within REPL, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2012-10-08&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.3.5]] is available. Highlights: support for external and recursive functions, optional Kodkod backend, [[TLA|TLA+ support]], performance improvements, pragmas, units inference, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2012-03-30&#039;&#039;&#039;&lt;br /&gt;
A first prototype of an online [[ProB_Logic_Calculator|ProB Logic Calculator]] is available.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2011-11-21&#039;&#039;&#039;&lt;br /&gt;
ProB 1.3.4 is available. Highlights: Evaluation View and Eval window, CSP assertion checking, improved editor, 64-bit version for Mac and Linux, performance improvements, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2011-02-10&#039;&#039;&#039;&lt;br /&gt;
ProB 1.3.3 and ProB for Rodin 2.3 is available. Highlights: improved performance, constrained-based deadlock checking, record detection, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2010-07-30&#039;&#039;&#039;&lt;br /&gt;
ProB 1.3.2 is available. Highlights: improved performance, constraint solving over integers (enable in Advanced Preferences), much improved Z support, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2009-12-07&#039;&#039;&#039;&lt;br /&gt;
ProB 1.3.1 is available. Highlights: new data-structure for large sets and relations (see FM 2009), multi-level validation for Event-B, improved constraint propagation for boolean connectives, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2009-03-20&#039;&#039;&#039;&lt;br /&gt;
ProB 1.3.0 is available for download. Highlights: New parser and integrated typechecker, install as AtelierB plugin, improved kernel with support for large sets/relations, improved CSP support, faster LTL model checker, Undo/Redo in text editor, graphical formula viewer, user definable custom animations with gifs.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Sequent_Prover&amp;diff=6038</id>
		<title>Sequent Prover</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Sequent_Prover&amp;diff=6038"/>
		<updated>2025-12-16T18:08:07Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: Created blank page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=ProB2-UI&amp;diff=6032</id>
		<title>ProB2-UI</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=ProB2-UI&amp;diff=6032"/>
		<updated>2025-11-07T13:34:37Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* Download */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;ProB2-UI&#039;&#039;&#039; is the new Java-based user interface for ProB. __NOTOC__&lt;br /&gt;
&lt;br /&gt;
== Download ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Download#ProB2-UI_(based_on_JavaFX)|Download the latest version of ProB2-UI here]]&#039;&#039;&#039;. See also the [https://github.com/hhu-stups/prob2_ui/blob/develop/doc/prob2ui_release_history.md release history].&lt;br /&gt;
&lt;br /&gt;
The source code for ProB2-UI is available at https://github.com/hhu-stups/prob2_ui and can be built by following [https://github.com/hhu-stups/prob2_ui#running-from-source these instructions].&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
&lt;br /&gt;
Compared to the original UI based on Tcl/Tk, this new UI has some unique new features:&lt;br /&gt;
* Projects which store formal models, ProB preferences, and verification settings&lt;br /&gt;
* Load Rodin models from Rodin workspaces (without having to export them within Rodin)&lt;br /&gt;
* Managing and storing multiple trace files for a model, being able to replay all traces&lt;br /&gt;
* MC/DC test-case generation&lt;br /&gt;
* A view for managing LTL formulas for a model&lt;br /&gt;
* Visualisation of models using [[VisB]] and SVG graphics&lt;br /&gt;
* An integrated view for all dot-based graph visualisations (state space, machine hierarchy, formulas, projection diagrams, enabling graphs, event refinement hierarchy, ....)&lt;br /&gt;
* An integrated view to access all table based statistics (event coverage, MC/DC coverage, read-write matrices, WD POs, ...)&lt;br /&gt;
* A multi-language interface, currently providing English, French, German and Russian&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We have developed a small&lt;br /&gt;
[https://mediathek.hhu.de/watch/1c7946da-3042-423f-a1c3-06833f348ec2 video highlighting the core features] (also on [https://youtu.be/HqTlr6y-hwk YouTube]) on a model the from [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples visb-visualisation-examples]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;iframe width=&#039;570&#039; height=&#039;321&#039; style=&#039;width: 570px; height: 321px; border: 1px solid #ccc;&#039; src=&#039;https://mediathek.hhu.de/embed/1c7946da-3042-423f-a1c3-06833f348ec2&#039; frameborder=&#039;0&#039; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Paper/Citing ==&lt;br /&gt;
&lt;br /&gt;
Paper: [https://link.springer.com/chapter/10.1007/978-3-030-85248-1_12 Springer Link], [https://www.researchgate.net/publication/353989368_ProB2-UI_A_Java-Based_User_Interface_for_ProB ResearchGate]&lt;br /&gt;
&lt;br /&gt;
BibTeX citation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@InProceedings{prob2ui,&lt;br /&gt;
author=&amp;quot;Bendisposto, Jens&lt;br /&gt;
and Gele{\ss}us, David&lt;br /&gt;
and Jansing, Yumiko&lt;br /&gt;
and Leuschel, Michael&lt;br /&gt;
and P{\&amp;quot;u}tz, Antonia&lt;br /&gt;
and Vu, Fabian&lt;br /&gt;
and Werth, Michelle&amp;quot;,&lt;br /&gt;
editor=&amp;quot;Lluch Lafuente, Alberto&lt;br /&gt;
and Mavridou, Anastasia&amp;quot;,&lt;br /&gt;
title=&amp;quot;ProB2-UI: A Java-Based User Interface for ProB&amp;quot;,&lt;br /&gt;
booktitle=&amp;quot;Formal Methods for Industrial Critical Systems&amp;quot;,&lt;br /&gt;
year=&amp;quot;2021&amp;quot;,&lt;br /&gt;
publisher=&amp;quot;Springer International Publishing&amp;quot;,&lt;br /&gt;
address=&amp;quot;Cham&amp;quot;,&lt;br /&gt;
pages=&amp;quot;193--201&amp;quot;,&lt;br /&gt;
abstract=&amp;quot;ProB2-UI is a modern JavaFX-based user interface for the animator, constraint solver, and model checker ProB. We present the main features of the tool, especially compared to ProB&#039;s previous user interfaces and other available tools for B, Event-B, and other formalisms. We also present some of ProB2-UI&#039;s history as well as its uses in the industry since its release in 2019.&amp;quot;,&lt;br /&gt;
isbn=&amp;quot;978-3-030-85248-1&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The ProB2-UI Main Window ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
By default the main window is split into three vertical panes (see below).&lt;br /&gt;
&lt;br /&gt;
* In the left pane, the Operations view , showing the operations whose preconditions and guards are true in this state (the view also uses a blue circular arrow icon when an operation does not change the state);&lt;br /&gt;
* In the middle the State View, containing the current state of the B machine, listing e.g., the current values of the machine variables;&lt;br /&gt;
* In the right pane there are a variety of subviews, which can be activated:&lt;br /&gt;
** [[History_View|The History of operations leading to this state (History)]]&lt;br /&gt;
** [[Project_View|The Project view]]&lt;br /&gt;
** [[Verification_View|The Verification view]]&lt;br /&gt;
** [[Statistics_View|The Statistics view]]&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2JavaFX_UI_Overview_New.png||1000px]]&lt;br /&gt;
&lt;br /&gt;
== The ProB2-UI Main Menu Bar ==&lt;br /&gt;
The menu bar contains the various commands to access the features of ProB. It includes the menus&lt;br /&gt;
*File,&lt;br /&gt;
*Edit,&lt;br /&gt;
*Formula,&lt;br /&gt;
*Consoles,&lt;br /&gt;
*Perspectives,&lt;br /&gt;
*View,&lt;br /&gt;
*Window and&lt;br /&gt;
*Help&lt;br /&gt;
[[File:File.png|none]]&lt;br /&gt;
The File submenu allows you to create a new Project, open an existing project or a machine, open recent projects shown as list and/or clear the list of recent projects, close the ProB2-UI, save your project or reload the currently running machine.&lt;br /&gt;
[[File:Edit.png|none]]&lt;br /&gt;
The Edit submenu provides two ways to edit the current machine (either in the editor provided by the ProB2-UI or in the your operating systems standard editor) and allows to edit your general and global preferences by opening a seperate window.&lt;br /&gt;
[[File:Formula.png|none]]&lt;br /&gt;
Here you can add formulas for visualization and open the history chart window.&lt;br /&gt;
[[File:Consoles.png|none]]&lt;br /&gt;
This submenu leads to two consoles, one Groovy, one B.&lt;br /&gt;
[[File:Perspectives.png|none]]&lt;br /&gt;
The Perspectives submenu allows you to change the appearance of the main view. The default view is shown at the top and two additional perspectives (Seperated History and Seperated History and Statistics) are preset. By &#039;&#039;Detach Components&#039;&#039; the view can be shown in seperate windows. &#039;&#039;Load&#039;&#039; allows you to make your own perspective by providing an FXML file containing the views but be aware that this might ruin the ability to detach components.&lt;br /&gt;
[[File:View.png|none]]&lt;br /&gt;
This submenu allows you to adjust font and button size in the ProB2-UI.&lt;br /&gt;
[[File:Help.png|none]]&lt;br /&gt;
The Help submenu provides you with help about the ProB2-UI, information about the ProB2 UI, ProB2 kernel, ProB CLI and Java version used here and a way to report issues regarding the ProB2-UI.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Download&amp;diff=6031</id>
		<title>Download</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Download&amp;diff=6031"/>
		<updated>2025-11-07T12:00:16Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* ProB2-UI (based on JavaFX) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Latest Release ==&lt;br /&gt;
&lt;br /&gt;
Below are links for downloading the latest stable release of probcli (the command line version of ProB) and ProB Tcl/Tk (ProB with a graphical user interface written in Tcl/Tk).&lt;br /&gt;
Note: please use the provided start scripts (StartProB.sh or StartProBWin.bat) to start ProB.&lt;br /&gt;
The list of changes can be found in the [[ProB_Release_History | ProB release history]].&lt;br /&gt;
&lt;br /&gt;
Details of the [[ProBLicence| ProB Licence can be found here]].&lt;br /&gt;
ProB is free to use and open source. For commercial support contact  [https://www.stups.uni-duesseldorf.de/~leuschel/ Michael Leuschel]. In particular, we can provide access to the validation report for using ProB as a tool of class T2 or T3 within the European norm [https://de.wikipedia.org/wiki/EN_50128 EN50128].&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;table table-bordered wikitable&amp;quot; &amp;lt;!-- table and table-bordered for Bootstrap (ProB skin), wikitable for MediaWiki (Vector, MonoBook, etc. skins) --&amp;gt;&lt;br /&gt;
! Platform&lt;br /&gt;
! Release Date&lt;br /&gt;
! Download&lt;br /&gt;
! Dependencies&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; style=&amp;quot;background-color:lightgrey;&amp;quot; | 1.15.0&lt;br /&gt;
|-&lt;br /&gt;
| Linux &lt;br /&gt;
| 26.6.2025 &lt;br /&gt;
| [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/1.15.0/ProB.linux64.tar.gz Tarball]&amp;lt;br/&amp;gt;&lt;br /&gt;
| Java 8 or newer ([[#Java Requirements for B parser|see below]]), Tcl/Tk 8.5 or 8.6 ([[#Tcl/Tk on Linux|see below]]), [https://www.graphviz.org/download/ GraphViz]&lt;br /&gt;
|-&lt;br /&gt;
| Windows&lt;br /&gt;
| 26.6.2025  &lt;br /&gt;
| [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/1.15.0/ProB.windows64.zip Zipfile] (Tcl/Tk 8.6), &amp;lt;br/&amp;gt; [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/1.15.0/ProB.windows64-tcltk-85.zip Zipfile] (Tcl/Tk 8.5)&lt;br /&gt;
| Tcl/Tk 8.5 or 8.6 ([[#Tcl/Tk on Windows|see below]]), Java 8 or newer ([[#Java Requirements for B parser|see below]]), [https://www.graphviz.org/download/ GraphViz], [[Windows Installation Instructions]]&lt;br /&gt;
|-&lt;br /&gt;
| macOS&lt;br /&gt;
| 26.6.2025  &lt;br /&gt;
| [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/1.15.0/ProB.macos.zip Zipfile] (Universal ARM/Intel notarized)&amp;lt;br/&amp;gt; &lt;br /&gt;
[https://github.com/hhu-stups/homebrew-prob Homebrew Tap]&lt;br /&gt;
| macOS 10.14 (Mojave) or newer, Tcl/Tk 8.6 ([[#Tcl/Tk on macOS|see below]]), Java 8 or newer ([[#Java Requirements for B parser|see below]]), [https://www.graphviz.org/download/ Graphviz] ([[#Graphviz_Requirements|see below]])&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The B parser of ProB requires Java 8 or newer. More details [[#Java Requirements for B parser|are available below]].&lt;br /&gt;
&lt;br /&gt;
The Graphical User Interface of ProB Tcl/Tk requires Tcl/Tk 8.5 or 8.6. More details [[#Tcl/Tk Requirements for ProB Tcl/Tk|are available below]].&lt;br /&gt;
The default Tcl/Tk on macOS is broken and will result in &amp;lt;b&amp;gt;black windows&amp;lt;/b&amp;gt;, and you have to [[#Tcl/Tk Requirements for ProB Tcl/Tk|install another version of Tcl/Tk]]. (Note: Tcl/Tk 9 is not binary compatible and cannot yet be used.)&lt;br /&gt;
All releases include the command-line version &amp;lt;b&amp;gt;probcli&amp;lt;/b&amp;gt; which does &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; require Tcl/Tk.&lt;br /&gt;
&lt;br /&gt;
Releases are compiled for the &#039;&#039;&#039;x86_64&#039;&#039;&#039; architecture (64-bit Intel).&lt;br /&gt;
macOS releases of ProB 1.12.0 and later also support &#039;&#039;&#039;aarch64&#039;&#039;&#039; (64-bit ARM/Apple Silicon).&lt;br /&gt;
The last version built for x86 (32-bit Intel) is ProB 1.8.0 (see [[DownloadPriorVersions|prior versions]]).&lt;br /&gt;
If you are using an unsupported architecture or system, you may still be able to [[Running ProB from source|run ProB from source]].&lt;br /&gt;
&lt;br /&gt;
Note that: on &amp;lt;b&amp;gt;macOS&amp;lt;/b&amp;gt; you  still have to right-click on the application and use &amp;quot;Open&amp;quot;, even though ProB Tcl/Tk (and probcli and all libraries) are signed and notarized. &lt;br /&gt;
 &lt;br /&gt;
=== Latest Beta Release ===&lt;br /&gt;
&lt;br /&gt;
The latest beta release is [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/1.13.1-beta1 1.13.1-beta1].&lt;br /&gt;
It may be older than the latest final release.&lt;br /&gt;
An official beta release always passes all of ProB&#039;s tests.&lt;br /&gt;
However, we do not follow the stringent checklist for final releases&lt;br /&gt;
(e.g., checking SICStus Prolog Spider warnings, checking coverage and additional manual&lt;br /&gt;
UI tests).&lt;br /&gt;
Also, we do not store coverage reports and other information necessary for T2 certification.&lt;br /&gt;
&lt;br /&gt;
=== Nightly Builds ===&lt;br /&gt;
&lt;br /&gt;
More current [https://stups.hhu-hosting.de/downloads/prob/tcltk/nightly/ nightly integration builds] are also available.&lt;br /&gt;
These releases are usually updated every night and old versions are not stored.&lt;br /&gt;
&lt;br /&gt;
Note for macOS users: Nightly builds of ProB are not signed or notarized, so macOS 10.15 and later (Catalina, Big Sur or Monterey, Ventura) will refuse to run them.&lt;br /&gt;
As a workaround, you will need to run &amp;lt;code&amp;gt;xattr -r -d com.apple.quarantine *&amp;lt;/code&amp;gt; inside the ProB directory before launching ProB.&lt;br /&gt;
The stable and beta releases listed above are signed and notarized, so they will run without extra steps.&lt;br /&gt;
&lt;br /&gt;
Automatically generated test [https://stups.hhu-hosting.de/internal/coverage/html/ coverage reports are also available].&lt;br /&gt;
They are usually updated once per week.&lt;br /&gt;
&lt;br /&gt;
=== Sourcecode ===&lt;br /&gt;
&lt;br /&gt;
You can download the latest Prolog sourcecode snapshot from: https://stups.hhu-hosting.de/downloads/prob/source/&lt;br /&gt;
&lt;br /&gt;
The source code for the ProB parsers (B, LTL, ...) can be obtained from: https://github.com/hhu-stups/probparsers&lt;br /&gt;
&lt;br /&gt;
=== Prior Versions ===&lt;br /&gt;
&lt;br /&gt;
Prior Versions of ProB going back to 1.3.1 [[DownloadPriorVersions|are available for download here]]. &lt;br /&gt;
If you are interested in still earlier releases, please have a look at the [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/ Download directory].&lt;br /&gt;
&lt;br /&gt;
== Other ProB tools ==&lt;br /&gt;
&lt;br /&gt;
=== ProB Jupyter Kernel ===&lt;br /&gt;
&lt;br /&gt;
You can now create Jupyter Notebooks in B using the ProB Jupyter kernel.&lt;br /&gt;
Downloads, instructions, and source code can be found on [https://gitlab.cs.uni-duesseldorf.de/general/stups/prob2-jupyter-kernel its own page].&lt;br /&gt;
&lt;br /&gt;
You can [https://mybinder.org/v2/git/https%3A%2F%2Fgitlab.cs.uni-duesseldorf.de%2Fgeneral%2Fstups%2Fprob2-jupyter-kernel.git/master?filepath=notebooks try out the ProB Jupyter kernel in your browser] without installing it first.&lt;br /&gt;
Note that &#039;&#039;&#039;notebooks are not saved permanently in this online version!&#039;&#039;&#039;&lt;br /&gt;
To keep your notebooks, you &#039;&#039;must&#039;&#039; download them before closing the page.&lt;br /&gt;
&lt;br /&gt;
=== ProB for Rodin ===&lt;br /&gt;
To install ProB for Rodin, first download a current version of Rodin (e.g., [https://sourceforge.net/projects/rodin-b-sharp/files/Core_Rodin_Platform/3.9/ Rodin 3.9]). Inside Rodin, choose Help -&amp;gt; Install New Software and choose the pre-configured ProB update site.&lt;br /&gt;
&lt;br /&gt;
More [[Tutorial Rodin First Step|detailed installation instructions and a brief tutorial]] are available.&lt;br /&gt;
&lt;br /&gt;
* Nightly builds of ProB for Rodin 3 can be obtained from within Rodin by using the update site https://stups.hhu-hosting.de/rodin/prob1/nightly.&lt;br /&gt;
&lt;br /&gt;
=== ProB2-UI (based on JavaFX)===&lt;br /&gt;
&lt;br /&gt;
Version 1.3.0 of the new JavaFX-based [[ProB2-UI]] is available.&lt;br /&gt;
See the [https://github.com/hhu-stups/prob2_ui/blob/develop/doc/prob2ui_release_history.md release history] for what&#039;s new.&lt;br /&gt;
You can use these stand-alone versions which come bundled with the right Java runtime environment:&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/1.3.0/ProB%202%20UI-1.3.0.exe Windows (x86_64) installer] - requires Windows 10 or later&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/1.3.0/ProB%202%20UI-aarch64-1.3.0.dmg macOS (Apple Silicon) application DMG] (not signed/notarized yet! [[#macOS issues|see below]]) - requires macOS 11 (Big Sur) or later&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/1.3.0/ProB%202%20UI-x86_64-1.3.0.dmg macOS (Intel) application DMG] (not signed/notarized yet! [[#macOS issues|see below]]) - requires macOS 11 (Big Sur) or later&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/1.3.0/prob2-ui_1.3.0_amd64.deb Debian (x86_64) package]&lt;br /&gt;
&lt;br /&gt;
You can also download a [https://stups.hhu-hosting.de/downloads/prob2/1.3.0/prob2-ui-1.3.0-multi.jar multi-platform jar], which works with Java 21 or later on all supported platforms (except macOS on arm64 - we recommend using the native macOS application instead).&lt;br /&gt;
&lt;br /&gt;
Details about new features and improvements can be found in the [https://github.com/hhu-stups/prob2_ui/blob/develop/doc/prob2ui_release_history.md release history], along with download links for older versions.&lt;br /&gt;
&lt;br /&gt;
Snapshot builds of the current &#039;&#039;development&#039;&#039; version of ProB2-UI (1.3.1-SNAPSHOT) are also available:&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/snapshot/ProB2-UI-1.3.1.exe Windows installer snapshot]&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/snapshot/ProB2-UI-aarch64-1.3.1.dmg macOS (Apple Silicon) application DMG snapshot] (not signed/notarized! [[#macOS issues|see below]])&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/snapshot/ProB2-UI-x86_64-1.3.1.dmg macOS (Intel) application DMG snapshot] (not signed/notarized! [[#macOS issues|see below]])&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/snapshot/prob2-ui_1.3.1_amd64.deb Debian package snapshot]&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/snapshot/prob2-ui-1.3.1-SNAPSHOT-multi.jar Multi-platform jar snapshot]&lt;br /&gt;
&lt;br /&gt;
The source code for ProB2-UI is available at https://github.com/hhu-stups/prob2_ui and can be built by following [https://github.com/hhu-stups/prob2_ui#running-from-source these instructions].&lt;br /&gt;
&lt;br /&gt;
The underlying [[ProB Java API]] of ProB2-UI (aka the ProB 2 kernel) is available to Java developers via [https://central.sonatype.com/artifact/de.hhu.stups/de.prob2.kernel Maven Central].&lt;br /&gt;
Its source code can be obtained from: https://github.com/hhu-stups/prob2_kernel.&lt;br /&gt;
&lt;br /&gt;
==== macOS issues ====&lt;br /&gt;
&lt;br /&gt;
When you run the macOS app for the first time, you might have to open the app &#039;&#039;twice&#039;&#039; for ProB 2 UI to start properly.&lt;br /&gt;
This should only happen once.&lt;br /&gt;
&lt;br /&gt;
The ProB 2 UI macOS app releases are signed and notarized, so they should run without issues.&lt;br /&gt;
However, the multi-platform jar and snapshot app builds are &#039;&#039;not&#039;&#039; signed or notarized, so macOS will refuse to run them or say that the application is damaged.&lt;br /&gt;
As a workaround, right-click the app, select &amp;quot;Open&amp;quot;, and confirm the security dialog.&lt;br /&gt;
If the dialog still doesn&#039;t give you an option to open the app, click &amp;quot;Cancel&amp;quot; and do the same thing again.&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
As a workaround, run this command in the folder where &#039;&#039;ProB 2 UI.app&#039;&#039; is located:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
xattr -r -d com.apple.quarantine &amp;quot;ProB 2 UI.app&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The multi-platform jar can also be started from the command line, which bypasses the signing/notarization check:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
java -jar prob2-ui-1.3.0-multi.jar&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Editor Support ===&lt;br /&gt;
&lt;br /&gt;
==== VSCODE ====&lt;br /&gt;
There is a [https://github.com/hhu-stups/b-language-extension B/ProB Language Support] extension for the Visual Studio Code (VS Code) editor. It integrates with [[Using the Command-Line Version of ProB|command line tool probcli]] to obtain error markers for syntax and type errors. It can also be used for [[Well-Definedness Checking#VSCode|well-definedness checking]].&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/vscode_plugin Download for manual installation]&lt;br /&gt;
&lt;br /&gt;
==== VIM ====&lt;br /&gt;
A [https://github.com/bivab/prob.vim VIM plugin for ProB is available]. It shows a quick fix list of parse and type errors for classical B machines (.mch) using the [[Using_the_Command-Line_Version_of_ProB|command line tool probcli]]. VIM has builtin syntax highlighting support for [https://github.com/vim/vim/blob/master/runtime/syntax/b.vim B].&lt;br /&gt;
&lt;br /&gt;
==== BBedit ====&lt;br /&gt;
Some [https://github.com/leuschel/bbedit-prob BBedit Language modules for B, TLA+, CSP and Prolog] are available; these do not use [[Using_the_Command-Line_Version_of_ProB|command line tool probcli]].&lt;br /&gt;
&lt;br /&gt;
== Java Requirements for B Parser ==&lt;br /&gt;
The B parser of ProB requires Java 8 or newer. Java 11, 17, etc. are also fully supported.&lt;br /&gt;
ProB 1.9.3 is the last version to support Java 7. ProB 1.5.0 is the last version to support Java 6.&lt;br /&gt;
&lt;br /&gt;
You can install a Java Runtime Environment (JRE) from various sources, such as [https://adoptium.net/ Eclipse Adoptium], [https://www.azul.com/downloads/?version=java-8-lts&amp;amp;package=jre-fx Azul Zulu], or your system package manager.&lt;br /&gt;
&lt;br /&gt;
Note: on some systems (macOS) you may have to install the full Java Development Kit (JDK), and not just the JRE, so that Java 8 becomes available to the command-line tools.&lt;br /&gt;
Type &amp;lt;code&amp;gt;java -version&amp;lt;/code&amp;gt; to check which version is used by default for command-line tools; see also [http://stackoverflow.com/questions/21964709/how-to-set-or-change-the-default-java-jdk-version-on-os-x this discussion on StackOverflow].&lt;br /&gt;
In case you have trouble starting the Java parser you can now set the &amp;lt;code&amp;gt;JAVA_PATH&amp;lt;/code&amp;gt; preference of ProB to point to the &amp;lt;code&amp;gt;java&amp;lt;/code&amp;gt; tool (or java.exe on Windows).&lt;br /&gt;
&lt;br /&gt;
To check whether ProB can correctly use its Java parser you can type the following (using probcli.exe on Windows):&lt;br /&gt;
 probcli -version -v&lt;br /&gt;
This will try and start the parser and obtain the parser version.&lt;br /&gt;
In case Java is not correctly installed you should get an error message.&lt;br /&gt;
If you see the error message&lt;br /&gt;
 &amp;lt;tt&amp;gt;Unsupported major.minor version 52.0&amp;lt;/tt&amp;gt;&lt;br /&gt;
this means you do not have Java 8 or newer installed. You can try setting the path to the correct java version by setting the JAVA_PATH preference as follows:&lt;br /&gt;
 probcli -p JAVA_PATH path/to/java -version -v&lt;br /&gt;
&lt;br /&gt;
== Tcl/Tk Requirements for ProB Tcl/Tk ==&lt;br /&gt;
&lt;br /&gt;
ProB Tcl/Tk requires an installation of Tcl/Tk 8.5 or Tcl/Tk 8.6. The command-line tool probcli does &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; require this.&lt;br /&gt;
&lt;br /&gt;
=== Tcl/Tk on macOS ===&lt;br /&gt;
Important note: macOS comes pre-installed with a version of Tcl/Tk which is broken.&lt;br /&gt;
This may result in the display of unreadable &amp;lt;b&amp;gt;black windows&amp;lt;/b&amp;gt; or crashes in the standard file dialogs.&lt;br /&gt;
There are various options to install Tcl/Tk:&lt;br /&gt;
* with Homebrew using the [https://formulae.brew.sh/formula/tcl-tk tcl-tk formula]&lt;br /&gt;
* with [https://ports.macports.org/port/tcl/ MacPorts]&lt;br /&gt;
* use the  [http://www.activestate.com/activetcl/downloads/ ActiveTcl version of Tcl/Tk]&lt;br /&gt;
You should probably start ProB using the &amp;lt;tt&amp;gt;StartProB.sh&amp;lt;/tt&amp;gt; script: it will auto-detect Tcl/Tk versions and set the SP_TCL_DSO environment variable.&lt;br /&gt;
Below are more details:&lt;br /&gt;
&lt;br /&gt;
==== Tcl/Tk from Homebrew or MacPorts ====&lt;br /&gt;
&lt;br /&gt;
You can install a newer Tcl/Tk (e.g., 8.6.13) using [https://brew.sh &amp;lt;b&amp;gt;Homebrew&amp;lt;/b&amp;gt;] or [https://www.macports.org &amp;lt;b&amp;gt;MacPorts&amp;lt;/b&amp;gt;].&lt;br /&gt;
Note: In the earlier release 8.6.11 [https://bugs.python.org/issue44828 file open and file save dialogs will not work].&lt;br /&gt;
For Homebrew the command to install the[https://formulae.brew.sh/formula/tcl-tk tcl-tk formula] is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 brew install tcl-tk&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The latest versions of Homebrew now install Tcl/Tk 9.0 which does not work yet with ProB.&lt;br /&gt;
In this case install&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 brew install tcl-tk@8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, as the location of the libraries is not standard, you have to define the variable &amp;lt;tt&amp;gt;SP_TCL_DSO&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The &amp;lt;tt&amp;gt;StartProB.sh&amp;lt;/tt&amp;gt; script should set SP_TCL_DSO automatically.&lt;br /&gt;
You can also define and export this variable yourself before starting ProB from the Terminal by typing this (you may have to adapt the link if you are using another version of Tcl/Tk):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
export SP_TCL_DSO=/opt/homebrew/Cellar/tcl-tk@8/8.6.16/lib/libtcl8.6.dylib&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you have uses MacPorts the path is probably &amp;lt;tt&amp;gt;/opt/local/lib/libtcl.dylib&amp;lt;/tt&amp;gt;.&lt;br /&gt;
You can also set the variable by adding &amp;lt;tt&amp;gt;-DSP_TCL_DSO=/usr/local/Cellar/tcl-tk/8.6.12/lib/libtcl8.6.dylib&amp;lt;/tt&amp;gt; to the command starting ProB. You may also have to install &amp;lt;tt&amp;gt;tk-table&amp;lt;/tt&amp;gt; package yourself (it is bundled with Active Tcl).&lt;br /&gt;
&lt;br /&gt;
==== Active Tcl ====&lt;br /&gt;
&lt;br /&gt;
The [http://www.activestate.com/activetcl/downloads/ the ActiveTcl version of Tcl/Tk] is automatically recognised by ProB and you do not have to set &amp;lt;tt&amp;gt;SP_TCL_DSO&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
However, in Active Tcl/Tk 8.6 on macOS the double click in the &amp;quot;Operations View&amp;quot; or other views  is not working correctly.&lt;br /&gt;
You have to hit the RETURN key in the &amp;quot;Operations View&amp;quot; or right-click on an operation and select &amp;quot;Perform ...&amp;quot;  to execute an operation until this is fixed.&lt;br /&gt;
The older ersion [http://bugs.python.org/issue15853 8.5.12 has a bug related to copying text], see also [http://sourceforge.net/tracker/?func=detail&amp;amp;aid=3555211&amp;amp;group_id=12997&amp;amp;atid=112997_type here]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Other Notes ====&lt;br /&gt;
Note: on macOS Catalina or later the Tcl/Tk menu bar is sometimes not working. Switching to another application and then back to ProB seems to solve the problem.&lt;br /&gt;
If you see the message &amp;quot;&amp;lt;tt&amp;gt;macOS 11 or later required !&amp;lt;/tt&amp;gt;&amp;quot;  in the terminal when launching &amp;lt;tt&amp;gt;prob&amp;lt;/tt&amp;gt; you should re-install Tcl/Tk as described above.&lt;br /&gt;
&lt;br /&gt;
=== Tcl/Tk on Windows ===&lt;br /&gt;
We currently provide two downloads of ProB, one for Tcl/Tk 8.6 (which we recommend)&lt;br /&gt;
and a version for Tcl/Tk 8.5.&lt;br /&gt;
You can use for example the  [https://www.activestate.com/products/tcl/ ActiveTcl releases].&lt;br /&gt;
Note: For the 64 bit version of ProB for Windows, you have to install the 64 bit Tcl/Tk 8.5 version!&lt;br /&gt;
ProB 1.12 (currently available as nightly build) works with both Tcl/Tk 8.5 and 8.6.&lt;br /&gt;
You may have to point the environment variable SP_TCL_DSO to the correct DLL before starting ProB. For Tcl/Tk 8.5 this is typically&lt;br /&gt;
base-tcl8.5-thread-win32-x86_64.dll.&lt;br /&gt;
You can either go to System -&amp;gt; Settings -&amp;gt; Advanced -&amp;gt; Environment Variables&lt;br /&gt;
or use the setx command for this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
setx SP_TCL_DSO C:\Tcl\bin\base-tcl8.5-thread-win32-x86_64.dll&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tcl/Tk on Linux ===&lt;br /&gt;
On Linux you can typically install Tcl/Tk using &amp;lt;tt&amp;gt;sudo apt-get install tcl8.5 tk8.5&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
On very recent Linux systems (such as Ubuntu 20.04) you may want to download (and compile) [https://www.tcl.tk/software/tcltk/downloadnow85.html Tcl/Tk 8.5] or use [https://ubuntu.pkgs.org/18.04/ubuntu-universe-amd64/tcl8.5_8.5.19-4_amd64.deb.html packages from earlier releases].&lt;br /&gt;
&lt;br /&gt;
On Linux OpenSuse (12.3) you may have to perform the following for ProB to work:&lt;br /&gt;
 ln -s /usr/lib/libtk8.5.so /usr/lib/libtk8.5.so.0&lt;br /&gt;
 ln -s /usr/lib/libtcl8.5.so /usr/lib/libtcl8.5.so.0&lt;br /&gt;
&lt;br /&gt;
Also, some of the feature require the table extension, which can be installed like this:&lt;br /&gt;
 sudo apt install tk-table&lt;br /&gt;
Finally, support for .png ANIMATION_IMG declarations requires the Img package:&lt;br /&gt;
 sudo apt install libtk-img&lt;br /&gt;
&lt;br /&gt;
== Graphviz Requirements ==&lt;br /&gt;
&lt;br /&gt;
If you wish to view various visualizations generated by ProB Tcl/Tk or probcli you will need [http://www.graphviz.org/ GraphViz].&lt;br /&gt;
ProB generates various graphs (state space, custom graph, machine hierarchy,...) as .dot files and then  uses the command-line tool &amp;lt;tt&amp;gt;dot&amp;lt;/tt&amp;gt; to layout the graph and convert it to PDF.&lt;br /&gt;
&lt;br /&gt;
ProB Tcl/Tk can also use dot-file viewer such as the &amp;lt;tt&amp;gt;dotty&amp;lt;/tt&amp;gt; program from GraphViz in Linux.&lt;br /&gt;
On macOS and Windows  it is more difficult to obtain a good viewer application for dot files. VS Code with the [https://marketplace.visualstudio.com/items?itemName=tintinweb.graphviz-interactive-preview Graphviz Interactive Preview] extension is a candidate.&lt;br /&gt;
The commercial OmniGraffle macOS application can import .dot files.  A free alternative on macOS may be [https://ports.macports.org/port/graphviz-gui/ graphviz-gui] by [https://www.macports.org MacPorts]. To install the application do this&lt;br /&gt;
* &amp;lt;tt&amp;gt;sudo port install graphviz-gui&amp;lt;/tt&amp;gt;&lt;br /&gt;
The viewer can now be found in /Applications/MacPorts/Graphviz.app (you may have to set the ProB graphical viewer preference &amp;lt;tt&amp;gt;dot_viewer&amp;lt;/tt&amp;gt; to this path).&lt;br /&gt;
If you do not manage to install a viewer, you should select Preferences -&amp;gt; Graphical Viewer -&amp;gt; PDF within ProB Tcl/Tk.&lt;br /&gt;
Indeed, many ProB commands work directly with the command-line tool &amp;lt;tt&amp;gt;dot&amp;lt;/tt&amp;gt; which you can install on macOS with MacPorts like this:&lt;br /&gt;
* &amp;lt;tt&amp;gt;sudo port install graphviz&amp;lt;/tt&amp;gt;&lt;br /&gt;
On Mac you can now install the latest version of Graphviz using [https://brew.sh HomeBrew]:&lt;br /&gt;
&lt;br /&gt;
 1. &amp;lt;tt&amp;gt;brew uninstall graphviz&amp;lt;/tt&amp;gt;&lt;br /&gt;
 2. &amp;lt;tt&amp;gt;brew install graphviz --with-gts&amp;lt;/tt&amp;gt;&lt;br /&gt;
 3. &amp;lt;tt&amp;gt;brew link --overwrite graphviz&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Step 1. is optional; you only need to use it if you have a prior version of Graphviz installed.&lt;br /&gt;
Step3 links the binaries to /usr/local/bin.&lt;br /&gt;
This is probably better than using the [http://www.pixelglow.com/graphviz/ older version from Pixelglow].&lt;br /&gt;
&lt;br /&gt;
You can also manually set the DOT (path_to_dot) preference if ProB cannot find the Graphviz dot binary you have installed.&lt;br /&gt;
&lt;br /&gt;
== Short Release History ==&lt;br /&gt;
&lt;br /&gt;
The full  [[ProB_Release_History | ProB release history can be found here]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2024-02-20&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.13.0]] is available. Better Rodin theory support. Template strings. Unicode improvements. READ_JSON and other new external functions. VisB support for groups and &amp;quot;use&amp;quot; element. [[Monte_Carlo_Tree_Search_Game_Play|MCTS game play]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2024-02-03&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.12.2-fix1]] is available.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2023-08-10&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.12.2]] is available. [[VisB#VisB_DEFINITIONS_2 |VisB]] improvements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2023-04-04&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.12.0]] is available. Call stack infos, performance improvements in parser and solver,  new [[LTL_Model_Checking#Supported_Syntax |LTL]] operators, [[VisB#VisB_Additional_SVG_Objects|VisB]] improvements, reals/floats for [[Event-B_Theories|Rodin theories]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2021-12-29&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.11.1]] is available. Highlights: identifiers between backquotes, flexible JSON trace replay, DPLLT solving command, improvements to Z3 backend.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2021-10-06&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.11.0]] is available. Highlights: improved support for infinite sets, operation caching (OPERATION_REUSE), faster LTL checking for safety formulas, more compact .prob files, VisB HTML export, constructive Z3 translation.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2020-12-15&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.10.0]] is available. Highlights: well-definedness prover, REAL datatype, -lint comand for VSCode and Atom, improved unsat core and error messages.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2020-02-19&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.9.3]] is available. Highlights: performance improvements, new external functions, performance monitoring.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2019-11-11&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.9.2]] is available. Minor bugfix release.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2019-11-08&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.9.1]] is available. Maintenance release.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2019-07-12&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.9.0]] is available. Highlights: improved error feedback, improved Unicode support, regular expression library, memoization.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2018-10-01&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.8.2]] is available. Highlights: improved error feedback, support [https://gitlab.cs.uni-duesseldorf.de/general/stups/prob2-jupyter-kernel Jupyter kernel], first [[Alloy|support for Alloy models]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2018-03-20&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.8.0]] is available. Highlights: terminal colour support, performance improvements for displaying very large values, improved symmetry breaking and constraint solving.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2017-10-05&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.7.1]] is available. Highlights: performance, non-deterministic assigned variables shown, Z improvements, export history to HTML.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2017-07-11&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.7.0]] is available. Highlights: improved [[Generating_Documents_with_ProB_and_Latex |Latex document generation]], improved XML/CSV data import and export, RULE DSL language, many improvements in constraint solver.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2016-10-20&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.6.1]] is available. Highlights: [[Generating_Documents_with_ProB_and_Latex |Latex document generation]], LET and IF-THEN-ELSE for expressions and predicates, XML logging, XML data import, performance improvements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2016-04-22&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.6.0]] is available. Highlights: [[Tutorial_Directed_Model_Checking|directed model checking]], [[Using_ProB_with_Z3|Z3 available as backend]], B line comments and unicode symbols, improved error messages, performance improvements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2015-02-19&#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, [[State_Space_Coverage_Analyses|MC/DC coverage]] analysis for guards and invariants, [[TLC|improved TLC interface]], bug fixes and improvements including but not limited to the constraint solver.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2014-08-29&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.4.1]], a small bugfix-only release is available. For a list of new features in 1.4.0 see below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2014-08-18&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.4.0]] is available. Highlights: CLP(FD)-based constraint solver enabled by default, kernel can handle more operations symbolically, [[TLC|integration of the TLC model checker]], bug fixes and performance improvements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2013-03-04&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.3.6]] is available. Highlights: improved constraint propagation for division, modulo, intervals, model checking progress bar, performance improvements, [[Using_ProB_with_KODKOD | improved Kodkod backend]] and use within REPL, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2012-10-08&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.3.5]] is available. Highlights: support for external and recursive functions, optional Kodkod backend, [[TLA|TLA+ support]], performance improvements, pragmas, units inference, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2012-03-30&#039;&#039;&#039;&lt;br /&gt;
A first prototype of an online [[ProB_Logic_Calculator|ProB Logic Calculator]] is available.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2011-11-21&#039;&#039;&#039;&lt;br /&gt;
ProB 1.3.4 is available. Highlights: Evaluation View and Eval window, CSP assertion checking, improved editor, 64-bit version for Mac and Linux, performance improvements, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2011-02-10&#039;&#039;&#039;&lt;br /&gt;
ProB 1.3.3 and ProB for Rodin 2.3 is available. Highlights: improved performance, constrained-based deadlock checking, record detection, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2010-07-30&#039;&#039;&#039;&lt;br /&gt;
ProB 1.3.2 is available. Highlights: improved performance, constraint solving over integers (enable in Advanced Preferences), much improved Z support, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2009-12-07&#039;&#039;&#039;&lt;br /&gt;
ProB 1.3.1 is available. Highlights: new data-structure for large sets and relations (see FM 2009), multi-level validation for Event-B, improved constraint propagation for boolean connectives, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2009-03-20&#039;&#039;&#039;&lt;br /&gt;
ProB 1.3.0 is available for download. Highlights: New parser and integrated typechecker, install as AtelierB plugin, improved kernel with support for large sets/relations, improved CSP support, faster LTL model checker, Undo/Redo in text editor, graphical formula viewer, user definable custom animations with gifs.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Handbook/Advanced_Features&amp;diff=6030</id>
		<title>Handbook/Advanced Features</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Handbook/Advanced_Features&amp;diff=6030"/>
		<updated>2025-10-28T07:09:15Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= [[Bash Completion]] =&lt;br /&gt;
{{:Bash Completion}}&lt;br /&gt;
&lt;br /&gt;
= [[B2SAT]] =&lt;br /&gt;
{{:B2SAT}}&lt;br /&gt;
&lt;br /&gt;
= [[Common Subexpression Elimination]] =&lt;br /&gt;
{{:Common Subexpression Elimination}}&lt;br /&gt;
&lt;br /&gt;
= [[PROBPATH|The ProB Search Path]] =&lt;br /&gt;
{{:PROBPATH}}&lt;br /&gt;
{{DISPLAYTITLE:Handbook/Advanced Features}} &amp;lt;!-- Undo custom display title set by PROBPATH page --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= [[TLC]] =&lt;br /&gt;
{{:TLC}}&lt;br /&gt;
&lt;br /&gt;
= [[Generating Documents with ProB and Latex]] =&lt;br /&gt;
{{:Generating Documents with ProB and Latex}}&lt;br /&gt;
&lt;br /&gt;
= [[Using ProB with Atelier B]] =&lt;br /&gt;
{{:Using ProB with Atelier B}}&lt;br /&gt;
&lt;br /&gt;
= [[Using ProB with KODKOD]] =&lt;br /&gt;
{{:Using ProB with KODKOD}}&lt;br /&gt;
&lt;br /&gt;
= [[Using ProB with Z3]] =&lt;br /&gt;
{{:Using ProB with Z3}}&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Download&amp;diff=6026</id>
		<title>Download</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Download&amp;diff=6026"/>
		<updated>2025-10-13T11:35:50Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* Editor Support */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Latest Release ==&lt;br /&gt;
&lt;br /&gt;
Below are links for downloading the latest stable release of probcli (the command line version of ProB) and ProB Tcl/Tk (ProB with a graphical user interface written in Tcl/Tk).&lt;br /&gt;
Note: please use the provided start scripts (StartProB.sh or StartProBWin.bat) to start ProB.&lt;br /&gt;
The list of changes can be found in the [[ProB_Release_History | ProB release history]].&lt;br /&gt;
&lt;br /&gt;
Details of the [[ProBLicence| ProB Licence can be found here]].&lt;br /&gt;
ProB is free to use and open source. For commercial support contact  [https://www.stups.uni-duesseldorf.de/~leuschel/ Michael Leuschel]. In particular, we can provide access to the validation report for using ProB as a tool of class T2 or T3 within the European norm [https://de.wikipedia.org/wiki/EN_50128 EN50128].&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;table table-bordered wikitable&amp;quot; &amp;lt;!-- table and table-bordered for Bootstrap (ProB skin), wikitable for MediaWiki (Vector, MonoBook, etc. skins) --&amp;gt;&lt;br /&gt;
! Platform&lt;br /&gt;
! Release Date&lt;br /&gt;
! Download&lt;br /&gt;
! Dependencies&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; style=&amp;quot;background-color:lightgrey;&amp;quot; | 1.15.0&lt;br /&gt;
|-&lt;br /&gt;
| Linux &lt;br /&gt;
| 26.6.2025 &lt;br /&gt;
| [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/1.15.0/ProB.linux64.tar.gz Tarball]&amp;lt;br/&amp;gt;&lt;br /&gt;
| Java 8 or newer ([[#Java Requirements for B parser|see below]]), Tcl/Tk 8.5 or 8.6 ([[#Tcl/Tk on Linux|see below]]), [https://www.graphviz.org/download/ GraphViz]&lt;br /&gt;
|-&lt;br /&gt;
| Windows&lt;br /&gt;
| 26.6.2025  &lt;br /&gt;
| [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/1.15.0/ProB.windows64.zip Zipfile] (Tcl/Tk 8.6), &amp;lt;br/&amp;gt; [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/1.15.0/ProB.windows64-tcltk-85.zip Zipfile] (Tcl/Tk 8.5)&lt;br /&gt;
| Tcl/Tk 8.5 or 8.6 ([[#Tcl/Tk on Windows|see below]]), Java 8 or newer ([[#Java Requirements for B parser|see below]]), [https://www.graphviz.org/download/ GraphViz], [[Windows Installation Instructions]]&lt;br /&gt;
|-&lt;br /&gt;
| macOS&lt;br /&gt;
| 26.6.2025  &lt;br /&gt;
| [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/1.15.0/ProB.macos.zip Zipfile] (Universal ARM/Intel notarized)&amp;lt;br/&amp;gt; &lt;br /&gt;
[https://github.com/hhu-stups/homebrew-prob Homebrew Tap]&lt;br /&gt;
| macOS 10.14 (Mojave) or newer, Tcl/Tk 8.6 ([[#Tcl/Tk on macOS|see below]]), Java 8 or newer ([[#Java Requirements for B parser|see below]]), [https://www.graphviz.org/download/ Graphviz] ([[#Graphviz_Requirements|see below]])&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The B parser of ProB requires Java 8 or newer. More details [[#Java Requirements for B parser|are available below]].&lt;br /&gt;
&lt;br /&gt;
The Graphical User Interface of ProB Tcl/Tk requires Tcl/Tk 8.5 or 8.6. More details [[#Tcl/Tk Requirements for ProB Tcl/Tk|are available below]].&lt;br /&gt;
The default Tcl/Tk on macOS is broken and will result in &amp;lt;b&amp;gt;black windows&amp;lt;/b&amp;gt;, and you have to [[#Tcl/Tk Requirements for ProB Tcl/Tk|install another version of Tcl/Tk]]. (Note: Tcl/Tk 9 is not binary compatible and cannot yet be used.)&lt;br /&gt;
All releases include the command-line version &amp;lt;b&amp;gt;probcli&amp;lt;/b&amp;gt; which does &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; require Tcl/Tk.&lt;br /&gt;
&lt;br /&gt;
Releases are compiled for the &#039;&#039;&#039;x86_64&#039;&#039;&#039; architecture (64-bit Intel).&lt;br /&gt;
macOS releases of ProB 1.12.0 and later also support &#039;&#039;&#039;aarch64&#039;&#039;&#039; (64-bit ARM/Apple Silicon).&lt;br /&gt;
The last version built for x86 (32-bit Intel) is ProB 1.8.0 (see [[DownloadPriorVersions|prior versions]]).&lt;br /&gt;
If you are using an unsupported architecture or system, you may still be able to [[Running ProB from source|run ProB from source]].&lt;br /&gt;
&lt;br /&gt;
Note that: on &amp;lt;b&amp;gt;macOS&amp;lt;/b&amp;gt; you  still have to right-click on the application and use &amp;quot;Open&amp;quot;, even though ProB Tcl/Tk (and probcli and all libraries) are signed and notarized. &lt;br /&gt;
 &lt;br /&gt;
=== Latest Beta Release ===&lt;br /&gt;
&lt;br /&gt;
The latest beta release is [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/1.13.1-beta1 1.13.1-beta1].&lt;br /&gt;
It may be older than the latest final release.&lt;br /&gt;
An official beta release always passes all of ProB&#039;s tests.&lt;br /&gt;
However, we do not follow the stringent checklist for final releases&lt;br /&gt;
(e.g., checking SICStus Prolog Spider warnings, checking coverage and additional manual&lt;br /&gt;
UI tests).&lt;br /&gt;
Also, we do not store coverage reports and other information necessary for T2 certification.&lt;br /&gt;
&lt;br /&gt;
=== Nightly Builds ===&lt;br /&gt;
&lt;br /&gt;
More current [https://stups.hhu-hosting.de/downloads/prob/tcltk/nightly/ nightly integration builds] are also available.&lt;br /&gt;
These releases are usually updated every night and old versions are not stored.&lt;br /&gt;
&lt;br /&gt;
Note for macOS users: Nightly builds of ProB are not signed or notarized, so macOS 10.15 and later (Catalina, Big Sur or Monterey, Ventura) will refuse to run them.&lt;br /&gt;
As a workaround, you will need to run &amp;lt;code&amp;gt;xattr -r -d com.apple.quarantine *&amp;lt;/code&amp;gt; inside the ProB directory before launching ProB.&lt;br /&gt;
The stable and beta releases listed above are signed and notarized, so they will run without extra steps.&lt;br /&gt;
&lt;br /&gt;
Automatically generated test [https://stups.hhu-hosting.de/internal/coverage/html/ coverage reports are also available].&lt;br /&gt;
They are usually updated once per week.&lt;br /&gt;
&lt;br /&gt;
=== Sourcecode ===&lt;br /&gt;
&lt;br /&gt;
You can download the latest Prolog sourcecode snapshot from: https://stups.hhu-hosting.de/downloads/prob/source/&lt;br /&gt;
&lt;br /&gt;
The source code for the ProB parsers (B, LTL, ...) can be obtained from: https://github.com/hhu-stups/probparsers&lt;br /&gt;
&lt;br /&gt;
=== Prior Versions ===&lt;br /&gt;
&lt;br /&gt;
Prior Versions of ProB going back to 1.3.1 [[DownloadPriorVersions|are available for download here]]. &lt;br /&gt;
If you are interested in still earlier releases, please have a look at the [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/ Download directory].&lt;br /&gt;
&lt;br /&gt;
== Other ProB tools ==&lt;br /&gt;
&lt;br /&gt;
=== ProB Jupyter Kernel ===&lt;br /&gt;
&lt;br /&gt;
You can now create Jupyter Notebooks in B using the ProB Jupyter kernel.&lt;br /&gt;
Downloads, instructions, and source code can be found on [https://gitlab.cs.uni-duesseldorf.de/general/stups/prob2-jupyter-kernel its own page].&lt;br /&gt;
&lt;br /&gt;
You can [https://mybinder.org/v2/git/https%3A%2F%2Fgitlab.cs.uni-duesseldorf.de%2Fgeneral%2Fstups%2Fprob2-jupyter-kernel.git/master?filepath=notebooks try out the ProB Jupyter kernel in your browser] without installing it first.&lt;br /&gt;
Note that &#039;&#039;&#039;notebooks are not saved permanently in this online version!&#039;&#039;&#039;&lt;br /&gt;
To keep your notebooks, you &#039;&#039;must&#039;&#039; download them before closing the page.&lt;br /&gt;
&lt;br /&gt;
=== ProB for Rodin ===&lt;br /&gt;
To install ProB for Rodin, first download a current version of Rodin (e.g., [https://sourceforge.net/projects/rodin-b-sharp/files/Core_Rodin_Platform/3.9/ Rodin 3.9]). Inside Rodin, choose Help -&amp;gt; Install New Software and choose the pre-configured ProB update site.&lt;br /&gt;
&lt;br /&gt;
More [[Tutorial Rodin First Step|detailed installation instructions and a brief tutorial]] are available.&lt;br /&gt;
&lt;br /&gt;
* Nightly builds of ProB for Rodin 3 can be obtained from within Rodin by using the update site https://stups.hhu-hosting.de/rodin/prob1/nightly.&lt;br /&gt;
&lt;br /&gt;
=== ProB2-UI (based on JavaFX)===&lt;br /&gt;
&lt;br /&gt;
Version 1.3.0 of the new JavaFX-based [[ProB2-UI]] is available.&lt;br /&gt;
See the [https://github.com/hhu-stups/prob2_ui/blob/develop/doc/prob2ui_release_history.md release history] for what&#039;s new.&lt;br /&gt;
You can use these stand-alone versions which come bundled with the right Java runtime environment:&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/1.3.0/ProB%202%20UI-1.3.0.exe Windows (x86_64) installer] - requires Windows 10 or later&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/1.3.0/ProB%202%20UI-aarch64-1.3.0.dmg macOS (Apple Silicon) application DMG] (not signed/notarized yet! [[#macOS issues|see below]]) - requires macOS 11 (Big Sur) or later&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/1.3.0/ProB%202%20UI-x86_64-1.3.0.dmg macOS (Intel) application DMG] (not signed/notarized yet! [[#macOS issues|see below]]) - requires macOS 11 (Big Sur) or later&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/1.3.0/prob2-ui_1.3.0_amd64.deb Debian (x86_64) package]&lt;br /&gt;
&lt;br /&gt;
You can also download a [https://stups.hhu-hosting.de/downloads/prob2/1.3.0/prob2-ui-1.3.0-multi.jar multi-platform jar], which works with Java 21 or later on all supported platforms (except macOS on arm64 - we recommend using the native macOS application instead).&lt;br /&gt;
&lt;br /&gt;
Details about new features and improvements can be found in the [https://github.com/hhu-stups/prob2_ui/blob/develop/doc/prob2ui_release_history.md release history], along with download links for older versions.&lt;br /&gt;
&lt;br /&gt;
Snapshot builds of the current &#039;&#039;development&#039;&#039; version of ProB2-UI (1.3.1-SNAPSHOT) are also available:&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/snapshot/ProB%202%20UI-1.3.1.exe Windows installer snapshot]&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/snapshot/ProB%202%20UI-aarch64-1.3.1.dmg macOS (Apple Silicon) application DMG snapshot] (not signed/notarized! [[#macOS issues|see below]])&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/snapshot/ProB%202%20UI-x86_64-1.3.1.dmg macOS (Intel) application DMG snapshot] (not signed/notarized! [[#macOS issues|see below]])&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/snapshot/prob2-ui_1.3.1_amd64.deb Debian package snapshot]&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/snapshot/prob2-ui-1.3.1-SNAPSHOT-multi.jar Multi-platform jar snapshot]&lt;br /&gt;
&lt;br /&gt;
The source code for ProB2-UI is available at https://github.com/hhu-stups/prob2_ui and can be built by following [https://github.com/hhu-stups/prob2_ui#running-from-source these instructions].&lt;br /&gt;
&lt;br /&gt;
The underlying [[ProB Java API]] of ProB2-UI (aka the ProB 2 kernel) is available to Java developers via [https://central.sonatype.com/artifact/de.hhu.stups/de.prob2.kernel Maven Central].&lt;br /&gt;
Its source code can be obtained from: https://github.com/hhu-stups/prob2_kernel.&lt;br /&gt;
&lt;br /&gt;
==== macOS issues ====&lt;br /&gt;
&lt;br /&gt;
When you run the macOS app for the first time, you might have to open the app &#039;&#039;twice&#039;&#039; for ProB 2 UI to start properly.&lt;br /&gt;
This should only happen once.&lt;br /&gt;
&lt;br /&gt;
The ProB 2 UI macOS app releases are signed and notarized, so they should run without issues.&lt;br /&gt;
However, the multi-platform jar and snapshot app builds are &#039;&#039;not&#039;&#039; signed or notarized, so macOS will refuse to run them or say that the application is damaged.&lt;br /&gt;
As a workaround, right-click the app, select &amp;quot;Open&amp;quot;, and confirm the security dialog.&lt;br /&gt;
If the dialog still doesn&#039;t give you an option to open the app, click &amp;quot;Cancel&amp;quot; and do the same thing again.&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
As a workaround, run this command in the folder where &#039;&#039;ProB 2 UI.app&#039;&#039; is located:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
xattr -r -d com.apple.quarantine &amp;quot;ProB 2 UI.app&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The multi-platform jar can also be started from the command line, which bypasses the signing/notarization check:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
java -jar prob2-ui-1.3.0-multi.jar&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Editor Support ===&lt;br /&gt;
&lt;br /&gt;
* There is a [https://github.com/hhu-stups/b-language-extension B/ProB Language Support] extension for the Visual Studio Code (VS Code) editor. It integrates with [[Using the Command-Line Version of ProB|command line tool probcli]] to obtain error markers for syntax and type errors. It can also be used for [[Well-Definedness Checking#VSCode|well-definedness checking]].&lt;br /&gt;
** [https://stups.hhu-hosting.de/downloads/vscode_plugin Download for manual installation]&lt;br /&gt;
&lt;br /&gt;
* A [https://github.com/bivab/prob.vim VIM plugin for ProB is available]. It shows a quick fix list of parse and type errors for classical B machines (.mch) using the [[Using_the_Command-Line_Version_of_ProB|command line tool probcli]]. VIM has builtin syntax highlighting support for [https://github.com/vim/vim/blob/master/runtime/syntax/b.vim B].&lt;br /&gt;
&lt;br /&gt;
* Some [https://github.com/leuschel/bbedit-prob BBedit Language modules for B, TLA+, CSP and Prolog] are available; these do not use [[Using_the_Command-Line_Version_of_ProB|command line tool probcli]].&lt;br /&gt;
&lt;br /&gt;
== Java Requirements for B Parser ==&lt;br /&gt;
The B parser of ProB requires Java 8 or newer. Java 11, 17, etc. are also fully supported.&lt;br /&gt;
ProB 1.9.3 is the last version to support Java 7. ProB 1.5.0 is the last version to support Java 6.&lt;br /&gt;
&lt;br /&gt;
You can install a Java Runtime Environment (JRE) from various sources, such as [https://adoptium.net/ Eclipse Adoptium], [https://www.azul.com/downloads/?version=java-8-lts&amp;amp;package=jre-fx Azul Zulu], or your system package manager.&lt;br /&gt;
&lt;br /&gt;
Note: on some systems (macOS) you may have to install the full Java Development Kit (JDK), and not just the JRE, so that Java 8 becomes available to the command-line tools.&lt;br /&gt;
Type &amp;lt;code&amp;gt;java -version&amp;lt;/code&amp;gt; to check which version is used by default for command-line tools; see also [http://stackoverflow.com/questions/21964709/how-to-set-or-change-the-default-java-jdk-version-on-os-x this discussion on StackOverflow].&lt;br /&gt;
In case you have trouble starting the Java parser you can now set the &amp;lt;code&amp;gt;JAVA_PATH&amp;lt;/code&amp;gt; preference of ProB to point to the &amp;lt;code&amp;gt;java&amp;lt;/code&amp;gt; tool (or java.exe on Windows).&lt;br /&gt;
&lt;br /&gt;
To check whether ProB can correctly use its Java parser you can type the following (using probcli.exe on Windows):&lt;br /&gt;
 probcli -version -v&lt;br /&gt;
This will try and start the parser and obtain the parser version.&lt;br /&gt;
In case Java is not correctly installed you should get an error message.&lt;br /&gt;
If you see the error message&lt;br /&gt;
 &amp;lt;tt&amp;gt;Unsupported major.minor version 52.0&amp;lt;/tt&amp;gt;&lt;br /&gt;
this means you do not have Java 8 or newer installed. You can try setting the path to the correct java version by setting the JAVA_PATH preference as follows:&lt;br /&gt;
 probcli -p JAVA_PATH path/to/java -version -v&lt;br /&gt;
&lt;br /&gt;
== Tcl/Tk Requirements for ProB Tcl/Tk ==&lt;br /&gt;
&lt;br /&gt;
ProB Tcl/Tk requires an installation of Tcl/Tk 8.5 or Tcl/Tk 8.6. The command-line tool probcli does &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; require this.&lt;br /&gt;
&lt;br /&gt;
=== Tcl/Tk on macOS ===&lt;br /&gt;
Important note: macOS comes pre-installed with a version of Tcl/Tk which is broken.&lt;br /&gt;
This may result in the display of unreadable &amp;lt;b&amp;gt;black windows&amp;lt;/b&amp;gt; or crashes in the standard file dialogs.&lt;br /&gt;
There are various options to install Tcl/Tk:&lt;br /&gt;
* with Homebrew using the [https://formulae.brew.sh/formula/tcl-tk tcl-tk formula]&lt;br /&gt;
* with [https://ports.macports.org/port/tcl/ MacPorts]&lt;br /&gt;
* use the  [http://www.activestate.com/activetcl/downloads/ ActiveTcl version of Tcl/Tk]&lt;br /&gt;
You should probably start ProB using the &amp;lt;tt&amp;gt;StartProB.sh&amp;lt;/tt&amp;gt; script: it will auto-detect Tcl/Tk versions and set the SP_TCL_DSO environment variable.&lt;br /&gt;
Below are more details:&lt;br /&gt;
&lt;br /&gt;
==== Tcl/Tk from Homebrew or MacPorts ====&lt;br /&gt;
&lt;br /&gt;
You can install a newer Tcl/Tk (e.g., 8.6.13) using [https://brew.sh &amp;lt;b&amp;gt;Homebrew&amp;lt;/b&amp;gt;] or [https://www.macports.org &amp;lt;b&amp;gt;MacPorts&amp;lt;/b&amp;gt;].&lt;br /&gt;
Note: In the earlier release 8.6.11 [https://bugs.python.org/issue44828 file open and file save dialogs will not work].&lt;br /&gt;
For Homebrew the command to install the[https://formulae.brew.sh/formula/tcl-tk tcl-tk formula] is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 brew install tcl-tk&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The latest versions of Homebrew now install Tcl/Tk 9.0 which does not work yet with ProB.&lt;br /&gt;
In this case install&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 brew install tcl-tk@8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, as the location of the libraries is not standard, you have to define the variable &amp;lt;tt&amp;gt;SP_TCL_DSO&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The &amp;lt;tt&amp;gt;StartProB.sh&amp;lt;/tt&amp;gt; script should set SP_TCL_DSO automatically.&lt;br /&gt;
You can also define and export this variable yourself before starting ProB from the Terminal by typing this (you may have to adapt the link if you are using another version of Tcl/Tk):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
export SP_TCL_DSO=/opt/homebrew/Cellar/tcl-tk@8/8.6.16/lib/libtcl8.6.dylib&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you have uses MacPorts the path is probably &amp;lt;tt&amp;gt;/opt/local/lib/libtcl.dylib&amp;lt;/tt&amp;gt;.&lt;br /&gt;
You can also set the variable by adding &amp;lt;tt&amp;gt;-DSP_TCL_DSO=/usr/local/Cellar/tcl-tk/8.6.12/lib/libtcl8.6.dylib&amp;lt;/tt&amp;gt; to the command starting ProB. You may also have to install &amp;lt;tt&amp;gt;tk-table&amp;lt;/tt&amp;gt; package yourself (it is bundled with Active Tcl).&lt;br /&gt;
&lt;br /&gt;
==== Active Tcl ====&lt;br /&gt;
&lt;br /&gt;
The [http://www.activestate.com/activetcl/downloads/ the ActiveTcl version of Tcl/Tk] is automatically recognised by ProB and you do not have to set &amp;lt;tt&amp;gt;SP_TCL_DSO&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
However, in Active Tcl/Tk 8.6 on macOS the double click in the &amp;quot;Operations View&amp;quot; or other views  is not working correctly.&lt;br /&gt;
You have to hit the RETURN key in the &amp;quot;Operations View&amp;quot; or right-click on an operation and select &amp;quot;Perform ...&amp;quot;  to execute an operation until this is fixed.&lt;br /&gt;
The older ersion [http://bugs.python.org/issue15853 8.5.12 has a bug related to copying text], see also [http://sourceforge.net/tracker/?func=detail&amp;amp;aid=3555211&amp;amp;group_id=12997&amp;amp;atid=112997_type here]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Other Notes ====&lt;br /&gt;
Note: on macOS Catalina or later the Tcl/Tk menu bar is sometimes not working. Switching to another application and then back to ProB seems to solve the problem.&lt;br /&gt;
If you see the message &amp;quot;&amp;lt;tt&amp;gt;macOS 11 or later required !&amp;lt;/tt&amp;gt;&amp;quot;  in the terminal when launching &amp;lt;tt&amp;gt;prob&amp;lt;/tt&amp;gt; you should re-install Tcl/Tk as described above.&lt;br /&gt;
&lt;br /&gt;
=== Tcl/Tk on Windows ===&lt;br /&gt;
We currently provide two downloads of ProB, one for Tcl/Tk 8.6 (which we recommend)&lt;br /&gt;
and a version for Tcl/Tk 8.5.&lt;br /&gt;
You can use for example the  [https://www.activestate.com/products/tcl/ ActiveTcl releases].&lt;br /&gt;
Note: For the 64 bit version of ProB for Windows, you have to install the 64 bit Tcl/Tk 8.5 version!&lt;br /&gt;
ProB 1.12 (currently available as nightly build) works with both Tcl/Tk 8.5 and 8.6.&lt;br /&gt;
You may have to point the environment variable SP_TCL_DSO to the correct DLL before starting ProB. For Tcl/Tk 8.5 this is typically&lt;br /&gt;
base-tcl8.5-thread-win32-x86_64.dll.&lt;br /&gt;
You can either go to System -&amp;gt; Settings -&amp;gt; Advanced -&amp;gt; Environment Variables&lt;br /&gt;
or use the setx command for this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
setx SP_TCL_DSO C:\Tcl\bin\base-tcl8.5-thread-win32-x86_64.dll&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tcl/Tk on Linux ===&lt;br /&gt;
On Linux you can typically install Tcl/Tk using &amp;lt;tt&amp;gt;sudo apt-get install tcl8.5 tk8.5&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
On very recent Linux systems (such as Ubuntu 20.04) you may want to download (and compile) [https://www.tcl.tk/software/tcltk/downloadnow85.html Tcl/Tk 8.5] or use [https://ubuntu.pkgs.org/18.04/ubuntu-universe-amd64/tcl8.5_8.5.19-4_amd64.deb.html packages from earlier releases].&lt;br /&gt;
&lt;br /&gt;
On Linux OpenSuse (12.3) you may have to perform the following for ProB to work:&lt;br /&gt;
 ln -s /usr/lib/libtk8.5.so /usr/lib/libtk8.5.so.0&lt;br /&gt;
 ln -s /usr/lib/libtcl8.5.so /usr/lib/libtcl8.5.so.0&lt;br /&gt;
&lt;br /&gt;
Also, some of the feature require the table extension, which can be installed like this:&lt;br /&gt;
 sudo apt install tk-table&lt;br /&gt;
Finally, support for .png ANIMATION_IMG declarations requires the Img package:&lt;br /&gt;
 sudo apt install libtk-img&lt;br /&gt;
&lt;br /&gt;
== Graphviz Requirements ==&lt;br /&gt;
&lt;br /&gt;
If you wish to view various visualizations generated by ProB Tcl/Tk or probcli you will need [http://www.graphviz.org/ GraphViz].&lt;br /&gt;
ProB generates various graphs (state space, custom graph, machine hierarchy,...) as .dot files and then  uses the command-line tool &amp;lt;tt&amp;gt;dot&amp;lt;/tt&amp;gt; to layout the graph and convert it to PDF.&lt;br /&gt;
&lt;br /&gt;
ProB Tcl/Tk can also use dot-file viewer such as the &amp;lt;tt&amp;gt;dotty&amp;lt;/tt&amp;gt; program from GraphViz in Linux.&lt;br /&gt;
On macOS and Windows  it is more difficult to obtain a good viewer application for dot files. VS Code with the [https://marketplace.visualstudio.com/items?itemName=tintinweb.graphviz-interactive-preview Graphviz Interactive Preview] extension is a candidate.&lt;br /&gt;
The commercial OmniGraffle macOS application can import .dot files.  A free alternative on macOS may be [https://ports.macports.org/port/graphviz-gui/ graphviz-gui] by [https://www.macports.org MacPorts]. To install the application do this&lt;br /&gt;
* &amp;lt;tt&amp;gt;sudo port install graphviz-gui&amp;lt;/tt&amp;gt;&lt;br /&gt;
The viewer can now be found in /Applications/MacPorts/Graphviz.app (you may have to set the ProB graphical viewer preference &amp;lt;tt&amp;gt;dot_viewer&amp;lt;/tt&amp;gt; to this path).&lt;br /&gt;
If you do not manage to install a viewer, you should select Preferences -&amp;gt; Graphical Viewer -&amp;gt; PDF within ProB Tcl/Tk.&lt;br /&gt;
Indeed, many ProB commands work directly with the command-line tool &amp;lt;tt&amp;gt;dot&amp;lt;/tt&amp;gt; which you can install on macOS with MacPorts like this:&lt;br /&gt;
* &amp;lt;tt&amp;gt;sudo port install graphviz&amp;lt;/tt&amp;gt;&lt;br /&gt;
On Mac you can now install the latest version of Graphviz using [https://brew.sh HomeBrew]:&lt;br /&gt;
&lt;br /&gt;
 1. &amp;lt;tt&amp;gt;brew uninstall graphviz&amp;lt;/tt&amp;gt;&lt;br /&gt;
 2. &amp;lt;tt&amp;gt;brew install graphviz --with-gts&amp;lt;/tt&amp;gt;&lt;br /&gt;
 3. &amp;lt;tt&amp;gt;brew link --overwrite graphviz&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Step 1. is optional; you only need to use it if you have a prior version of Graphviz installed.&lt;br /&gt;
Step3 links the binaries to /usr/local/bin.&lt;br /&gt;
This is probably better than using the [http://www.pixelglow.com/graphviz/ older version from Pixelglow].&lt;br /&gt;
&lt;br /&gt;
You can also manually set the DOT (path_to_dot) preference if ProB cannot find the Graphviz dot binary you have installed.&lt;br /&gt;
&lt;br /&gt;
== Short Release History ==&lt;br /&gt;
&lt;br /&gt;
The full  [[ProB_Release_History | ProB release history can be found here]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2024-02-20&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.13.0]] is available. Better Rodin theory support. Template strings. Unicode improvements. READ_JSON and other new external functions. VisB support for groups and &amp;quot;use&amp;quot; element. [[Monte_Carlo_Tree_Search_Game_Play|MCTS game play]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2024-02-03&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.12.2-fix1]] is available.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2023-08-10&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.12.2]] is available. [[VisB#VisB_DEFINITIONS_2 |VisB]] improvements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2023-04-04&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.12.0]] is available. Call stack infos, performance improvements in parser and solver,  new [[LTL_Model_Checking#Supported_Syntax |LTL]] operators, [[VisB#VisB_Additional_SVG_Objects|VisB]] improvements, reals/floats for [[Event-B_Theories|Rodin theories]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2021-12-29&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.11.1]] is available. Highlights: identifiers between backquotes, flexible JSON trace replay, DPLLT solving command, improvements to Z3 backend.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2021-10-06&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.11.0]] is available. Highlights: improved support for infinite sets, operation caching (OPERATION_REUSE), faster LTL checking for safety formulas, more compact .prob files, VisB HTML export, constructive Z3 translation.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2020-12-15&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.10.0]] is available. Highlights: well-definedness prover, REAL datatype, -lint comand for VSCode and Atom, improved unsat core and error messages.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2020-02-19&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.9.3]] is available. Highlights: performance improvements, new external functions, performance monitoring.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2019-11-11&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.9.2]] is available. Minor bugfix release.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2019-11-08&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.9.1]] is available. Maintenance release.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2019-07-12&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.9.0]] is available. Highlights: improved error feedback, improved Unicode support, regular expression library, memoization.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2018-10-01&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.8.2]] is available. Highlights: improved error feedback, support [https://gitlab.cs.uni-duesseldorf.de/general/stups/prob2-jupyter-kernel Jupyter kernel], first [[Alloy|support for Alloy models]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2018-03-20&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.8.0]] is available. Highlights: terminal colour support, performance improvements for displaying very large values, improved symmetry breaking and constraint solving.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2017-10-05&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.7.1]] is available. Highlights: performance, non-deterministic assigned variables shown, Z improvements, export history to HTML.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2017-07-11&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.7.0]] is available. Highlights: improved [[Generating_Documents_with_ProB_and_Latex |Latex document generation]], improved XML/CSV data import and export, RULE DSL language, many improvements in constraint solver.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2016-10-20&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.6.1]] is available. Highlights: [[Generating_Documents_with_ProB_and_Latex |Latex document generation]], LET and IF-THEN-ELSE for expressions and predicates, XML logging, XML data import, performance improvements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2016-04-22&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.6.0]] is available. Highlights: [[Tutorial_Directed_Model_Checking|directed model checking]], [[Using_ProB_with_Z3|Z3 available as backend]], B line comments and unicode symbols, improved error messages, performance improvements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2015-02-19&#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, [[State_Space_Coverage_Analyses|MC/DC coverage]] analysis for guards and invariants, [[TLC|improved TLC interface]], bug fixes and improvements including but not limited to the constraint solver.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2014-08-29&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.4.1]], a small bugfix-only release is available. For a list of new features in 1.4.0 see below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2014-08-18&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.4.0]] is available. Highlights: CLP(FD)-based constraint solver enabled by default, kernel can handle more operations symbolically, [[TLC|integration of the TLC model checker]], bug fixes and performance improvements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2013-03-04&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.3.6]] is available. Highlights: improved constraint propagation for division, modulo, intervals, model checking progress bar, performance improvements, [[Using_ProB_with_KODKOD | improved Kodkod backend]] and use within REPL, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2012-10-08&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.3.5]] is available. Highlights: support for external and recursive functions, optional Kodkod backend, [[TLA|TLA+ support]], performance improvements, pragmas, units inference, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2012-03-30&#039;&#039;&#039;&lt;br /&gt;
A first prototype of an online [[ProB_Logic_Calculator|ProB Logic Calculator]] is available.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2011-11-21&#039;&#039;&#039;&lt;br /&gt;
ProB 1.3.4 is available. Highlights: Evaluation View and Eval window, CSP assertion checking, improved editor, 64-bit version for Mac and Linux, performance improvements, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2011-02-10&#039;&#039;&#039;&lt;br /&gt;
ProB 1.3.3 and ProB for Rodin 2.3 is available. Highlights: improved performance, constrained-based deadlock checking, record detection, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2010-07-30&#039;&#039;&#039;&lt;br /&gt;
ProB 1.3.2 is available. Highlights: improved performance, constraint solving over integers (enable in Advanced Preferences), much improved Z support, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2009-12-07&#039;&#039;&#039;&lt;br /&gt;
ProB 1.3.1 is available. Highlights: new data-structure for large sets and relations (see FM 2009), multi-level validation for Event-B, improved constraint propagation for boolean connectives, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2009-03-20&#039;&#039;&#039;&lt;br /&gt;
ProB 1.3.0 is available for download. Highlights: New parser and integrated typechecker, install as AtelierB plugin, improved kernel with support for large sets/relations, improved CSP support, faster LTL model checker, Undo/Redo in text editor, graphical formula viewer, user definable custom animations with gifs.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Download&amp;diff=6025</id>
		<title>Download</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Download&amp;diff=6025"/>
		<updated>2025-10-13T11:34:48Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* Editor Support */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Latest Release ==&lt;br /&gt;
&lt;br /&gt;
Below are links for downloading the latest stable release of probcli (the command line version of ProB) and ProB Tcl/Tk (ProB with a graphical user interface written in Tcl/Tk).&lt;br /&gt;
Note: please use the provided start scripts (StartProB.sh or StartProBWin.bat) to start ProB.&lt;br /&gt;
The list of changes can be found in the [[ProB_Release_History | ProB release history]].&lt;br /&gt;
&lt;br /&gt;
Details of the [[ProBLicence| ProB Licence can be found here]].&lt;br /&gt;
ProB is free to use and open source. For commercial support contact  [https://www.stups.uni-duesseldorf.de/~leuschel/ Michael Leuschel]. In particular, we can provide access to the validation report for using ProB as a tool of class T2 or T3 within the European norm [https://de.wikipedia.org/wiki/EN_50128 EN50128].&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;table table-bordered wikitable&amp;quot; &amp;lt;!-- table and table-bordered for Bootstrap (ProB skin), wikitable for MediaWiki (Vector, MonoBook, etc. skins) --&amp;gt;&lt;br /&gt;
! Platform&lt;br /&gt;
! Release Date&lt;br /&gt;
! Download&lt;br /&gt;
! Dependencies&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; style=&amp;quot;background-color:lightgrey;&amp;quot; | 1.15.0&lt;br /&gt;
|-&lt;br /&gt;
| Linux &lt;br /&gt;
| 26.6.2025 &lt;br /&gt;
| [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/1.15.0/ProB.linux64.tar.gz Tarball]&amp;lt;br/&amp;gt;&lt;br /&gt;
| Java 8 or newer ([[#Java Requirements for B parser|see below]]), Tcl/Tk 8.5 or 8.6 ([[#Tcl/Tk on Linux|see below]]), [https://www.graphviz.org/download/ GraphViz]&lt;br /&gt;
|-&lt;br /&gt;
| Windows&lt;br /&gt;
| 26.6.2025  &lt;br /&gt;
| [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/1.15.0/ProB.windows64.zip Zipfile] (Tcl/Tk 8.6), &amp;lt;br/&amp;gt; [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/1.15.0/ProB.windows64-tcltk-85.zip Zipfile] (Tcl/Tk 8.5)&lt;br /&gt;
| Tcl/Tk 8.5 or 8.6 ([[#Tcl/Tk on Windows|see below]]), Java 8 or newer ([[#Java Requirements for B parser|see below]]), [https://www.graphviz.org/download/ GraphViz], [[Windows Installation Instructions]]&lt;br /&gt;
|-&lt;br /&gt;
| macOS&lt;br /&gt;
| 26.6.2025  &lt;br /&gt;
| [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/1.15.0/ProB.macos.zip Zipfile] (Universal ARM/Intel notarized)&amp;lt;br/&amp;gt; &lt;br /&gt;
[https://github.com/hhu-stups/homebrew-prob Homebrew Tap]&lt;br /&gt;
| macOS 10.14 (Mojave) or newer, Tcl/Tk 8.6 ([[#Tcl/Tk on macOS|see below]]), Java 8 or newer ([[#Java Requirements for B parser|see below]]), [https://www.graphviz.org/download/ Graphviz] ([[#Graphviz_Requirements|see below]])&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The B parser of ProB requires Java 8 or newer. More details [[#Java Requirements for B parser|are available below]].&lt;br /&gt;
&lt;br /&gt;
The Graphical User Interface of ProB Tcl/Tk requires Tcl/Tk 8.5 or 8.6. More details [[#Tcl/Tk Requirements for ProB Tcl/Tk|are available below]].&lt;br /&gt;
The default Tcl/Tk on macOS is broken and will result in &amp;lt;b&amp;gt;black windows&amp;lt;/b&amp;gt;, and you have to [[#Tcl/Tk Requirements for ProB Tcl/Tk|install another version of Tcl/Tk]]. (Note: Tcl/Tk 9 is not binary compatible and cannot yet be used.)&lt;br /&gt;
All releases include the command-line version &amp;lt;b&amp;gt;probcli&amp;lt;/b&amp;gt; which does &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; require Tcl/Tk.&lt;br /&gt;
&lt;br /&gt;
Releases are compiled for the &#039;&#039;&#039;x86_64&#039;&#039;&#039; architecture (64-bit Intel).&lt;br /&gt;
macOS releases of ProB 1.12.0 and later also support &#039;&#039;&#039;aarch64&#039;&#039;&#039; (64-bit ARM/Apple Silicon).&lt;br /&gt;
The last version built for x86 (32-bit Intel) is ProB 1.8.0 (see [[DownloadPriorVersions|prior versions]]).&lt;br /&gt;
If you are using an unsupported architecture or system, you may still be able to [[Running ProB from source|run ProB from source]].&lt;br /&gt;
&lt;br /&gt;
Note that: on &amp;lt;b&amp;gt;macOS&amp;lt;/b&amp;gt; you  still have to right-click on the application and use &amp;quot;Open&amp;quot;, even though ProB Tcl/Tk (and probcli and all libraries) are signed and notarized. &lt;br /&gt;
 &lt;br /&gt;
=== Latest Beta Release ===&lt;br /&gt;
&lt;br /&gt;
The latest beta release is [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/1.13.1-beta1 1.13.1-beta1].&lt;br /&gt;
It may be older than the latest final release.&lt;br /&gt;
An official beta release always passes all of ProB&#039;s tests.&lt;br /&gt;
However, we do not follow the stringent checklist for final releases&lt;br /&gt;
(e.g., checking SICStus Prolog Spider warnings, checking coverage and additional manual&lt;br /&gt;
UI tests).&lt;br /&gt;
Also, we do not store coverage reports and other information necessary for T2 certification.&lt;br /&gt;
&lt;br /&gt;
=== Nightly Builds ===&lt;br /&gt;
&lt;br /&gt;
More current [https://stups.hhu-hosting.de/downloads/prob/tcltk/nightly/ nightly integration builds] are also available.&lt;br /&gt;
These releases are usually updated every night and old versions are not stored.&lt;br /&gt;
&lt;br /&gt;
Note for macOS users: Nightly builds of ProB are not signed or notarized, so macOS 10.15 and later (Catalina, Big Sur or Monterey, Ventura) will refuse to run them.&lt;br /&gt;
As a workaround, you will need to run &amp;lt;code&amp;gt;xattr -r -d com.apple.quarantine *&amp;lt;/code&amp;gt; inside the ProB directory before launching ProB.&lt;br /&gt;
The stable and beta releases listed above are signed and notarized, so they will run without extra steps.&lt;br /&gt;
&lt;br /&gt;
Automatically generated test [https://stups.hhu-hosting.de/internal/coverage/html/ coverage reports are also available].&lt;br /&gt;
They are usually updated once per week.&lt;br /&gt;
&lt;br /&gt;
=== Sourcecode ===&lt;br /&gt;
&lt;br /&gt;
You can download the latest Prolog sourcecode snapshot from: https://stups.hhu-hosting.de/downloads/prob/source/&lt;br /&gt;
&lt;br /&gt;
The source code for the ProB parsers (B, LTL, ...) can be obtained from: https://github.com/hhu-stups/probparsers&lt;br /&gt;
&lt;br /&gt;
=== Prior Versions ===&lt;br /&gt;
&lt;br /&gt;
Prior Versions of ProB going back to 1.3.1 [[DownloadPriorVersions|are available for download here]]. &lt;br /&gt;
If you are interested in still earlier releases, please have a look at the [https://stups.hhu-hosting.de/downloads/prob/tcltk/releases/ Download directory].&lt;br /&gt;
&lt;br /&gt;
== Other ProB tools ==&lt;br /&gt;
&lt;br /&gt;
=== ProB Jupyter Kernel ===&lt;br /&gt;
&lt;br /&gt;
You can now create Jupyter Notebooks in B using the ProB Jupyter kernel.&lt;br /&gt;
Downloads, instructions, and source code can be found on [https://gitlab.cs.uni-duesseldorf.de/general/stups/prob2-jupyter-kernel its own page].&lt;br /&gt;
&lt;br /&gt;
You can [https://mybinder.org/v2/git/https%3A%2F%2Fgitlab.cs.uni-duesseldorf.de%2Fgeneral%2Fstups%2Fprob2-jupyter-kernel.git/master?filepath=notebooks try out the ProB Jupyter kernel in your browser] without installing it first.&lt;br /&gt;
Note that &#039;&#039;&#039;notebooks are not saved permanently in this online version!&#039;&#039;&#039;&lt;br /&gt;
To keep your notebooks, you &#039;&#039;must&#039;&#039; download them before closing the page.&lt;br /&gt;
&lt;br /&gt;
=== ProB for Rodin ===&lt;br /&gt;
To install ProB for Rodin, first download a current version of Rodin (e.g., [https://sourceforge.net/projects/rodin-b-sharp/files/Core_Rodin_Platform/3.9/ Rodin 3.9]). Inside Rodin, choose Help -&amp;gt; Install New Software and choose the pre-configured ProB update site.&lt;br /&gt;
&lt;br /&gt;
More [[Tutorial Rodin First Step|detailed installation instructions and a brief tutorial]] are available.&lt;br /&gt;
&lt;br /&gt;
* Nightly builds of ProB for Rodin 3 can be obtained from within Rodin by using the update site https://stups.hhu-hosting.de/rodin/prob1/nightly.&lt;br /&gt;
&lt;br /&gt;
=== ProB2-UI (based on JavaFX)===&lt;br /&gt;
&lt;br /&gt;
Version 1.3.0 of the new JavaFX-based [[ProB2-UI]] is available.&lt;br /&gt;
See the [https://github.com/hhu-stups/prob2_ui/blob/develop/doc/prob2ui_release_history.md release history] for what&#039;s new.&lt;br /&gt;
You can use these stand-alone versions which come bundled with the right Java runtime environment:&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/1.3.0/ProB%202%20UI-1.3.0.exe Windows (x86_64) installer] - requires Windows 10 or later&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/1.3.0/ProB%202%20UI-aarch64-1.3.0.dmg macOS (Apple Silicon) application DMG] (not signed/notarized yet! [[#macOS issues|see below]]) - requires macOS 11 (Big Sur) or later&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/1.3.0/ProB%202%20UI-x86_64-1.3.0.dmg macOS (Intel) application DMG] (not signed/notarized yet! [[#macOS issues|see below]]) - requires macOS 11 (Big Sur) or later&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/1.3.0/prob2-ui_1.3.0_amd64.deb Debian (x86_64) package]&lt;br /&gt;
&lt;br /&gt;
You can also download a [https://stups.hhu-hosting.de/downloads/prob2/1.3.0/prob2-ui-1.3.0-multi.jar multi-platform jar], which works with Java 21 or later on all supported platforms (except macOS on arm64 - we recommend using the native macOS application instead).&lt;br /&gt;
&lt;br /&gt;
Details about new features and improvements can be found in the [https://github.com/hhu-stups/prob2_ui/blob/develop/doc/prob2ui_release_history.md release history], along with download links for older versions.&lt;br /&gt;
&lt;br /&gt;
Snapshot builds of the current &#039;&#039;development&#039;&#039; version of ProB2-UI (1.3.1-SNAPSHOT) are also available:&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/snapshot/ProB%202%20UI-1.3.1.exe Windows installer snapshot]&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/snapshot/ProB%202%20UI-aarch64-1.3.1.dmg macOS (Apple Silicon) application DMG snapshot] (not signed/notarized! [[#macOS issues|see below]])&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/snapshot/ProB%202%20UI-x86_64-1.3.1.dmg macOS (Intel) application DMG snapshot] (not signed/notarized! [[#macOS issues|see below]])&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/snapshot/prob2-ui_1.3.1_amd64.deb Debian package snapshot]&lt;br /&gt;
* [https://stups.hhu-hosting.de/downloads/prob2/snapshot/prob2-ui-1.3.1-SNAPSHOT-multi.jar Multi-platform jar snapshot]&lt;br /&gt;
&lt;br /&gt;
The source code for ProB2-UI is available at https://github.com/hhu-stups/prob2_ui and can be built by following [https://github.com/hhu-stups/prob2_ui#running-from-source these instructions].&lt;br /&gt;
&lt;br /&gt;
The underlying [[ProB Java API]] of ProB2-UI (aka the ProB 2 kernel) is available to Java developers via [https://central.sonatype.com/artifact/de.hhu.stups/de.prob2.kernel Maven Central].&lt;br /&gt;
Its source code can be obtained from: https://github.com/hhu-stups/prob2_kernel.&lt;br /&gt;
&lt;br /&gt;
==== macOS issues ====&lt;br /&gt;
&lt;br /&gt;
When you run the macOS app for the first time, you might have to open the app &#039;&#039;twice&#039;&#039; for ProB 2 UI to start properly.&lt;br /&gt;
This should only happen once.&lt;br /&gt;
&lt;br /&gt;
The ProB 2 UI macOS app releases are signed and notarized, so they should run without issues.&lt;br /&gt;
However, the multi-platform jar and snapshot app builds are &#039;&#039;not&#039;&#039; signed or notarized, so macOS will refuse to run them or say that the application is damaged.&lt;br /&gt;
As a workaround, right-click the app, select &amp;quot;Open&amp;quot;, and confirm the security dialog.&lt;br /&gt;
If the dialog still doesn&#039;t give you an option to open the app, click &amp;quot;Cancel&amp;quot; and do the same thing again.&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
As a workaround, run this command in the folder where &#039;&#039;ProB 2 UI.app&#039;&#039; is located:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
xattr -r -d com.apple.quarantine &amp;quot;ProB 2 UI.app&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The multi-platform jar can also be started from the command line, which bypasses the signing/notarization check:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
java -jar prob2-ui-1.3.0-multi.jar&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Editor Support ===&lt;br /&gt;
&lt;br /&gt;
* There is a [https://github.com/hhu-stups/b-language-extension B/ProB Language Support] extension for the VSCode editor. It integrates with [[Using the Command-Line Version of ProB|command line tool probcli]] to obtain error markers for syntax and type errors. It can also be used for [[Well-Definedness Checking#VSCode|well-definedness checking]].&lt;br /&gt;
** [https://stups.hhu-hosting.de/downloads/vscode_plugin Download for manual installation]&lt;br /&gt;
&lt;br /&gt;
* A [https://github.com/bivab/prob.vim VIM plugin for ProB is available]. It shows a quick fix list of parse and type errors for classical B machines (.mch) using the [[Using_the_Command-Line_Version_of_ProB|command line tool probcli]]. VIM has builtin syntax highlighting support for [https://github.com/vim/vim/blob/master/runtime/syntax/b.vim B].&lt;br /&gt;
&lt;br /&gt;
* Some [https://github.com/leuschel/bbedit-prob BBedit Language modules for B, TLA+, CSP and Prolog] are available; these do not use [[Using_the_Command-Line_Version_of_ProB|command line tool probcli]].&lt;br /&gt;
&lt;br /&gt;
== Java Requirements for B Parser ==&lt;br /&gt;
The B parser of ProB requires Java 8 or newer. Java 11, 17, etc. are also fully supported.&lt;br /&gt;
ProB 1.9.3 is the last version to support Java 7. ProB 1.5.0 is the last version to support Java 6.&lt;br /&gt;
&lt;br /&gt;
You can install a Java Runtime Environment (JRE) from various sources, such as [https://adoptium.net/ Eclipse Adoptium], [https://www.azul.com/downloads/?version=java-8-lts&amp;amp;package=jre-fx Azul Zulu], or your system package manager.&lt;br /&gt;
&lt;br /&gt;
Note: on some systems (macOS) you may have to install the full Java Development Kit (JDK), and not just the JRE, so that Java 8 becomes available to the command-line tools.&lt;br /&gt;
Type &amp;lt;code&amp;gt;java -version&amp;lt;/code&amp;gt; to check which version is used by default for command-line tools; see also [http://stackoverflow.com/questions/21964709/how-to-set-or-change-the-default-java-jdk-version-on-os-x this discussion on StackOverflow].&lt;br /&gt;
In case you have trouble starting the Java parser you can now set the &amp;lt;code&amp;gt;JAVA_PATH&amp;lt;/code&amp;gt; preference of ProB to point to the &amp;lt;code&amp;gt;java&amp;lt;/code&amp;gt; tool (or java.exe on Windows).&lt;br /&gt;
&lt;br /&gt;
To check whether ProB can correctly use its Java parser you can type the following (using probcli.exe on Windows):&lt;br /&gt;
 probcli -version -v&lt;br /&gt;
This will try and start the parser and obtain the parser version.&lt;br /&gt;
In case Java is not correctly installed you should get an error message.&lt;br /&gt;
If you see the error message&lt;br /&gt;
 &amp;lt;tt&amp;gt;Unsupported major.minor version 52.0&amp;lt;/tt&amp;gt;&lt;br /&gt;
this means you do not have Java 8 or newer installed. You can try setting the path to the correct java version by setting the JAVA_PATH preference as follows:&lt;br /&gt;
 probcli -p JAVA_PATH path/to/java -version -v&lt;br /&gt;
&lt;br /&gt;
== Tcl/Tk Requirements for ProB Tcl/Tk ==&lt;br /&gt;
&lt;br /&gt;
ProB Tcl/Tk requires an installation of Tcl/Tk 8.5 or Tcl/Tk 8.6. The command-line tool probcli does &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; require this.&lt;br /&gt;
&lt;br /&gt;
=== Tcl/Tk on macOS ===&lt;br /&gt;
Important note: macOS comes pre-installed with a version of Tcl/Tk which is broken.&lt;br /&gt;
This may result in the display of unreadable &amp;lt;b&amp;gt;black windows&amp;lt;/b&amp;gt; or crashes in the standard file dialogs.&lt;br /&gt;
There are various options to install Tcl/Tk:&lt;br /&gt;
* with Homebrew using the [https://formulae.brew.sh/formula/tcl-tk tcl-tk formula]&lt;br /&gt;
* with [https://ports.macports.org/port/tcl/ MacPorts]&lt;br /&gt;
* use the  [http://www.activestate.com/activetcl/downloads/ ActiveTcl version of Tcl/Tk]&lt;br /&gt;
You should probably start ProB using the &amp;lt;tt&amp;gt;StartProB.sh&amp;lt;/tt&amp;gt; script: it will auto-detect Tcl/Tk versions and set the SP_TCL_DSO environment variable.&lt;br /&gt;
Below are more details:&lt;br /&gt;
&lt;br /&gt;
==== Tcl/Tk from Homebrew or MacPorts ====&lt;br /&gt;
&lt;br /&gt;
You can install a newer Tcl/Tk (e.g., 8.6.13) using [https://brew.sh &amp;lt;b&amp;gt;Homebrew&amp;lt;/b&amp;gt;] or [https://www.macports.org &amp;lt;b&amp;gt;MacPorts&amp;lt;/b&amp;gt;].&lt;br /&gt;
Note: In the earlier release 8.6.11 [https://bugs.python.org/issue44828 file open and file save dialogs will not work].&lt;br /&gt;
For Homebrew the command to install the[https://formulae.brew.sh/formula/tcl-tk tcl-tk formula] is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 brew install tcl-tk&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The latest versions of Homebrew now install Tcl/Tk 9.0 which does not work yet with ProB.&lt;br /&gt;
In this case install&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 brew install tcl-tk@8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, as the location of the libraries is not standard, you have to define the variable &amp;lt;tt&amp;gt;SP_TCL_DSO&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The &amp;lt;tt&amp;gt;StartProB.sh&amp;lt;/tt&amp;gt; script should set SP_TCL_DSO automatically.&lt;br /&gt;
You can also define and export this variable yourself before starting ProB from the Terminal by typing this (you may have to adapt the link if you are using another version of Tcl/Tk):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
export SP_TCL_DSO=/opt/homebrew/Cellar/tcl-tk@8/8.6.16/lib/libtcl8.6.dylib&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you have uses MacPorts the path is probably &amp;lt;tt&amp;gt;/opt/local/lib/libtcl.dylib&amp;lt;/tt&amp;gt;.&lt;br /&gt;
You can also set the variable by adding &amp;lt;tt&amp;gt;-DSP_TCL_DSO=/usr/local/Cellar/tcl-tk/8.6.12/lib/libtcl8.6.dylib&amp;lt;/tt&amp;gt; to the command starting ProB. You may also have to install &amp;lt;tt&amp;gt;tk-table&amp;lt;/tt&amp;gt; package yourself (it is bundled with Active Tcl).&lt;br /&gt;
&lt;br /&gt;
==== Active Tcl ====&lt;br /&gt;
&lt;br /&gt;
The [http://www.activestate.com/activetcl/downloads/ the ActiveTcl version of Tcl/Tk] is automatically recognised by ProB and you do not have to set &amp;lt;tt&amp;gt;SP_TCL_DSO&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
However, in Active Tcl/Tk 8.6 on macOS the double click in the &amp;quot;Operations View&amp;quot; or other views  is not working correctly.&lt;br /&gt;
You have to hit the RETURN key in the &amp;quot;Operations View&amp;quot; or right-click on an operation and select &amp;quot;Perform ...&amp;quot;  to execute an operation until this is fixed.&lt;br /&gt;
The older ersion [http://bugs.python.org/issue15853 8.5.12 has a bug related to copying text], see also [http://sourceforge.net/tracker/?func=detail&amp;amp;aid=3555211&amp;amp;group_id=12997&amp;amp;atid=112997_type here]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Other Notes ====&lt;br /&gt;
Note: on macOS Catalina or later the Tcl/Tk menu bar is sometimes not working. Switching to another application and then back to ProB seems to solve the problem.&lt;br /&gt;
If you see the message &amp;quot;&amp;lt;tt&amp;gt;macOS 11 or later required !&amp;lt;/tt&amp;gt;&amp;quot;  in the terminal when launching &amp;lt;tt&amp;gt;prob&amp;lt;/tt&amp;gt; you should re-install Tcl/Tk as described above.&lt;br /&gt;
&lt;br /&gt;
=== Tcl/Tk on Windows ===&lt;br /&gt;
We currently provide two downloads of ProB, one for Tcl/Tk 8.6 (which we recommend)&lt;br /&gt;
and a version for Tcl/Tk 8.5.&lt;br /&gt;
You can use for example the  [https://www.activestate.com/products/tcl/ ActiveTcl releases].&lt;br /&gt;
Note: For the 64 bit version of ProB for Windows, you have to install the 64 bit Tcl/Tk 8.5 version!&lt;br /&gt;
ProB 1.12 (currently available as nightly build) works with both Tcl/Tk 8.5 and 8.6.&lt;br /&gt;
You may have to point the environment variable SP_TCL_DSO to the correct DLL before starting ProB. For Tcl/Tk 8.5 this is typically&lt;br /&gt;
base-tcl8.5-thread-win32-x86_64.dll.&lt;br /&gt;
You can either go to System -&amp;gt; Settings -&amp;gt; Advanced -&amp;gt; Environment Variables&lt;br /&gt;
or use the setx command for this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
setx SP_TCL_DSO C:\Tcl\bin\base-tcl8.5-thread-win32-x86_64.dll&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tcl/Tk on Linux ===&lt;br /&gt;
On Linux you can typically install Tcl/Tk using &amp;lt;tt&amp;gt;sudo apt-get install tcl8.5 tk8.5&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
On very recent Linux systems (such as Ubuntu 20.04) you may want to download (and compile) [https://www.tcl.tk/software/tcltk/downloadnow85.html Tcl/Tk 8.5] or use [https://ubuntu.pkgs.org/18.04/ubuntu-universe-amd64/tcl8.5_8.5.19-4_amd64.deb.html packages from earlier releases].&lt;br /&gt;
&lt;br /&gt;
On Linux OpenSuse (12.3) you may have to perform the following for ProB to work:&lt;br /&gt;
 ln -s /usr/lib/libtk8.5.so /usr/lib/libtk8.5.so.0&lt;br /&gt;
 ln -s /usr/lib/libtcl8.5.so /usr/lib/libtcl8.5.so.0&lt;br /&gt;
&lt;br /&gt;
Also, some of the feature require the table extension, which can be installed like this:&lt;br /&gt;
 sudo apt install tk-table&lt;br /&gt;
Finally, support for .png ANIMATION_IMG declarations requires the Img package:&lt;br /&gt;
 sudo apt install libtk-img&lt;br /&gt;
&lt;br /&gt;
== Graphviz Requirements ==&lt;br /&gt;
&lt;br /&gt;
If you wish to view various visualizations generated by ProB Tcl/Tk or probcli you will need [http://www.graphviz.org/ GraphViz].&lt;br /&gt;
ProB generates various graphs (state space, custom graph, machine hierarchy,...) as .dot files and then  uses the command-line tool &amp;lt;tt&amp;gt;dot&amp;lt;/tt&amp;gt; to layout the graph and convert it to PDF.&lt;br /&gt;
&lt;br /&gt;
ProB Tcl/Tk can also use dot-file viewer such as the &amp;lt;tt&amp;gt;dotty&amp;lt;/tt&amp;gt; program from GraphViz in Linux.&lt;br /&gt;
On macOS and Windows  it is more difficult to obtain a good viewer application for dot files. VS Code with the [https://marketplace.visualstudio.com/items?itemName=tintinweb.graphviz-interactive-preview Graphviz Interactive Preview] extension is a candidate.&lt;br /&gt;
The commercial OmniGraffle macOS application can import .dot files.  A free alternative on macOS may be [https://ports.macports.org/port/graphviz-gui/ graphviz-gui] by [https://www.macports.org MacPorts]. To install the application do this&lt;br /&gt;
* &amp;lt;tt&amp;gt;sudo port install graphviz-gui&amp;lt;/tt&amp;gt;&lt;br /&gt;
The viewer can now be found in /Applications/MacPorts/Graphviz.app (you may have to set the ProB graphical viewer preference &amp;lt;tt&amp;gt;dot_viewer&amp;lt;/tt&amp;gt; to this path).&lt;br /&gt;
If you do not manage to install a viewer, you should select Preferences -&amp;gt; Graphical Viewer -&amp;gt; PDF within ProB Tcl/Tk.&lt;br /&gt;
Indeed, many ProB commands work directly with the command-line tool &amp;lt;tt&amp;gt;dot&amp;lt;/tt&amp;gt; which you can install on macOS with MacPorts like this:&lt;br /&gt;
* &amp;lt;tt&amp;gt;sudo port install graphviz&amp;lt;/tt&amp;gt;&lt;br /&gt;
On Mac you can now install the latest version of Graphviz using [https://brew.sh HomeBrew]:&lt;br /&gt;
&lt;br /&gt;
 1. &amp;lt;tt&amp;gt;brew uninstall graphviz&amp;lt;/tt&amp;gt;&lt;br /&gt;
 2. &amp;lt;tt&amp;gt;brew install graphviz --with-gts&amp;lt;/tt&amp;gt;&lt;br /&gt;
 3. &amp;lt;tt&amp;gt;brew link --overwrite graphviz&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Step 1. is optional; you only need to use it if you have a prior version of Graphviz installed.&lt;br /&gt;
Step3 links the binaries to /usr/local/bin.&lt;br /&gt;
This is probably better than using the [http://www.pixelglow.com/graphviz/ older version from Pixelglow].&lt;br /&gt;
&lt;br /&gt;
You can also manually set the DOT (path_to_dot) preference if ProB cannot find the Graphviz dot binary you have installed.&lt;br /&gt;
&lt;br /&gt;
== Short Release History ==&lt;br /&gt;
&lt;br /&gt;
The full  [[ProB_Release_History | ProB release history can be found here]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2024-02-20&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.13.0]] is available. Better Rodin theory support. Template strings. Unicode improvements. READ_JSON and other new external functions. VisB support for groups and &amp;quot;use&amp;quot; element. [[Monte_Carlo_Tree_Search_Game_Play|MCTS game play]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2024-02-03&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.12.2-fix1]] is available.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2023-08-10&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.12.2]] is available. [[VisB#VisB_DEFINITIONS_2 |VisB]] improvements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2023-04-04&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.12.0]] is available. Call stack infos, performance improvements in parser and solver,  new [[LTL_Model_Checking#Supported_Syntax |LTL]] operators, [[VisB#VisB_Additional_SVG_Objects|VisB]] improvements, reals/floats for [[Event-B_Theories|Rodin theories]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2021-12-29&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.11.1]] is available. Highlights: identifiers between backquotes, flexible JSON trace replay, DPLLT solving command, improvements to Z3 backend.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2021-10-06&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.11.0]] is available. Highlights: improved support for infinite sets, operation caching (OPERATION_REUSE), faster LTL checking for safety formulas, more compact .prob files, VisB HTML export, constructive Z3 translation.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2020-12-15&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.10.0]] is available. Highlights: well-definedness prover, REAL datatype, -lint comand for VSCode and Atom, improved unsat core and error messages.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2020-02-19&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.9.3]] is available. Highlights: performance improvements, new external functions, performance monitoring.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2019-11-11&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.9.2]] is available. Minor bugfix release.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2019-11-08&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.9.1]] is available. Maintenance release.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2019-07-12&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.9.0]] is available. Highlights: improved error feedback, improved Unicode support, regular expression library, memoization.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2018-10-01&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.8.2]] is available. Highlights: improved error feedback, support [https://gitlab.cs.uni-duesseldorf.de/general/stups/prob2-jupyter-kernel Jupyter kernel], first [[Alloy|support for Alloy models]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2018-03-20&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.8.0]] is available. Highlights: terminal colour support, performance improvements for displaying very large values, improved symmetry breaking and constraint solving.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2017-10-05&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.7.1]] is available. Highlights: performance, non-deterministic assigned variables shown, Z improvements, export history to HTML.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2017-07-11&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.7.0]] is available. Highlights: improved [[Generating_Documents_with_ProB_and_Latex |Latex document generation]], improved XML/CSV data import and export, RULE DSL language, many improvements in constraint solver.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2016-10-20&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.6.1]] is available. Highlights: [[Generating_Documents_with_ProB_and_Latex |Latex document generation]], LET and IF-THEN-ELSE for expressions and predicates, XML logging, XML data import, performance improvements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2016-04-22&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.6.0]] is available. Highlights: [[Tutorial_Directed_Model_Checking|directed model checking]], [[Using_ProB_with_Z3|Z3 available as backend]], B line comments and unicode symbols, improved error messages, performance improvements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2015-02-19&#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, [[State_Space_Coverage_Analyses|MC/DC coverage]] analysis for guards and invariants, [[TLC|improved TLC interface]], bug fixes and improvements including but not limited to the constraint solver.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2014-08-29&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.4.1]], a small bugfix-only release is available. For a list of new features in 1.4.0 see below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2014-08-18&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.4.0]] is available. Highlights: CLP(FD)-based constraint solver enabled by default, kernel can handle more operations symbolically, [[TLC|integration of the TLC model checker]], bug fixes and performance improvements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2013-03-04&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.3.6]] is available. Highlights: improved constraint propagation for division, modulo, intervals, model checking progress bar, performance improvements, [[Using_ProB_with_KODKOD | improved Kodkod backend]] and use within REPL, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2012-10-08&#039;&#039;&#039;&lt;br /&gt;
[[Download|ProB 1.3.5]] is available. Highlights: support for external and recursive functions, optional Kodkod backend, [[TLA|TLA+ support]], performance improvements, pragmas, units inference, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2012-03-30&#039;&#039;&#039;&lt;br /&gt;
A first prototype of an online [[ProB_Logic_Calculator|ProB Logic Calculator]] is available.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2011-11-21&#039;&#039;&#039;&lt;br /&gt;
ProB 1.3.4 is available. Highlights: Evaluation View and Eval window, CSP assertion checking, improved editor, 64-bit version for Mac and Linux, performance improvements, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2011-02-10&#039;&#039;&#039;&lt;br /&gt;
ProB 1.3.3 and ProB for Rodin 2.3 is available. Highlights: improved performance, constrained-based deadlock checking, record detection, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2010-07-30&#039;&#039;&#039;&lt;br /&gt;
ProB 1.3.2 is available. Highlights: improved performance, constraint solving over integers (enable in Advanced Preferences), much improved Z support, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2009-12-07&#039;&#039;&#039;&lt;br /&gt;
ProB 1.3.1 is available. Highlights: new data-structure for large sets and relations (see FM 2009), multi-level validation for Event-B, improved constraint propagation for boolean connectives, and many more.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2009-03-20&#039;&#039;&#039;&lt;br /&gt;
ProB 1.3.0 is available for download. Highlights: New parser and integrated typechecker, install as AtelierB plugin, improved kernel with support for large sets/relations, improved CSP support, faster LTL model checker, Undo/Redo in text editor, graphical formula viewer, user definable custom animations with gifs.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Editors_for_ProB&amp;diff=6024</id>
		<title>Editors for ProB</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Editors_for_ProB&amp;diff=6024"/>
		<updated>2025-10-13T11:31:37Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* Visual Studio Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== ProB Tcl/Tk Editor ==&lt;br /&gt;
&lt;br /&gt;
ProB Tcl/Tk contains an editor in which syntax errors are displayed and which can be used to edit B, CSP, Z and TLA+ models.&lt;br /&gt;
The editor of Tcl/Tk, however, has a few limitations:&lt;br /&gt;
* it can become very slow with long or very long lines&lt;br /&gt;
* the syntax highlighting can become slow with very large files. Hence, syntax highlighting is automatically turned off in some circumstances (when more than 50,000 characters are encountered or when a line is longer than 500 characters).&lt;br /&gt;
&lt;br /&gt;
It is possible to open the files in an external editor. You can setup the editor to be used by modifying the preference &amp;quot;Path to External Text Editor&amp;quot; in the &amp;quot;Advanced Preferences&amp;quot; list (available in the &amp;quot;Preferences&amp;quot; menu).&lt;br /&gt;
You can then use the command &amp;quot;Open FILE in external editor&amp;quot; in the &amp;quot;File&amp;quot; menu to open your main specification file with this editor. You can also use the command-key shortcut &amp;quot;Cmd-E&amp;quot; for this.&lt;br /&gt;
&lt;br /&gt;
== Launching the editor in probcli ==&lt;br /&gt;
&lt;br /&gt;
The [[Using_the_Command-Line_Version_of_ProB|probcli]] REPL (read-eval-print-loop) supports the command &amp;lt;tt&amp;gt;:e&amp;lt;/tt&amp;gt; to open the current file in the external editor, as specified in the &amp;quot;EDITOR&amp;quot; preference.&lt;br /&gt;
You can set this preference using&lt;br /&gt;
 probcli -repl -p EDITOR PATH&lt;br /&gt;
In case errors occurred with the last command, this will also try and move the cursor to the corresponding location in the file.&lt;br /&gt;
&lt;br /&gt;
== External Editors ==&lt;br /&gt;
&lt;br /&gt;
=== Visual Studio Code ===&lt;br /&gt;
There is a package called [https://github.com/hhu-stups/b-language-extension B/ProB Language Support] available for the Visual Studio Code (VS Code) editor.&lt;br /&gt;
A &amp;lt;tt&amp;gt;.vsix&amp;lt;/tt&amp;gt; file can be obtained [https://stups.hhu-hosting.de/downloads/vscode_plugin here] (for manual installation).&lt;br /&gt;
The plugin adds syntax highlighting and snippets for the specification languages B and Event-B to VS Code. &lt;br /&gt;
It integrates with probcli to obtain error markers for syntax and type errors. It can also be used for [[Well-Definedness_Checking#VSCode|well-definedness checking]]. There is also support for ProB&#039;s [[Rules-DSL|Rules-DSL]].&lt;br /&gt;
&lt;br /&gt;
=== VIM ===&lt;br /&gt;
&lt;br /&gt;
A [https://github.com/bivab/prob.vim VIM plugin for ProB is available].&lt;br /&gt;
It shows a quick fix list of parse and type errors for classical B machines (.mch) using the [[Using_the_Command-Line_Version_of_ProB|command line tool probcli]]. VIM has builtin syntax highlighting support for [https://github.com/vim/vim/blob/master/runtime/syntax/b.vim B].&lt;br /&gt;
&lt;br /&gt;
=== Atom ===&lt;br /&gt;
&lt;br /&gt;
There is a package [https://atom.io/packages/language-b-eventb language-b-eventb] available for the Atom editor.&lt;br /&gt;
It adds syntax highlighting and snippets for the specification languages B and Event-B to Atom.&lt;br /&gt;
It integrates with probcli to obtain error markers for syntax and type errors.&lt;br /&gt;
&lt;br /&gt;
With the Atom plugin you can now also visualize WD (well-definedness) issues in your B machines. See [https://youtu.be/td7CKFkAvaw this small demo video].&lt;br /&gt;
&lt;br /&gt;
Note that Atom is no longer being updated as of [https://github.blog/2022-06-08-sunsetting-atom/ December 2022].&lt;br /&gt;
&lt;br /&gt;
=== BBEdit ===&lt;br /&gt;
&lt;br /&gt;
Some [https://github.com/leuschel/bbedit-prob BBedit Language modules for B, TLA+, CSP and Prolog] are available.&lt;br /&gt;
&lt;br /&gt;
=== Emacs ===&lt;br /&gt;
&lt;br /&gt;
A package [[File:b-mode.el.zip]] is available.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Editors_for_ProB&amp;diff=6023</id>
		<title>Editors for ProB</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Editors_for_ProB&amp;diff=6023"/>
		<updated>2025-10-13T11:31:07Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* External Editors */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== ProB Tcl/Tk Editor ==&lt;br /&gt;
&lt;br /&gt;
ProB Tcl/Tk contains an editor in which syntax errors are displayed and which can be used to edit B, CSP, Z and TLA+ models.&lt;br /&gt;
The editor of Tcl/Tk, however, has a few limitations:&lt;br /&gt;
* it can become very slow with long or very long lines&lt;br /&gt;
* the syntax highlighting can become slow with very large files. Hence, syntax highlighting is automatically turned off in some circumstances (when more than 50,000 characters are encountered or when a line is longer than 500 characters).&lt;br /&gt;
&lt;br /&gt;
It is possible to open the files in an external editor. You can setup the editor to be used by modifying the preference &amp;quot;Path to External Text Editor&amp;quot; in the &amp;quot;Advanced Preferences&amp;quot; list (available in the &amp;quot;Preferences&amp;quot; menu).&lt;br /&gt;
You can then use the command &amp;quot;Open FILE in external editor&amp;quot; in the &amp;quot;File&amp;quot; menu to open your main specification file with this editor. You can also use the command-key shortcut &amp;quot;Cmd-E&amp;quot; for this.&lt;br /&gt;
&lt;br /&gt;
== Launching the editor in probcli ==&lt;br /&gt;
&lt;br /&gt;
The [[Using_the_Command-Line_Version_of_ProB|probcli]] REPL (read-eval-print-loop) supports the command &amp;lt;tt&amp;gt;:e&amp;lt;/tt&amp;gt; to open the current file in the external editor, as specified in the &amp;quot;EDITOR&amp;quot; preference.&lt;br /&gt;
You can set this preference using&lt;br /&gt;
 probcli -repl -p EDITOR PATH&lt;br /&gt;
In case errors occurred with the last command, this will also try and move the cursor to the corresponding location in the file.&lt;br /&gt;
&lt;br /&gt;
== External Editors ==&lt;br /&gt;
&lt;br /&gt;
=== Visual Studio Code ===&lt;br /&gt;
There is a package called [https://github.com/hhu-stups/b-language-extension B/ProB Language Support] available for the Visual Studio Code (VS Code) editor.&lt;br /&gt;
A &amp;lt;tt&amp;gt;.vsix&amp;lt;/tt&amp;gt; file can be obtained [https://stups.hhu-hosting.de/downloads/vscode_plugin here] (for manual installation).&lt;br /&gt;
The plugin adds syntax highlighting and snippets for the specification languages B and Event-B to VS Code. &lt;br /&gt;
It integrates with probcli to obtain error markers for syntax and type errors. It can also be used for [[Well-Definedness_Checking#VSCode|well-definedness checking]]. There is also support for ProB&#039;s [[Rules-DSL|B Rules-DSL]].&lt;br /&gt;
&lt;br /&gt;
=== VIM ===&lt;br /&gt;
&lt;br /&gt;
A [https://github.com/bivab/prob.vim VIM plugin for ProB is available].&lt;br /&gt;
It shows a quick fix list of parse and type errors for classical B machines (.mch) using the [[Using_the_Command-Line_Version_of_ProB|command line tool probcli]]. VIM has builtin syntax highlighting support for [https://github.com/vim/vim/blob/master/runtime/syntax/b.vim B].&lt;br /&gt;
&lt;br /&gt;
=== Atom ===&lt;br /&gt;
&lt;br /&gt;
There is a package [https://atom.io/packages/language-b-eventb language-b-eventb] available for the Atom editor.&lt;br /&gt;
It adds syntax highlighting and snippets for the specification languages B and Event-B to Atom.&lt;br /&gt;
It integrates with probcli to obtain error markers for syntax and type errors.&lt;br /&gt;
&lt;br /&gt;
With the Atom plugin you can now also visualize WD (well-definedness) issues in your B machines. See [https://youtu.be/td7CKFkAvaw this small demo video].&lt;br /&gt;
&lt;br /&gt;
Note that Atom is no longer being updated as of [https://github.blog/2022-06-08-sunsetting-atom/ December 2022].&lt;br /&gt;
&lt;br /&gt;
=== BBEdit ===&lt;br /&gt;
&lt;br /&gt;
Some [https://github.com/leuschel/bbedit-prob BBedit Language modules for B, TLA+, CSP and Prolog] are available.&lt;br /&gt;
&lt;br /&gt;
=== Emacs ===&lt;br /&gt;
&lt;br /&gt;
A package [[File:b-mode.el.zip]] is available.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Editors_for_ProB&amp;diff=6022</id>
		<title>Editors for ProB</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Editors_for_ProB&amp;diff=6022"/>
		<updated>2025-10-13T11:29:51Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* VSCode */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== ProB Tcl/Tk Editor ==&lt;br /&gt;
&lt;br /&gt;
ProB Tcl/Tk contains an editor in which syntax errors are displayed and which can be used to edit B, CSP, Z and TLA+ models.&lt;br /&gt;
The editor of Tcl/Tk, however, has a few limitations:&lt;br /&gt;
* it can become very slow with long or very long lines&lt;br /&gt;
* the syntax highlighting can become slow with very large files. Hence, syntax highlighting is automatically turned off in some circumstances (when more than 50,000 characters are encountered or when a line is longer than 500 characters).&lt;br /&gt;
&lt;br /&gt;
It is possible to open the files in an external editor. You can setup the editor to be used by modifying the preference &amp;quot;Path to External Text Editor&amp;quot; in the &amp;quot;Advanced Preferences&amp;quot; list (available in the &amp;quot;Preferences&amp;quot; menu).&lt;br /&gt;
You can then use the command &amp;quot;Open FILE in external editor&amp;quot; in the &amp;quot;File&amp;quot; menu to open your main specification file with this editor. You can also use the command-key shortcut &amp;quot;Cmd-E&amp;quot; for this.&lt;br /&gt;
&lt;br /&gt;
== Launching the editor in probcli ==&lt;br /&gt;
&lt;br /&gt;
The [[Using_the_Command-Line_Version_of_ProB|probcli]] REPL (read-eval-print-loop) supports the command &amp;lt;tt&amp;gt;:e&amp;lt;/tt&amp;gt; to open the current file in the external editor, as specified in the &amp;quot;EDITOR&amp;quot; preference.&lt;br /&gt;
You can set this preference using&lt;br /&gt;
 probcli -repl -p EDITOR PATH&lt;br /&gt;
In case errors occurred with the last command, this will also try and move the cursor to the corresponding location in the file.&lt;br /&gt;
&lt;br /&gt;
== External Editors ==&lt;br /&gt;
&lt;br /&gt;
=== VIM ===&lt;br /&gt;
&lt;br /&gt;
A [https://github.com/bivab/prob.vim VIM plugin for ProB is available].&lt;br /&gt;
It shows a quick fix list of parse and type errors for classical B machines (.mch) using the [[Using_the_Command-Line_Version_of_ProB|command line tool probcli]]. VIM has builtin syntax highlighting support for [https://github.com/vim/vim/blob/master/runtime/syntax/b.vim B].&lt;br /&gt;
&lt;br /&gt;
=== Visual Studio Code ===&lt;br /&gt;
There is a package called [https://github.com/hhu-stups/b-language-extension B/ProB Language Support] available for the Visual Studio Code (VS Code) editor.&lt;br /&gt;
A &amp;lt;tt&amp;gt;.vsix&amp;lt;/tt&amp;gt; file can be obtained [https://stups.hhu-hosting.de/downloads/vscode_plugin here] (for manual installation).&lt;br /&gt;
The plugin adds syntax highlighting and snippets for the specification languages B and Event-B to VS Code. &lt;br /&gt;
It integrates with probcli to obtain error markers for syntax and type errors. It can also be used for [[Well-Definedness_Checking#VSCode|well-definedness checking]]. There is also support for ProB&#039;s [[Rules-DSL|B Rules-DSL]].&lt;br /&gt;
&lt;br /&gt;
=== Atom ===&lt;br /&gt;
&lt;br /&gt;
There is a package [https://atom.io/packages/language-b-eventb language-b-eventb] available for the Atom editor.&lt;br /&gt;
It adds syntax highlighting and snippets for the specification languages B and Event-B to Atom.&lt;br /&gt;
It integrates with probcli to obtain error markers for syntax and type errors.&lt;br /&gt;
&lt;br /&gt;
With the Atom plugin you can now also visualize WD (well-definedness) issues in your B machines. See [https://youtu.be/td7CKFkAvaw this small demo video].&lt;br /&gt;
&lt;br /&gt;
Note that Atom is no longer being updated as of [https://github.blog/2022-06-08-sunsetting-atom/ December 2022].&lt;br /&gt;
&lt;br /&gt;
=== BBEdit ===&lt;br /&gt;
&lt;br /&gt;
Some [https://github.com/leuschel/bbedit-prob BBedit Language modules for B, TLA+, CSP and Prolog] are available.&lt;br /&gt;
&lt;br /&gt;
=== Emacs ===&lt;br /&gt;
&lt;br /&gt;
A package [[File:b-mode.el.zip]] is available.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Using_ProB_with_Atelier_B&amp;diff=6021</id>
		<title>Using ProB with Atelier B</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Using_ProB_with_Atelier_B&amp;diff=6021"/>
		<updated>2025-10-12T15:44:28Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* Atelier B Plugin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Atelier B Plugin ==&lt;br /&gt;
&lt;br /&gt;
ProB Tcl/Tk can be installed as a plugin for Atelier B, so that ProB can be launched directly from within [http://www.atelierb.eu/ Atelier B] projects.&lt;br /&gt;
With this you can animate and model check B machines directly from within the IDE of Atelier-B.&lt;br /&gt;
&lt;br /&gt;
The easiest is to perform the menu command &amp;quot;Install AtelierB 4 Plugin...&amp;quot; in the Help menu of ProB Tcl/Tk. This will create a file called &amp;lt;tt&amp;gt;probtclk.etool&amp;lt;/tt&amp;gt; in  an extensions folder next to Atelier B&#039;s bbin folder. The extensions folder is created if necessary.&lt;br /&gt;
&lt;br /&gt;
Note: as the layout of Atelier-B&#039;s directories has changed, you need to use ProB 1.12.0 or newer for Atelier-B 4.7.1 or newer on macOS.&lt;br /&gt;
You can also create the above file yourself.&lt;br /&gt;
&lt;br /&gt;
Here is a typical &amp;lt;tt&amp;gt;probtclk.etool&amp;lt;/tt&amp;gt; file (where PathToProB depends on your location of the ProB installation folder containing the prob and probcli binaries):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;externalTool category=&amp;quot;component&amp;quot;   name=&amp;quot;ProBTclTk&amp;quot; label=&amp;quot;&amp;amp;amp;Animate with ProB (Tcl/Tk)&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;toolParameter name=&amp;quot;editor&amp;quot; type=&amp;quot;tool&amp;quot; configure=&amp;quot;yes&amp;quot;&lt;br /&gt;
   default=&amp;quot;PathToProB/StartProB.sh&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;command&amp;gt;${editor}&amp;lt;/command&amp;gt;&lt;br /&gt;
    &amp;lt;param&amp;gt;${componentPath}&amp;lt;/param&amp;gt;&lt;br /&gt;
 &amp;lt;/externalTool&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, you can also [[ProB2-UI]] within Atelier-B by creating a suitable file &amp;lt;tt&amp;gt;prob2ui.etool&amp;lt;/tt&amp;gt; in this extensions folder. Here is a typical file for macOS; the path needs to be adapted for your location and operating system (we plan to provide an installer within ProB2-UI):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;externalTool category=&amp;quot;component&amp;quot;   name=&amp;quot;ProB2UI&amp;quot; label=&amp;quot;&amp;amp;amp;Animate with ProB2-UI&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;toolParameter name=&amp;quot;editor&amp;quot; type=&amp;quot;tool&amp;quot; configure=&amp;quot;yes&amp;quot;&lt;br /&gt;
   default=&amp;quot;/Applications/Development/ProB/ProB 2 UI.app/Contents/MacOS/ProB 2 UI&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;command&amp;gt;${editor}&amp;lt;/command&amp;gt;&lt;br /&gt;
    &amp;lt;param&amp;gt;--machine-file&amp;lt;/param&amp;gt;&lt;br /&gt;
    &amp;lt;param&amp;gt;${componentPath}&amp;lt;/param&amp;gt;&lt;br /&gt;
&amp;lt;/externalTool&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After installing the plugins you can launch ProB for selected B machines by right-clicking on a B machine within Atelier B:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:ProB_AtelierB_StartProB_Menu.png|300px|center]]&lt;br /&gt;
&lt;br /&gt;
== ProB as Atelier B Prover==&lt;br /&gt;
Atelier B also enables to use ProB as a prover/disprover in the interactive proof window.&lt;br /&gt;
For this you need to set the ProB_Path resource to point to probcli (command-line version of ProB). To do this you need to add the following line to the resource file of your project (replacing PATH by the the path on your machine to probcli):&lt;br /&gt;
 ATB*PR*ProB_Path:PATH/probcli&lt;br /&gt;
&lt;br /&gt;
[[File:ProB_AtelierB_Resource.png|600px|center]]&lt;br /&gt;
&lt;br /&gt;
Then you can type, e.g., the command &amp;lt;tt&amp;gt;prob(1)&amp;lt;/tt&amp;gt;in the interactive proof window.&lt;br /&gt;
&lt;br /&gt;
[[File:ProB_AtelierB_Proof.png|600px|center]]&lt;br /&gt;
&lt;br /&gt;
Two commands are provided within Atelier-B:&lt;br /&gt;
* &amp;lt;tt&amp;gt;prob(n)&amp;lt;/tt&amp;gt; tries to prove the goal with the selected hypotheses (selected using rp.n as is done for th e pp command of Atelier-B)&lt;br /&gt;
* &amp;lt;tt&amp;gt;prob(n|t)&amp;lt;/tt&amp;gt; is similar but also limits the execution time of ProB to t seconds&lt;br /&gt;
&lt;br /&gt;
Atelier-B will call probcli using the commands &amp;lt;tt&amp;gt;-cbc_assertions_tautology_proof&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;-cbc_result_file&amp;lt;/tt&amp;gt; after having encoded the proof obligation into the ASSERTIONS clause of a generated B machine.&lt;br /&gt;
&lt;br /&gt;
The generated machine typically has the form:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE probNr&lt;br /&gt;
SETS ...&lt;br /&gt;
CONSTANTS ...&lt;br /&gt;
PROPERTIES&lt;br /&gt;
  &amp;lt;&amp;lt; ALL HYPOTHESES &amp;gt;&amp;gt;&lt;br /&gt;
ASSERTIONS&lt;br /&gt;
  ( &amp;lt;&amp;lt;SELECTED HYPOTHESES &amp;gt;&amp;gt;&lt;br /&gt;
   =&amp;gt;&lt;br /&gt;
  &amp;lt;&amp;lt; PROOF GOAL &amp;gt;&amp;gt;&lt;br /&gt;
  )&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Using the Atelier B Provers inside ProB ==&lt;br /&gt;
&lt;br /&gt;
In the REPL of probcli you can [[Proving_Theorems_in_the_ProB_REPL#Calling_Atelier-B_Provers | call the provers ML and PP of Atelier-B]].&lt;br /&gt;
&lt;br /&gt;
== Differences with Atelier B ==&lt;br /&gt;
&lt;br /&gt;
As of version 1.3, ProB contains a much improved parser which tries be compliant with&lt;br /&gt;
Atelier B but provides extra features.&lt;br /&gt;
&lt;br /&gt;
=== Extra Features of ProB ===&lt;br /&gt;
&lt;br /&gt;
* Identifiers: ProB also allows identifiers consisting of a single letter. ProB also accepts enumerated set elements to be used as identifiers. Arbitrary identifiers can be used in backquotes (e..g, &amp;lt;tt&amp;gt;`id-1*`&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
* Lexing: The Atelier-B parser (&amp;lt;tt&amp;gt;bcomp&amp;lt;/tt&amp;gt;) reports a lexical error (&amp;lt;tt&amp;gt;illegal token |-&amp;lt;/tt&amp;gt;) if the vertical bar (|) of a lambda abstraction is followed directly by the minus sign.&lt;br /&gt;
&lt;br /&gt;
* Typing: &lt;br /&gt;
** ProB makes use of a unification-based type inference algorithm. As such, typing information can not only flow from left-to-right inside a formula, but also from right-to-left. For example, it is sufficient to type &amp;lt;tt&amp;gt;xx&amp;lt;:yy &amp;amp; yy&amp;lt;:NAT&amp;lt;/tt&amp;gt; instead of typing both &amp;lt;tt&amp;gt;xx&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;yy&amp;lt;/tt&amp;gt; in ProB.&lt;br /&gt;
** Similar to Rodin, ProB extracts typing information from all predicates. As such, it is sufficient to write &amp;lt;tt&amp;gt;xx/:{1,2}&amp;lt;/tt&amp;gt; to assign a type to &amp;lt;tt&amp;gt;xx&amp;lt;/tt&amp;gt;.&lt;br /&gt;
** the fields of records are normalized (sorted); hence the predicate &amp;lt;tt&amp;gt;rec(a:0,b:1) = rec(b:y,a:x)&amp;lt;/tt&amp;gt; is correctly typed for ProB.&lt;br /&gt;
** As of version 1.12.1 you can apply prj1 and prj2 without providing the type arguments. For example, you can write &amp;lt;tt&amp;gt;prj2(prj1(1|-&amp;gt;2|-&amp;gt;3))&amp;lt;/tt&amp;gt; instead of &amp;lt;tt&amp;gt;prj2(INTEGER,INTEGER)(prj1(INTEGER*INTEGER,INTEGER)(1|-&amp;gt;2|-&amp;gt;3))&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* DEFINITIONS: the definitions and its arguments are checked by ProB. We believe this to be an important feature for a formal method language. However, as such, every DEFINITION must be either a predicate, an expression or a substitution. You &#039;&#039;&#039;cannot&#039;&#039;&#039; use, for example, lists of identifiers as a definition. Also, for the moment, the arguments to DEFINITIONS have to be expressions. Finally, when replacing DEFINITIONS the associativity is not changed. E.g., with &amp;lt;tt&amp;gt;PLUS(x,y) == x+y&amp;lt;/tt&amp;gt;, the expression &amp;lt;tt&amp;gt;PLUS(2,3)*10&amp;lt;/tt&amp;gt; will evaluate to 50 (and not to 32 as with Atelier-B).&lt;br /&gt;
&lt;br /&gt;
* for a LET substitution, Atelier-B does not allow introduced identifiers to be used in the right-hand side of equations; ProB allows &amp;lt;tt&amp;gt;LET x,y BE x=2 &amp;amp; y=x*x IN ... END&amp;lt;/tt&amp;gt; but only if the preference &amp;lt;tt&amp;gt;ALLOW_COMPLEX_LETS&amp;lt;/tt&amp;gt; is set to TRUE.&lt;br /&gt;
&lt;br /&gt;
* ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
&lt;br /&gt;
* ProB now allows the IF-THEN-ELSE for expressions and predicates: &amp;lt;tt&amp;gt;IF x&amp;lt;0 THEN -x ELSE x END&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ProB now allows LET constructs for expressions and predicates&lt;br /&gt;
&lt;br /&gt;
* ProB allows &amp;lt;tt&amp;gt;btrue&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;bfalse&amp;lt;/tt&amp;gt; as predicates.&lt;br /&gt;
&lt;br /&gt;
* ProB allows to use the Event-B relation operators &amp;lt;tt&amp;gt;&amp;lt;&amp;lt;-&amp;gt;&amp;lt;/tt&amp;gt;,  &amp;lt;tt&amp;gt;&amp;lt;-&amp;gt;&amp;gt;&amp;lt;/tt&amp;gt;,  &amp;lt;tt&amp;gt;&amp;lt;&amp;lt;-&amp;gt;&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,  and ProB allows multi-line string literals written using three apostrophes (&amp;lt;tt&amp;gt;&amp;quot;&#039;&#039;&#039;&#039;string&#039;&#039;&#039;&#039;&amp;quot;&amp;lt;/tt&amp;gt;) as well as template strings using three backquotes (e.g., &amp;lt;tt&amp;gt;```1+2=${1+2}```&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
* ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
&lt;br /&gt;
* Some of the sequence operators can be applied to strings (unless you set the preference STRING_AS_SEQUENCE to FALSE): &amp;lt;tt&amp;gt;size&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;rev&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;^&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;conc&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* As of version 1.12.1 you can write Event-B style set comprehensions with an extra expression like {x•x:1..10|x*x}. You have to use the middle dot, the bullet (•) or a Unicode dot for this, though.&lt;br /&gt;
&lt;br /&gt;
* ProB comes with several libraries of [[External_Functions | external functions]] for string manipulations, mathematical functions, Hilbert&#039;s choice operator, etc.&lt;br /&gt;
&lt;br /&gt;
=== Differences ===&lt;br /&gt;
* for ProB the order of fields in a record is not relevant (internally the fields are  sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
&lt;br /&gt;
* [[Well-Definedness_Checking|Well-definedness]]: ProB will try to check if your predicates are well-defined during animation or model checking, but there is currently no guarantee that all well-definedness errors will be detected. To be on the safe side, you should ensure that your formulas are well-defined according to the  left-to-right definition of well-definedness employed in Rodin for Event-B. ProB now has a [[Well-Definedness_Checking|static checker for well-definedness]] which you can use for this. Note, however, that ProB may re-order conjuncts if this improves well-definedness. For example, for &amp;lt;tt&amp;gt;x:0..3 &amp;amp; y=10/x &amp;amp; x /=0&amp;lt;/tt&amp;gt; ProB will not report an error as the conjunct &amp;lt;tt&amp;gt;x/=0&amp;lt;/tt&amp;gt; is processed before the division. Indeed, while this predicate is not well-defined according to Rodin&#039;s left-to-right rule, it is well-defined according to the more liberal commutative definition of well-definedness.&lt;br /&gt;
&lt;br /&gt;
== Reflexive Closure ==&lt;br /&gt;
&lt;br /&gt;
In version 1.8.0 (March 2018) ProB changed the definition of the transitive and reflexive closure operator of B.&lt;br /&gt;
PorB now uses to the mathematical definition: &lt;br /&gt;
&amp;lt;pre&amp;gt; closure(X) = id(TypeOfX) \/ closure1(X)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This means that &amp;lt;tt&amp;gt;closure({1|-&amp;gt;2}) &amp;lt;/tt&amp;gt;is now infinite and contains for example the pair &amp;lt;tt&amp;gt;3|-&amp;gt;3&amp;lt;/tt&amp;gt;. The same holds for &amp;lt;tt&amp;gt; iterate({1|-&amp;gt;2},0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The previous definition was closure(X) = id(ran(X)\/dom(X)) \/ closure1(X) and&lt;br /&gt;
the definition in Atelier-B was closure(X) = id(dom(X)) \/ closure1(X).&lt;br /&gt;
However, both were not compatible with the following law in the B-Book on page 169:&lt;br /&gt;
&amp;lt;pre&amp;gt; r[a] &amp;lt;: a =&amp;gt; closure(r)[a]=a&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Take  r = {1|-&amp;gt;2}, then  r[{3}] &amp;lt;: {3}.&lt;br /&gt;
So, according to the law we have: &amp;lt;tt&amp;gt; closure(r)[{3}] = {3}&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In the next version of Atelier-B in 2025 closure(R) will be defined as &amp;quot;the smallest relation&lt;br /&gt;
that contains R that is transitive and reflexive.&amp;quot;&lt;br /&gt;
This corresponds to ProB&#039;s definition prior to version 1.8.0 closure(X) = id(ran(X)\/dom(X)) \/ closure1(X) and is thus different to the B-Book.&lt;br /&gt;
ProB may provide a preference in the next release to allow the user to choose between the two interpretations.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Limitations ===&lt;br /&gt;
&lt;br /&gt;
* Parsing:  ProB will require parentheses around the comma, the relational composition, and parallel product operators. For example, you cannot write &amp;lt;tt&amp;gt;r2=rel;rel&amp;lt;/tt&amp;gt;. You need to write &amp;lt;tt&amp;gt;r2=(rel;rel)&amp;lt;/tt&amp;gt;. This allows ProB to distinguish the relational composition from the sequential composition (or other uses of the semicolon). You also generally need to put BEGIN and END around the sequential composition operator, e.g., &amp;lt;tt&amp;gt;Op = BEGIN x:=1;y:=2 END&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* Similarly,  tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
&lt;br /&gt;
* Unsupported Operators:&lt;br /&gt;
** Trees and binary trees: some tree operators (mirror, infix) are not supported by ProB. The tree operators may disappear in future version of Atelier B and may also disappear from ProB.&lt;br /&gt;
** &amp;lt;tt&amp;gt;VALUES&amp;lt;/tt&amp;gt;: This clause of the &amp;lt;tt&amp;gt;IMPLEMENTATION&amp;lt;/tt&amp;gt; machines is not yet fully supported;&lt;br /&gt;
&lt;br /&gt;
* There are also some general limitations wrt refinements. See [[Current Limitations#Multiple Machines and Refinements]] for more details.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Template:ProBSourceCode&amp;diff=6020</id>
		<title>Template:ProBSourceCode</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Template:ProBSourceCode&amp;diff=6020"/>
		<updated>2025-10-08T12:20:40Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
The kernel of ProB is written in Prolog and you can download the latest Prolog sourcecode snapshot from: https://stups.hhu-hosting.de/downloads/prob/source/&lt;br /&gt;
&lt;br /&gt;
You may also wish to obtain related Java sources:&lt;br /&gt;
* The source code for the ProB parsers (B, LTL, ...) can be obtained from: [https://github.com/hhu-stups/probparsers https://github.com/hhu-stups/probparsers].&lt;br /&gt;
* The ProB2-Java-API (also known as ProB2) source code can be obtained from: [https://github.com/hhu-stups/prob2_kernel https://github.com/hhu-stups/prob2_kernel].&lt;br /&gt;
* The ProB2-Java-FX UI source code can be obtained from: [https://github.com/hhu-stups/prob2_ui https://github.com/hhu-stups/prob2_ui].&lt;br /&gt;
* The B to Java value translator can also be useful and is a separate project: [https://github.com/hhu-stups/value-translator https://github.com/hhu-stups/value-translator].&lt;br /&gt;
* The Plugin for Rodin is also a separate project: [https://gitlab.cs.uni-duesseldorf.de/general/stups/prob_rodin_plugin https://gitlab.cs.uni-duesseldorf.de/general/stups/prob_rodin_plugin].&lt;br /&gt;
* The Alloy to B translator is here: [https://github.com/hhu-stups/alloy2b https://github.com/hhu-stups/alloy2b].&lt;br /&gt;
* The TLC4B B to TLA+ translator is here: [https://gitlab.cs.uni-duesseldorf.de/general/stups/tlc4b https://gitlab.cs.uni-duesseldorf.de/general/stups/tlc4b].&lt;br /&gt;
* The TLA2B TLA+ to B translator is here: [https://gitlab.cs.uni-duesseldorf.de/general/stups/tla2bAST https://gitlab.cs.uni-duesseldorf.de/general/stups/tla2bAST].&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6019</id>
		<title>Other languages</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6019"/>
		<updated>2025-10-06T16:34:17Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: XTL VisB&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]&lt;br /&gt;
[[Category:Developer Manual]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== XTL Prolog Format for Transition Systems ==&lt;br /&gt;
&lt;br /&gt;
You can also use ProB to animate and model check other specification languages by writing your own Prolog interpreter. To do this you should create a Prolog file with the .P extension and which defines three predicates:&lt;br /&gt;
* &amp;lt;tt&amp;gt;trans/3&amp;lt;/tt&amp;gt;: this predicate should compute for every state (second argument), the outgoing transitions (first argument), and the resulting new states (third argument)&lt;br /&gt;
* &amp;lt;tt&amp;gt;prop/2&amp;lt;/tt&amp;gt;: this predicate should compute the properties for the states of your system&lt;br /&gt;
* &amp;lt;tt&amp;gt;start/1&amp;lt;/tt&amp;gt;: this defines the initial states of your system&lt;br /&gt;
&lt;br /&gt;
For example, the following defines a system with two states (a and b) and two transitions (lock and unlock):&lt;br /&gt;
&lt;br /&gt;
 start(a).&lt;br /&gt;
 trans(lock,a,b).&lt;br /&gt;
 trans(unlock,b,a).&lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
These Prolog files can be loaded with ProB&#039;s open command (be sure to use the .P extension and to either choose &amp;quot;All files&amp;quot; or &amp;quot;Other Formalisms&amp;quot; in the file filtering menu).&lt;br /&gt;
&lt;br /&gt;
=== All recognised Prolog Predicates ===&lt;br /&gt;
&lt;br /&gt;
As of ProB 1.15.0, it is possible to specify symbolic transitions using the predicate &amp;lt;tt&amp;gt;symb_trans/3&amp;lt;/tt&amp;gt;. Such transitions are only available via the execute by predicate dialog and are intended for transitions that require user input or have side effects.&lt;br /&gt;
&amp;lt;tt&amp;gt;symb_trans_enabled(Name,State)&amp;lt;/tt&amp;gt; can be optionally used to mark states in which a symbolic transition is potentially enabled (not guaranteed).&lt;br /&gt;
&lt;br /&gt;
To provide dynamic transition properties, such as descriptions, the two predicates &amp;lt;tt&amp;gt;trans/4&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;start/2&amp;lt;/tt&amp;gt; can be used, where the last parameter is a list of properties, e.g.&lt;br /&gt;
 trans(toggle_button,button(A),button(B),[description(toggle_from_to(A,B))]) :- toggle(A,B).&lt;br /&gt;
Static properties, such as parameter names, can be provided using &amp;lt;tt&amp;gt;trans_prop(TransName,Prop)&amp;lt;/tt&amp;gt;, e.g.&lt;br /&gt;
 trans_prop(set_button,param_names([&#039;ButtonState&#039;])).&lt;br /&gt;
For symbolic transitions it is required to provide parameter names.&lt;br /&gt;
&lt;br /&gt;
The following can be used to set up an animation image matrix with corresponding actions:&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image(Nr,Path)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_function_result(State,List)&amp;lt;/tt&amp;gt; where List is a list of terms of the form ((Row,Col),Img) where Img is either a declared animation_image number or another Prolog term&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_right_click_transition(Row,Col,TransitionTemplate)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_click_transition(FromRow,FromCol,ToRow,ToCol,ListOfTransitionTemplates,ImageNr)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example for visualisation can be found at [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]].&lt;br /&gt;
&lt;br /&gt;
Further recognised predicates are:&lt;br /&gt;
* &amp;lt;tt&amp;gt;prob_pragma_string(DefinionName,Value)&amp;lt;/tt&amp;gt;: a way to mimic B DEFINITION Strings in XTL mode&lt;br /&gt;
* &amp;lt;tt&amp;gt;nr_state_properties(Nr)&amp;lt;/tt&amp;gt;: number of state properties displayed in the state view&lt;br /&gt;
* &amp;lt;tt&amp;gt;heuristic_function_active&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;heuristic_function_result(State,Res)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
The following predicates specify a simple button:&lt;br /&gt;
&lt;br /&gt;
 start(button(on)).&lt;br /&gt;
 trans(toggle_button,button(X),button(Y)) :- toggle(X,Y).&lt;br /&gt;
 trans(set_button(X),_,button(X)) :- X=on ; X=off.&lt;br /&gt;
 prop(button(X),&#039;=&#039;(button,X)).&lt;br /&gt;
 toggle(on,off).&lt;br /&gt;
 toggle(off,on).&lt;br /&gt;
&lt;br /&gt;
Another simple example for a very basic process algebra is as follows:&lt;br /&gt;
&lt;br /&gt;
 % start(PossibleInitialState)&lt;br /&gt;
 start(choice(pref(a,stop),intl(pref(b,pref(c,stop)),pref(d,stop)))).&lt;br /&gt;
 &lt;br /&gt;
 % trans(Event, StateBefore, StateAfter)&lt;br /&gt;
 trans(A,pref(A,P),P). % action prefix&lt;br /&gt;
 trans(A,intl(P,Q),intl(P2,Q)) :- trans(A,P,P2). % interleave&lt;br /&gt;
 trans(A,intl(P,Q),intl(P,Q2)) :- trans(A,Q,Q2).&lt;br /&gt;
 trans(A,par(P,Q),par(P2,Q2)) :- trans(A,P,P2), trans(A,Q,Q2). % parallel composition&lt;br /&gt;
 trans(A,choice(P,Q),P2) :- trans(A,P,P2). % choice&lt;br /&gt;
 trans(A,choice(P,Q),Q2) :- trans(A,Q,Q2).&lt;br /&gt;
 &lt;br /&gt;
 % prop(State, PropertyOfState)&lt;br /&gt;
 prop(pref(A,P),prefix).&lt;br /&gt;
 prop(intl(P,Q),interleave).&lt;br /&gt;
 prop(A,A).&lt;br /&gt;
 &lt;br /&gt;
If you have a working interpreter, you can also contact the ProB developers in order for your interpreter to be included in the standard ProB distribution (in the style of the CSP-M or Promela interpreters).&lt;br /&gt;
With this you can add syntax highlighting, error highlighting in the source code, highlighting during animation, support for new LTL properties,...&lt;br /&gt;
&lt;br /&gt;
Another, slightly more elaborate example, is the following interpreter for regular expressions:&lt;br /&gt;
&lt;br /&gt;
 /* A simple animator for regular expressions */&lt;br /&gt;
 &lt;br /&gt;
 start(&#039;|&#039;(&#039;.&#039;(&#039;*&#039;(a),b) ,  &#039;.&#039;(&#039;*&#039;(b),a))). &lt;br /&gt;
 &lt;br /&gt;
 trans(_,[],_) :- !,fail.&lt;br /&gt;
 trans(X,X,[]) :- atomic(X),!.&lt;br /&gt;
 trans(X,&#039;|&#039;(R1,R2),R) :- &lt;br /&gt;
  trans(X,R1,R) ; trans(X,R2,R).&lt;br /&gt;
 trans(X,&#039;.&#039;(R1,B),R) :- trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,B,R).&lt;br /&gt;
 trans(X,&#039;?&#039;(R1),R) :-&lt;br /&gt;
  trans(X,R1,R) ; (X=epsilon,R=[]).&lt;br /&gt;
 trans(epsilon,&#039;*&#039;(_R1),[]). &lt;br /&gt;
 trans(X,&#039;*&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 trans(X,&#039;+&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 &lt;br /&gt;
 gen_concat(R1,R2,R) :- &lt;br /&gt;
  (R1=[] -&amp;gt; R = R2 ; R = &#039;.&#039;(R1,R2)).&lt;br /&gt;
 &lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
Finally, a more complex example is [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]] which also includes a graphical visualisation (using the &amp;lt;tt&amp;gt;animation_function_result&amp;lt;/tt&amp;gt; predicate recognised by ProB as of version 1.4.0-rc3).&lt;br /&gt;
&lt;br /&gt;
=== Using VisB in XTL mode ===&lt;br /&gt;
&lt;br /&gt;
Since ProB 1.15.0, it is possible to use [[VisB|VisB]] with XTL specifications. For this, a B (!) definition file (&amp;lt;tt&amp;gt;.def&amp;lt;/tt&amp;gt;) must be used, as with B models, which enables the use of VisB DEFINITIONS. The B definition file can the be linked to the specification using&lt;br /&gt;
 prob_pragma_string(&#039;VISB_DEFINITIONS_FILE&#039;,PathToFile).&lt;br /&gt;
(or via the VisB view in ProB2-UI).&lt;br /&gt;
To access the value of state properties in the current state, e.g. for VisB updates, the external function &amp;lt;tt&amp;gt;STATE_PROPERTY(NameOfProp)&amp;lt;/tt&amp;gt; can be used, where &amp;lt;tt&amp;gt;NameOfProp&amp;lt;/tt&amp;gt; corresponds to a property of the special style &amp;lt;tt&amp;gt;&#039;=&#039;(Name,Value)&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;prop/2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Note that for event predicates the parameter values must be wrapped in &amp;lt;tt&amp;gt;STRING_TO_TERM&amp;lt;/tt&amp;gt;, e.g.&lt;br /&gt;
 rec(event: &amp;quot;set_button&amp;quot;, predicate: &amp;quot;buttonState = STRING_TO_TERM(\&amp;quot;on\&amp;quot;)&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
== Promela ==&lt;br /&gt;
&lt;br /&gt;
Version 1.2.7 of ProB  (July 2008) was able to open Promela files. This mode provided source-level highlighting during animation. The main purpose was to debug and animate Promela specifications in a user-friendly way. We do not plan to compete in terms of model checking speed with Spin (Spin compiles Promela to C code, ProB uses a Prolog interpreter). To animate a Promela model, simply open the file with the .pml or .prom extension with the &amp;quot;File-&amp;gt;Open...&amp;quot; command. You will have to choose &amp;quot;Other Formalisms&amp;quot; or &amp;quot;All Files&amp;quot; in the filter pop-up-menu to be able to select the file.&lt;br /&gt;
&lt;br /&gt;
This direct support of Promela files has been discontinued, but the Promela interpreter is still available as an XTL Prolog specification (see above) and can thus be used to animate Promela specifications with ProB.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Team&amp;diff=6018</id>
		<title>Team</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Team&amp;diff=6018"/>
		<updated>2025-10-06T16:22:09Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: Links gefixt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;ProB is based on research and implemention effort by:&lt;br /&gt;
* [https://www.cs.hhu.de/lehrstuehle-und-arbeitsgruppen/softwaretechnik-und-programmiersprachen/unser-team/team/leuschel Michael Leuschel],&lt;br /&gt;
* Michael Butler,&lt;br /&gt;
* [https://www.cs.hhu.de/lehrstuehle-und-arbeitsgruppen/softwaretechnik-und-programmiersprachen/unser-team/team/bendisposto Jens Bendisposto],&lt;br /&gt;
* [https://www.cs.hhu.de/lehrstuehle-und-arbeitsgruppen/softwaretechnik-und-programmiersprachen/unser-team/alumni Ivaylo Dobrikov],&lt;br /&gt;
* [https://www.cs.hhu.de/lehrstuehle-und-arbeitsgruppen/softwaretechnik-und-programmiersprachen/unser-team/alumni Dominik Hansen],&lt;br /&gt;
* [https://www.cs.hhu.de/lehrstuehle-und-arbeitsgruppen/softwaretechnik-und-programmiersprachen/unser-team/alumni Philipp Körner],&lt;br /&gt;
* [https://www.cs.hhu.de/lehrstuehle-und-arbeitsgruppen/softwaretechnik-und-programmiersprachen/unser-team/alumni Sebastian Krings],&lt;br /&gt;
* [https://www.cs.hhu.de/lehrstuehle-und-arbeitsgruppen/softwaretechnik-und-programmiersprachen/unser-team/alumni Lukas Ladenberger],&lt;br /&gt;
* [https://www.cs.hhu.de/lehrstuehle-und-arbeitsgruppen/softwaretechnik-und-programmiersprachen/unser-team/alumni David Schneider],&lt;br /&gt;
* [https://www.cs.hhu.de/lehrstuehle-und-arbeitsgruppen/softwaretechnik-und-programmiersprachen/unser-team/alumni Joshua Schmidt],&lt;br /&gt;
* [https://www.cs.hhu.de/lehrstuehle-und-arbeitsgruppen/softwaretechnik-und-programmiersprachen/unser-team/alumni Daniel Plagge],&lt;br /&gt;
* [https://www.cs.hhu.de/lehrstuehle-und-arbeitsgruppen/softwaretechnik-und-programmiersprachen/unser-team/alumni Marc Fontaine],&lt;br /&gt;
* [https://www.cs.hhu.de/lehrstuehle-und-arbeitsgruppen/softwaretechnik-und-programmiersprachen/unser-team/alumni Fabian Fritz],&lt;br /&gt;
* [https://www.cs.hhu.de/lehrstuehle-und-arbeitsgruppen/softwaretechnik-und-programmiersprachen/unser-team/alumni Corina Spermann],&lt;br /&gt;
* Joy Clark,&lt;br /&gt;
* David Geleßus,&lt;br /&gt;
* [https://www.cs.hhu.de/lehrstuehle-und-arbeitsgruppen/softwaretechnik-und-programmiersprachen/unser-team/team/gruteser Jan Gruteser],&lt;br /&gt;
* [https://www.cs.hhu.de/lehrstuehle-und-arbeitsgruppen/softwaretechnik-und-programmiersprachen/unser-team/team/vu Fabian Vu],&lt;br /&gt;
* Antonia Pütz,&lt;br /&gt;
* Sherin Schneider,&lt;br /&gt;
* Yumiko Takahashi,&lt;br /&gt;
* Miles Vella,&lt;br /&gt;
* Michelle Werth,&lt;br /&gt;
* Michael Jastram,&lt;br /&gt;
* Philip Hoefges,&lt;br /&gt;
* Edward Turner,&lt;br /&gt;
* Dennis Winter,&lt;br /&gt;
* Sonja Holl,&lt;br /&gt;
* Jens Krüger,&lt;br /&gt;
* Michael Birkhoff,&lt;br /&gt;
* Carla Ferreira,&lt;br /&gt;
* Stéphane Lo Presti,&lt;br /&gt;
* Leonid Mikhailov,&lt;br /&gt;
* Laksono Adhianto, ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Part of the research and development was conducted within various research projects, such as the EPSRC funded projects ABCD and 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] projects [http://www.gepavas.de/ Gepavas], Gepavas II and IVOIRE.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6017</id>
		<title>Other languages</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6017"/>
		<updated>2025-10-06T08:13:07Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* All recognised Prolog Predicates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]&lt;br /&gt;
[[Category:Developer Manual]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== XTL Prolog Format for Transition Systems ==&lt;br /&gt;
&lt;br /&gt;
You can also use ProB to animate and model check other specification languages by writing your own Prolog interpreter. To do this you should create a Prolog file with the .P extension and which defines three predicates:&lt;br /&gt;
* &amp;lt;tt&amp;gt;trans/3&amp;lt;/tt&amp;gt;: this predicate should compute for every state (second argument), the outgoing transitions (first argument), and the resulting new states (third argument)&lt;br /&gt;
* &amp;lt;tt&amp;gt;prop/2&amp;lt;/tt&amp;gt;: this predicate should compute the properties for the states of your system&lt;br /&gt;
* &amp;lt;tt&amp;gt;start/1&amp;lt;/tt&amp;gt;: this defines the initial states of your system&lt;br /&gt;
&lt;br /&gt;
For example, the following defines a system with two states (a and b) and two transitions (lock and unlock):&lt;br /&gt;
&lt;br /&gt;
 start(a).&lt;br /&gt;
 trans(lock,a,b).&lt;br /&gt;
 trans(unlock,b,a).&lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
These Prolog files can be loaded with ProB&#039;s open command (be sure to use the .P extension and to either choose &amp;quot;All files&amp;quot; or &amp;quot;Other Formalisms&amp;quot; in the file filtering menu).&lt;br /&gt;
&lt;br /&gt;
=== All recognised Prolog Predicates ===&lt;br /&gt;
&lt;br /&gt;
As of ProB 1.15.0, it is possible to specify symbolic transitions using the predicate &amp;lt;tt&amp;gt;symb_trans/3&amp;lt;/tt&amp;gt;. Such transitions are only available via the execute by predicate dialog and are intended for transitions that require user input or have side effects.&lt;br /&gt;
&amp;lt;tt&amp;gt;symb_trans_enabled(Name,State)&amp;lt;/tt&amp;gt; can be optionally used to mark states in which a symbolic transition is potentially enabled (not guaranteed).&lt;br /&gt;
&lt;br /&gt;
To provide dynamic transition properties, such as descriptions, the two predicates &amp;lt;tt&amp;gt;trans/4&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;start/2&amp;lt;/tt&amp;gt; can be used, where the last parameter is a list of properties, e.g.&lt;br /&gt;
 trans(toggle_button,button(A),button(B),[description(toggle_from_to(A,B))]) :- toggle(A,B).&lt;br /&gt;
Static properties, such as parameter names, can be provided using &amp;lt;tt&amp;gt;trans_prop(TransName,Prop)&amp;lt;/tt&amp;gt;, e.g.&lt;br /&gt;
 trans_prop(set_button,param_names([&#039;ButtonState&#039;])).&lt;br /&gt;
For symbolic transitions it is required to provide parameter names.&lt;br /&gt;
&lt;br /&gt;
The following can be used to set up an animation image matrix with corresponding actions:&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image(Nr,Path)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_function_result(State,List)&amp;lt;/tt&amp;gt; where List is a list of terms of the form ((Row,Col),Img) where Img is either a declared animation_image number or another Prolog term&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_right_click_transition(Row,Col,TransitionTemplate)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_click_transition(FromRow,FromCol,ToRow,ToCol,ListOfTransitionTemplates,ImageNr)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example for visualisation can be found at [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]].&lt;br /&gt;
&lt;br /&gt;
Further recognised predicates are:&lt;br /&gt;
* &amp;lt;tt&amp;gt;prob_pragma_string(DefinionName,Value)&amp;lt;/tt&amp;gt;: a way to mimic B DEFINITION Strings in XTL mode&lt;br /&gt;
* &amp;lt;tt&amp;gt;nr_state_properties(Nr)&amp;lt;/tt&amp;gt;: number of state properties displayed in the state view&lt;br /&gt;
* &amp;lt;tt&amp;gt;heuristic_function_active&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;heuristic_function_result(State,Res)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
The following predicates specify a simple button:&lt;br /&gt;
&lt;br /&gt;
 start(button(on)).&lt;br /&gt;
 trans(toggle_button,button(X),button(Y)) :- toggle(X,Y).&lt;br /&gt;
 trans(set_button(X),_,button(X)) :- X=on ; X=off.&lt;br /&gt;
 prop(button(X),&#039;=&#039;(button,X)).&lt;br /&gt;
 toggle(on,off).&lt;br /&gt;
 toggle(off,on).&lt;br /&gt;
&lt;br /&gt;
Another simple example for a very basic process algebra is as follows:&lt;br /&gt;
&lt;br /&gt;
 % start(PossibleInitialState)&lt;br /&gt;
 start(choice(pref(a,stop),intl(pref(b,pref(c,stop)),pref(d,stop)))).&lt;br /&gt;
 &lt;br /&gt;
 % trans(Event, StateBefore, StateAfter)&lt;br /&gt;
 trans(A,pref(A,P),P). % action prefix&lt;br /&gt;
 trans(A,intl(P,Q),intl(P2,Q)) :- trans(A,P,P2). % interleave&lt;br /&gt;
 trans(A,intl(P,Q),intl(P,Q2)) :- trans(A,Q,Q2).&lt;br /&gt;
 trans(A,par(P,Q),par(P2,Q2)) :- trans(A,P,P2), trans(A,Q,Q2). % parallel composition&lt;br /&gt;
 trans(A,choice(P,Q),P2) :- trans(A,P,P2). % choice&lt;br /&gt;
 trans(A,choice(P,Q),Q2) :- trans(A,Q,Q2).&lt;br /&gt;
 &lt;br /&gt;
 % prop(State, PropertyOfState)&lt;br /&gt;
 prop(pref(A,P),prefix).&lt;br /&gt;
 prop(intl(P,Q),interleave).&lt;br /&gt;
 prop(A,A).&lt;br /&gt;
 &lt;br /&gt;
If you have a working interpreter, you can also contact the ProB developers in order for your interpreter to be included in the standard ProB distribution (in the style of the CSP-M or Promela interpreters).&lt;br /&gt;
With this you can add syntax highlighting, error highlighting in the source code, highlighting during animation, support for new LTL properties,...&lt;br /&gt;
&lt;br /&gt;
Another, slightly more elaborate example, is the following interpreter for regular expressions:&lt;br /&gt;
&lt;br /&gt;
 /* A simple animator for regular expressions */&lt;br /&gt;
 &lt;br /&gt;
 start(&#039;|&#039;(&#039;.&#039;(&#039;*&#039;(a),b) ,  &#039;.&#039;(&#039;*&#039;(b),a))). &lt;br /&gt;
 &lt;br /&gt;
 trans(_,[],_) :- !,fail.&lt;br /&gt;
 trans(X,X,[]) :- atomic(X),!.&lt;br /&gt;
 trans(X,&#039;|&#039;(R1,R2),R) :- &lt;br /&gt;
  trans(X,R1,R) ; trans(X,R2,R).&lt;br /&gt;
 trans(X,&#039;.&#039;(R1,B),R) :- trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,B,R).&lt;br /&gt;
 trans(X,&#039;?&#039;(R1),R) :-&lt;br /&gt;
  trans(X,R1,R) ; (X=epsilon,R=[]).&lt;br /&gt;
 trans(epsilon,&#039;*&#039;(_R1),[]). &lt;br /&gt;
 trans(X,&#039;*&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 trans(X,&#039;+&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 &lt;br /&gt;
 gen_concat(R1,R2,R) :- &lt;br /&gt;
  (R1=[] -&amp;gt; R = R2 ; R = &#039;.&#039;(R1,R2)).&lt;br /&gt;
 &lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
Finally, a more complex example is [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]] which also includes a graphical visualisation (using the &amp;lt;tt&amp;gt;animation_function_result&amp;lt;/tt&amp;gt; predicate recognised by ProB as of version 1.4.0-rc3).&lt;br /&gt;
&lt;br /&gt;
== Promela ==&lt;br /&gt;
&lt;br /&gt;
Version 1.2.7 of ProB  (July 2008) was able to open Promela files. This mode provided source-level highlighting during animation. The main purpose was to debug and animate Promela specifications in a user-friendly way. We do not plan to compete in terms of model checking speed with Spin (Spin compiles Promela to C code, ProB uses a Prolog interpreter). To animate a Promela model, simply open the file with the .pml or .prom extension with the &amp;quot;File-&amp;gt;Open...&amp;quot; command. You will have to choose &amp;quot;Other Formalisms&amp;quot; or &amp;quot;All Files&amp;quot; in the filter pop-up-menu to be able to select the file.&lt;br /&gt;
&lt;br /&gt;
This direct support of Promela files has been discontinued, but the Promela interpreter is still available as an XTL Prolog specification (see above) and can thus be used to animate Promela specifications with ProB.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6016</id>
		<title>Other languages</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6016"/>
		<updated>2025-10-06T08:12:32Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* All recognised Prolog Predicates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]&lt;br /&gt;
[[Category:Developer Manual]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== XTL Prolog Format for Transition Systems ==&lt;br /&gt;
&lt;br /&gt;
You can also use ProB to animate and model check other specification languages by writing your own Prolog interpreter. To do this you should create a Prolog file with the .P extension and which defines three predicates:&lt;br /&gt;
* &amp;lt;tt&amp;gt;trans/3&amp;lt;/tt&amp;gt;: this predicate should compute for every state (second argument), the outgoing transitions (first argument), and the resulting new states (third argument)&lt;br /&gt;
* &amp;lt;tt&amp;gt;prop/2&amp;lt;/tt&amp;gt;: this predicate should compute the properties for the states of your system&lt;br /&gt;
* &amp;lt;tt&amp;gt;start/1&amp;lt;/tt&amp;gt;: this defines the initial states of your system&lt;br /&gt;
&lt;br /&gt;
For example, the following defines a system with two states (a and b) and two transitions (lock and unlock):&lt;br /&gt;
&lt;br /&gt;
 start(a).&lt;br /&gt;
 trans(lock,a,b).&lt;br /&gt;
 trans(unlock,b,a).&lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
These Prolog files can be loaded with ProB&#039;s open command (be sure to use the .P extension and to either choose &amp;quot;All files&amp;quot; or &amp;quot;Other Formalisms&amp;quot; in the file filtering menu).&lt;br /&gt;
&lt;br /&gt;
=== All recognised Prolog Predicates ===&lt;br /&gt;
&lt;br /&gt;
As of ProB 1.15.0, it is possible to specify symbolic transitions using the predicate &amp;lt;tt&amp;gt;symb_trans/3&amp;lt;/tt&amp;gt;. Such transitions are only available via the execute by predicate dialog and are intended for transitions that require user input or have side effects.&lt;br /&gt;
&amp;lt;tt&amp;gt;symb_trans_enabled(Name,State)&amp;lt;/tt&amp;gt; can be optionally used to mark states in which a symbolic transition is potentially enabled (not guaranteed).&lt;br /&gt;
&lt;br /&gt;
To provide dynamic transition properties, such as descriptions, the two predicates &amp;lt;tt&amp;gt;trans/4&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;start/2&amp;lt;/tt&amp;gt; can be used, where the last parameter is a list of properties, e.g.&lt;br /&gt;
 trans(toggle_button,button(A),button(B),[description(toggle_from_to(A,B))]) :- toggle(A,B).&lt;br /&gt;
Static properties, such as parameter names, can be provided using &amp;lt;tt&amp;gt;trans_prop(TransName,Prop)&amp;lt;/tt&amp;gt;, e.g.&lt;br /&gt;
 trans_prop(set_button,param_names([&#039;ButtonState&#039;])).&lt;br /&gt;
For symbolic transitions it is required to provide parameter names.&lt;br /&gt;
&lt;br /&gt;
The following can be used to set up an animation image matrix with corresponding actions:&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image(Nr,Path)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_function_result(State,List)&amp;lt;/tt&amp;gt; where List is a list of terms of the form ((Row,Col),Img) where Img is either a declared animation_image number or another Prolog term&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_right_click_transition(Row,Col,TransitionTemplate)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_click_transition(FromRow,FromCol,ToRow,ToCol,ListOfTransitionTemplates,ImageNr)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example for visualisation can be found at [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]].&lt;br /&gt;
&lt;br /&gt;
Further recognised predicates are:&lt;br /&gt;
* &amp;lt;tt&amp;gt;prob_pragma_string(DefinionName,Value)&amp;lt;/tt&amp;gt; a way to mimic B DEFINITION Strings in XTL mode&lt;br /&gt;
* &amp;lt;tt&amp;gt;nr_state_properties(Nr)&amp;lt;/tt&amp;gt; number of state properties displayed in the state view&lt;br /&gt;
* &amp;lt;tt&amp;gt;heuristic_function_active&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;heuristic_function_result(State,Res)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
The following predicates specify a simple button:&lt;br /&gt;
&lt;br /&gt;
 start(button(on)).&lt;br /&gt;
 trans(toggle_button,button(X),button(Y)) :- toggle(X,Y).&lt;br /&gt;
 trans(set_button(X),_,button(X)) :- X=on ; X=off.&lt;br /&gt;
 prop(button(X),&#039;=&#039;(button,X)).&lt;br /&gt;
 toggle(on,off).&lt;br /&gt;
 toggle(off,on).&lt;br /&gt;
&lt;br /&gt;
Another simple example for a very basic process algebra is as follows:&lt;br /&gt;
&lt;br /&gt;
 % start(PossibleInitialState)&lt;br /&gt;
 start(choice(pref(a,stop),intl(pref(b,pref(c,stop)),pref(d,stop)))).&lt;br /&gt;
 &lt;br /&gt;
 % trans(Event, StateBefore, StateAfter)&lt;br /&gt;
 trans(A,pref(A,P),P). % action prefix&lt;br /&gt;
 trans(A,intl(P,Q),intl(P2,Q)) :- trans(A,P,P2). % interleave&lt;br /&gt;
 trans(A,intl(P,Q),intl(P,Q2)) :- trans(A,Q,Q2).&lt;br /&gt;
 trans(A,par(P,Q),par(P2,Q2)) :- trans(A,P,P2), trans(A,Q,Q2). % parallel composition&lt;br /&gt;
 trans(A,choice(P,Q),P2) :- trans(A,P,P2). % choice&lt;br /&gt;
 trans(A,choice(P,Q),Q2) :- trans(A,Q,Q2).&lt;br /&gt;
 &lt;br /&gt;
 % prop(State, PropertyOfState)&lt;br /&gt;
 prop(pref(A,P),prefix).&lt;br /&gt;
 prop(intl(P,Q),interleave).&lt;br /&gt;
 prop(A,A).&lt;br /&gt;
 &lt;br /&gt;
If you have a working interpreter, you can also contact the ProB developers in order for your interpreter to be included in the standard ProB distribution (in the style of the CSP-M or Promela interpreters).&lt;br /&gt;
With this you can add syntax highlighting, error highlighting in the source code, highlighting during animation, support for new LTL properties,...&lt;br /&gt;
&lt;br /&gt;
Another, slightly more elaborate example, is the following interpreter for regular expressions:&lt;br /&gt;
&lt;br /&gt;
 /* A simple animator for regular expressions */&lt;br /&gt;
 &lt;br /&gt;
 start(&#039;|&#039;(&#039;.&#039;(&#039;*&#039;(a),b) ,  &#039;.&#039;(&#039;*&#039;(b),a))). &lt;br /&gt;
 &lt;br /&gt;
 trans(_,[],_) :- !,fail.&lt;br /&gt;
 trans(X,X,[]) :- atomic(X),!.&lt;br /&gt;
 trans(X,&#039;|&#039;(R1,R2),R) :- &lt;br /&gt;
  trans(X,R1,R) ; trans(X,R2,R).&lt;br /&gt;
 trans(X,&#039;.&#039;(R1,B),R) :- trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,B,R).&lt;br /&gt;
 trans(X,&#039;?&#039;(R1),R) :-&lt;br /&gt;
  trans(X,R1,R) ; (X=epsilon,R=[]).&lt;br /&gt;
 trans(epsilon,&#039;*&#039;(_R1),[]). &lt;br /&gt;
 trans(X,&#039;*&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 trans(X,&#039;+&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 &lt;br /&gt;
 gen_concat(R1,R2,R) :- &lt;br /&gt;
  (R1=[] -&amp;gt; R = R2 ; R = &#039;.&#039;(R1,R2)).&lt;br /&gt;
 &lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
Finally, a more complex example is [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]] which also includes a graphical visualisation (using the &amp;lt;tt&amp;gt;animation_function_result&amp;lt;/tt&amp;gt; predicate recognised by ProB as of version 1.4.0-rc3).&lt;br /&gt;
&lt;br /&gt;
== Promela ==&lt;br /&gt;
&lt;br /&gt;
Version 1.2.7 of ProB  (July 2008) was able to open Promela files. This mode provided source-level highlighting during animation. The main purpose was to debug and animate Promela specifications in a user-friendly way. We do not plan to compete in terms of model checking speed with Spin (Spin compiles Promela to C code, ProB uses a Prolog interpreter). To animate a Promela model, simply open the file with the .pml or .prom extension with the &amp;quot;File-&amp;gt;Open...&amp;quot; command. You will have to choose &amp;quot;Other Formalisms&amp;quot; or &amp;quot;All Files&amp;quot; in the filter pop-up-menu to be able to select the file.&lt;br /&gt;
&lt;br /&gt;
This direct support of Promela files has been discontinued, but the Promela interpreter is still available as an XTL Prolog specification (see above) and can thus be used to animate Promela specifications with ProB.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6015</id>
		<title>Other languages</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6015"/>
		<updated>2025-10-06T07:46:58Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* All recognised Prolog Predicates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]&lt;br /&gt;
[[Category:Developer Manual]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== XTL Prolog Format for Transition Systems ==&lt;br /&gt;
&lt;br /&gt;
You can also use ProB to animate and model check other specification languages by writing your own Prolog interpreter. To do this you should create a Prolog file with the .P extension and which defines three predicates:&lt;br /&gt;
* &amp;lt;tt&amp;gt;trans/3&amp;lt;/tt&amp;gt;: this predicate should compute for every state (second argument), the outgoing transitions (first argument), and the resulting new states (third argument)&lt;br /&gt;
* &amp;lt;tt&amp;gt;prop/2&amp;lt;/tt&amp;gt;: this predicate should compute the properties for the states of your system&lt;br /&gt;
* &amp;lt;tt&amp;gt;start/1&amp;lt;/tt&amp;gt;: this defines the initial states of your system&lt;br /&gt;
&lt;br /&gt;
For example, the following defines a system with two states (a and b) and two transitions (lock and unlock):&lt;br /&gt;
&lt;br /&gt;
 start(a).&lt;br /&gt;
 trans(lock,a,b).&lt;br /&gt;
 trans(unlock,b,a).&lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
These Prolog files can be loaded with ProB&#039;s open command (be sure to use the .P extension and to either choose &amp;quot;All files&amp;quot; or &amp;quot;Other Formalisms&amp;quot; in the file filtering menu).&lt;br /&gt;
&lt;br /&gt;
=== All recognised Prolog Predicates ===&lt;br /&gt;
&lt;br /&gt;
As of ProB 1.15.0, it is possible to specify symbolic transitions using the predicate &amp;lt;tt&amp;gt;symb_trans/3&amp;lt;/tt&amp;gt;. Such transitions are only available via the execute by predicate dialog and are intended for transitions that require user input or have side effects.&lt;br /&gt;
&amp;lt;tt&amp;gt;symb_trans_enabled(Name,State)&amp;lt;/tt&amp;gt; can be optionally used to mark states in which a symbolic transition is potentially enabled (not guaranteed).&lt;br /&gt;
&lt;br /&gt;
To provide dynamic transition properties, such as descriptions, the two predicates &amp;lt;tt&amp;gt;trans/4&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;start/2&amp;lt;/tt&amp;gt; can be used, where the last parameter is a list of properties, e.g.&lt;br /&gt;
 trans(toggle_button,button(A),button(B),[description(toggle_from_to(A,B))]) :- toggle(A,B).&lt;br /&gt;
Static properties, such as parameter names, can be provided using &amp;lt;tt&amp;gt;trans_prop(TransName,Prop)&amp;lt;/tt&amp;gt;, e.g.&lt;br /&gt;
 trans_prop(set_button,param_names([&#039;ButtonState&#039;])).&lt;br /&gt;
For symbolic transitions it is required to provide parameter names.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;prob_pragma_string(DefinionName,Value)&amp;lt;/tt&amp;gt; a way to mimic B DEFINITION Strings in XTL mode&lt;br /&gt;
* &amp;lt;tt&amp;gt;nr_state_properties(Nr)&amp;lt;/tt&amp;gt; number of state properties displayed in the state view&lt;br /&gt;
* &amp;lt;tt&amp;gt;heuristic_function_active&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;heuristic_function_result(State,Res)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following can be used to set up an animation image matrix with corresponding actions:&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image(Nr,Path)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_function_result(State,List)&amp;lt;/tt&amp;gt; where List is a list of terms of the form ((Row,Col),Img) where Img is either a declared animation_image number or another Prolog term&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_right_click_transition(Row,Col,TransitionTemplate)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_click_transition(FromRow,FromCol,ToRow,ToCol,ListOfTransitionTemplates,ImageNr)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example for visualisation can be found at [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]].&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
The following predicates specify a simple button:&lt;br /&gt;
&lt;br /&gt;
 start(button(on)).&lt;br /&gt;
 trans(toggle_button,button(X),button(Y)) :- toggle(X,Y).&lt;br /&gt;
 trans(set_button(X),_,button(X)) :- X=on ; X=off.&lt;br /&gt;
 prop(button(X),&#039;=&#039;(button,X)).&lt;br /&gt;
 toggle(on,off).&lt;br /&gt;
 toggle(off,on).&lt;br /&gt;
&lt;br /&gt;
Another simple example for a very basic process algebra is as follows:&lt;br /&gt;
&lt;br /&gt;
 % start(PossibleInitialState)&lt;br /&gt;
 start(choice(pref(a,stop),intl(pref(b,pref(c,stop)),pref(d,stop)))).&lt;br /&gt;
 &lt;br /&gt;
 % trans(Event, StateBefore, StateAfter)&lt;br /&gt;
 trans(A,pref(A,P),P). % action prefix&lt;br /&gt;
 trans(A,intl(P,Q),intl(P2,Q)) :- trans(A,P,P2). % interleave&lt;br /&gt;
 trans(A,intl(P,Q),intl(P,Q2)) :- trans(A,Q,Q2).&lt;br /&gt;
 trans(A,par(P,Q),par(P2,Q2)) :- trans(A,P,P2), trans(A,Q,Q2). % parallel composition&lt;br /&gt;
 trans(A,choice(P,Q),P2) :- trans(A,P,P2). % choice&lt;br /&gt;
 trans(A,choice(P,Q),Q2) :- trans(A,Q,Q2).&lt;br /&gt;
 &lt;br /&gt;
 % prop(State, PropertyOfState)&lt;br /&gt;
 prop(pref(A,P),prefix).&lt;br /&gt;
 prop(intl(P,Q),interleave).&lt;br /&gt;
 prop(A,A).&lt;br /&gt;
 &lt;br /&gt;
If you have a working interpreter, you can also contact the ProB developers in order for your interpreter to be included in the standard ProB distribution (in the style of the CSP-M or Promela interpreters).&lt;br /&gt;
With this you can add syntax highlighting, error highlighting in the source code, highlighting during animation, support for new LTL properties,...&lt;br /&gt;
&lt;br /&gt;
Another, slightly more elaborate example, is the following interpreter for regular expressions:&lt;br /&gt;
&lt;br /&gt;
 /* A simple animator for regular expressions */&lt;br /&gt;
 &lt;br /&gt;
 start(&#039;|&#039;(&#039;.&#039;(&#039;*&#039;(a),b) ,  &#039;.&#039;(&#039;*&#039;(b),a))). &lt;br /&gt;
 &lt;br /&gt;
 trans(_,[],_) :- !,fail.&lt;br /&gt;
 trans(X,X,[]) :- atomic(X),!.&lt;br /&gt;
 trans(X,&#039;|&#039;(R1,R2),R) :- &lt;br /&gt;
  trans(X,R1,R) ; trans(X,R2,R).&lt;br /&gt;
 trans(X,&#039;.&#039;(R1,B),R) :- trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,B,R).&lt;br /&gt;
 trans(X,&#039;?&#039;(R1),R) :-&lt;br /&gt;
  trans(X,R1,R) ; (X=epsilon,R=[]).&lt;br /&gt;
 trans(epsilon,&#039;*&#039;(_R1),[]). &lt;br /&gt;
 trans(X,&#039;*&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 trans(X,&#039;+&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 &lt;br /&gt;
 gen_concat(R1,R2,R) :- &lt;br /&gt;
  (R1=[] -&amp;gt; R = R2 ; R = &#039;.&#039;(R1,R2)).&lt;br /&gt;
 &lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
Finally, a more complex example is [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]] which also includes a graphical visualisation (using the &amp;lt;tt&amp;gt;animation_function_result&amp;lt;/tt&amp;gt; predicate recognised by ProB as of version 1.4.0-rc3).&lt;br /&gt;
&lt;br /&gt;
== Promela ==&lt;br /&gt;
&lt;br /&gt;
Version 1.2.7 of ProB  (July 2008) was able to open Promela files. This mode provided source-level highlighting during animation. The main purpose was to debug and animate Promela specifications in a user-friendly way. We do not plan to compete in terms of model checking speed with Spin (Spin compiles Promela to C code, ProB uses a Prolog interpreter). To animate a Promela model, simply open the file with the .pml or .prom extension with the &amp;quot;File-&amp;gt;Open...&amp;quot; command. You will have to choose &amp;quot;Other Formalisms&amp;quot; or &amp;quot;All Files&amp;quot; in the filter pop-up-menu to be able to select the file.&lt;br /&gt;
&lt;br /&gt;
This direct support of Promela files has been discontinued, but the Promela interpreter is still available as an XTL Prolog specification (see above) and can thus be used to animate Promela specifications with ProB.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6014</id>
		<title>Other languages</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6014"/>
		<updated>2025-10-06T07:45:07Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* All recognised Prolog Predicates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]&lt;br /&gt;
[[Category:Developer Manual]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== XTL Prolog Format for Transition Systems ==&lt;br /&gt;
&lt;br /&gt;
You can also use ProB to animate and model check other specification languages by writing your own Prolog interpreter. To do this you should create a Prolog file with the .P extension and which defines three predicates:&lt;br /&gt;
* &amp;lt;tt&amp;gt;trans/3&amp;lt;/tt&amp;gt;: this predicate should compute for every state (second argument), the outgoing transitions (first argument), and the resulting new states (third argument)&lt;br /&gt;
* &amp;lt;tt&amp;gt;prop/2&amp;lt;/tt&amp;gt;: this predicate should compute the properties for the states of your system&lt;br /&gt;
* &amp;lt;tt&amp;gt;start/1&amp;lt;/tt&amp;gt;: this defines the initial states of your system&lt;br /&gt;
&lt;br /&gt;
For example, the following defines a system with two states (a and b) and two transitions (lock and unlock):&lt;br /&gt;
&lt;br /&gt;
 start(a).&lt;br /&gt;
 trans(lock,a,b).&lt;br /&gt;
 trans(unlock,b,a).&lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
These Prolog files can be loaded with ProB&#039;s open command (be sure to use the .P extension and to either choose &amp;quot;All files&amp;quot; or &amp;quot;Other Formalisms&amp;quot; in the file filtering menu).&lt;br /&gt;
&lt;br /&gt;
=== All recognised Prolog Predicates ===&lt;br /&gt;
&lt;br /&gt;
As of ProB 1.15.0, it is possible to specify symoblic transitions using the predicate &amp;lt;tt&amp;gt;symb_trans/3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;tt&amp;gt;symb_trans_enabled(Name,State)&amp;lt;/tt&amp;gt; can be optionally used to mark states in which a symbolic transition is potentially enabled (not guaranteed).&lt;br /&gt;
&lt;br /&gt;
To provide dynamic transition properties, such as descriptions, the two predicates &amp;lt;tt&amp;gt;trans/4&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;start/2&amp;lt;/tt&amp;gt; can be used, where the last parameter is a list of properties, e.g.&lt;br /&gt;
 trans(toggle_button,button(A),button(B),[description(toggle_from_to(A,B))]) :- toggle(A,B).&lt;br /&gt;
Static properties, such as parameter names, can be provided using &amp;lt;tt&amp;gt;trans_prop(TransName,Prop)&amp;lt;/tt&amp;gt;, e.g.&lt;br /&gt;
 trans_prop(set_button,param_names([&#039;ButtonState&#039;])).&lt;br /&gt;
For symbolic transitions it is required to provide parameter names.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;prob_pragma_string(DefinionName,Value)&amp;lt;/tt&amp;gt; a way to mimic B DEFINITION Strings in XTL mode&lt;br /&gt;
* &amp;lt;tt&amp;gt;nr_state_properties(Nr)&amp;lt;/tt&amp;gt; number of state properties displayed in the state view&lt;br /&gt;
* &amp;lt;tt&amp;gt;heuristic_function_active&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;heuristic_function_result(State,Res)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following can be used to set up an animation image matrix with corresponding actions:&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image(Nr,Path)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_function_result(State,List)&amp;lt;/tt&amp;gt; where List is a list of terms of the form ((Row,Col),Img) where Img is either a declared animation_image number or another Prolog term&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_right_click_transition(Row,Col,TransitionTemplate)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_click_transition(FromRow,FromCol,ToRow,ToCol,ListOfTransitionTemplates,ImageNr)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example for visualisation can be found at [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]].&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
The following predicates specify a simple button:&lt;br /&gt;
&lt;br /&gt;
 start(button(on)).&lt;br /&gt;
 trans(toggle_button,button(X),button(Y)) :- toggle(X,Y).&lt;br /&gt;
 trans(set_button(X),_,button(X)) :- X=on ; X=off.&lt;br /&gt;
 prop(button(X),&#039;=&#039;(button,X)).&lt;br /&gt;
 toggle(on,off).&lt;br /&gt;
 toggle(off,on).&lt;br /&gt;
&lt;br /&gt;
Another simple example for a very basic process algebra is as follows:&lt;br /&gt;
&lt;br /&gt;
 % start(PossibleInitialState)&lt;br /&gt;
 start(choice(pref(a,stop),intl(pref(b,pref(c,stop)),pref(d,stop)))).&lt;br /&gt;
 &lt;br /&gt;
 % trans(Event, StateBefore, StateAfter)&lt;br /&gt;
 trans(A,pref(A,P),P). % action prefix&lt;br /&gt;
 trans(A,intl(P,Q),intl(P2,Q)) :- trans(A,P,P2). % interleave&lt;br /&gt;
 trans(A,intl(P,Q),intl(P,Q2)) :- trans(A,Q,Q2).&lt;br /&gt;
 trans(A,par(P,Q),par(P2,Q2)) :- trans(A,P,P2), trans(A,Q,Q2). % parallel composition&lt;br /&gt;
 trans(A,choice(P,Q),P2) :- trans(A,P,P2). % choice&lt;br /&gt;
 trans(A,choice(P,Q),Q2) :- trans(A,Q,Q2).&lt;br /&gt;
 &lt;br /&gt;
 % prop(State, PropertyOfState)&lt;br /&gt;
 prop(pref(A,P),prefix).&lt;br /&gt;
 prop(intl(P,Q),interleave).&lt;br /&gt;
 prop(A,A).&lt;br /&gt;
 &lt;br /&gt;
If you have a working interpreter, you can also contact the ProB developers in order for your interpreter to be included in the standard ProB distribution (in the style of the CSP-M or Promela interpreters).&lt;br /&gt;
With this you can add syntax highlighting, error highlighting in the source code, highlighting during animation, support for new LTL properties,...&lt;br /&gt;
&lt;br /&gt;
Another, slightly more elaborate example, is the following interpreter for regular expressions:&lt;br /&gt;
&lt;br /&gt;
 /* A simple animator for regular expressions */&lt;br /&gt;
 &lt;br /&gt;
 start(&#039;|&#039;(&#039;.&#039;(&#039;*&#039;(a),b) ,  &#039;.&#039;(&#039;*&#039;(b),a))). &lt;br /&gt;
 &lt;br /&gt;
 trans(_,[],_) :- !,fail.&lt;br /&gt;
 trans(X,X,[]) :- atomic(X),!.&lt;br /&gt;
 trans(X,&#039;|&#039;(R1,R2),R) :- &lt;br /&gt;
  trans(X,R1,R) ; trans(X,R2,R).&lt;br /&gt;
 trans(X,&#039;.&#039;(R1,B),R) :- trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,B,R).&lt;br /&gt;
 trans(X,&#039;?&#039;(R1),R) :-&lt;br /&gt;
  trans(X,R1,R) ; (X=epsilon,R=[]).&lt;br /&gt;
 trans(epsilon,&#039;*&#039;(_R1),[]). &lt;br /&gt;
 trans(X,&#039;*&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 trans(X,&#039;+&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 &lt;br /&gt;
 gen_concat(R1,R2,R) :- &lt;br /&gt;
  (R1=[] -&amp;gt; R = R2 ; R = &#039;.&#039;(R1,R2)).&lt;br /&gt;
 &lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
Finally, a more complex example is [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]] which also includes a graphical visualisation (using the &amp;lt;tt&amp;gt;animation_function_result&amp;lt;/tt&amp;gt; predicate recognised by ProB as of version 1.4.0-rc3).&lt;br /&gt;
&lt;br /&gt;
== Promela ==&lt;br /&gt;
&lt;br /&gt;
Version 1.2.7 of ProB  (July 2008) was able to open Promela files. This mode provided source-level highlighting during animation. The main purpose was to debug and animate Promela specifications in a user-friendly way. We do not plan to compete in terms of model checking speed with Spin (Spin compiles Promela to C code, ProB uses a Prolog interpreter). To animate a Promela model, simply open the file with the .pml or .prom extension with the &amp;quot;File-&amp;gt;Open...&amp;quot; command. You will have to choose &amp;quot;Other Formalisms&amp;quot; or &amp;quot;All Files&amp;quot; in the filter pop-up-menu to be able to select the file.&lt;br /&gt;
&lt;br /&gt;
This direct support of Promela files has been discontinued, but the Promela interpreter is still available as an XTL Prolog specification (see above) and can thus be used to animate Promela specifications with ProB.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6013</id>
		<title>Other languages</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6013"/>
		<updated>2025-10-06T07:41:05Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* All recognised Prolog Predicates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]&lt;br /&gt;
[[Category:Developer Manual]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== XTL Prolog Format for Transition Systems ==&lt;br /&gt;
&lt;br /&gt;
You can also use ProB to animate and model check other specification languages by writing your own Prolog interpreter. To do this you should create a Prolog file with the .P extension and which defines three predicates:&lt;br /&gt;
* &amp;lt;tt&amp;gt;trans/3&amp;lt;/tt&amp;gt;: this predicate should compute for every state (second argument), the outgoing transitions (first argument), and the resulting new states (third argument)&lt;br /&gt;
* &amp;lt;tt&amp;gt;prop/2&amp;lt;/tt&amp;gt;: this predicate should compute the properties for the states of your system&lt;br /&gt;
* &amp;lt;tt&amp;gt;start/1&amp;lt;/tt&amp;gt;: this defines the initial states of your system&lt;br /&gt;
&lt;br /&gt;
For example, the following defines a system with two states (a and b) and two transitions (lock and unlock):&lt;br /&gt;
&lt;br /&gt;
 start(a).&lt;br /&gt;
 trans(lock,a,b).&lt;br /&gt;
 trans(unlock,b,a).&lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
These Prolog files can be loaded with ProB&#039;s open command (be sure to use the .P extension and to either choose &amp;quot;All files&amp;quot; or &amp;quot;Other Formalisms&amp;quot; in the file filtering menu).&lt;br /&gt;
&lt;br /&gt;
=== All recognised Prolog Predicates ===&lt;br /&gt;
&lt;br /&gt;
To provide dynamic transition properties, such as descriptions, the two predicates &amp;lt;tt&amp;gt;trans/4&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;start/2&amp;lt;/tt&amp;gt; can be used, where the last parameter is a list of properties, e.g.&lt;br /&gt;
 trans(toggle_button,button(A),button(B),[description(toggle_from_to(A,B))]) :- toggle(A,B).&lt;br /&gt;
Static properties, such as parameter names, can be provided using &amp;lt;tt&amp;gt;trans_prop(TransName,Prop)&amp;lt;/tt&amp;gt;, e.g.&lt;br /&gt;
 trans_prop(set_button,param_names([&#039;ButtonState&#039;])).&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;prob_pragma_string(DefinionName,Value)&amp;lt;/tt&amp;gt; a way to mimic B DEFINITION Strings in XTL mode&lt;br /&gt;
* &amp;lt;tt&amp;gt;nr_state_properties(Nr)&amp;lt;/tt&amp;gt; number of state properties displayed in the state view&lt;br /&gt;
* &amp;lt;tt&amp;gt;heuristic_function_active&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;heuristic_function_result(State,Res)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following can be used to set up an animation image matrix with corresponding actions:&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image(Nr,Path)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_function_result(State,List)&amp;lt;/tt&amp;gt; where List is a list of terms of the form ((Row,Col),Img) where Img is either a declared animation_image number or another Prolog term&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_right_click_transition(Row,Col,TransitionTemplate)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_click_transition(FromRow,FromCol,ToRow,ToCol,ListOfTransitionTemplates,ImageNr)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example for visualisation can be found at [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]].&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
The following predicates specify a simple button:&lt;br /&gt;
&lt;br /&gt;
 start(button(on)).&lt;br /&gt;
 trans(toggle_button,button(X),button(Y)) :- toggle(X,Y).&lt;br /&gt;
 trans(set_button(X),_,button(X)) :- X=on ; X=off.&lt;br /&gt;
 prop(button(X),&#039;=&#039;(button,X)).&lt;br /&gt;
 toggle(on,off).&lt;br /&gt;
 toggle(off,on).&lt;br /&gt;
&lt;br /&gt;
Another simple example for a very basic process algebra is as follows:&lt;br /&gt;
&lt;br /&gt;
 % start(PossibleInitialState)&lt;br /&gt;
 start(choice(pref(a,stop),intl(pref(b,pref(c,stop)),pref(d,stop)))).&lt;br /&gt;
 &lt;br /&gt;
 % trans(Event, StateBefore, StateAfter)&lt;br /&gt;
 trans(A,pref(A,P),P). % action prefix&lt;br /&gt;
 trans(A,intl(P,Q),intl(P2,Q)) :- trans(A,P,P2). % interleave&lt;br /&gt;
 trans(A,intl(P,Q),intl(P,Q2)) :- trans(A,Q,Q2).&lt;br /&gt;
 trans(A,par(P,Q),par(P2,Q2)) :- trans(A,P,P2), trans(A,Q,Q2). % parallel composition&lt;br /&gt;
 trans(A,choice(P,Q),P2) :- trans(A,P,P2). % choice&lt;br /&gt;
 trans(A,choice(P,Q),Q2) :- trans(A,Q,Q2).&lt;br /&gt;
 &lt;br /&gt;
 % prop(State, PropertyOfState)&lt;br /&gt;
 prop(pref(A,P),prefix).&lt;br /&gt;
 prop(intl(P,Q),interleave).&lt;br /&gt;
 prop(A,A).&lt;br /&gt;
 &lt;br /&gt;
If you have a working interpreter, you can also contact the ProB developers in order for your interpreter to be included in the standard ProB distribution (in the style of the CSP-M or Promela interpreters).&lt;br /&gt;
With this you can add syntax highlighting, error highlighting in the source code, highlighting during animation, support for new LTL properties,...&lt;br /&gt;
&lt;br /&gt;
Another, slightly more elaborate example, is the following interpreter for regular expressions:&lt;br /&gt;
&lt;br /&gt;
 /* A simple animator for regular expressions */&lt;br /&gt;
 &lt;br /&gt;
 start(&#039;|&#039;(&#039;.&#039;(&#039;*&#039;(a),b) ,  &#039;.&#039;(&#039;*&#039;(b),a))). &lt;br /&gt;
 &lt;br /&gt;
 trans(_,[],_) :- !,fail.&lt;br /&gt;
 trans(X,X,[]) :- atomic(X),!.&lt;br /&gt;
 trans(X,&#039;|&#039;(R1,R2),R) :- &lt;br /&gt;
  trans(X,R1,R) ; trans(X,R2,R).&lt;br /&gt;
 trans(X,&#039;.&#039;(R1,B),R) :- trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,B,R).&lt;br /&gt;
 trans(X,&#039;?&#039;(R1),R) :-&lt;br /&gt;
  trans(X,R1,R) ; (X=epsilon,R=[]).&lt;br /&gt;
 trans(epsilon,&#039;*&#039;(_R1),[]). &lt;br /&gt;
 trans(X,&#039;*&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 trans(X,&#039;+&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 &lt;br /&gt;
 gen_concat(R1,R2,R) :- &lt;br /&gt;
  (R1=[] -&amp;gt; R = R2 ; R = &#039;.&#039;(R1,R2)).&lt;br /&gt;
 &lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
Finally, a more complex example is [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]] which also includes a graphical visualisation (using the &amp;lt;tt&amp;gt;animation_function_result&amp;lt;/tt&amp;gt; predicate recognised by ProB as of version 1.4.0-rc3).&lt;br /&gt;
&lt;br /&gt;
== Promela ==&lt;br /&gt;
&lt;br /&gt;
Version 1.2.7 of ProB  (July 2008) was able to open Promela files. This mode provided source-level highlighting during animation. The main purpose was to debug and animate Promela specifications in a user-friendly way. We do not plan to compete in terms of model checking speed with Spin (Spin compiles Promela to C code, ProB uses a Prolog interpreter). To animate a Promela model, simply open the file with the .pml or .prom extension with the &amp;quot;File-&amp;gt;Open...&amp;quot; command. You will have to choose &amp;quot;Other Formalisms&amp;quot; or &amp;quot;All Files&amp;quot; in the filter pop-up-menu to be able to select the file.&lt;br /&gt;
&lt;br /&gt;
This direct support of Promela files has been discontinued, but the Promela interpreter is still available as an XTL Prolog specification (see above) and can thus be used to animate Promela specifications with ProB.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6012</id>
		<title>Other languages</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6012"/>
		<updated>2025-10-06T07:38:21Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* All recognised Prolog Predicates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]&lt;br /&gt;
[[Category:Developer Manual]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== XTL Prolog Format for Transition Systems ==&lt;br /&gt;
&lt;br /&gt;
You can also use ProB to animate and model check other specification languages by writing your own Prolog interpreter. To do this you should create a Prolog file with the .P extension and which defines three predicates:&lt;br /&gt;
* &amp;lt;tt&amp;gt;trans/3&amp;lt;/tt&amp;gt;: this predicate should compute for every state (second argument), the outgoing transitions (first argument), and the resulting new states (third argument)&lt;br /&gt;
* &amp;lt;tt&amp;gt;prop/2&amp;lt;/tt&amp;gt;: this predicate should compute the properties for the states of your system&lt;br /&gt;
* &amp;lt;tt&amp;gt;start/1&amp;lt;/tt&amp;gt;: this defines the initial states of your system&lt;br /&gt;
&lt;br /&gt;
For example, the following defines a system with two states (a and b) and two transitions (lock and unlock):&lt;br /&gt;
&lt;br /&gt;
 start(a).&lt;br /&gt;
 trans(lock,a,b).&lt;br /&gt;
 trans(unlock,b,a).&lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
These Prolog files can be loaded with ProB&#039;s open command (be sure to use the .P extension and to either choose &amp;quot;All files&amp;quot; or &amp;quot;Other Formalisms&amp;quot; in the file filtering menu).&lt;br /&gt;
&lt;br /&gt;
=== All recognised Prolog Predicates ===&lt;br /&gt;
&lt;br /&gt;
To provide dynamic transition properties, such as descriptions, the two predicates &amp;lt;tt&amp;gt;trans/4&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;start/2&amp;lt;/tt&amp;gt; can be used, where the last parameter is a list of properties, e.g.&lt;br /&gt;
 trans(toggle_button,button(A),button(B),[description(toggle_from_to(A,B))]) :- toggle(A,B). &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;prob_pragma_string(DefinionName,Value)&amp;lt;/tt&amp;gt; a way to mimic B DEFINITION Strings in XTL mode&lt;br /&gt;
* &amp;lt;tt&amp;gt;nr_state_properties(Nr)&amp;lt;/tt&amp;gt; number of state properties displayed in the state view&lt;br /&gt;
* &amp;lt;tt&amp;gt;heuristic_function_active&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;heuristic_function_result(State,Res)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following can be used to set up an animation image matrix with corresponding actions:&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image(Nr,Path)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_function_result(State,List)&amp;lt;/tt&amp;gt; where List is a list of terms of the form ((Row,Col),Img) where Img is either a declared animation_image number or another Prolog term&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_right_click_transition(Row,Col,TransitionTemplate)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_click_transition(FromRow,FromCol,ToRow,ToCol,ListOfTransitionTemplates,ImageNr)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example for visualisation can be found at [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]].&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
The following predicates specify a simple button:&lt;br /&gt;
&lt;br /&gt;
 start(button(on)).&lt;br /&gt;
 trans(toggle_button,button(X),button(Y)) :- toggle(X,Y).&lt;br /&gt;
 trans(set_button(X),_,button(X)) :- X=on ; X=off.&lt;br /&gt;
 prop(button(X),&#039;=&#039;(button,X)).&lt;br /&gt;
 toggle(on,off).&lt;br /&gt;
 toggle(off,on).&lt;br /&gt;
&lt;br /&gt;
Another simple example for a very basic process algebra is as follows:&lt;br /&gt;
&lt;br /&gt;
 % start(PossibleInitialState)&lt;br /&gt;
 start(choice(pref(a,stop),intl(pref(b,pref(c,stop)),pref(d,stop)))).&lt;br /&gt;
 &lt;br /&gt;
 % trans(Event, StateBefore, StateAfter)&lt;br /&gt;
 trans(A,pref(A,P),P). % action prefix&lt;br /&gt;
 trans(A,intl(P,Q),intl(P2,Q)) :- trans(A,P,P2). % interleave&lt;br /&gt;
 trans(A,intl(P,Q),intl(P,Q2)) :- trans(A,Q,Q2).&lt;br /&gt;
 trans(A,par(P,Q),par(P2,Q2)) :- trans(A,P,P2), trans(A,Q,Q2). % parallel composition&lt;br /&gt;
 trans(A,choice(P,Q),P2) :- trans(A,P,P2). % choice&lt;br /&gt;
 trans(A,choice(P,Q),Q2) :- trans(A,Q,Q2).&lt;br /&gt;
 &lt;br /&gt;
 % prop(State, PropertyOfState)&lt;br /&gt;
 prop(pref(A,P),prefix).&lt;br /&gt;
 prop(intl(P,Q),interleave).&lt;br /&gt;
 prop(A,A).&lt;br /&gt;
 &lt;br /&gt;
If you have a working interpreter, you can also contact the ProB developers in order for your interpreter to be included in the standard ProB distribution (in the style of the CSP-M or Promela interpreters).&lt;br /&gt;
With this you can add syntax highlighting, error highlighting in the source code, highlighting during animation, support for new LTL properties,...&lt;br /&gt;
&lt;br /&gt;
Another, slightly more elaborate example, is the following interpreter for regular expressions:&lt;br /&gt;
&lt;br /&gt;
 /* A simple animator for regular expressions */&lt;br /&gt;
 &lt;br /&gt;
 start(&#039;|&#039;(&#039;.&#039;(&#039;*&#039;(a),b) ,  &#039;.&#039;(&#039;*&#039;(b),a))). &lt;br /&gt;
 &lt;br /&gt;
 trans(_,[],_) :- !,fail.&lt;br /&gt;
 trans(X,X,[]) :- atomic(X),!.&lt;br /&gt;
 trans(X,&#039;|&#039;(R1,R2),R) :- &lt;br /&gt;
  trans(X,R1,R) ; trans(X,R2,R).&lt;br /&gt;
 trans(X,&#039;.&#039;(R1,B),R) :- trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,B,R).&lt;br /&gt;
 trans(X,&#039;?&#039;(R1),R) :-&lt;br /&gt;
  trans(X,R1,R) ; (X=epsilon,R=[]).&lt;br /&gt;
 trans(epsilon,&#039;*&#039;(_R1),[]). &lt;br /&gt;
 trans(X,&#039;*&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 trans(X,&#039;+&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 &lt;br /&gt;
 gen_concat(R1,R2,R) :- &lt;br /&gt;
  (R1=[] -&amp;gt; R = R2 ; R = &#039;.&#039;(R1,R2)).&lt;br /&gt;
 &lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
Finally, a more complex example is [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]] which also includes a graphical visualisation (using the &amp;lt;tt&amp;gt;animation_function_result&amp;lt;/tt&amp;gt; predicate recognised by ProB as of version 1.4.0-rc3).&lt;br /&gt;
&lt;br /&gt;
== Promela ==&lt;br /&gt;
&lt;br /&gt;
Version 1.2.7 of ProB  (July 2008) was able to open Promela files. This mode provided source-level highlighting during animation. The main purpose was to debug and animate Promela specifications in a user-friendly way. We do not plan to compete in terms of model checking speed with Spin (Spin compiles Promela to C code, ProB uses a Prolog interpreter). To animate a Promela model, simply open the file with the .pml or .prom extension with the &amp;quot;File-&amp;gt;Open...&amp;quot; command. You will have to choose &amp;quot;Other Formalisms&amp;quot; or &amp;quot;All Files&amp;quot; in the filter pop-up-menu to be able to select the file.&lt;br /&gt;
&lt;br /&gt;
This direct support of Promela files has been discontinued, but the Promela interpreter is still available as an XTL Prolog specification (see above) and can thus be used to animate Promela specifications with ProB.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6011</id>
		<title>Other languages</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6011"/>
		<updated>2025-10-06T07:29:37Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* Examples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]&lt;br /&gt;
[[Category:Developer Manual]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== XTL Prolog Format for Transition Systems ==&lt;br /&gt;
&lt;br /&gt;
You can also use ProB to animate and model check other specification languages by writing your own Prolog interpreter. To do this you should create a Prolog file with the .P extension and which defines three predicates:&lt;br /&gt;
* &amp;lt;tt&amp;gt;trans/3&amp;lt;/tt&amp;gt;: this predicate should compute for every state (second argument), the outgoing transitions (first argument), and the resulting new states (third argument)&lt;br /&gt;
* &amp;lt;tt&amp;gt;prop/2&amp;lt;/tt&amp;gt;: this predicate should compute the properties for the states of your system&lt;br /&gt;
* &amp;lt;tt&amp;gt;start/1&amp;lt;/tt&amp;gt;: this defines the initial states of your system&lt;br /&gt;
&lt;br /&gt;
For example, the following defines a system with two states (a and b) and two transitions (lock and unlock):&lt;br /&gt;
&lt;br /&gt;
 start(a).&lt;br /&gt;
 trans(lock,a,b).&lt;br /&gt;
 trans(unlock,b,a).&lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
These Prolog files can be loaded with ProB&#039;s open command (be sure to use the .P extension and to either choose &amp;quot;All files&amp;quot; or &amp;quot;Other Formalisms&amp;quot; in the file filtering menu).&lt;br /&gt;
&lt;br /&gt;
=== All recognised Prolog Predicates ===&lt;br /&gt;
&lt;br /&gt;
The following can be used to set up an animation image matrix with corresponding actions:&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image(Nr,Path)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_function_result(State,List)&amp;lt;/tt&amp;gt; where List is a list of terms of the form ((Row,Col),Img) where Img is either a declared animation_image number or another Prolog term&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_right_click_transition(Row,Col,TransitionTemplate)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_click_transition(FromRow,FromCol,ToRow,ToCol,ListOfTransitionTemplates,ImageNr)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example for visualisation can be found at [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]].&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
The following predicates specify a simple button:&lt;br /&gt;
&lt;br /&gt;
 start(button(on)).&lt;br /&gt;
 trans(toggle_button,button(X),button(Y)) :- toggle(X,Y).&lt;br /&gt;
 trans(set_button(X),_,button(X)) :- X=on ; X=off.&lt;br /&gt;
 prop(button(X),&#039;=&#039;(button,X)).&lt;br /&gt;
 toggle(on,off).&lt;br /&gt;
 toggle(off,on).&lt;br /&gt;
&lt;br /&gt;
Another simple example for a very basic process algebra is as follows:&lt;br /&gt;
&lt;br /&gt;
 % start(PossibleInitialState)&lt;br /&gt;
 start(choice(pref(a,stop),intl(pref(b,pref(c,stop)),pref(d,stop)))).&lt;br /&gt;
 &lt;br /&gt;
 % trans(Event, StateBefore, StateAfter)&lt;br /&gt;
 trans(A,pref(A,P),P). % action prefix&lt;br /&gt;
 trans(A,intl(P,Q),intl(P2,Q)) :- trans(A,P,P2). % interleave&lt;br /&gt;
 trans(A,intl(P,Q),intl(P,Q2)) :- trans(A,Q,Q2).&lt;br /&gt;
 trans(A,par(P,Q),par(P2,Q2)) :- trans(A,P,P2), trans(A,Q,Q2). % parallel composition&lt;br /&gt;
 trans(A,choice(P,Q),P2) :- trans(A,P,P2). % choice&lt;br /&gt;
 trans(A,choice(P,Q),Q2) :- trans(A,Q,Q2).&lt;br /&gt;
 &lt;br /&gt;
 % prop(State, PropertyOfState)&lt;br /&gt;
 prop(pref(A,P),prefix).&lt;br /&gt;
 prop(intl(P,Q),interleave).&lt;br /&gt;
 prop(A,A).&lt;br /&gt;
 &lt;br /&gt;
If you have a working interpreter, you can also contact the ProB developers in order for your interpreter to be included in the standard ProB distribution (in the style of the CSP-M or Promela interpreters).&lt;br /&gt;
With this you can add syntax highlighting, error highlighting in the source code, highlighting during animation, support for new LTL properties,...&lt;br /&gt;
&lt;br /&gt;
Another, slightly more elaborate example, is the following interpreter for regular expressions:&lt;br /&gt;
&lt;br /&gt;
 /* A simple animator for regular expressions */&lt;br /&gt;
 &lt;br /&gt;
 start(&#039;|&#039;(&#039;.&#039;(&#039;*&#039;(a),b) ,  &#039;.&#039;(&#039;*&#039;(b),a))). &lt;br /&gt;
 &lt;br /&gt;
 trans(_,[],_) :- !,fail.&lt;br /&gt;
 trans(X,X,[]) :- atomic(X),!.&lt;br /&gt;
 trans(X,&#039;|&#039;(R1,R2),R) :- &lt;br /&gt;
  trans(X,R1,R) ; trans(X,R2,R).&lt;br /&gt;
 trans(X,&#039;.&#039;(R1,B),R) :- trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,B,R).&lt;br /&gt;
 trans(X,&#039;?&#039;(R1),R) :-&lt;br /&gt;
  trans(X,R1,R) ; (X=epsilon,R=[]).&lt;br /&gt;
 trans(epsilon,&#039;*&#039;(_R1),[]). &lt;br /&gt;
 trans(X,&#039;*&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 trans(X,&#039;+&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 &lt;br /&gt;
 gen_concat(R1,R2,R) :- &lt;br /&gt;
  (R1=[] -&amp;gt; R = R2 ; R = &#039;.&#039;(R1,R2)).&lt;br /&gt;
 &lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
Finally, a more complex example is [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]] which also includes a graphical visualisation (using the &amp;lt;tt&amp;gt;animation_function_result&amp;lt;/tt&amp;gt; predicate recognised by ProB as of version 1.4.0-rc3).&lt;br /&gt;
&lt;br /&gt;
== Promela ==&lt;br /&gt;
&lt;br /&gt;
Version 1.2.7 of ProB  (July 2008) was able to open Promela files. This mode provided source-level highlighting during animation. The main purpose was to debug and animate Promela specifications in a user-friendly way. We do not plan to compete in terms of model checking speed with Spin (Spin compiles Promela to C code, ProB uses a Prolog interpreter). To animate a Promela model, simply open the file with the .pml or .prom extension with the &amp;quot;File-&amp;gt;Open...&amp;quot; command. You will have to choose &amp;quot;Other Formalisms&amp;quot; or &amp;quot;All Files&amp;quot; in the filter pop-up-menu to be able to select the file.&lt;br /&gt;
&lt;br /&gt;
This direct support of Promela files has been discontinued, but the Promela interpreter is still available as an XTL Prolog specification (see above) and can thus be used to animate Promela specifications with ProB.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6010</id>
		<title>Other languages</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6010"/>
		<updated>2025-10-06T07:27:35Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* XTL Prolog Format for Transition Systems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]&lt;br /&gt;
[[Category:Developer Manual]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== XTL Prolog Format for Transition Systems ==&lt;br /&gt;
&lt;br /&gt;
You can also use ProB to animate and model check other specification languages by writing your own Prolog interpreter. To do this you should create a Prolog file with the .P extension and which defines three predicates:&lt;br /&gt;
* &amp;lt;tt&amp;gt;trans/3&amp;lt;/tt&amp;gt;: this predicate should compute for every state (second argument), the outgoing transitions (first argument), and the resulting new states (third argument)&lt;br /&gt;
* &amp;lt;tt&amp;gt;prop/2&amp;lt;/tt&amp;gt;: this predicate should compute the properties for the states of your system&lt;br /&gt;
* &amp;lt;tt&amp;gt;start/1&amp;lt;/tt&amp;gt;: this defines the initial states of your system&lt;br /&gt;
&lt;br /&gt;
For example, the following defines a system with two states (a and b) and two transitions (lock and unlock):&lt;br /&gt;
&lt;br /&gt;
 start(a).&lt;br /&gt;
 trans(lock,a,b).&lt;br /&gt;
 trans(unlock,b,a).&lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
These Prolog files can be loaded with ProB&#039;s open command (be sure to use the .P extension and to either choose &amp;quot;All files&amp;quot; or &amp;quot;Other Formalisms&amp;quot; in the file filtering menu).&lt;br /&gt;
&lt;br /&gt;
=== All recognised Prolog Predicates ===&lt;br /&gt;
&lt;br /&gt;
The following can be used to set up an animation image matrix with corresponding actions:&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image(Nr,Path)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_function_result(State,List)&amp;lt;/tt&amp;gt; where List is a list of terms of the form ((Row,Col),Img) where Img is either a declared animation_image number or another Prolog term&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_right_click_transition(Row,Col,TransitionTemplate)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_click_transition(FromRow,FromCol,ToRow,ToCol,ListOfTransitionTemplates,ImageNr)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example for visualisation can be found at [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]].&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
Another simple example for a very basic process algebra is as follows:&lt;br /&gt;
&lt;br /&gt;
 % start(PossibleInitialState)&lt;br /&gt;
 start(choice(pref(a,stop),intl(pref(b,pref(c,stop)),pref(d,stop)))).&lt;br /&gt;
 &lt;br /&gt;
 % trans(Event, StateBefore, StateAfter)&lt;br /&gt;
 trans(A,pref(A,P),P). % action prefix&lt;br /&gt;
 trans(A,intl(P,Q),intl(P2,Q)) :- trans(A,P,P2). % interleave&lt;br /&gt;
 trans(A,intl(P,Q),intl(P,Q2)) :- trans(A,Q,Q2).&lt;br /&gt;
 trans(A,par(P,Q),par(P2,Q2)) :- trans(A,P,P2), trans(A,Q,Q2). % parallel composition&lt;br /&gt;
 trans(A,choice(P,Q),P2) :- trans(A,P,P2). % choice&lt;br /&gt;
 trans(A,choice(P,Q),Q2) :- trans(A,Q,Q2).&lt;br /&gt;
 &lt;br /&gt;
 % prop(State, PropertyOfState)&lt;br /&gt;
 prop(pref(A,P),prefix).&lt;br /&gt;
 prop(intl(P,Q),interleave).&lt;br /&gt;
 prop(A,A).&lt;br /&gt;
 &lt;br /&gt;
If you have a working interpreter, you can also contact the ProB developers in order for your interpreter to be included in the standard ProB distribution (in the style of the CSP-M or Promela interpreters).&lt;br /&gt;
With this you can add syntax highlighting, error highlighting in the source code, highlighting during animation, support for new LTL properties,...&lt;br /&gt;
&lt;br /&gt;
Another, slightly more elaborate example, is the following interpreter for regular expressions:&lt;br /&gt;
&lt;br /&gt;
 /* A simple animator for regular expressions */&lt;br /&gt;
 &lt;br /&gt;
 start(&#039;|&#039;(&#039;.&#039;(&#039;*&#039;(a),b) ,  &#039;.&#039;(&#039;*&#039;(b),a))). &lt;br /&gt;
 &lt;br /&gt;
 trans(_,[],_) :- !,fail.&lt;br /&gt;
 trans(X,X,[]) :- atomic(X),!.&lt;br /&gt;
 trans(X,&#039;|&#039;(R1,R2),R) :- &lt;br /&gt;
  trans(X,R1,R) ; trans(X,R2,R).&lt;br /&gt;
 trans(X,&#039;.&#039;(R1,B),R) :- trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,B,R).&lt;br /&gt;
 trans(X,&#039;?&#039;(R1),R) :-&lt;br /&gt;
  trans(X,R1,R) ; (X=epsilon,R=[]).&lt;br /&gt;
 trans(epsilon,&#039;*&#039;(_R1),[]). &lt;br /&gt;
 trans(X,&#039;*&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 trans(X,&#039;+&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 &lt;br /&gt;
 gen_concat(R1,R2,R) :- &lt;br /&gt;
  (R1=[] -&amp;gt; R = R2 ; R = &#039;.&#039;(R1,R2)).&lt;br /&gt;
 &lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
Finally, a more complex example is [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]] which also includes a graphical visualisation (using the &amp;lt;tt&amp;gt;animation_function_result&amp;lt;/tt&amp;gt; predicate recognised by ProB as of version 1.4.0-rc3).&lt;br /&gt;
&lt;br /&gt;
== Promela ==&lt;br /&gt;
&lt;br /&gt;
Version 1.2.7 of ProB  (July 2008) was able to open Promela files. This mode provided source-level highlighting during animation. The main purpose was to debug and animate Promela specifications in a user-friendly way. We do not plan to compete in terms of model checking speed with Spin (Spin compiles Promela to C code, ProB uses a Prolog interpreter). To animate a Promela model, simply open the file with the .pml or .prom extension with the &amp;quot;File-&amp;gt;Open...&amp;quot; command. You will have to choose &amp;quot;Other Formalisms&amp;quot; or &amp;quot;All Files&amp;quot; in the filter pop-up-menu to be able to select the file.&lt;br /&gt;
&lt;br /&gt;
This direct support of Promela files has been discontinued, but the Promela interpreter is still available as an XTL Prolog specification (see above) and can thus be used to animate Promela specifications with ProB.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6009</id>
		<title>Other languages</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6009"/>
		<updated>2025-10-06T07:25:49Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* All recognised Prolog predicates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]&lt;br /&gt;
[[Category:Developer Manual]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== XTL Prolog Format for Transition Systems ==&lt;br /&gt;
&lt;br /&gt;
You can also use ProB to animate and model check other specification languages by writing your own Prolog interpreter. To do this you should create a Prolog file with the .P extension and which defines three predicates:&lt;br /&gt;
* &amp;lt;tt&amp;gt;trans/3&amp;lt;/tt&amp;gt;: this predicate should compute for every state (second argument), the outgoing transitions (first argument), and the resulting new states (third argument)&lt;br /&gt;
* &amp;lt;tt&amp;gt;prop/2&amp;lt;/tt&amp;gt;: this predicate should compute the properties for the states of your system&lt;br /&gt;
* &amp;lt;tt&amp;gt;start/1&amp;lt;/tt&amp;gt;: this defines the initial states of your system&lt;br /&gt;
&lt;br /&gt;
For example, the following defines a system with two states (a and b) and two transitions (lock and unlock):&lt;br /&gt;
&lt;br /&gt;
 start(a).&lt;br /&gt;
 trans(lock,a,b).&lt;br /&gt;
 trans(unlock,b,a).&lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
These Prolog files can be loaded with ProB&#039;s open command (be sure to use the .P extension and to either choose &amp;quot;All files&amp;quot; or &amp;quot;Other Formalisms&amp;quot; in the file filtering menu).&lt;br /&gt;
&lt;br /&gt;
=== All recognised Prolog Predicates ===&lt;br /&gt;
&lt;br /&gt;
The following can be used to set up an animation image matrix with corresponding actions:&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image(Nr,Path)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_function_result(State,List)&amp;lt;/tt&amp;gt; where List is a list of terms of the form ((Row,Col),Img) where Img is either a declared animation_image number or another Prolog term&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_right_click_transition(Row,Col,TransitionTemplate)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;animation_image_click_transition(FromRow,FromCol,ToRow,ToCol,ListOfTransitionTemplates,ImageNr)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
Another simple example for a very basic process algebra is as follows:&lt;br /&gt;
&lt;br /&gt;
 % start(PossibleInitialState)&lt;br /&gt;
 start(choice(pref(a,stop),intl(pref(b,pref(c,stop)),pref(d,stop)))).&lt;br /&gt;
 &lt;br /&gt;
 % trans(Event, StateBefore, StateAfter)&lt;br /&gt;
 trans(A,pref(A,P),P). % action prefix&lt;br /&gt;
 trans(A,intl(P,Q),intl(P2,Q)) :- trans(A,P,P2). % interleave&lt;br /&gt;
 trans(A,intl(P,Q),intl(P,Q2)) :- trans(A,Q,Q2).&lt;br /&gt;
 trans(A,par(P,Q),par(P2,Q2)) :- trans(A,P,P2), trans(A,Q,Q2). % parallel composition&lt;br /&gt;
 trans(A,choice(P,Q),P2) :- trans(A,P,P2). % choice&lt;br /&gt;
 trans(A,choice(P,Q),Q2) :- trans(A,Q,Q2).&lt;br /&gt;
 &lt;br /&gt;
 % prop(State, PropertyOfState)&lt;br /&gt;
 prop(pref(A,P),prefix).&lt;br /&gt;
 prop(intl(P,Q),interleave).&lt;br /&gt;
 prop(A,A).&lt;br /&gt;
 &lt;br /&gt;
If you have a working interpreter, you can also contact the ProB developers in order for your interpreter to be included in the standard ProB distribution (in the style of the CSP-M or Promela interpreters).&lt;br /&gt;
With this you can add syntax highlighting, error highlighting in the source code, highlighting during animation, support for new LTL properties,...&lt;br /&gt;
&lt;br /&gt;
Another, slightly more elaborate example, is the following interpreter for regular expressions:&lt;br /&gt;
&lt;br /&gt;
 /* A simple animator for regular expressions */&lt;br /&gt;
 &lt;br /&gt;
 start(&#039;|&#039;(&#039;.&#039;(&#039;*&#039;(a),b) ,  &#039;.&#039;(&#039;*&#039;(b),a))). &lt;br /&gt;
 &lt;br /&gt;
 trans(_,[],_) :- !,fail.&lt;br /&gt;
 trans(X,X,[]) :- atomic(X),!.&lt;br /&gt;
 trans(X,&#039;|&#039;(R1,R2),R) :- &lt;br /&gt;
  trans(X,R1,R) ; trans(X,R2,R).&lt;br /&gt;
 trans(X,&#039;.&#039;(R1,B),R) :- trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,B,R).&lt;br /&gt;
 trans(X,&#039;?&#039;(R1),R) :-&lt;br /&gt;
  trans(X,R1,R) ; (X=epsilon,R=[]).&lt;br /&gt;
 trans(epsilon,&#039;*&#039;(_R1),[]). &lt;br /&gt;
 trans(X,&#039;*&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 trans(X,&#039;+&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 &lt;br /&gt;
 gen_concat(R1,R2,R) :- &lt;br /&gt;
  (R1=[] -&amp;gt; R = R2 ; R = &#039;.&#039;(R1,R2)).&lt;br /&gt;
 &lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
Finally, a more complex example is [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]] which also includes a graphical visualisation (using the &amp;lt;tt&amp;gt;animation_function_result&amp;lt;/tt&amp;gt; predicate recognised by ProB as of version 1.4.0-rc3).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Promela ==&lt;br /&gt;
&lt;br /&gt;
Version 1.2.7 of ProB  (July 2008) was able to open Promela files. This mode provided source-level highlighting during animation. The main purpose was to debug and animate Promela specifications in a user-friendly way. We do not plan to compete in terms of model checking speed with Spin (Spin compiles Promela to C code, ProB uses a Prolog interpreter). To animate a Promela model, simply open the file with the .pml or .prom extension with the &amp;quot;File-&amp;gt;Open...&amp;quot; command. You will have to choose &amp;quot;Other Formalisms&amp;quot; or &amp;quot;All Files&amp;quot; in the filter pop-up-menu to be able to select the file.&lt;br /&gt;
&lt;br /&gt;
This direct support of Promela files has been discontinued, but the Promela interpreter is still available as an XTL Prolog specification (see above) and can thus be used to animate Promela specifications with ProB.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6008</id>
		<title>Other languages</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6008"/>
		<updated>2025-10-06T07:25:06Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* XTL Prolog Format for Transition Systems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]&lt;br /&gt;
[[Category:Developer Manual]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== XTL Prolog Format for Transition Systems ==&lt;br /&gt;
&lt;br /&gt;
You can also use ProB to animate and model check other specification languages by writing your own Prolog interpreter. To do this you should create a Prolog file with the .P extension and which defines three predicates:&lt;br /&gt;
* &amp;lt;tt&amp;gt;trans/3&amp;lt;/tt&amp;gt;: this predicate should compute for every state (second argument), the outgoing transitions (first argument), and the resulting new states (third argument)&lt;br /&gt;
* &amp;lt;tt&amp;gt;prop/2&amp;lt;/tt&amp;gt;: this predicate should compute the properties for the states of your system&lt;br /&gt;
* &amp;lt;tt&amp;gt;start/1&amp;lt;/tt&amp;gt;: this defines the initial states of your system&lt;br /&gt;
&lt;br /&gt;
For example, the following defines a system with two states (a and b) and two transitions (lock and unlock):&lt;br /&gt;
&lt;br /&gt;
 start(a).&lt;br /&gt;
 trans(lock,a,b).&lt;br /&gt;
 trans(unlock,b,a).&lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
These Prolog files can be loaded with ProB&#039;s open command (be sure to use the .P extension and to either choose &amp;quot;All files&amp;quot; or &amp;quot;Other Formalisms&amp;quot; in the file filtering menu).&lt;br /&gt;
&lt;br /&gt;
=== All recognised Prolog predicates ===&lt;br /&gt;
&lt;br /&gt;
The following can be used to set up an animation image matrix with corresponding actions:&lt;br /&gt;
* animation_image(Nr,Path)&lt;br /&gt;
* animation_function_result(State,List) where List is a list of terms of the form ((Row,Col),Img) where Img is either a declared animation_image number or another Prolog term&lt;br /&gt;
* animation_image_right_click_transition(Row,Col,TransitionTemplate)&lt;br /&gt;
* animation_image_click_transition(FromRow,FromCol,ToRow,ToCol,ListOfTransitionTemplates,ImageNr)&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
Another simple example for a very basic process algebra is as follows:&lt;br /&gt;
&lt;br /&gt;
 % start(PossibleInitialState)&lt;br /&gt;
 start(choice(pref(a,stop),intl(pref(b,pref(c,stop)),pref(d,stop)))).&lt;br /&gt;
 &lt;br /&gt;
 % trans(Event, StateBefore, StateAfter)&lt;br /&gt;
 trans(A,pref(A,P),P). % action prefix&lt;br /&gt;
 trans(A,intl(P,Q),intl(P2,Q)) :- trans(A,P,P2). % interleave&lt;br /&gt;
 trans(A,intl(P,Q),intl(P,Q2)) :- trans(A,Q,Q2).&lt;br /&gt;
 trans(A,par(P,Q),par(P2,Q2)) :- trans(A,P,P2), trans(A,Q,Q2). % parallel composition&lt;br /&gt;
 trans(A,choice(P,Q),P2) :- trans(A,P,P2). % choice&lt;br /&gt;
 trans(A,choice(P,Q),Q2) :- trans(A,Q,Q2).&lt;br /&gt;
 &lt;br /&gt;
 % prop(State, PropertyOfState)&lt;br /&gt;
 prop(pref(A,P),prefix).&lt;br /&gt;
 prop(intl(P,Q),interleave).&lt;br /&gt;
 prop(A,A).&lt;br /&gt;
 &lt;br /&gt;
If you have a working interpreter, you can also contact the ProB developers in order for your interpreter to be included in the standard ProB distribution (in the style of the CSP-M or Promela interpreters).&lt;br /&gt;
With this you can add syntax highlighting, error highlighting in the source code, highlighting during animation, support for new LTL properties,...&lt;br /&gt;
&lt;br /&gt;
Another, slightly more elaborate example, is the following interpreter for regular expressions:&lt;br /&gt;
&lt;br /&gt;
 /* A simple animator for regular expressions */&lt;br /&gt;
 &lt;br /&gt;
 start(&#039;|&#039;(&#039;.&#039;(&#039;*&#039;(a),b) ,  &#039;.&#039;(&#039;*&#039;(b),a))). &lt;br /&gt;
 &lt;br /&gt;
 trans(_,[],_) :- !,fail.&lt;br /&gt;
 trans(X,X,[]) :- atomic(X),!.&lt;br /&gt;
 trans(X,&#039;|&#039;(R1,R2),R) :- &lt;br /&gt;
  trans(X,R1,R) ; trans(X,R2,R).&lt;br /&gt;
 trans(X,&#039;.&#039;(R1,B),R) :- trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,B,R).&lt;br /&gt;
 trans(X,&#039;?&#039;(R1),R) :-&lt;br /&gt;
  trans(X,R1,R) ; (X=epsilon,R=[]).&lt;br /&gt;
 trans(epsilon,&#039;*&#039;(_R1),[]). &lt;br /&gt;
 trans(X,&#039;*&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 trans(X,&#039;+&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 &lt;br /&gt;
 gen_concat(R1,R2,R) :- &lt;br /&gt;
  (R1=[] -&amp;gt; R = R2 ; R = &#039;.&#039;(R1,R2)).&lt;br /&gt;
 &lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
Finally, a more complex example is [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]] which also includes a graphical visualisation (using the &amp;lt;tt&amp;gt;animation_function_result&amp;lt;/tt&amp;gt; predicate recognised by ProB as of version 1.4.0-rc3).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Promela ==&lt;br /&gt;
&lt;br /&gt;
Version 1.2.7 of ProB  (July 2008) was able to open Promela files. This mode provided source-level highlighting during animation. The main purpose was to debug and animate Promela specifications in a user-friendly way. We do not plan to compete in terms of model checking speed with Spin (Spin compiles Promela to C code, ProB uses a Prolog interpreter). To animate a Promela model, simply open the file with the .pml or .prom extension with the &amp;quot;File-&amp;gt;Open...&amp;quot; command. You will have to choose &amp;quot;Other Formalisms&amp;quot; or &amp;quot;All Files&amp;quot; in the filter pop-up-menu to be able to select the file.&lt;br /&gt;
&lt;br /&gt;
This direct support of Promela files has been discontinued, but the Promela interpreter is still available as an XTL Prolog specification (see above) and can thus be used to animate Promela specifications with ProB.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6007</id>
		<title>Other languages</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Other_languages&amp;diff=6007"/>
		<updated>2025-10-06T07:22:49Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* XTL Prolog Format for Transition Systems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]&lt;br /&gt;
[[Category:Developer Manual]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= XTL Prolog Format for Transition Systems =&lt;br /&gt;
&lt;br /&gt;
You can also use ProB to animate and model check other specification languages by writing your own Prolog interpreter. To do this you should create a Prolog file with the .P extension and which defines three predicates:&lt;br /&gt;
* &amp;lt;tt&amp;gt;trans/3&amp;lt;/tt&amp;gt;: this predicate should compute for every state (second argument), the outgoing transitions (first argument), and the resulting new states (third argument)&lt;br /&gt;
* &amp;lt;tt&amp;gt;prop/2&amp;lt;/tt&amp;gt;: this predicate should compute the properties for the states of your system&lt;br /&gt;
* &amp;lt;tt&amp;gt;start/1&amp;lt;/tt&amp;gt;: this defines the initial states of your system&lt;br /&gt;
&lt;br /&gt;
For example, the following defines a system with two states (a and b) and two transitions (lock and unlock):&lt;br /&gt;
&lt;br /&gt;
 start(a).&lt;br /&gt;
 trans(lock,a,b).&lt;br /&gt;
 trans(unlock,b,a).&lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
These Prolog files can be loaded with ProB&#039;s open command (be sure to use the .P extension and to either choose &amp;quot;All files&amp;quot; or &amp;quot;Other Formalisms&amp;quot; in the file filtering menu).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Another simple example for a very basic process algebra is as follows:&lt;br /&gt;
&lt;br /&gt;
 % start(PossibleInitialState)&lt;br /&gt;
 start(choice(pref(a,stop),intl(pref(b,pref(c,stop)),pref(d,stop)))).&lt;br /&gt;
 &lt;br /&gt;
 % trans(Event, StateBefore, StateAfter)&lt;br /&gt;
 trans(A,pref(A,P),P). % action prefix&lt;br /&gt;
 trans(A,intl(P,Q),intl(P2,Q)) :- trans(A,P,P2). % interleave&lt;br /&gt;
 trans(A,intl(P,Q),intl(P,Q2)) :- trans(A,Q,Q2).&lt;br /&gt;
 trans(A,par(P,Q),par(P2,Q2)) :- trans(A,P,P2), trans(A,Q,Q2). % parallel composition&lt;br /&gt;
 trans(A,choice(P,Q),P2) :- trans(A,P,P2). % choice&lt;br /&gt;
 trans(A,choice(P,Q),Q2) :- trans(A,Q,Q2).&lt;br /&gt;
 &lt;br /&gt;
 % prop(State, PropertyOfState)&lt;br /&gt;
 prop(pref(A,P),prefix).&lt;br /&gt;
 prop(intl(P,Q),interleave).&lt;br /&gt;
 prop(A,A).&lt;br /&gt;
 &lt;br /&gt;
If you have a working interpreter, you can also contact the ProB developers in order for your interpreter to be included in the standard ProB distribution (in the style of the CSP-M or Promela interpreters).&lt;br /&gt;
With this you can add syntax highlighting, error highlighting in the source code, highlighting during animation, support for new LTL properties,...&lt;br /&gt;
&lt;br /&gt;
Another, slightly more elaborate example, is the following interpreter for regular expressions:&lt;br /&gt;
&lt;br /&gt;
 /* A simple animator for regular expressions */&lt;br /&gt;
 &lt;br /&gt;
 start(&#039;|&#039;(&#039;.&#039;(&#039;*&#039;(a),b) ,  &#039;.&#039;(&#039;*&#039;(b),a))). &lt;br /&gt;
 &lt;br /&gt;
 trans(_,[],_) :- !,fail.&lt;br /&gt;
 trans(X,X,[]) :- atomic(X),!.&lt;br /&gt;
 trans(X,&#039;|&#039;(R1,R2),R) :- &lt;br /&gt;
  trans(X,R1,R) ; trans(X,R2,R).&lt;br /&gt;
 trans(X,&#039;.&#039;(R1,B),R) :- trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,B,R).&lt;br /&gt;
 trans(X,&#039;?&#039;(R1),R) :-&lt;br /&gt;
  trans(X,R1,R) ; (X=epsilon,R=[]).&lt;br /&gt;
 trans(epsilon,&#039;*&#039;(_R1),[]). &lt;br /&gt;
 trans(X,&#039;*&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 trans(X,&#039;+&#039;(R1),R) :- &lt;br /&gt;
  trans(X,R1,R2),&lt;br /&gt;
  gen_concat(R2,&#039;*&#039;(R1),R).&lt;br /&gt;
 &lt;br /&gt;
 gen_concat(R1,R2,R) :- &lt;br /&gt;
  (R1=[] -&amp;gt; R = R2 ; R = &#039;.&#039;(R1,R2)).&lt;br /&gt;
 &lt;br /&gt;
 prop(X,X).&lt;br /&gt;
&lt;br /&gt;
Finally, a more complex example is [[Rush_Hour_XTL|an encoding of the Rush Hour puzzle]] which also includes a graphical visualisation (using the &amp;lt;tt&amp;gt;animation_function_result&amp;lt;/tt&amp;gt; predicate recognised by ProB as of version 1.4.0-rc3).&lt;br /&gt;
&lt;br /&gt;
== Other recognised Prolog predicates ==&lt;br /&gt;
&lt;br /&gt;
The following can be used to set up an animation image matrix with corresponding actions:&lt;br /&gt;
* animation_image(Nr,Path)&lt;br /&gt;
* animation_function_result(State,List) where List is a list of terms of the form ((Row,Col),Img) where Img is either a declared animation_image number or another Prolog term&lt;br /&gt;
* animation_image_right_click_transition(Row,Col,TransitionTemplate)&lt;br /&gt;
* animation_image_click_transition(FromRow,FromCol,ToRow,ToCol,ListOfTransitionTemplates,ImageNr)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Promela ==&lt;br /&gt;
&lt;br /&gt;
Version 1.2.7 of ProB  (July 2008) was able to open Promela files. This mode provided source-level highlighting during animation. The main purpose was to debug and animate Promela specifications in a user-friendly way. We do not plan to compete in terms of model checking speed with Spin (Spin compiles Promela to C code, ProB uses a Prolog interpreter). To animate a Promela model, simply open the file with the .pml or .prom extension with the &amp;quot;File-&amp;gt;Open...&amp;quot; command. You will have to choose &amp;quot;Other Formalisms&amp;quot; or &amp;quot;All Files&amp;quot; in the filter pop-up-menu to be able to select the file.&lt;br /&gt;
&lt;br /&gt;
This direct support of Promela files has been discontinued, but the Promela interpreter is still available as an XTL Prolog specification (see above) and can thus be used to animate Promela specifications with ProB.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=ProB%27s_Prolog_Datastructures&amp;diff=5997</id>
		<title>ProB&#039;s Prolog Datastructures</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=ProB%27s_Prolog_Datastructures&amp;diff=5997"/>
		<updated>2025-07-09T08:02:35Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* Data Values */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Data Values ==&lt;br /&gt;
&lt;br /&gt;
Integer value:&lt;br /&gt;
 int(Nr)&lt;br /&gt;
where Nr is an integer&lt;br /&gt;
&lt;br /&gt;
Booleans:&lt;br /&gt;
 pred_true&lt;br /&gt;
 pred_false&lt;br /&gt;
&lt;br /&gt;
Enumerated or deferred set elements:&lt;br /&gt;
 fd(Nr,Type)&lt;br /&gt;
where Nr is an integer &amp;gt;= 1 and Type is an atom representing the type of enumerated/deferred set&lt;br /&gt;
&lt;br /&gt;
Strings&lt;br /&gt;
 string(S)&lt;br /&gt;
where S is an atom&lt;br /&gt;
&lt;br /&gt;
Pairs/couples&lt;br /&gt;
 (Val1,Val2)&lt;br /&gt;
where Val1 and Val2 are values&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Records&lt;br /&gt;
 rec(Fields)&lt;br /&gt;
where Fields is a list of terms:&lt;br /&gt;
 field(Name,Val)&lt;br /&gt;
where Name is atom representing the field name and Val is a value.&lt;br /&gt;
&lt;br /&gt;
The fields are sorted by name!&lt;br /&gt;
&lt;br /&gt;
Sets&lt;br /&gt;
Here is an overview of the set representations:&lt;br /&gt;
 []&lt;br /&gt;
 [Val|Set]&lt;br /&gt;
 avl_set(AVL)&lt;br /&gt;
 closure(P,T,B)&lt;br /&gt;
 global_set(GS)&lt;br /&gt;
 freetype(T)&lt;br /&gt;
&lt;br /&gt;
The empty set is encoded as the empty list.&lt;br /&gt;
 []&lt;br /&gt;
This represents a set containing at least the value Val and the rest:&lt;br /&gt;
 [Val|Set]&lt;br /&gt;
Note that Set can in principle be any other form (e.g., avl_set(.)).&lt;br /&gt;
The predicate &amp;lt;tt&amp;gt;expand_custom_set_to_list&amp;lt;/tt&amp;gt; can be used to transform a set into a form using only the empty list and the &amp;lt;tt&amp;gt;[.|.]&amp;lt;/tt&amp;gt; functor.&lt;br /&gt;
&lt;br /&gt;
The next are called custom explicit sets, they always represent a fully known set.&lt;br /&gt;
&lt;br /&gt;
A set can be represented by a non-empty AVL tree:&lt;br /&gt;
 avl_set(AVL)&lt;br /&gt;
&lt;br /&gt;
Given a list of parameter identifiers, a list of types and a predicate AST B, we can represent the set {P| P:T &amp;amp; B} as follows:&lt;br /&gt;
 closure(P,T,B)&lt;br /&gt;
&lt;br /&gt;
There are custom representations for complete types, these may be phased out in the future and replaced by the closure(.,.,.) representation:&lt;br /&gt;
 global_set(GS)&lt;br /&gt;
 freetype(T)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Freetype values&lt;br /&gt;
 freeval(Id,Case,Value)&lt;br /&gt;
&lt;br /&gt;
Constructor for denoting special values (undefined values, experimental support for reals,..)&lt;br /&gt;
 term(Term)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;term(undefined)&amp;lt;/tt&amp;gt; is used for uninitialised variables (e.g., when using the B &amp;lt;tt&amp;gt;VAR&amp;lt;/tt&amp;gt; construct).&lt;br /&gt;
&amp;lt;tt&amp;gt;term(floating(Nr))&amp;lt;/tt&amp;gt; is currently used for floating numbers, but this will probably change in the future.&lt;br /&gt;
&lt;br /&gt;
== AST (Abstract Syntax Tree) ==&lt;br /&gt;
&lt;br /&gt;
An AST node has the form:&lt;br /&gt;
 b(Expr,Type,Infos)&lt;br /&gt;
&lt;br /&gt;
Expr generally has the form Functor(AST1,...,ASTk). Below we list possible cases.&lt;br /&gt;
The predicate &amp;lt;tt&amp;gt;syntaxelement&amp;lt;/tt&amp;gt; in bsyntaxtree.pl lists all allowed forms of Expr.&lt;br /&gt;
Type is either &amp;lt;tt&amp;gt;pred&amp;lt;/tt&amp;gt; for predicates, &amp;lt;tt&amp;gt;subst&amp;lt;/tt&amp;gt; for substitutions or the value type for expressions, see below.&lt;br /&gt;
Infos contains information about the AST node and is explained next.&lt;br /&gt;
&lt;br /&gt;
=== Information list ===&lt;br /&gt;
Infos should be a ground list of informations.&lt;br /&gt;
Some important information fields are:&lt;br /&gt;
 contains_wd_condition&lt;br /&gt;
 used_ids(Ids)&lt;br /&gt;
 nodeid(PositionInfo)&lt;br /&gt;
 refers_to_old_state(References)&lt;br /&gt;
&lt;br /&gt;
=== AST types ===&lt;br /&gt;
Possible types are:&lt;br /&gt;
 pred&lt;br /&gt;
 subst&lt;br /&gt;
 integer&lt;br /&gt;
 real&lt;br /&gt;
 boolean&lt;br /&gt;
 string&lt;br /&gt;
 global(G)&lt;br /&gt;
 couple(Type1,Type2)&lt;br /&gt;
 record(FieldTypes)&lt;br /&gt;
 set(Type)&lt;br /&gt;
 seq(Type)&lt;br /&gt;
 freetype(F)&lt;br /&gt;
where FieldTypes is a list containing:&lt;br /&gt;
 field(Name,Type)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;real&amp;lt;/tt&amp;gt; type has been added in version 1.10 of ProB.&lt;br /&gt;
&lt;br /&gt;
=== Operators without arguments ===&lt;br /&gt;
&lt;br /&gt;
 boolean_false&lt;br /&gt;
 boolean_true&lt;br /&gt;
 bool_set&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
=== Unary operators ===&lt;br /&gt;
&lt;br /&gt;
 card(AST)&lt;br /&gt;
 domain(AST)&lt;br /&gt;
 front(AST)&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
=== Binary operators ===&lt;br /&gt;
&lt;br /&gt;
 cartesian_product(AST1,AST2)&lt;br /&gt;
 composition(AST1,AST2)&lt;br /&gt;
 concat(AST1,AST2)&lt;br /&gt;
 conjunct(AST1,AST2)&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
=== Special operators ===&lt;br /&gt;
&lt;br /&gt;
 general_sum(Ids,AST,AST)&lt;br /&gt;
 general_product(Ids,AST,AST)&lt;br /&gt;
 lambda(Ids,AST,AST)&lt;br /&gt;
 quantified_union(Ids,AST,AST)&lt;br /&gt;
 quantified_intersection(Ids,AST,AST)&lt;br /&gt;
 set_extension(ListOfASTs)&lt;br /&gt;
 sequence_extension(ListOfASTs)&lt;br /&gt;
...&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=LTL_Model_Checking&amp;diff=5970</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=5970"/>
		<updated>2025-06-13T16:10:21Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: &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;DEFINITIONS&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;
&lt;br /&gt;
&#039;&#039;&#039;With Safety Check&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
This checks whether a formula is a safety property or not.&lt;br /&gt;
If it is, this property is treated in an optimised way.&lt;br /&gt;
In some cases, this means that not the entire state space has to be computed.&lt;br /&gt;
For this optimisation to work, ProB needs the LTL2BA translator.&lt;br /&gt;
You can download and put it into ProB&#039;s lib folder, by choosing&lt;br /&gt;
 Download and Install LTL2BA Tool&lt;br /&gt;
from the Help menu.&lt;br /&gt;
More details can be found below.&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:&lt;br /&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;
** The following are now also available in ProB 1.12:&lt;br /&gt;
*** `unchanged({BExpr})`   check if the B expression BExpr is unchanged compared to the next state&lt;br /&gt;
*** `changed({BExpr}) `    check if the BExpr is changed by the next transition&lt;br /&gt;
***  `decreasing({BExpr})`  check if the BExpr will decrease due to the next transition&lt;br /&gt;
***` increasing({BExpr}) ` check if the BExpr will increase due to the next transition&lt;br /&gt;
*** ` BA({BPred}) `  check before-after B predicate BPred on current and next state, where x$0 refers to value in current (before) state, and x to value in next (after) state&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;
==Safety Properties ==&lt;br /&gt;
&lt;br /&gt;
For safety properties ProB uses another checking algorithm, to avoid having to explore the entire SCC (strongly connected component) of a counter example.&lt;br /&gt;
In general this requires installing the LTL2BA tool (see Help menu), but  the following patterns are supported directly without LTL2BA:&lt;br /&gt;
    G StateProposition&lt;br /&gt;
    G (StateProposition =&amp;gt; X StateProposition)&lt;br /&gt;
where StateProposition is either an atomic proposition ({Pred}, e(Op), [Op], deadlock,...) or a propositional operators (not, &amp;amp;, =&amp;gt;, or) applied to StatePropositions.&lt;br /&gt;
  &lt;br /&gt;
Here are a few example patterns covered by the above:&lt;br /&gt;
   &lt;br /&gt;
   G {Pred}                       Invariant&lt;br /&gt;
   G(e(Op) =&amp;gt; {Pred})             Necessary precondition for operation Op&lt;br /&gt;
   G({Pred} =&amp;gt; e(Op))             Sufficient precondition for operation Op&lt;br /&gt;
   G([Op] =&amp;gt; X{Pred})             Postcondition of operation Op&lt;br /&gt;
   G(e(Op1) =&amp;gt; not(e(Op2)))       Enabling relations between operations&lt;br /&gt;
   G(not(deadlock(Op1,...,Opk)))  Relative deadlock freedom&lt;br /&gt;
   G(deterministic(Op1,...,Opk))  Relative deadlock freedom&lt;br /&gt;
   G(controller(Op1,...,Opk))     Relative deadlock freedom and determinism&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 [[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 [[Mutual Exclusion (Fairness)|here]&lt;br /&gt;
&lt;br /&gt;
== Summary of CTL Syntax supported by ProB ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
CTL formulas f can be constructed from:&lt;br /&gt;
&lt;br /&gt;
- atomic propositions:&lt;br /&gt;
   { Pred } to check if a B predicate Pred holds in the current state, e.g. {card(someset) &amp;gt; 1}&lt;br /&gt;
   e(op)    to check if an operation op is enabled&lt;br /&gt;
&lt;br /&gt;
- propositional logic operators:&lt;br /&gt;
   not f&lt;br /&gt;
   f or g&lt;br /&gt;
   f &amp;amp; g&lt;br /&gt;
   f =&amp;gt; g&lt;br /&gt;
&lt;br /&gt;
- temporal operators:&lt;br /&gt;
   EX f     there is a next state satisfying f&lt;br /&gt;
   EX[Op] f there is a next state via Op satisfying f, e.g. EX[reset]{db={}}&lt;br /&gt;
   AX f     all next states satisfy f&lt;br /&gt;
   EF f     there exists a path where f holds in the future&lt;br /&gt;
   EG f     there exists a path where f holds globally&lt;br /&gt;
   AF f     for all paths f holds in the future&lt;br /&gt;
   AG f     for all paths f holds globally&lt;br /&gt;
   E f U g  there exists a path where f holds until g&lt;br /&gt;
&lt;br /&gt;
Note: a model satisfies a CTL formula iff the formula holds in all initial states.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=LTL_Model_Checking&amp;diff=5969</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=5969"/>
		<updated>2025-06-13T15:54:43Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* Summary of CTL Syntax supported by ProB */&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;
&lt;br /&gt;
&#039;&#039;&#039;With Safety Check&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
This checks whether a formula is a safety property or not.&lt;br /&gt;
If it is, this property is treated in an optimised way.&lt;br /&gt;
In some cases, this means that not the entire state space has to be computed.&lt;br /&gt;
For this optimisation to work, ProB needs the LTL2BA translator.&lt;br /&gt;
You can download and put it into ProB&#039;s lib folder, by choosing&lt;br /&gt;
 Download and Install LTL2BA Tool&lt;br /&gt;
from the Help menu.&lt;br /&gt;
More details can be found below.&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:&lt;br /&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;
** The following are now also available in ProB 1.12:&lt;br /&gt;
*** `unchanged({BExpr})`   check if the B expression BExpr is unchanged compared to the next state&lt;br /&gt;
*** `changed({BExpr}) `    check if the BExpr is changed by the next transition&lt;br /&gt;
***  `decreasing({BExpr})`  check if the BExpr will decrease due to the next transition&lt;br /&gt;
***` increasing({BExpr}) ` check if the BExpr will increase due to the next transition&lt;br /&gt;
*** ` BA({BPred}) `  check before-after B predicate BPred on current and next state, where x$0 refers to value in current (before) state, and x to value in next (after) state&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;
==Safety Properties ==&lt;br /&gt;
&lt;br /&gt;
For safety properties ProB uses another checking algorithm, to avoid having to explore the entire SCC (strongly connected component) of a counter example.&lt;br /&gt;
In general this requires installing the LTL2BA tool (see Help menu), but  the following patterns are supported directly without LTL2BA:&lt;br /&gt;
    G StateProposition&lt;br /&gt;
    G (StateProposition =&amp;gt; X StateProposition)&lt;br /&gt;
where StateProposition is either an atomic proposition ({Pred}, e(Op), [Op], deadlock,...) or a propositional operators (not, &amp;amp;, =&amp;gt;, or) applied to StatePropositions.&lt;br /&gt;
  &lt;br /&gt;
Here are a few example patterns covered by the above:&lt;br /&gt;
   &lt;br /&gt;
   G {Pred}                       Invariant&lt;br /&gt;
   G(e(Op) =&amp;gt; {Pred})             Necessary precondition for operation Op&lt;br /&gt;
   G({Pred} =&amp;gt; e(Op))             Sufficient precondition for operation Op&lt;br /&gt;
   G([Op] =&amp;gt; X{Pred})             Postcondition of operation Op&lt;br /&gt;
   G(e(Op1) =&amp;gt; not(e(Op2)))       Enabling relations between operations&lt;br /&gt;
   G(not(deadlock(Op1,...,Opk)))  Relative deadlock freedom&lt;br /&gt;
   G(deterministic(Op1,...,Opk))  Relative deadlock freedom&lt;br /&gt;
   G(controller(Op1,...,Opk))     Relative deadlock freedom and determinism&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 [[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 [[Mutual Exclusion (Fairness)|here]&lt;br /&gt;
&lt;br /&gt;
== Summary of CTL Syntax supported by ProB ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
CTL formulas f can be constructed from:&lt;br /&gt;
&lt;br /&gt;
- atomic propositions:&lt;br /&gt;
   { Pred } to check if a B predicate Pred holds in the current state, e.g. {card(someset) &amp;gt; 1}&lt;br /&gt;
   e(op)    to check if an operation op is enabled&lt;br /&gt;
&lt;br /&gt;
- propositional logic operators:&lt;br /&gt;
   not f&lt;br /&gt;
   f or g&lt;br /&gt;
   f &amp;amp; g&lt;br /&gt;
   f =&amp;gt; g&lt;br /&gt;
&lt;br /&gt;
- temporal operators:&lt;br /&gt;
   EX f     there is a next state satisfying f&lt;br /&gt;
   EX[Op] f there is a next state via Op satisfying f, e.g. EX[reset]{db={}}&lt;br /&gt;
   AX f     all next states satisfy f&lt;br /&gt;
   EF f     there exists a path where f holds in the future&lt;br /&gt;
   EG f     there exists a path where f holds globally&lt;br /&gt;
   AF f     for all paths f holds in the future&lt;br /&gt;
   AG f     for all paths f holds globally&lt;br /&gt;
   E f U g  there exists a path where f holds until g&lt;br /&gt;
&lt;br /&gt;
Note: a model satisfies a CTL formula iff the formula holds in all initial states.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Rules-DSL&amp;diff=5966</id>
		<title>Rules-DSL</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Rules-DSL&amp;diff=5966"/>
		<updated>2025-04-30T17:06:52Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* Computations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== B-Rules DSL ==&lt;br /&gt;
&lt;br /&gt;
The B-Rules domain-specific language (B-Rules DSL) mainly provides operations for data validation. &amp;lt;em&amp;gt;Rules&amp;lt;/em&amp;gt; allow checking for expected properties, while &amp;lt;em&amp;gt;computations&amp;lt;/em&amp;gt; can be used to define and compute variables based on the successful execution of certain rules. Furthermore you can use &amp;lt;em&amp;gt;functions&amp;lt;/em&amp;gt; to compute values multiple times depending on different inputs.&lt;br /&gt;
&lt;br /&gt;
===Setting up a Rules Machine===&lt;br /&gt;
Rules machines are stored in &amp;lt;code&amp;gt;.rmch&amp;lt;/code&amp;gt;-files. The general setup for the machine header is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULES_MACHINE machine_name&lt;br /&gt;
REFERENCES list of rules machines&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The latter allows the inclusion of other rules machines and ordinary B machines that contain only constants, but not yet any other B machines. Below, &amp;lt;code&amp;gt;SETS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;DEFINITIONS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;PROPERTIES&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;CONSTANTS&amp;lt;/code&amp;gt; can be used as in a normal B machine. Note that &amp;lt;code&amp;gt;VARIABLES&amp;lt;/code&amp;gt; are not allowed as they are set by rule based computations.&lt;br /&gt;
&lt;br /&gt;
====Rules====&lt;br /&gt;
Rules can be defined in the &amp;lt;code&amp;gt;OPERATIONS&amp;lt;/code&amp;gt;-section of a rules machine. Depending on whether the expectations are met, a rule returns &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;FAIL&amp;lt;/code&amp;gt;. If a rule fails, additionally provided string messages are returned as counterexamples.&lt;br /&gt;
In the B Rules-DSL a rule has the following structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE rule_name // will be the name of the operation and variable storing the result&lt;br /&gt;
DEPENDS_ON_RULE list of rules&lt;br /&gt;
DEPENDS_ON_COMPUTATION list of computations&lt;br /&gt;
ACTIVATION predicate&lt;br /&gt;
ERROR_TYPES positive number of error types&lt;br /&gt;
BODY&lt;br /&gt;
    arbitrarily many rule bodys (see below)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The specified &amp;lt;code&amp;gt;rule_name&amp;lt;/code&amp;gt; will be the name of the operation and variable storing the result.&lt;br /&gt;
If a rule depends on other rules, it can only be executed if the specified rules have been successfully checked, i.e. their corresponding variables &amp;lt;code&amp;gt;rule_name&amp;lt;/code&amp;gt; have the value &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt;. In addition, rules can depend on computations. In this case, a rule is enabled when the specified computations have been executed. If a rule uses variables that are defined by computations, the corresponding computations are added implicitly as dependencies and do not have to be declared explicitly. Any other preconditions can be specified as an &amp;lt;code&amp;gt;ACTIVATION&amp;lt;/code&amp;gt; predicate. An important note is that the activation predicate is evaluated statically at initialisation and disables the rule if the predicate is false. Activation predicates and dependencies can be omitted if they are not needed.&lt;br /&gt;
&lt;br /&gt;
To use different error types (for example, if a rule has multiple bodies and it is necessary to distinguish between them), the number of error types has to be declared in the rule header.&lt;br /&gt;
Error types are also optional.&lt;br /&gt;
&lt;br /&gt;
The actual rule conditions are specified within the body of a rule, which contains the name and the preconditions.&lt;br /&gt;
A rule succeeds if and only if all rule conditions in its body are satisfied.&lt;br /&gt;
There are two constructs for rule bodies that can be used arbitrarily often in the body of a rule.&lt;br /&gt;
The following is formulated in a positive way, i.e. the execution of the rule leads to &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt; if the conditions in the &amp;lt;code&amp;gt;EXPECT&amp;lt;/code&amp;gt;-part are fulfilled.&lt;br /&gt;
In contrast to the &amp;lt;code&amp;gt;RULE_FAIL&amp;lt;/code&amp;gt; body (see below), in &amp;lt;code&amp;gt;RULE_FORALL&amp;lt;/code&amp;gt; you can obtain success messages (such as counter examples) for successful applications of the rule.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    RULE_FORALL&lt;br /&gt;
        list of identifiers&lt;br /&gt;
    WHERE &lt;br /&gt;
        conditions on identifiers&lt;br /&gt;
    EXPECT&lt;br /&gt;
        conditions that must be fulfilled for this rule&lt;br /&gt;
    ERROR_TYPE&lt;br /&gt;
        number encoding error type, must be in range of error types&lt;br /&gt;
    ON_SUCCESS &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list) or&lt;br /&gt;
        ```${identifier from list}``` (template string)&lt;br /&gt;
    COUNTEREXAMPLE &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list) or&lt;br /&gt;
        ```${identifier from list}``` (template string)&lt;br /&gt;
    END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, a negated rule can be formulated. Here the execution of the rule results in &amp;lt;code&amp;gt;FAIL&amp;lt;/code&amp;gt; if the conditions in the &amp;lt;code&amp;gt;WHEN&amp;lt;/code&amp;gt;-part are fulfilled.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    RULE_FAIL &lt;br /&gt;
        list of identifiers&lt;br /&gt;
    WHEN &lt;br /&gt;
        conditions on identifiers for a failing rule&lt;br /&gt;
    ERROR_TYPE&lt;br /&gt;
        number encoding error type, must be in range of error types&lt;br /&gt;
    COUNTEREXAMPLE &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list)&lt;br /&gt;
    END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Counterexamples are of the type &amp;lt;code&amp;gt;INTEGER &amp;lt;-&amp;gt; STRING&amp;lt;/code&amp;gt;. The integer contains the error type, while the string contains the message of the counterexample.&lt;br /&gt;
&lt;br /&gt;
Also valid for the rules header are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULEID id&lt;br /&gt;
CLASSIFICATION identifier&lt;br /&gt;
TAGS identifier&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;CLASSIFICATION&amp;lt;/code&amp;gt; keyword can be used to group the rules in the [[#Rule_Validation_in_ProB2-UI|HTML validation report]] according to their classification.&lt;br /&gt;
&lt;br /&gt;
====Computations====&lt;br /&gt;
Computations can be used to define variables. As for rules, their activation can depend on further rules, computations or any other predicate specified as an activation condition. Again, the activation condition is evaluated at initialisation and sets the computation status variable to &amp;lt;code&amp;gt;COMPUTATION_DISABLED&amp;lt;/code&amp;gt; if the predicate is false. Furthermore, a &amp;lt;code&amp;gt;DUMMY_VALUE&amp;lt;/code&amp;gt; can be set, which initialises the variable with the specified value instead of the empty set before execution of the computation. This mechanism implies that each variable defined by a computation must be a set of type &amp;lt;code&amp;gt;POW(S)&amp;lt;/code&amp;gt; for any &amp;lt;code&amp;gt;TYPE&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;S&amp;lt;/code&amp;gt; (note: the &amp;lt;tt&amp;gt;TYPE&amp;lt;/tt&amp;gt; section is optional since ProB parser version 2.15.1). A computation can be replaced by a previously defined computation if it sets the same variable (of the same type) by using &amp;lt;code&amp;gt;REPLACES&amp;lt;/code&amp;gt;. The general syntax for computations is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
COMPUTATION computation_name&lt;br /&gt;
DEPENDS_ON_RULE list of rules&lt;br /&gt;
DEPENDS_ON_COMPUTATION list of computations&lt;br /&gt;
ACTIVATION predicate&lt;br /&gt;
REPLACES identifier of exactly one computation&lt;br /&gt;
BODY&lt;br /&gt;
    DEFINE variable_name&lt;br /&gt;
        TYPE type of variable&lt;br /&gt;
        DUMMY_VALUE value of variable before execution (initialisation)&lt;br /&gt;
        VALUE value of variable after execution&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Activation predicates, dependencies, and also the dummy value can be omitted if they are not needed. After the execution of a computation, the value of the corresponding variable &amp;lt;code&amp;gt;computation_name&amp;lt;/code&amp;gt; is changed from &amp;lt;code&amp;gt;NOT_EXECUTED&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;EXECUTED&amp;lt;/code&amp;gt;  and the variable &amp;lt;code&amp;gt;variable_name&amp;lt;/code&amp;gt; has the value \texttt{VALUE}. For related computations, it may be useful to use multiple &amp;lt;code&amp;gt;DEFINE&amp;lt;/code&amp;gt; blocks in one computation.&lt;br /&gt;
Separated by &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt;, the body of a computation can contain any number of variable definitions.&lt;br /&gt;
&lt;br /&gt;
====Functions====&lt;br /&gt;
Functions can be called from any rules machine that references the machine containing the function. Depending on input parameters that must fulfil specified preconditions, the functions returns output value(s) that must fulfil optional postconditions. In the body, any B statement can be used to (sequentially) compute the output value.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FUNCTION output &amp;lt;-- function_name(list of input parameters)&lt;br /&gt;
PRECONDITION&lt;br /&gt;
    predicate&lt;br /&gt;
POSTCONDITION&lt;br /&gt;
    predicate&lt;br /&gt;
BODY&lt;br /&gt;
   some B statements&lt;br /&gt;
   output := ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Additional Syntax====&lt;br /&gt;
There are some useful predicates available in rules machines that can be used to check the success or failure of rules. It is also possible to check whether a certain error type was returned by a rule. These are:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SUCCEEDED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 succeeded&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SUCCEEDED_RULE_ERROR_TYPE(rule1,1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 did not fail with error type 1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;GET_RULE_COUNTEREXAMPLES(rule1)&amp;lt;/code&amp;gt;: set of counterexamples of rule1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 failed&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE_ERROR_TYPE(rule1,2)&amp;lt;/code&amp;gt;: TRUE, if check of rule1 failed with error type 2&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE_ALL_ERROR_TYPES(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 failed with all possible error types for rule1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;NOT_CHECKED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if rule1 has not yet been checked&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;DISABLED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if rule1 is disabled (its preconditions are not fulfilled)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another functionality of rules machines are FOR-loops. Their syntax is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FOR variable(s) IN set&lt;br /&gt;
DO&lt;br /&gt;
    operation(s)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
An example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE example_rule&lt;br /&gt;
BODY&lt;br /&gt;
    FOR x,y IN {1 |-&amp;gt; TRUE, 2 |-&amp;gt; FALSE, 3 |-&amp;gt; FALSE} DO &lt;br /&gt;
        RULE_FAIL &lt;br /&gt;
        WHEN y = FALSE&lt;br /&gt;
        COUNTEREXAMPLE STRING_FORMAT(&amp;quot;example_rule_fail: ~w&amp;quot;, x)&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This rule always fails and returns &amp;lt;code&amp;gt;{1 |-&amp;gt; &amp;quot;example_rule_fail: 2&amp;quot;, 1 |-&amp;gt; &amp;quot;example_rule_fail: 3&amp;quot;}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Rule Validation in ProB2-UI===&lt;br /&gt;
Rule validation has been integrated into the ProB2-UI since version 1.2.2 (not yet released).&lt;br /&gt;
It allows convenient execution of rules and computations together with a graphical representation of the results.&lt;br /&gt;
Rules are grouped by their classification and can be additionally filtered by their name, ID, or tags.&lt;br /&gt;
The results can also be exported as an HTML report.&lt;br /&gt;
In addition, dependencies of rules and computations can be visualised as a graph either for all operations or for just one operation (the HTML report and the dependency graph are generated by the ProB Java API and can also be created without ProB2-UI).&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2 UI Rules View.png|500px|ProB2-UI Rules View]]&lt;br /&gt;
&lt;br /&gt;
===Rule Validation with probcli===&lt;br /&gt;
The probcli recognises the option &amp;lt;code&amp;gt;-rule_report &amp;lt;file&amp;gt;&amp;lt;/code&amp;gt; which generates the same HTML/XML validation report as in ProB2-UI for the current animation state.&lt;br /&gt;
The provided file extension is used to determine whether the HTML or the XML version of the report is generated.&lt;br /&gt;
To validate all rules, use this option in combination with &amp;lt;code&amp;gt;-execute_all&amp;lt;/code&amp;gt;.&lt;br /&gt;
There is also a dot visualisation command &amp;quot;rule_dependency graph&amp;quot; that can be used to create a graph of the dependencies of rules and computations (including results of the current state); example call:&lt;br /&gt;
&amp;lt;pre&amp;gt;probcli myMch.mch -execute_all -rule_report myReport.html -dot &amp;quot;rule_dependency_graph&amp;quot; myGraph.pdf&amp;lt;/pre&amp;gt;&lt;br /&gt;
All three export options are also available in ProB Tcl/Tk via the visualization menu.&lt;br /&gt;
Using the special definition &amp;lt;code&amp;gt;RULE_REPORT_CONTEXT&amp;lt;/code&amp;gt; you can include context information about the check in the report (of the type &amp;lt;tt&amp;gt;STRING&amp;lt;/tt&amp;gt;), e.g. the file name of a validated XML file.&lt;br /&gt;
&lt;br /&gt;
===Use Rules for Data Validation===&lt;br /&gt;
The concept of rule validation can be used to validate data from external sources such as CSV or XML files and load the validated data into ProB by successive computations.&lt;br /&gt;
For an XML file, this could look as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULES_MACHINE XML_import&lt;br /&gt;
DEFINITIONS&lt;br /&gt;
    &amp;quot;LibraryXML.def&amp;quot;&lt;br /&gt;
CONSTANTS&lt;br /&gt;
    xml_data&lt;br /&gt;
PROPERTIES&lt;br /&gt;
    xml_data = READ_XML(&amp;quot;xml_file.xml&amp;quot;, &amp;quot;auto&amp;quot;)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now some properties can be validated. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE is_supported_version_of_type_xyz&lt;br /&gt;
ERROR_TYPES 2&lt;br /&gt;
BODY&lt;br /&gt;
    RULE_FAIL e&lt;br /&gt;
    WHEN&lt;br /&gt;
        1 : dom(xml_data) &amp;amp; e = data(1)&#039;element &amp;amp; e /= &amp;quot;xyz&amp;quot;&lt;br /&gt;
    ERROR_TYPE 1 // optional: 1 is standard type&lt;br /&gt;
    COUNTEREXAMPLE&lt;br /&gt;
        STRING_FORMAT(&amp;quot;Error: could not find element &#039;xyz&#039;, was &#039;&amp;quot;^e^&amp;quot;&#039;&amp;quot;)&lt;br /&gt;
    END;&lt;br /&gt;
    RULE_FAIL v&lt;br /&gt;
    WHEN&lt;br /&gt;
        v = xml_data(1)&#039;attributes(&amp;quot;version&amp;quot;) &amp;amp; v /: supported_versions&lt;br /&gt;
    ERROR_TYPE 2&lt;br /&gt;
    COUNTEREXAMPLE&lt;br /&gt;
        &amp;quot;xyz of version &amp;quot;^v^&amp;quot; is currently not supported&amp;quot;&lt;br /&gt;
    END&lt;br /&gt;
END;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Internal Representation===&lt;br /&gt;
Each rules machine is internally translated to an ordinary B machine, which can be accessed as its internal representation.&lt;br /&gt;
Consider the following example rule:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE rule1 BODY RULE_FAIL WHEN bfalse COUNTEREXAMPLE &amp;quot;&amp;quot; END END;&lt;br /&gt;
&lt;br /&gt;
COMPUTATION comp1&lt;br /&gt;
BODY&lt;br /&gt;
    DEFINE x&lt;br /&gt;
    TYPE POW(INTEGER)&lt;br /&gt;
    VALUE 1..10&lt;br /&gt;
    END&lt;br /&gt;
END;&lt;br /&gt;
&lt;br /&gt;
RULE rule2&lt;br /&gt;
DEPENDS_ON_RULE rule1&lt;br /&gt;
// DEPENDS_ON_COMPUTATION comp1&lt;br /&gt;
BODY&lt;br /&gt;
    RULE_FORALL i&lt;br /&gt;
        WHERE i : 1..10&lt;br /&gt;
        EXPECT i &amp;gt; 5&lt;br /&gt;
        COUNTEREXAMPLE STRING_FORMAT(&amp;quot;~w &amp;lt;= 5&amp;quot;, i)&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Its internal representation in classical B is the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
`$RESULT`,`$COUNTEREXAMPLES` &amp;lt;-- rule1 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        rule1 = &amp;quot;NOT_CHECKED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
      rule1,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;SUCCESS&amp;quot;,&amp;quot;SUCCESS&amp;quot;,{}&lt;br /&gt;
    END;&lt;br /&gt;
  &lt;br /&gt;
  comp1 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        comp1 = &amp;quot;NOT_EXECUTED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
      x,comp1 := FORCE(1 .. 10),&amp;quot;EXECUTED&amp;quot;&lt;br /&gt;
    END;&lt;br /&gt;
  &lt;br /&gt;
  `$RESULT`,`$COUNTEREXAMPLES` &amp;lt;-- rule2 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        rule2 = &amp;quot;NOT_CHECKED&amp;quot;&lt;br /&gt;
      &amp;amp; rule1 = &amp;quot;SUCCESS&amp;quot;&lt;br /&gt;
      &amp;amp; comp1 = &amp;quot;EXECUTED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
        rule2,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;SUCCESS&amp;quot;,&amp;quot;SUCCESS&amp;quot;,{} ;&lt;br /&gt;
        VAR `$ResultTuple`,`$ResultStrings`&lt;br /&gt;
        IN&lt;br /&gt;
            `$ResultTuple` := FORCE({i|i : x &amp;amp; not(i &amp;gt; 5)}) ;&lt;br /&gt;
            `$ResultStrings` := FORCE({`$String`|`$String` : STRING &amp;amp; #i.(i : `$ResultTuple` &amp;amp; `$String` = FORMAT_TO_STRING(&amp;quot;~w &amp;lt;= 5&amp;quot;,[TO_STRING(i)]))});&lt;br /&gt;
              rule2_Counterexamples := rule2_Counterexamples \/ {1} * `$ResultStrings` ;&lt;br /&gt;
          IF `$ResultTuple` /= {} THEN&lt;br /&gt;
              rule2,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;FAIL&amp;quot;,&amp;quot;FAIL&amp;quot;,rule2_Counterexamples&lt;br /&gt;
          END&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Observe that the implicit dependency of rule2 on comp1 (rule2 uses its variable x) is detected automatically without explicit declaration.&lt;br /&gt;
&lt;br /&gt;
===Include Rules Machines into other Projects===&lt;br /&gt;
Currently, it is not possible to include rules machines directly into any other machines. Instead, use the rules machine at the top of the hierarchy (of the rules project) and save the internal generated machine as &amp;lt;code&amp;gt;.mch&amp;lt;/code&amp;gt;-file. After changing the machine name accordingly, the rules can be included and used via this machine.&lt;br /&gt;
Note that in this case it is not possible to perform Rules-DSL specific methods of the ProB Java API (like detailed information about rule results).&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Generating_UML_Sequence_Charts&amp;diff=5960</id>
		<title>Generating UML Sequence Charts</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Generating_UML_Sequence_Charts&amp;diff=5960"/>
		<updated>2025-04-14T13:51:47Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* Installation and Using */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Installation and Using ===&lt;br /&gt;
&lt;br /&gt;
ProB has a new experimental feature to generate a UML sequence chart from the current animation trace using [https://plantuml.com PlantUML].&lt;br /&gt;
The feature is available in ProB CLI, ProB Tcl/Tk and ProB2-UI.&lt;br /&gt;
It currently works for classical B and TLA+ models and you need to copy the [https://plantuml.com/download plantuml.jar]  file to ProB&#039;s lib folder. The file should be named plantuml.jar (without any version numbers).&lt;br /&gt;
&lt;br /&gt;
You can also use the command-line version of ProB to install it&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 probcli --install plantuml&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This should generate output similar to this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Installing component plantuml from https://github.com/plantuml/plantuml/releases/download/v1.2024.7/&lt;br /&gt;
 --&amp;gt; curl -L https://github.com/plantuml/plantuml/releases/download/v1.2024.7/plantuml-epl-1.2024.7.jar -o .../lib/plantuml.jar&lt;br /&gt;
Installation complete&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For ProB2-UI a dialog will pop-up when trying to use the feature giving you instructions on where to put the plantuml.jar file.&lt;br /&gt;
With ProB2-UI it is also possible to include a sequence chart in a VisB HTML export.&lt;br /&gt;
&lt;br /&gt;
=== Using the Command ===&lt;br /&gt;
&lt;br /&gt;
It is available in the Visualize menu of Tcl/Tk:&lt;br /&gt;
&lt;br /&gt;
[[file:ProBUMLSeqChartCmd.png|center||300px]]&lt;br /&gt;
&lt;br /&gt;
The UML sequence chart is also available in ProB2-UI in the Graph &amp;amp; Table Visualisation View accessible in the Visualisation menu.&lt;br /&gt;
&lt;br /&gt;
[[file:ProBUMLSeqChartProB2UICmd.png|center||300px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ProBUMLSeqChartProB2UIDialog.png|center||500px]]&lt;br /&gt;
&lt;br /&gt;
=== Specifying the Actors ===&lt;br /&gt;
&lt;br /&gt;
For every B Operation Op that you want to visualise you need to add a definition&lt;br /&gt;
 SEQUENCE_CHART_Op&lt;br /&gt;
in your DEFINITIONS.&lt;br /&gt;
The definition can take arguments, in which case the actual arguments in the trace are passed to the definition. The definition can take fewer arguments (but not more) than the B operation.&lt;br /&gt;
&lt;br /&gt;
The definition should either return&lt;br /&gt;
* the empty string, meaning this operation should be ignored&lt;br /&gt;
* a couple &amp;lt;tt&amp;gt;(ActorFrom,ActorTo)&amp;lt;/tt&amp;gt; specifying the name of the actor sending the message (ActorFrom) and the one receiving the message (ActorTo). You can use strings or other values (which will be converted to strings).&lt;br /&gt;
* a triple &amp;lt;tt&amp;gt;(ActorFrom,ArrowStyle,ActorTo)&amp;lt;/tt&amp;gt;, where the actors are like above and ArrowStyle is a string representing a valid plantUML arrow.&lt;br /&gt;
* a triple &amp;lt;tt&amp;gt;(ActorFrom,ArrowStyle,ArrowSuffix,ActorTo)&amp;lt;/tt&amp;gt;, where the actors and arrow style are like above and ArrowSuffix is a string representing a valid plantUML arrow suffix.&lt;br /&gt;
* a record &amp;lt;tt&amp;gt;rec(from:ActorFrom,to:ActorTo,arrow:ArrowStyle,suffix:ArrowSuffix)&amp;lt;/tt&amp;gt;. Note that the arrow fields are optional.&lt;br /&gt;
&lt;br /&gt;
Currently these arrow styles are supported:&lt;br /&gt;
* &#039;&#039;&#039;--&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-&amp;gt;x&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-&amp;gt;&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-\\&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;\\\\-&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;//--&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-&amp;gt;o&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;o\\\\--&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;-&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;-&amp;gt;o&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-[#green]&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-[#green]-&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-[#blue]-&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-[#red]-&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-[#red]&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-[#0000FF]-&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;-&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;--&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Optionally you can add these suffixes:&lt;br /&gt;
* &#039;&#039;&#039;++&#039;&#039;&#039; (activate the target)&lt;br /&gt;
* &#039;&#039;&#039;--&#039;&#039;&#039; (deactivate source)&lt;br /&gt;
* &#039;&#039;&#039;**&#039;&#039;&#039; (create an instance of target)&lt;br /&gt;
* &#039;&#039;&#039;!!&#039;&#039;&#039; (destroy an instance of target)&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
The following diagram can be created using the model below after animating and then using the command above.&lt;br /&gt;
&lt;br /&gt;
[[file:ProBUMLSeqCharScheduler.png|center||300px]]&lt;br /&gt;
&lt;br /&gt;
And here is the well-known scheduler example with example SEQUENCE_CHART definitions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE scheduler_UML&lt;br /&gt;
SETS&lt;br /&gt;
	PID  = {process1,process2,process3}&lt;br /&gt;
VARIABLES active, ready, waiting&lt;br /&gt;
DEFINITIONS&lt;br /&gt;
      &amp;quot;CHOOSE.def&amp;quot;;&lt;br /&gt;
      SEQUENCE_CHART_INITIALISATION == &amp;quot;&amp;quot;; // ignore&lt;br /&gt;
      SEQUENCE_CHART_new(pp) == (&amp;quot;Master&amp;quot;, &amp;quot;--&amp;gt;&amp;quot;,&amp;quot;**&amp;quot;,pp);&lt;br /&gt;
      SEQUENCE_CHART_del(pp) == (&amp;quot;Master&amp;quot;, &amp;quot;--&amp;gt;&amp;quot;,&amp;quot;!!&amp;quot;,pp);&lt;br /&gt;
      SEQUENCE_CHART_ready(pp) == (pp, &amp;quot;--&amp;gt;&amp;quot;,&amp;quot;Master&amp;quot;);&lt;br /&gt;
      SEQUENCE_CHART_swap == (&amp;quot;Master&amp;quot;, &amp;quot;--&amp;gt;&amp;quot;,&amp;quot;--&amp;quot;,CHOOSE(active))&lt;br /&gt;
INVARIANT&lt;br /&gt;
           active &amp;lt;: PID &amp;amp;&lt;br /&gt;
           ready &amp;lt;: PID   &amp;amp;&lt;br /&gt;
           waiting &amp;lt;: PID &amp;amp;&lt;br /&gt;
           (ready /\ waiting) = {} &amp;amp;&lt;br /&gt;
           active /\ (ready \/ waiting) = {} &amp;amp;&lt;br /&gt;
           /*@label &amp;quot;SAF&amp;quot; */ card(active) &amp;lt;= 1 &amp;amp;&lt;br /&gt;
           ((active = {})  =&amp;gt; (ready = {}))&lt;br /&gt;
INITIALISATION&lt;br /&gt;
	active := {} || ready := {} || waiting := {}&lt;br /&gt;
OPERATIONS&lt;br /&gt;
new(pp) =&lt;br /&gt;
	SELECT&lt;br /&gt;
		pp : PID  &amp;amp;&lt;br /&gt;
		pp /: active &amp;amp;&lt;br /&gt;
		pp /: (ready \/ waiting)&lt;br /&gt;
	THEN&lt;br /&gt;
		waiting := (waiting \/ { pp })&lt;br /&gt;
	END;&lt;br /&gt;
del(pp) =&lt;br /&gt;
	SELECT&lt;br /&gt;
		pp : waiting&lt;br /&gt;
	THEN&lt;br /&gt;
		waiting := waiting - {pp}&lt;br /&gt;
	END;&lt;br /&gt;
ready(rr) =&lt;br /&gt;
        SELECT&lt;br /&gt;
                rr : waiting&lt;br /&gt;
        THEN&lt;br /&gt;
                waiting := (waiting - {rr}) ||&lt;br /&gt;
                IF (active = {}) THEN&lt;br /&gt;
                   active := {rr}&lt;br /&gt;
                ELSE&lt;br /&gt;
                   ready := ready \/ {rr}&lt;br /&gt;
                END&lt;br /&gt;
        END;&lt;br /&gt;
swap =&lt;br /&gt;
        SELECT&lt;br /&gt;
                active /= {}&lt;br /&gt;
        THEN&lt;br /&gt;
                waiting := (waiting \/ active) ||&lt;br /&gt;
                IF (ready = {}) THEN&lt;br /&gt;
                   active := {}&lt;br /&gt;
                ELSE&lt;br /&gt;
                   ANY pp WHERE pp : ready&lt;br /&gt;
                   THEN&lt;br /&gt;
                       active := {pp} ||&lt;br /&gt;
                       ready := ready - {pp}&lt;br /&gt;
                   END&lt;br /&gt;
                END&lt;br /&gt;
        END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Generating_UML_Sequence_Charts&amp;diff=5959</id>
		<title>Generating UML Sequence Charts</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Generating_UML_Sequence_Charts&amp;diff=5959"/>
		<updated>2025-04-14T13:51:16Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* Installation and Using */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Installation and Using ===&lt;br /&gt;
&lt;br /&gt;
ProB has a new experimental feature to generate a UML sequence chart from the current animation trace using [https://plantuml.com PlantUML].&lt;br /&gt;
The feature is available in ProB CLI, ProB Tcl/Tk and ProB2-UI.&lt;br /&gt;
With ProB2-UI it is also possible to include a sequence chart in a VisB HTML export.&lt;br /&gt;
It currently works for classical B and TLA+ models and you need to copy the [https://plantuml.com/download plantuml.jar]  file to ProB&#039;s lib folder. The file should be named plantuml.jar (without any version numbers).&lt;br /&gt;
&lt;br /&gt;
You can also use the command-line version of ProB to install it&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 probcli --install plantuml&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This should generate output similar to this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Installing component plantuml from https://github.com/plantuml/plantuml/releases/download/v1.2024.7/&lt;br /&gt;
 --&amp;gt; curl -L https://github.com/plantuml/plantuml/releases/download/v1.2024.7/plantuml-epl-1.2024.7.jar -o .../lib/plantuml.jar&lt;br /&gt;
Installation complete&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For ProB2-UI a dialog will pop-up when trying to use the feature giving you instructions on where to put the plantuml.jar file.&lt;br /&gt;
&lt;br /&gt;
=== Using the Command ===&lt;br /&gt;
&lt;br /&gt;
It is available in the Visualize menu of Tcl/Tk:&lt;br /&gt;
&lt;br /&gt;
[[file:ProBUMLSeqChartCmd.png|center||300px]]&lt;br /&gt;
&lt;br /&gt;
The UML sequence chart is also available in ProB2-UI in the Graph &amp;amp; Table Visualisation View accessible in the Visualisation menu.&lt;br /&gt;
&lt;br /&gt;
[[file:ProBUMLSeqChartProB2UICmd.png|center||300px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ProBUMLSeqChartProB2UIDialog.png|center||500px]]&lt;br /&gt;
&lt;br /&gt;
=== Specifying the Actors ===&lt;br /&gt;
&lt;br /&gt;
For every B Operation Op that you want to visualise you need to add a definition&lt;br /&gt;
 SEQUENCE_CHART_Op&lt;br /&gt;
in your DEFINITIONS.&lt;br /&gt;
The definition can take arguments, in which case the actual arguments in the trace are passed to the definition. The definition can take fewer arguments (but not more) than the B operation.&lt;br /&gt;
&lt;br /&gt;
The definition should either return&lt;br /&gt;
* the empty string, meaning this operation should be ignored&lt;br /&gt;
* a couple &amp;lt;tt&amp;gt;(ActorFrom,ActorTo)&amp;lt;/tt&amp;gt; specifying the name of the actor sending the message (ActorFrom) and the one receiving the message (ActorTo). You can use strings or other values (which will be converted to strings).&lt;br /&gt;
* a triple &amp;lt;tt&amp;gt;(ActorFrom,ArrowStyle,ActorTo)&amp;lt;/tt&amp;gt;, where the actors are like above and ArrowStyle is a string representing a valid plantUML arrow.&lt;br /&gt;
* a triple &amp;lt;tt&amp;gt;(ActorFrom,ArrowStyle,ArrowSuffix,ActorTo)&amp;lt;/tt&amp;gt;, where the actors and arrow style are like above and ArrowSuffix is a string representing a valid plantUML arrow suffix.&lt;br /&gt;
* a record &amp;lt;tt&amp;gt;rec(from:ActorFrom,to:ActorTo,arrow:ArrowStyle,suffix:ArrowSuffix)&amp;lt;/tt&amp;gt;. Note that the arrow fields are optional.&lt;br /&gt;
&lt;br /&gt;
Currently these arrow styles are supported:&lt;br /&gt;
* &#039;&#039;&#039;--&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-&amp;gt;x&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-&amp;gt;&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-\\&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;\\\\-&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;//--&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-&amp;gt;o&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;o\\\\--&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;-&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;-&amp;gt;o&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-[#green]&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-[#green]-&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-[#blue]-&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-[#red]-&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-[#red]&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;-[#0000FF]-&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;-&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;--&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Optionally you can add these suffixes:&lt;br /&gt;
* &#039;&#039;&#039;++&#039;&#039;&#039; (activate the target)&lt;br /&gt;
* &#039;&#039;&#039;--&#039;&#039;&#039; (deactivate source)&lt;br /&gt;
* &#039;&#039;&#039;**&#039;&#039;&#039; (create an instance of target)&lt;br /&gt;
* &#039;&#039;&#039;!!&#039;&#039;&#039; (destroy an instance of target)&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
The following diagram can be created using the model below after animating and then using the command above.&lt;br /&gt;
&lt;br /&gt;
[[file:ProBUMLSeqCharScheduler.png|center||300px]]&lt;br /&gt;
&lt;br /&gt;
And here is the well-known scheduler example with example SEQUENCE_CHART definitions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE scheduler_UML&lt;br /&gt;
SETS&lt;br /&gt;
	PID  = {process1,process2,process3}&lt;br /&gt;
VARIABLES active, ready, waiting&lt;br /&gt;
DEFINITIONS&lt;br /&gt;
      &amp;quot;CHOOSE.def&amp;quot;;&lt;br /&gt;
      SEQUENCE_CHART_INITIALISATION == &amp;quot;&amp;quot;; // ignore&lt;br /&gt;
      SEQUENCE_CHART_new(pp) == (&amp;quot;Master&amp;quot;, &amp;quot;--&amp;gt;&amp;quot;,&amp;quot;**&amp;quot;,pp);&lt;br /&gt;
      SEQUENCE_CHART_del(pp) == (&amp;quot;Master&amp;quot;, &amp;quot;--&amp;gt;&amp;quot;,&amp;quot;!!&amp;quot;,pp);&lt;br /&gt;
      SEQUENCE_CHART_ready(pp) == (pp, &amp;quot;--&amp;gt;&amp;quot;,&amp;quot;Master&amp;quot;);&lt;br /&gt;
      SEQUENCE_CHART_swap == (&amp;quot;Master&amp;quot;, &amp;quot;--&amp;gt;&amp;quot;,&amp;quot;--&amp;quot;,CHOOSE(active))&lt;br /&gt;
INVARIANT&lt;br /&gt;
           active &amp;lt;: PID &amp;amp;&lt;br /&gt;
           ready &amp;lt;: PID   &amp;amp;&lt;br /&gt;
           waiting &amp;lt;: PID &amp;amp;&lt;br /&gt;
           (ready /\ waiting) = {} &amp;amp;&lt;br /&gt;
           active /\ (ready \/ waiting) = {} &amp;amp;&lt;br /&gt;
           /*@label &amp;quot;SAF&amp;quot; */ card(active) &amp;lt;= 1 &amp;amp;&lt;br /&gt;
           ((active = {})  =&amp;gt; (ready = {}))&lt;br /&gt;
INITIALISATION&lt;br /&gt;
	active := {} || ready := {} || waiting := {}&lt;br /&gt;
OPERATIONS&lt;br /&gt;
new(pp) =&lt;br /&gt;
	SELECT&lt;br /&gt;
		pp : PID  &amp;amp;&lt;br /&gt;
		pp /: active &amp;amp;&lt;br /&gt;
		pp /: (ready \/ waiting)&lt;br /&gt;
	THEN&lt;br /&gt;
		waiting := (waiting \/ { pp })&lt;br /&gt;
	END;&lt;br /&gt;
del(pp) =&lt;br /&gt;
	SELECT&lt;br /&gt;
		pp : waiting&lt;br /&gt;
	THEN&lt;br /&gt;
		waiting := waiting - {pp}&lt;br /&gt;
	END;&lt;br /&gt;
ready(rr) =&lt;br /&gt;
        SELECT&lt;br /&gt;
                rr : waiting&lt;br /&gt;
        THEN&lt;br /&gt;
                waiting := (waiting - {rr}) ||&lt;br /&gt;
                IF (active = {}) THEN&lt;br /&gt;
                   active := {rr}&lt;br /&gt;
                ELSE&lt;br /&gt;
                   ready := ready \/ {rr}&lt;br /&gt;
                END&lt;br /&gt;
        END;&lt;br /&gt;
swap =&lt;br /&gt;
        SELECT&lt;br /&gt;
                active /= {}&lt;br /&gt;
        THEN&lt;br /&gt;
                waiting := (waiting \/ active) ||&lt;br /&gt;
                IF (ready = {}) THEN&lt;br /&gt;
                   active := {}&lt;br /&gt;
                ELSE&lt;br /&gt;
                   ANY pp WHERE pp : ready&lt;br /&gt;
                   THEN&lt;br /&gt;
                       active := {pp} ||&lt;br /&gt;
                       ready := ready - {pp}&lt;br /&gt;
                   END&lt;br /&gt;
                END&lt;br /&gt;
        END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Rules-DSL&amp;diff=5958</id>
		<title>Rules-DSL</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Rules-DSL&amp;diff=5958"/>
		<updated>2025-04-14T13:45:11Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* Rule Validation with probcli */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== B-Rules DSL ==&lt;br /&gt;
&lt;br /&gt;
The B-Rules domain-specific language (B-Rules DSL) mainly provides operations for data validation. &amp;lt;em&amp;gt;Rules&amp;lt;/em&amp;gt; allow checking for expected properties, while &amp;lt;em&amp;gt;computations&amp;lt;/em&amp;gt; can be used to define and compute variables based on the successful execution of certain rules. Furthermore you can use &amp;lt;em&amp;gt;functions&amp;lt;/em&amp;gt; to compute values multiple times depending on different inputs.&lt;br /&gt;
&lt;br /&gt;
===Setting up a Rules Machine===&lt;br /&gt;
Rules machines are stored in &amp;lt;code&amp;gt;.rmch&amp;lt;/code&amp;gt;-files. The general setup for the machine header is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULES_MACHINE machine_name&lt;br /&gt;
REFERENCES list of rules machines&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The latter allows the inclusion of other rules machines and ordinary B machines that contain only constants, but not yet any other B machines. Below, &amp;lt;code&amp;gt;SETS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;DEFINITIONS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;PROPERTIES&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;CONSTANTS&amp;lt;/code&amp;gt; can be used as in a normal B machine. Note that &amp;lt;code&amp;gt;VARIABLES&amp;lt;/code&amp;gt; are not allowed as they are set by rule based computations.&lt;br /&gt;
&lt;br /&gt;
====Rules====&lt;br /&gt;
Rules can be defined in the &amp;lt;code&amp;gt;OPERATIONS&amp;lt;/code&amp;gt;-section of a rules machine. Depending on whether the expectations are met, a rule returns &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;FAIL&amp;lt;/code&amp;gt;. If a rule fails, additionally provided string messages are returned as counterexamples.&lt;br /&gt;
In the B Rules-DSL a rule has the following structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE rule_name // will be the name of the operation and variable storing the result&lt;br /&gt;
DEPENDS_ON_RULE list of rules&lt;br /&gt;
DEPENDS_ON_COMPUTATION list of computations&lt;br /&gt;
ACTIVATION predicate&lt;br /&gt;
ERROR_TYPES positive number of error types&lt;br /&gt;
BODY&lt;br /&gt;
    arbitrarily many rule bodys (see below)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The specified &amp;lt;code&amp;gt;rule_name&amp;lt;/code&amp;gt; will be the name of the operation and variable storing the result.&lt;br /&gt;
If a rule depends on other rules, it can only be executed if the specified rules have been successfully checked, i.e. their corresponding variables &amp;lt;code&amp;gt;rule_name&amp;lt;/code&amp;gt; have the value &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt;. In addition, rules can depend on computations. In this case, a rule is enabled when the specified computations have been executed. If a rule uses variables that are defined by computations, the corresponding computations are added implicitly as dependencies and do not have to be declared explicitly. Any other preconditions can be specified as an &amp;lt;code&amp;gt;ACTIVATION&amp;lt;/code&amp;gt; predicate. An important note is that the activation predicate is evaluated statically at initialisation and disables the rule if the predicate is false. Activation predicates and dependencies can be omitted if they are not needed.&lt;br /&gt;
&lt;br /&gt;
To use different error types (for example, if a rule has multiple bodies and it is necessary to distinguish between them), the number of error types has to be declared in the rule header.&lt;br /&gt;
Error types are also optional.&lt;br /&gt;
&lt;br /&gt;
The actual rule conditions are specified within the body of a rule, which contains the name and the preconditions.&lt;br /&gt;
A rule succeeds if and only if all rule conditions in its body are satisfied.&lt;br /&gt;
There are two constructs for rule bodies that can be used arbitrarily often in the body of a rule.&lt;br /&gt;
The following is formulated in a positive way, i.e. the execution of the rule leads to &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt; if the conditions in the &amp;lt;code&amp;gt;EXPECT&amp;lt;/code&amp;gt;-part are fulfilled.&lt;br /&gt;
In contrast to the &amp;lt;code&amp;gt;RULE_FAIL&amp;lt;/code&amp;gt; body (see below), in &amp;lt;code&amp;gt;RULE_FORALL&amp;lt;/code&amp;gt; you can obtain success messages (such as counter examples) for successful applications of the rule.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    RULE_FORALL&lt;br /&gt;
        list of identifiers&lt;br /&gt;
    WHERE &lt;br /&gt;
        conditions on identifiers&lt;br /&gt;
    EXPECT&lt;br /&gt;
        conditions that must be fulfilled for this rule&lt;br /&gt;
    ERROR_TYPE&lt;br /&gt;
        number encoding error type, must be in range of error types&lt;br /&gt;
    ON_SUCCESS &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list) or&lt;br /&gt;
        ```${identifier from list}``` (template string)&lt;br /&gt;
    COUNTEREXAMPLE &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list) or&lt;br /&gt;
        ```${identifier from list}``` (template string)&lt;br /&gt;
    END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, a negated rule can be formulated. Here the execution of the rule results in &amp;lt;code&amp;gt;FAIL&amp;lt;/code&amp;gt; if the conditions in the &amp;lt;code&amp;gt;WHEN&amp;lt;/code&amp;gt;-part are fulfilled.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    RULE_FAIL &lt;br /&gt;
        list of identifiers&lt;br /&gt;
    WHEN &lt;br /&gt;
        conditions on identifiers for a failing rule&lt;br /&gt;
    ERROR_TYPE&lt;br /&gt;
        number encoding error type, must be in range of error types&lt;br /&gt;
    COUNTEREXAMPLE &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list)&lt;br /&gt;
    END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Counterexamples are of the type &amp;lt;code&amp;gt;INTEGER &amp;lt;-&amp;gt; STRING&amp;lt;/code&amp;gt;. The integer contains the error type, while the string contains the message of the counterexample.&lt;br /&gt;
&lt;br /&gt;
Also valid for the rules header are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULEID id&lt;br /&gt;
CLASSIFICATION identifier&lt;br /&gt;
TAGS identifier&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;CLASSIFICATION&amp;lt;/code&amp;gt; keyword can be used to group the rules in the [[#Rule_Validation_in_ProB2-UI|HTML validation report]] according to their classification.&lt;br /&gt;
&lt;br /&gt;
====Computations====&lt;br /&gt;
Computations can be used to define variables. As for rules, their activation can depend on further rules, computations or any other predicate specified as an activation condition. Again, the activation condition is evaluated at initialisation and sets the computation status variable to &amp;lt;code&amp;gt;COMPUTATION_DISABLED&amp;lt;/code&amp;gt; if the predicate is false. Furthermore, a &amp;lt;code&amp;gt;DUMMY_VALUE&amp;lt;/code&amp;gt; can be set, which initialises the variable with the specified value instead of the empty set before execution of the computation. This mechanism implies that each variable defined by a computation must be a set of type &amp;lt;code&amp;gt;POW(S)&amp;lt;/code&amp;gt; for any &amp;lt;code&amp;gt;TYPE&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;S&amp;lt;/code&amp;gt;. A computation can be replaced by a previously defined computation if it sets the same variable (of the same type) by using &amp;lt;code&amp;gt;REPLACES&amp;lt;/code&amp;gt;. The general syntax for computations is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
COMPUTATION computation_name&lt;br /&gt;
DEPENDS_ON_RULE list of rules&lt;br /&gt;
DEPENDS_ON_COMPUTATION list of computations&lt;br /&gt;
ACTIVATION predicate&lt;br /&gt;
REPLACES identifier of exactly one computation&lt;br /&gt;
BODY&lt;br /&gt;
    DEFINE variable_name&lt;br /&gt;
        TYPE type of variable&lt;br /&gt;
        DUMMY_VALUE value of variable before execution (initialisation)&lt;br /&gt;
        VALUE value of variable after execution&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Activation predicates, dependencies, and also the dummy value can be omitted if they are not needed. After the execution of a computation, the value of the corresponding variable &amp;lt;code&amp;gt;computation_name&amp;lt;/code&amp;gt; is changed from &amp;lt;code&amp;gt;NOT_EXECUTED&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;EXECUTED&amp;lt;/code&amp;gt;  and the variable &amp;lt;code&amp;gt;variable_name&amp;lt;/code&amp;gt; has the value \texttt{VALUE}. For related computations, it may be useful to use multiple &amp;lt;code&amp;gt;DEFINE&amp;lt;/code&amp;gt; blocks in one computation.&lt;br /&gt;
Separated by &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt;, the body of a computation can contain any number of variable definitions.&lt;br /&gt;
&lt;br /&gt;
====Functions====&lt;br /&gt;
Functions can be called from any rules machine that references the machine containing the function. Depending on input parameters that must fulfil specified preconditions, the functions returns output value(s) that must fulfil optional postconditions. In the body, any B statement can be used to (sequentially) compute the output value.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FUNCTION output &amp;lt;-- function_name(list of input parameters)&lt;br /&gt;
PRECONDITION&lt;br /&gt;
    predicate&lt;br /&gt;
POSTCONDITION&lt;br /&gt;
    predicate&lt;br /&gt;
BODY&lt;br /&gt;
   some B statements&lt;br /&gt;
   output := ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Additional Syntax====&lt;br /&gt;
There are some useful predicates available in rules machines that can be used to check the success or failure of rules. It is also possible to check whether a certain error type was returned by a rule. These are:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SUCCEEDED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 succeeded&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SUCCEEDED_RULE_ERROR_TYPE(rule1,1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 did not fail with error type 1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;GET_RULE_COUNTEREXAMPLES(rule1)&amp;lt;/code&amp;gt;: set of counterexamples of rule1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 failed&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE_ERROR_TYPE(rule1,2)&amp;lt;/code&amp;gt;: TRUE, if check of rule1 failed with error type 2&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE_ALL_ERROR_TYPES(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 failed with all possible error types for rule1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;NOT_CHECKED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if rule1 has not yet been checked&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;DISABLED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if rule1 is disabled (its preconditions are not fulfilled)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another functionality of rules machines are FOR-loops. Their syntax is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FOR variable(s) IN set&lt;br /&gt;
DO&lt;br /&gt;
    operation(s)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
An example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE example_rule&lt;br /&gt;
BODY&lt;br /&gt;
    FOR x,y IN {1 |-&amp;gt; TRUE, 2 |-&amp;gt; FALSE, 3 |-&amp;gt; FALSE} DO &lt;br /&gt;
        RULE_FAIL &lt;br /&gt;
        WHEN y = FALSE&lt;br /&gt;
        COUNTEREXAMPLE STRING_FORMAT(&amp;quot;example_rule_fail: ~w&amp;quot;, x)&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This rule always fails and returns &amp;lt;code&amp;gt;{1 |-&amp;gt; &amp;quot;example_rule_fail: 2&amp;quot;, 1 |-&amp;gt; &amp;quot;example_rule_fail: 3&amp;quot;}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Rule Validation in ProB2-UI===&lt;br /&gt;
Rule validation has been integrated into the ProB2-UI since version 1.2.2 (not yet released).&lt;br /&gt;
It allows convenient execution of rules and computations together with a graphical representation of the results.&lt;br /&gt;
Rules are grouped by their classification and can be additionally filtered by their name, ID, or tags.&lt;br /&gt;
The results can also be exported as an HTML report.&lt;br /&gt;
In addition, dependencies of rules and computations can be visualised as a graph either for all operations or for just one operation (the HTML report and the dependency graph are generated by the ProB Java API and can also be created without ProB2-UI).&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2 UI Rules View.png|500px|ProB2-UI Rules View]]&lt;br /&gt;
&lt;br /&gt;
===Rule Validation with probcli===&lt;br /&gt;
The probcli recognises the option &amp;lt;code&amp;gt;-rule_report &amp;lt;file&amp;gt;&amp;lt;/code&amp;gt; which generates the same HTML/XML validation report as in ProB2-UI for the current animation state.&lt;br /&gt;
The provided file extension is used to determine whether the HTML or the XML version of the report is generated.&lt;br /&gt;
To validate all rules, use this option in combination with &amp;lt;code&amp;gt;-execute_all&amp;lt;/code&amp;gt;.&lt;br /&gt;
There is also a dot visualisation command &amp;quot;rule_dependency graph&amp;quot; that can be used to create a graph of the dependencies of rules and computations (including results of the current state); example call:&lt;br /&gt;
&amp;lt;pre&amp;gt;probcli myMch.mch -execute_all -rule_report myReport.html -dot &amp;quot;rule_dependency_graph&amp;quot; myGraph.pdf&amp;lt;/pre&amp;gt;&lt;br /&gt;
All three export options are also available in ProB Tcl/Tk via the visualization menu.&lt;br /&gt;
Using the special definition &amp;lt;code&amp;gt;RULE_REPORT_CONTEXT&amp;lt;/code&amp;gt; you can include context information about the check in the report (of the type &amp;lt;tt&amp;gt;STRING&amp;lt;/tt&amp;gt;), e.g. the file name of a validated XML file.&lt;br /&gt;
&lt;br /&gt;
===Use Rules for Data Validation===&lt;br /&gt;
The concept of rule validation can be used to validate data from external sources such as CSV or XML files and load the validated data into ProB by successive computations.&lt;br /&gt;
For an XML file, this could look as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULES_MACHINE XML_import&lt;br /&gt;
DEFINITIONS&lt;br /&gt;
    &amp;quot;LibraryXML.def&amp;quot;&lt;br /&gt;
CONSTANTS&lt;br /&gt;
    xml_data&lt;br /&gt;
PROPERTIES&lt;br /&gt;
    xml_data = READ_XML(&amp;quot;xml_file.xml&amp;quot;, &amp;quot;auto&amp;quot;)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now some properties can be validated. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE is_supported_version_of_type_xyz&lt;br /&gt;
ERROR_TYPES 2&lt;br /&gt;
BODY&lt;br /&gt;
    RULE_FAIL e&lt;br /&gt;
    WHEN&lt;br /&gt;
        1 : dom(xml_data) &amp;amp; e = data(1)&#039;element &amp;amp; e /= &amp;quot;xyz&amp;quot;&lt;br /&gt;
    ERROR_TYPE 1 // optional: 1 is standard type&lt;br /&gt;
    COUNTEREXAMPLE&lt;br /&gt;
        STRING_FORMAT(&amp;quot;Error: could not find element &#039;xyz&#039;, was &#039;&amp;quot;^e^&amp;quot;&#039;&amp;quot;)&lt;br /&gt;
    END;&lt;br /&gt;
    RULE_FAIL v&lt;br /&gt;
    WHEN&lt;br /&gt;
        v = xml_data(1)&#039;attributes(&amp;quot;version&amp;quot;) &amp;amp; v /: supported_versions&lt;br /&gt;
    ERROR_TYPE 2&lt;br /&gt;
    COUNTEREXAMPLE&lt;br /&gt;
        &amp;quot;xyz of version &amp;quot;^v^&amp;quot; is currently not supported&amp;quot;&lt;br /&gt;
    END&lt;br /&gt;
END;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Internal Representation===&lt;br /&gt;
Each rules machine is internally translated to an ordinary B machine, which can be accessed as its internal representation.&lt;br /&gt;
Consider the following example rule:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE rule1 BODY RULE_FAIL WHEN bfalse COUNTEREXAMPLE &amp;quot;&amp;quot; END END;&lt;br /&gt;
&lt;br /&gt;
COMPUTATION comp1&lt;br /&gt;
BODY&lt;br /&gt;
    DEFINE x&lt;br /&gt;
    TYPE POW(INTEGER)&lt;br /&gt;
    VALUE 1..10&lt;br /&gt;
    END&lt;br /&gt;
END;&lt;br /&gt;
&lt;br /&gt;
RULE rule2&lt;br /&gt;
DEPENDS_ON_RULE rule1&lt;br /&gt;
// DEPENDS_ON_COMPUTATION comp1&lt;br /&gt;
BODY&lt;br /&gt;
    RULE_FORALL i&lt;br /&gt;
        WHERE i : 1..10&lt;br /&gt;
        EXPECT i &amp;gt; 5&lt;br /&gt;
        COUNTEREXAMPLE STRING_FORMAT(&amp;quot;~w &amp;lt;= 5&amp;quot;, i)&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Its internal representation in classical B is the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
`$RESULT`,`$COUNTEREXAMPLES` &amp;lt;-- rule1 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        rule1 = &amp;quot;NOT_CHECKED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
      rule1,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;SUCCESS&amp;quot;,&amp;quot;SUCCESS&amp;quot;,{}&lt;br /&gt;
    END;&lt;br /&gt;
  &lt;br /&gt;
  comp1 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        comp1 = &amp;quot;NOT_EXECUTED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
      x,comp1 := FORCE(1 .. 10),&amp;quot;EXECUTED&amp;quot;&lt;br /&gt;
    END;&lt;br /&gt;
  &lt;br /&gt;
  `$RESULT`,`$COUNTEREXAMPLES` &amp;lt;-- rule2 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        rule2 = &amp;quot;NOT_CHECKED&amp;quot;&lt;br /&gt;
      &amp;amp; rule1 = &amp;quot;SUCCESS&amp;quot;&lt;br /&gt;
      &amp;amp; comp1 = &amp;quot;EXECUTED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
        rule2,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;SUCCESS&amp;quot;,&amp;quot;SUCCESS&amp;quot;,{} ;&lt;br /&gt;
        VAR `$ResultTuple`,`$ResultStrings`&lt;br /&gt;
        IN&lt;br /&gt;
            `$ResultTuple` := FORCE({i|i : x &amp;amp; not(i &amp;gt; 5)}) ;&lt;br /&gt;
            `$ResultStrings` := FORCE({`$String`|`$String` : STRING &amp;amp; #i.(i : `$ResultTuple` &amp;amp; `$String` = FORMAT_TO_STRING(&amp;quot;~w &amp;lt;= 5&amp;quot;,[TO_STRING(i)]))});&lt;br /&gt;
              rule2_Counterexamples := rule2_Counterexamples \/ {1} * `$ResultStrings` ;&lt;br /&gt;
          IF `$ResultTuple` /= {} THEN&lt;br /&gt;
              rule2,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;FAIL&amp;quot;,&amp;quot;FAIL&amp;quot;,rule2_Counterexamples&lt;br /&gt;
          END&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Observe that the implicit dependency of rule2 on comp1 (rule2 uses its variable x) is detected automatically without explicit declaration.&lt;br /&gt;
&lt;br /&gt;
===Include Rules Machines into other Projects===&lt;br /&gt;
Currently, it is not possible to include rules machines directly into any other machines. Instead, use the rules machine at the top of the hierarchy (of the rules project) and save the internal generated machine as &amp;lt;code&amp;gt;.mch&amp;lt;/code&amp;gt;-file. After changing the machine name accordingly, the rules can be included and used via this machine.&lt;br /&gt;
Note that in this case it is not possible to perform Rules-DSL specific methods of the ProB Java API (like detailed information about rule results).&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Rules-DSL&amp;diff=5957</id>
		<title>Rules-DSL</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Rules-DSL&amp;diff=5957"/>
		<updated>2025-04-14T13:08:12Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* Rule Validation with probcli */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== B-Rules DSL ==&lt;br /&gt;
&lt;br /&gt;
The B-Rules domain-specific language (B-Rules DSL) mainly provides operations for data validation. &amp;lt;em&amp;gt;Rules&amp;lt;/em&amp;gt; allow checking for expected properties, while &amp;lt;em&amp;gt;computations&amp;lt;/em&amp;gt; can be used to define and compute variables based on the successful execution of certain rules. Furthermore you can use &amp;lt;em&amp;gt;functions&amp;lt;/em&amp;gt; to compute values multiple times depending on different inputs.&lt;br /&gt;
&lt;br /&gt;
===Setting up a Rules Machine===&lt;br /&gt;
Rules machines are stored in &amp;lt;code&amp;gt;.rmch&amp;lt;/code&amp;gt;-files. The general setup for the machine header is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULES_MACHINE machine_name&lt;br /&gt;
REFERENCES list of rules machines&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The latter allows the inclusion of other rules machines and ordinary B machines that contain only constants, but not yet any other B machines. Below, &amp;lt;code&amp;gt;SETS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;DEFINITIONS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;PROPERTIES&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;CONSTANTS&amp;lt;/code&amp;gt; can be used as in a normal B machine. Note that &amp;lt;code&amp;gt;VARIABLES&amp;lt;/code&amp;gt; are not allowed as they are set by rule based computations.&lt;br /&gt;
&lt;br /&gt;
====Rules====&lt;br /&gt;
Rules can be defined in the &amp;lt;code&amp;gt;OPERATIONS&amp;lt;/code&amp;gt;-section of a rules machine. Depending on whether the expectations are met, a rule returns &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;FAIL&amp;lt;/code&amp;gt;. If a rule fails, additionally provided string messages are returned as counterexamples.&lt;br /&gt;
In the B Rules-DSL a rule has the following structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE rule_name // will be the name of the operation and variable storing the result&lt;br /&gt;
DEPENDS_ON_RULE list of rules&lt;br /&gt;
DEPENDS_ON_COMPUTATION list of computations&lt;br /&gt;
ACTIVATION predicate&lt;br /&gt;
ERROR_TYPES positive number of error types&lt;br /&gt;
BODY&lt;br /&gt;
    arbitrarily many rule bodys (see below)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The specified &amp;lt;code&amp;gt;rule_name&amp;lt;/code&amp;gt; will be the name of the operation and variable storing the result.&lt;br /&gt;
If a rule depends on other rules, it can only be executed if the specified rules have been successfully checked, i.e. their corresponding variables &amp;lt;code&amp;gt;rule_name&amp;lt;/code&amp;gt; have the value &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt;. In addition, rules can depend on computations. In this case, a rule is enabled when the specified computations have been executed. If a rule uses variables that are defined by computations, the corresponding computations are added implicitly as dependencies and do not have to be declared explicitly. Any other preconditions can be specified as an &amp;lt;code&amp;gt;ACTIVATION&amp;lt;/code&amp;gt; predicate. An important note is that the activation predicate is evaluated statically at initialisation and disables the rule if the predicate is false. Activation predicates and dependencies can be omitted if they are not needed.&lt;br /&gt;
&lt;br /&gt;
To use different error types (for example, if a rule has multiple bodies and it is necessary to distinguish between them), the number of error types has to be declared in the rule header.&lt;br /&gt;
Error types are also optional.&lt;br /&gt;
&lt;br /&gt;
The actual rule conditions are specified within the body of a rule, which contains the name and the preconditions.&lt;br /&gt;
A rule succeeds if and only if all rule conditions in its body are satisfied.&lt;br /&gt;
There are two constructs for rule bodies that can be used arbitrarily often in the body of a rule.&lt;br /&gt;
The following is formulated in a positive way, i.e. the execution of the rule leads to &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt; if the conditions in the &amp;lt;code&amp;gt;EXPECT&amp;lt;/code&amp;gt;-part are fulfilled.&lt;br /&gt;
In contrast to the &amp;lt;code&amp;gt;RULE_FAIL&amp;lt;/code&amp;gt; body (see below), in &amp;lt;code&amp;gt;RULE_FORALL&amp;lt;/code&amp;gt; you can obtain success messages (such as counter examples) for successful applications of the rule.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    RULE_FORALL&lt;br /&gt;
        list of identifiers&lt;br /&gt;
    WHERE &lt;br /&gt;
        conditions on identifiers&lt;br /&gt;
    EXPECT&lt;br /&gt;
        conditions that must be fulfilled for this rule&lt;br /&gt;
    ERROR_TYPE&lt;br /&gt;
        number encoding error type, must be in range of error types&lt;br /&gt;
    ON_SUCCESS &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list) or&lt;br /&gt;
        ```${identifier from list}``` (template string)&lt;br /&gt;
    COUNTEREXAMPLE &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list) or&lt;br /&gt;
        ```${identifier from list}``` (template string)&lt;br /&gt;
    END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, a negated rule can be formulated. Here the execution of the rule results in &amp;lt;code&amp;gt;FAIL&amp;lt;/code&amp;gt; if the conditions in the &amp;lt;code&amp;gt;WHEN&amp;lt;/code&amp;gt;-part are fulfilled.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    RULE_FAIL &lt;br /&gt;
        list of identifiers&lt;br /&gt;
    WHEN &lt;br /&gt;
        conditions on identifiers for a failing rule&lt;br /&gt;
    ERROR_TYPE&lt;br /&gt;
        number encoding error type, must be in range of error types&lt;br /&gt;
    COUNTEREXAMPLE &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list)&lt;br /&gt;
    END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Counterexamples are of the type &amp;lt;code&amp;gt;INTEGER &amp;lt;-&amp;gt; STRING&amp;lt;/code&amp;gt;. The integer contains the error type, while the string contains the message of the counterexample.&lt;br /&gt;
&lt;br /&gt;
Also valid for the rules header are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULEID id&lt;br /&gt;
CLASSIFICATION identifier&lt;br /&gt;
TAGS identifier&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;CLASSIFICATION&amp;lt;/code&amp;gt; keyword can be used to group the rules in the [[#Rule_Validation_in_ProB2-UI|HTML validation report]] according to their classification.&lt;br /&gt;
&lt;br /&gt;
====Computations====&lt;br /&gt;
Computations can be used to define variables. As for rules, their activation can depend on further rules, computations or any other predicate specified as an activation condition. Again, the activation condition is evaluated at initialisation and sets the computation status variable to &amp;lt;code&amp;gt;COMPUTATION_DISABLED&amp;lt;/code&amp;gt; if the predicate is false. Furthermore, a &amp;lt;code&amp;gt;DUMMY_VALUE&amp;lt;/code&amp;gt; can be set, which initialises the variable with the specified value instead of the empty set before execution of the computation. This mechanism implies that each variable defined by a computation must be a set of type &amp;lt;code&amp;gt;POW(S)&amp;lt;/code&amp;gt; for any &amp;lt;code&amp;gt;TYPE&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;S&amp;lt;/code&amp;gt;. A computation can be replaced by a previously defined computation if it sets the same variable (of the same type) by using &amp;lt;code&amp;gt;REPLACES&amp;lt;/code&amp;gt;. The general syntax for computations is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
COMPUTATION computation_name&lt;br /&gt;
DEPENDS_ON_RULE list of rules&lt;br /&gt;
DEPENDS_ON_COMPUTATION list of computations&lt;br /&gt;
ACTIVATION predicate&lt;br /&gt;
REPLACES identifier of exactly one computation&lt;br /&gt;
BODY&lt;br /&gt;
    DEFINE variable_name&lt;br /&gt;
        TYPE type of variable&lt;br /&gt;
        DUMMY_VALUE value of variable before execution (initialisation)&lt;br /&gt;
        VALUE value of variable after execution&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Activation predicates, dependencies, and also the dummy value can be omitted if they are not needed. After the execution of a computation, the value of the corresponding variable &amp;lt;code&amp;gt;computation_name&amp;lt;/code&amp;gt; is changed from &amp;lt;code&amp;gt;NOT_EXECUTED&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;EXECUTED&amp;lt;/code&amp;gt;  and the variable &amp;lt;code&amp;gt;variable_name&amp;lt;/code&amp;gt; has the value \texttt{VALUE}. For related computations, it may be useful to use multiple &amp;lt;code&amp;gt;DEFINE&amp;lt;/code&amp;gt; blocks in one computation.&lt;br /&gt;
Separated by &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt;, the body of a computation can contain any number of variable definitions.&lt;br /&gt;
&lt;br /&gt;
====Functions====&lt;br /&gt;
Functions can be called from any rules machine that references the machine containing the function. Depending on input parameters that must fulfil specified preconditions, the functions returns output value(s) that must fulfil optional postconditions. In the body, any B statement can be used to (sequentially) compute the output value.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FUNCTION output &amp;lt;-- function_name(list of input parameters)&lt;br /&gt;
PRECONDITION&lt;br /&gt;
    predicate&lt;br /&gt;
POSTCONDITION&lt;br /&gt;
    predicate&lt;br /&gt;
BODY&lt;br /&gt;
   some B statements&lt;br /&gt;
   output := ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Additional Syntax====&lt;br /&gt;
There are some useful predicates available in rules machines that can be used to check the success or failure of rules. It is also possible to check whether a certain error type was returned by a rule. These are:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SUCCEEDED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 succeeded&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SUCCEEDED_RULE_ERROR_TYPE(rule1,1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 did not fail with error type 1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;GET_RULE_COUNTEREXAMPLES(rule1)&amp;lt;/code&amp;gt;: set of counterexamples of rule1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 failed&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE_ERROR_TYPE(rule1,2)&amp;lt;/code&amp;gt;: TRUE, if check of rule1 failed with error type 2&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE_ALL_ERROR_TYPES(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 failed with all possible error types for rule1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;NOT_CHECKED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if rule1 has not yet been checked&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;DISABLED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if rule1 is disabled (its preconditions are not fulfilled)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another functionality of rules machines are FOR-loops. Their syntax is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FOR variable(s) IN set&lt;br /&gt;
DO&lt;br /&gt;
    operation(s)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
An example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE example_rule&lt;br /&gt;
BODY&lt;br /&gt;
    FOR x,y IN {1 |-&amp;gt; TRUE, 2 |-&amp;gt; FALSE, 3 |-&amp;gt; FALSE} DO &lt;br /&gt;
        RULE_FAIL &lt;br /&gt;
        WHEN y = FALSE&lt;br /&gt;
        COUNTEREXAMPLE STRING_FORMAT(&amp;quot;example_rule_fail: ~w&amp;quot;, x)&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This rule always fails and returns &amp;lt;code&amp;gt;{1 |-&amp;gt; &amp;quot;example_rule_fail: 2&amp;quot;, 1 |-&amp;gt; &amp;quot;example_rule_fail: 3&amp;quot;}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Rule Validation in ProB2-UI===&lt;br /&gt;
Rule validation has been integrated into the ProB2-UI since version 1.2.2 (not yet released).&lt;br /&gt;
It allows convenient execution of rules and computations together with a graphical representation of the results.&lt;br /&gt;
Rules are grouped by their classification and can be additionally filtered by their name, ID, or tags.&lt;br /&gt;
The results can also be exported as an HTML report.&lt;br /&gt;
In addition, dependencies of rules and computations can be visualised as a graph either for all operations or for just one operation (the HTML report and the dependency graph are generated by the ProB Java API and can also be created without ProB2-UI).&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2 UI Rules View.png|500px|ProB2-UI Rules View]]&lt;br /&gt;
&lt;br /&gt;
===Rule Validation with probcli===&lt;br /&gt;
The probcli recognises the option &amp;lt;code&amp;gt;-rule_report &amp;lt;file&amp;gt;&amp;lt;/code&amp;gt; which generates the same HTML/XML validation report as in ProB2-UI for the current animation state.&lt;br /&gt;
The provided file extension is used to determine whether the HTML or the XML version of the report is generated.&lt;br /&gt;
To validate all rules, use this option in combination with &amp;lt;code&amp;gt;-execute_all&amp;lt;/code&amp;gt;.&lt;br /&gt;
Both report options are also available in ProB Tcl/Tk via the visualization menu.&lt;br /&gt;
Using the special definition &amp;lt;code&amp;gt;RULE_REPORT_CONTEXT&amp;lt;/code&amp;gt; you can include context information about the check in the report (of the type &amp;lt;tt&amp;gt;STRING&amp;lt;/tt&amp;gt;), e.g. the file name of a validated XML file.&lt;br /&gt;
&lt;br /&gt;
===Use Rules for Data Validation===&lt;br /&gt;
The concept of rule validation can be used to validate data from external sources such as CSV or XML files and load the validated data into ProB by successive computations.&lt;br /&gt;
For an XML file, this could look as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULES_MACHINE XML_import&lt;br /&gt;
DEFINITIONS&lt;br /&gt;
    &amp;quot;LibraryXML.def&amp;quot;&lt;br /&gt;
CONSTANTS&lt;br /&gt;
    xml_data&lt;br /&gt;
PROPERTIES&lt;br /&gt;
    xml_data = READ_XML(&amp;quot;xml_file.xml&amp;quot;, &amp;quot;auto&amp;quot;)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now some properties can be validated. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE is_supported_version_of_type_xyz&lt;br /&gt;
ERROR_TYPES 2&lt;br /&gt;
BODY&lt;br /&gt;
    RULE_FAIL e&lt;br /&gt;
    WHEN&lt;br /&gt;
        1 : dom(xml_data) &amp;amp; e = data(1)&#039;element &amp;amp; e /= &amp;quot;xyz&amp;quot;&lt;br /&gt;
    ERROR_TYPE 1 // optional: 1 is standard type&lt;br /&gt;
    COUNTEREXAMPLE&lt;br /&gt;
        STRING_FORMAT(&amp;quot;Error: could not find element &#039;xyz&#039;, was &#039;&amp;quot;^e^&amp;quot;&#039;&amp;quot;)&lt;br /&gt;
    END;&lt;br /&gt;
    RULE_FAIL v&lt;br /&gt;
    WHEN&lt;br /&gt;
        v = xml_data(1)&#039;attributes(&amp;quot;version&amp;quot;) &amp;amp; v /: supported_versions&lt;br /&gt;
    ERROR_TYPE 2&lt;br /&gt;
    COUNTEREXAMPLE&lt;br /&gt;
        &amp;quot;xyz of version &amp;quot;^v^&amp;quot; is currently not supported&amp;quot;&lt;br /&gt;
    END&lt;br /&gt;
END;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Internal Representation===&lt;br /&gt;
Each rules machine is internally translated to an ordinary B machine, which can be accessed as its internal representation.&lt;br /&gt;
Consider the following example rule:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE rule1 BODY RULE_FAIL WHEN bfalse COUNTEREXAMPLE &amp;quot;&amp;quot; END END;&lt;br /&gt;
&lt;br /&gt;
COMPUTATION comp1&lt;br /&gt;
BODY&lt;br /&gt;
    DEFINE x&lt;br /&gt;
    TYPE POW(INTEGER)&lt;br /&gt;
    VALUE 1..10&lt;br /&gt;
    END&lt;br /&gt;
END;&lt;br /&gt;
&lt;br /&gt;
RULE rule2&lt;br /&gt;
DEPENDS_ON_RULE rule1&lt;br /&gt;
// DEPENDS_ON_COMPUTATION comp1&lt;br /&gt;
BODY&lt;br /&gt;
    RULE_FORALL i&lt;br /&gt;
        WHERE i : 1..10&lt;br /&gt;
        EXPECT i &amp;gt; 5&lt;br /&gt;
        COUNTEREXAMPLE STRING_FORMAT(&amp;quot;~w &amp;lt;= 5&amp;quot;, i)&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Its internal representation in classical B is the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
`$RESULT`,`$COUNTEREXAMPLES` &amp;lt;-- rule1 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        rule1 = &amp;quot;NOT_CHECKED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
      rule1,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;SUCCESS&amp;quot;,&amp;quot;SUCCESS&amp;quot;,{}&lt;br /&gt;
    END;&lt;br /&gt;
  &lt;br /&gt;
  comp1 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        comp1 = &amp;quot;NOT_EXECUTED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
      x,comp1 := FORCE(1 .. 10),&amp;quot;EXECUTED&amp;quot;&lt;br /&gt;
    END;&lt;br /&gt;
  &lt;br /&gt;
  `$RESULT`,`$COUNTEREXAMPLES` &amp;lt;-- rule2 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        rule2 = &amp;quot;NOT_CHECKED&amp;quot;&lt;br /&gt;
      &amp;amp; rule1 = &amp;quot;SUCCESS&amp;quot;&lt;br /&gt;
      &amp;amp; comp1 = &amp;quot;EXECUTED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
        rule2,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;SUCCESS&amp;quot;,&amp;quot;SUCCESS&amp;quot;,{} ;&lt;br /&gt;
        VAR `$ResultTuple`,`$ResultStrings`&lt;br /&gt;
        IN&lt;br /&gt;
            `$ResultTuple` := FORCE({i|i : x &amp;amp; not(i &amp;gt; 5)}) ;&lt;br /&gt;
            `$ResultStrings` := FORCE({`$String`|`$String` : STRING &amp;amp; #i.(i : `$ResultTuple` &amp;amp; `$String` = FORMAT_TO_STRING(&amp;quot;~w &amp;lt;= 5&amp;quot;,[TO_STRING(i)]))});&lt;br /&gt;
              rule2_Counterexamples := rule2_Counterexamples \/ {1} * `$ResultStrings` ;&lt;br /&gt;
          IF `$ResultTuple` /= {} THEN&lt;br /&gt;
              rule2,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;FAIL&amp;quot;,&amp;quot;FAIL&amp;quot;,rule2_Counterexamples&lt;br /&gt;
          END&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Observe that the implicit dependency of rule2 on comp1 (rule2 uses its variable x) is detected automatically without explicit declaration.&lt;br /&gt;
&lt;br /&gt;
===Include Rules Machines into other Projects===&lt;br /&gt;
Currently, it is not possible to include rules machines directly into any other machines. Instead, use the rules machine at the top of the hierarchy (of the rules project) and save the internal generated machine as &amp;lt;code&amp;gt;.mch&amp;lt;/code&amp;gt;-file. After changing the machine name accordingly, the rules can be included and used via this machine.&lt;br /&gt;
Note that in this case it is not possible to perform Rules-DSL specific methods of the ProB Java API (like detailed information about rule results).&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Using_the_Command-Line_Version_of_ProB&amp;diff=5956</id>
		<title>Using the Command-Line Version of ProB</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Using_the_Command-Line_Version_of_ProB&amp;diff=5956"/>
		<updated>2025-04-14T12:41:53Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* -rule_report  */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
[[Category:ProB Cli]]&lt;br /&gt;
&lt;br /&gt;
The command-line version of ProB, called &amp;lt;b&amp;gt;probcli&amp;lt;/b&amp;gt;, offers many of the features of the standalone Tcl/Tk Version via the command-line. As such, you can run ProB from your shell scripts or in your Makefiles.&lt;br /&gt;
These pages refer to version 1.6 of ProB. Some features are only available in the nightly build of ProB. You can run &amp;lt;tt&amp;gt;probcli –help&amp;lt;/tt&amp;gt; to find out which commands are supported by your version of ProB. For Bash users we provide [[Bash Completion|command completion]] support.&lt;br /&gt;
&lt;br /&gt;
Note: the order of commands is not relevant for &amp;lt;tt&amp;gt;probcli&amp;lt;/tt&amp;gt; (except within groups of commands such as &amp;lt;tt&amp;gt;-p MAXINT 127&amp;lt;/tt&amp;gt;). Any argument that is not recognised by &amp;lt;tt&amp;gt;probcli&amp;lt;/tt&amp;gt; is treated as a filename to be analysed.&lt;br /&gt;
&lt;br /&gt;
[[file:ProBTerminalizerDemo.gif|center||600px]]&lt;br /&gt;
&lt;br /&gt;
== Conventions used ==&lt;br /&gt;
&lt;br /&gt;
The following conventions are used in this guide:&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;10&amp;quot;&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &amp;lt;replaceme&amp;gt;&lt;br /&gt;
| All values that should be replaced with some value are shown withing &amp;lt; &amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | line breaks&lt;br /&gt;
| Command synopsis for command may be broken up on several lines. When typing commands enter all option on the same line.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;probcli [--help]&lt;br /&gt;
&amp;lt;filename&amp;gt; [ &amp;lt;options&amp;gt; ]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The underscore within all options can as of version 1.5.1-beta7 be replaced with dashes. Also, all commands can either be typed with single leading dashes or double leading dashes.&lt;br /&gt;
For example, all of the following commands have the same effect:&lt;br /&gt;
 probcli M.mch -model_check&lt;br /&gt;
 probcli M.mch -model-check&lt;br /&gt;
 probcli M.mch --model_check&lt;br /&gt;
 probcli M.mch --model-check&lt;br /&gt;
&lt;br /&gt;
== Options ==&lt;br /&gt;
&lt;br /&gt;
=== -mc &amp;lt;nr&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| model check; checking at most &amp;lt;nr&amp;gt; states&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
  probcli my.mch -mc 100&lt;br /&gt;
&lt;br /&gt;
Note: with a value of nr=1 ProB will only inspect the &amp;quot;virtual&amp;quot; root node (and compute its outgoing transitions).&lt;br /&gt;
Also see the related options &amp;lt;tt&amp;gt;-nodead, -noinv, -nogoal, -noass&amp;lt;/tt&amp;gt; to influence which kinds of errors are reported by &amp;lt;tt&amp;gt;-mc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
You can also set a target goal predicate using the &amp;lt;tt&amp;gt;-goal &amp;quot;PRED&amp;quot;&amp;lt;/tt&amp;gt; command and limit the scope of the model checking using the &amp;lt;tt&amp;gt;-scope &amp;quot;PRED&amp;quot;&amp;lt;/tt&amp;gt; command. &lt;br /&gt;
&lt;br /&gt;
=== -model_check ===&lt;br /&gt;
&lt;br /&gt;
The same as &amp;lt;tt&amp;gt;-mc&amp;lt;/tt&amp;gt; but without a limit on the number of nodes checked.&lt;br /&gt;
ProB will run until the entire state space is explored.&lt;br /&gt;
&lt;br /&gt;
=== -no&amp;lt;x&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| restrict errors reported by model checking (-mc), TLC model checking (-mc_with_tlc), animation (-animate) and execution (-execute) with &amp;lt;x&amp;gt;=dead,inv,goal,ass&lt;br /&gt;
* -nodead : do not report deadlocks&lt;br /&gt;
* -noinv : do not report invariant violations&lt;br /&gt;
* -nogoal : do not stop if a state satisfying the GOAL predicate has been found&lt;br /&gt;
* -noass : do not report assertion violations&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
  probcli my.mch -mc 1000 -nodead -nogoal&lt;br /&gt;
&lt;br /&gt;
=== -disable_timeout ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| turn off ProB&#039;s timeout mechanism, e.g., for computing enabled operations and invariant checking; this can sometimes speed up model checking (-mc or -model_check) and animation (-animate). Available as of version 1.5.1-beta7.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
  probcli my.mch -model-check -disable-timeout&lt;br /&gt;
&lt;br /&gt;
=== -bf ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| proceed breadth-first during model checking&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
  probcli my.mch -bf -mc 1000&lt;br /&gt;
&lt;br /&gt;
=== -df ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| proceed depth-first during model checking&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
  probcli my.mch -df -mc 1000&lt;br /&gt;
&lt;br /&gt;
=== -mc_mode &amp;lt;M&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| influence how the model checker proceeds. Available as of version 1.5.1. Supersedes the &amp;lt;tt&amp;gt;-df&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;-bf&amp;lt;/tt&amp;gt; switches.&lt;br /&gt;
Possible values for the mode &amp;lt;M&amp;gt; are: &amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;df&amp;lt;/tt&amp;gt; (depth-first traversal),&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;bf&amp;lt;/tt&amp;gt; (breadth-first traversal),&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;mixed&amp;lt;/tt&amp;gt; (mixed depth-first / breadth-first traversal with random choice; currently the default),&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;random&amp;lt;/tt&amp;gt; (choosing next node to process completely at random), &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;hash&amp;lt;/tt&amp;gt; (similar to random, but uses the Prolog hash function of a node instead of a random number generator),&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;heuristic&amp;lt;/tt&amp;gt; (try and use &amp;lt;tt&amp;gt;HEURISTIC_FUNCTION&amp;lt;/tt&amp;gt; provided by user in &amp;lt;tt&amp;gt;DEFINITIONS&amp;lt;/tt&amp;gt; clause). Some explanations can be found [[Blocks_World_(Directed_Model_Checking)|in an example about directed model checking]].&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;out_degree_hash&amp;lt;/tt&amp;gt; (prioritise nodes with fewer outgoing transitions; mainly useful for deadlock checking)&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
  probcli my.mch -model_check -mc_mode random&lt;br /&gt;
&lt;br /&gt;
=== --timeout &amp;lt;N&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Global timeout in ms for model checking and refinement checking. &lt;br /&gt;
This does not influence the timeout used for computing individual transitions/operations.&lt;br /&gt;
This has to be set with the -p TIME_OUT &amp;lt;N&amp;gt;. Note that the &amp;lt;tt&amp;gt;TIME_OUT&amp;lt;/tt&amp;gt; preference also influences other computations, such as invariant checking or static assertion checking, where it is multiplied by a factor. See the description of the -p option.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -timeout 10000&lt;br /&gt;
&lt;br /&gt;
=== -t ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| trace check (associated .trace file must exist)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -t&lt;br /&gt;
&lt;br /&gt;
=== -init ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| initialise specification&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -init&lt;br /&gt;
 nr_of_components(1)&lt;br /&gt;
 % checking_component_properties(1,[])&lt;br /&gt;
 % enumerating_constants_without_constraints([typedval(fd(_24428,ID),global(ID),iv)])&lt;br /&gt;
 % grounding_wait_flags&lt;br /&gt;
 grounding_component(1)&lt;br /&gt;
 grounding_component(2)&lt;br /&gt;
 % found_enumeration_of_constants(0,2)&lt;br /&gt;
 % backtrack(found_enumeration_of_constants(0,2))&lt;br /&gt;
 % found_enumeration_of_constants(0,1)&lt;br /&gt;
 % backtrack(found_enumeration_of_constants(0,1))&lt;br /&gt;
 &amp;lt;- 0: SETUP_CONSTANTS :: root&lt;br /&gt;
 % Could not set up constants with parameters from trace file.&lt;br /&gt;
 % Will attempt any possible initialisation of constants.&lt;br /&gt;
  | 0: SETUP_CONSTANTS success --&amp;gt;0&lt;br /&gt;
  - &amp;lt;- 1: INITIALISATION :: 0&lt;br /&gt;
 % Could not initialise with parameters from trace file.&lt;br /&gt;
 % Will attempt any possible initialisation.&lt;br /&gt;
 ALL OPERATIONS COVERED&lt;br /&gt;
  -  | 1: INITIALISATION success --&amp;gt;2&lt;br /&gt;
  -  - SUCCESS&lt;br /&gt;
&lt;br /&gt;
=== -cbc &amp;lt;OPNAME&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| constraint-based invariant checking for an operation (also use &amp;lt;OPNAME&amp;gt;=all)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -cbc all&lt;br /&gt;
&lt;br /&gt;
=== -cbc_deadlock ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Perform constraint-based deadlock checking (also use -cbc_deadlock_pred PRED)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This will try to find a state which satisfies the invariant and properties and where no operation/event is enabled.&lt;br /&gt;
Note: if ProB finds a counter example then the machine cannot be proven to be deadlock free. However, the particular state may not be reachable from the initial state(s). If you want to find a reachable deadlock you have to use the model checker.&lt;br /&gt;
&lt;br /&gt;
=== -cbc_deadlock_pred &amp;lt;PRED&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Constraint-based deadlock finding given a predicate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is like -cbc_deadlock but you provide an additional predicate. ProB will only find deadlocks which also make this predicate true.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch  -cbc_deadlock_pred &amp;quot;n=15&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== -cbc_assertions ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Constraint-based checking of assertions on constants&lt;br /&gt;
|}&lt;br /&gt;
This will try and find a solution for the constants which make an assertion (on constants) false.&lt;br /&gt;
&lt;br /&gt;
You can use the extra command &amp;lt;tt&amp;gt;-cbc_output_file FILE&amp;lt;/tt&amp;gt; to write the result of this check to a file.&lt;br /&gt;
You can also use the extra command &amp;lt;tt&amp;gt;-cbc_option contradiction_check&amp;lt;/tt&amp;gt; to ask ProB to check if there is a contradiction in the properties (in case the check did not find a counter-example to the assertions). The extra command &amp;lt;tt&amp;gt;-cbc_option unsat_core&amp;lt;/tt&amp;gt; tells ProB to compute the unsatisfiable core in case a proof the assertions was found.&lt;br /&gt;
Note that the &amp;lt;tt&amp;gt;TIME_OUT&amp;lt;/tt&amp;gt; preference is multiplied by 10 for this command.&lt;br /&gt;
&lt;br /&gt;
There are various variations of this command:&lt;br /&gt;
 -cbc_assertions_proof&lt;br /&gt;
 -cbc_assertions_tautology_proof &lt;br /&gt;
Both commands do not allow enumeration warnings to occur.&lt;br /&gt;
The latter command  ignores the PROPERTIES and tries to check whether the ASSERTION(s) are tautologies.&lt;br /&gt;
Both commands can be useful to use ProB as a Prover/Disprover (as is done in Atelier-B 4.3).&lt;br /&gt;
&lt;br /&gt;
=== -cbc_sequence &amp;lt;SEQ&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Constraint-based searching for a sequence of operation names (separated by semicolons)&lt;br /&gt;
|}&lt;br /&gt;
This will try and find a solution for the constants, initial variable values and parameters which make execution of the given sequence of operations possible.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch  -cbc_sequence &amp;quot;op1;op2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== -strict ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| raise error and stop probcli if anything unexpected happens, e.g., if model checking finds a counter example or trace checking fails or any unexpected error happens&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -t -strict&lt;br /&gt;
&lt;br /&gt;
=== -expcterr &amp;lt;ERR&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| expect error to occur (&amp;lt;ERR&amp;gt;=cbc,mc,ltl,...)&lt;br /&gt;
Tell ProB that you expect a certain error to occur. Mainly useful for regression tests (in conjunction with the -strict option).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli examples/B/Benchmarks/CarlaTravelAgencyErr.mch -mc 1000 -expcterr invariant_violation -strict&lt;br /&gt;
&lt;br /&gt;
=== -animate &amp;lt;Nr&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| random animation (max Nr steps)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Animates the machine randomly, maximally Nr of steps. It will stop if a deadlock is reached and report an error. You can also use the command &amp;lt;tt&amp;gt;-animate_all&amp;lt;/tt&amp;gt;, which will only stop at a deadlock (and not report an error). Be careful: &amp;lt;tt&amp;gt;-animate_all&amp;lt;/tt&amp;gt; could run forever.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -animate 100&lt;br /&gt;
&lt;br /&gt;
=== -execute &amp;lt;Nr&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| execution (max Nr steps)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Executes the &amp;quot;first&amp;quot; enabled operation of a machine, maximally Nr of steps. It will stop if a deadlock is reached and report an error. You can also use the command &amp;lt;tt&amp;gt;-execute_all&amp;lt;/tt&amp;gt;, which will only stop at a deadlock (and not report an error). Be careful: &amp;lt;tt&amp;gt;-execute_all&amp;lt;/tt&amp;gt; could run forever.&lt;br /&gt;
&lt;br /&gt;
In contrast to -animate, -execute will&lt;br /&gt;
* always choose the first enabled operation it finds and stop searching for further enabled operations in that state (-animate will compute all enabled operations up to the limit set by the &amp;lt;tt&amp;gt;MAX_OPERATIONS&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;MAX_INITIALISATIONS&amp;lt;/tt&amp;gt; preference and then choose randomly); the order of operations in the B machine is thus important for -execute&lt;br /&gt;
* not store intermediate states in the state space; as such -execute is faster but after execution one only has access to the first state and the final state of execution&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -execute 100&lt;br /&gt;
&lt;br /&gt;
=== -execute_all===&lt;br /&gt;
&lt;br /&gt;
See &amp;lt;tt&amp;gt;-execute &amp;lt;Nr&amp;gt;&amp;lt;/tt&amp;gt; above.&lt;br /&gt;
&lt;br /&gt;
=== -det_check ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| check if animation steps are deterministic&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Checks if every step of the animation is deterministic (i.e., only one operation is possible, and it can only be executed in one possible way as far as parameters and result is concerned).&lt;br /&gt;
Currently this option has only an effect for the -animate &amp;lt;Nr&amp;gt; and the -init commands.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -animate 100 -det_check&lt;br /&gt;
&lt;br /&gt;
=== -det_constants ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| check if animation steps are deterministic&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Checks if the SETUP_CONSTANTS step is deterministic (i.e., only one way to set up the constants is possible).&lt;br /&gt;
Currently this option has only an effect for the -animate &amp;lt;Nr&amp;gt; and the -init commands.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -init -det_constants&lt;br /&gt;
=== -his &amp;lt;FILE&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| save animation history to a file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save the animation (or model checking) history to a text file. Operations are separated by semicolons.&lt;br /&gt;
The output can be adapted using the -his_option command. With -his_option show_states the -his command will also write out all states to the file (in the form of comments before and after operations). With -his_option show_init only the initial state is written out.&lt;br /&gt;
The -his command is executed after the -init, -animate, -t or -mc commands.&lt;br /&gt;
See also the -sptxt command to only write the current values of variables and constants to a file.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli -animate 5 -his history.txt  supersimple.mch&lt;br /&gt;
&lt;br /&gt;
Additionally we can have the initialised variables and constants:&lt;br /&gt;
&lt;br /&gt;
 probcli -animate 5 -his history.txt -his_option show_init supersimple.mch&lt;br /&gt;
&lt;br /&gt;
And we can have in addition the values of the variables in between (and at the end):&lt;br /&gt;
&lt;br /&gt;
 probcli -animate 5 -his history.txt -his_option show_states supersimple.mch&lt;br /&gt;
&lt;br /&gt;
With -his_option trace_file as only option, probcli will write the history in Prolog format, which can later be used by the -t command.&lt;br /&gt;
&lt;br /&gt;
=== -i ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| interactive animation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After performing the other commands, ProB stays in interactive mode and allows the user to manually animate the loaded specification.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -i&lt;br /&gt;
&lt;br /&gt;
=== -repl ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| start interactive read-eval-print-loop&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -p CLPFD TRUE -repl&lt;br /&gt;
&lt;br /&gt;
A list of commands can be obtained by typing &amp;lt;tt&amp;gt;:help&amp;lt;/tt&amp;gt; (just help for versions 1.3.x of probcli). The interactive read-eval-print-loop can be exited using &amp;lt;tt&amp;gt;:q&amp;lt;/tt&amp;gt; (just typing a return on a blank line for versions 1.3.x of probcli)..&lt;br /&gt;
If in addition you want see a graphical representation of the solutions found you can use the following command and open the &amp;lt;tt&amp;gt;out.dot&amp;lt;/tt&amp;gt; file using dotty or GraphViz:&lt;br /&gt;
 probcli -repl -evaldot ~/out.dot&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also use the &amp;lt;tt&amp;gt;-eval&amp;lt;/tt&amp;gt; command to evaluate specific formulas or expressions:&lt;br /&gt;
 probcli -eval &amp;quot;1+2&amp;quot;&lt;br /&gt;
For convenience, these formulas can also be put into a separate file:&lt;br /&gt;
 probcli -eval_file MyFormula.txt&lt;br /&gt;
&lt;br /&gt;
=== -c ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| print coverage statistics&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 -c&lt;br /&gt;
&lt;br /&gt;
You can also use the longer name for the command:&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 --coverage&lt;br /&gt;
&lt;br /&gt;
There is also a version which prints a shorter summary (and which is much faster for large state spaces):&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 --coverage_summary&lt;br /&gt;
&lt;br /&gt;
=== -cc &amp;lt;Nr&amp;gt; &amp;lt;Nr&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| print and check coverage statistics&lt;br /&gt;
Print coverage statistics and check that the given number of nodes and transitions have been computed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 -cc 10 25&lt;br /&gt;
&lt;br /&gt;
=== -p &amp;lt;PREFERENCE&amp;gt; &amp;lt;VALUE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Set &amp;lt;PREFERENCE&amp;gt; to &amp;lt;VALUE&amp;gt;. For more information about preferences please have a look at [[Using_the_Command-Line_Version_of_ProB#Preferences | Preferences]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
You can also use --pref instead of -p.&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -p TIME_OUT 8000 -p CLPFD TRUE -mc 10000&lt;br /&gt;
&lt;br /&gt;
=== -pref_group &amp;lt;PREFGROUP&amp;gt; &amp;lt;SETTING&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| set to the group of preferences &amp;lt;PREFGROUP&amp;gt; to a predefined setting &amp;lt;SETTING&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -pref_group model_check unlimited&lt;br /&gt;
&lt;br /&gt;
Available groups and settings are:&lt;br /&gt;
&lt;br /&gt;
* PREFERENCE GROUP integer : SETTINGS [int32] : Values for MAXINT and MININT&lt;br /&gt;
* PREFERENCE GROUP time_out : SETTINGS [disable_time_out] : To disable TIME_OUT&lt;br /&gt;
* PREFERENCE GROUP model_check : SETTINGS [disable_max,unlimited] : Model Checking Limits&lt;br /&gt;
* PREFERENCE GROUP dot_colors : SETTINGS [classic,dreams,winter] : Colours for Dot graphs&lt;br /&gt;
&lt;br /&gt;
=== -prefs &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Set preferences from preference file &amp;lt;FILE&amp;gt;. The file should be created by the Tcl/Tk version of ProB; this version automatically creates a file called ProB_Preferences.pl. For more information about preferences please have a look at [[Using_the_Command-Line_Version_of_ProB#Preferences | Preferences]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -prefs ProB_Preferences.pl&lt;br /&gt;
&lt;br /&gt;
=== -card &amp;lt;GS&amp;gt; &amp;lt;VAL&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| set cardinality (scope in Alloy terminology) of a B deferred set. This overrides the default cardinality (which can be set using &amp;lt;tt&amp;gt;-p DEFAULT_SETSIZE &amp;lt;VAL&amp;gt;&amp;lt;/tt&amp;gt;).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -card PID 5&lt;br /&gt;
&lt;br /&gt;
=== -goal &amp;lt;PRED&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| set GOAL predicate for model checker&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 10000000 -goal &amp;quot;n=18&amp;quot;  -strict -expcterr goal_found&lt;br /&gt;
&lt;br /&gt;
=== -scope &amp;lt;PRED&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| set SCOPE predicate for model checker; states which do not satisfy the SCOPE predicate will be ignored (invariant will not be checked and no outgoing transitions will be computed)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 10000000 -scope &amp;quot;n&amp;lt;18&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
=== -s &amp;lt;PORT&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| start socket server on given port&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -ss ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| start socket server on port 9000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -sf ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| start socket server on some free port&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -sptxt &amp;lt;FILE&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| save constants and variables to a file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save the values of constants and variables to a text file in classical B syntax.&lt;br /&gt;
The -sptxt command is executed after the -init, -animate, -t or -mc commands.&lt;br /&gt;
The values are fully written out (some sets, e.g., infinite sets may be written out symbolically).&lt;br /&gt;
&lt;br /&gt;
See also the -his command.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli -animate 5 -sptxt state.txt  supersimple.mch&lt;br /&gt;
&lt;br /&gt;
This will write the values of all variables and constants to the file state.txt after animating the machine 5 steps.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== -cache &amp;lt;DIRECTORY&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| save constants (and in future also variables) to a file to avoid recomputation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This commands saves the values of constants for the current B machine and puts those values into files in the specified directory. The command will also tell ProB to try and reuse constants saved for subsidiary machines (included using SEES for example) whenever possible.&lt;br /&gt;
The purpose of the command is to avoid recomputing constants as much as possible, as this can be very time consuming.&lt;br /&gt;
This also works for values of variables computed in the initialisation or even using operations.&lt;br /&gt;
However, we do not support refinements at the moment.&lt;br /&gt;
&lt;br /&gt;
Note: this command can also be used when starting up the ProB Tcl/Tk version.&lt;br /&gt;
&lt;br /&gt;
=== -logxml &amp;lt;LogFile&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| log activities and results of probcli in XML format in &amp;lt;LogFile&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A schema declaration file (xsd) can be found at &amp;lt;tt&amp;gt;doc/logxml_xsd.xml&amp;lt;/tt&amp;gt; in the ProB [[Download#Sourcecode|Prolog sources]].&lt;br /&gt;
The log file contains information about the various commands performed by probcli.&lt;br /&gt;
It also contains version information, the parameters provided to probcli and details about the errors that occured.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 -logxml log.xml&lt;br /&gt;
&lt;br /&gt;
=== -logxml_write_vars &amp;lt;PREFIX&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| after processing other commands (such as -execute) write values of variables having prefix PREFIX in their name into the XML log file (if XML logging has been activated using the -logxml command)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -execute 1000 -logxml log.xml -logxml_write_vars out&lt;br /&gt;
&lt;br /&gt;
=== -l &amp;lt;LogFile&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| log activities in &amp;lt;LogFile&amp;gt; using Prolog format&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 -l my.log&lt;br /&gt;
&lt;br /&gt;
=== -ll ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| log activities in /tmp/prob_cli_debug.log&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 -ll&lt;br /&gt;
&lt;br /&gt;
=== -lg &amp;lt;LogFile&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| analyse &amp;lt;LogFile&amp;gt; using gnuplot&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -pp &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| pretty-print internal representation to &amp;lt;FILE&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -pp my_pp.mch&lt;br /&gt;
&lt;br /&gt;
=== -ppf &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| pretty-print internal representation to &amp;lt;FILE&amp;gt;, force printing of all type infos&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -ppf my_ppf.mch&lt;br /&gt;
&lt;br /&gt;
=== -v ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| set ProB into verbose mode&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 -v&lt;br /&gt;
&lt;br /&gt;
=== -version ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| print version information&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
There is also an alternate command called -svers which just prints the version number of ProB.&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli -version&lt;br /&gt;
 ProB Command Line Interface&lt;br /&gt;
   VERSION 1.3.4-rc1 (9556:9570M)&lt;br /&gt;
   $LastChangedDate: 2011-11-16 18:36:18 +0100 (Wed, 16 Nov 2011) $&lt;br /&gt;
   Prolog: SICStus 4.2.0 (x86_64-darwin-10.6.0): Mon Mar  7 20:03:36 CET 2011&lt;br /&gt;
   Application Path: /Users/leuschel/svn_root/NewProB&lt;br /&gt;
&lt;br /&gt;
 probcli -svers&lt;br /&gt;
 VERSION 1.3.4-rc1 (9556:9570M)&lt;br /&gt;
&lt;br /&gt;
You can use &amp;lt;tt&amp;gt;probcli -version -v&amp;lt;/tt&amp;gt; to obtain more information about your version of probcli.&lt;br /&gt;
&lt;br /&gt;
=== -check_java_version ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| check Java and B parser version information&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This command is available as of ProB version 1.5.1-beta5 or higher. It can be useful to check that your Java is correctly installed and that the ProB B parser can operate correctly&lt;br /&gt;
&lt;br /&gt;
 probcli -check_java_version&lt;br /&gt;
 Result of checking Java version:&lt;br /&gt;
  Java is correctly installed and version 1.7.0_55-b13 is compatible with ProB requirements (&amp;gt;= 1.7).&lt;br /&gt;
  ProB B Java Parser available in version: 2016-02-25 15:27:18.55.&lt;br /&gt;
&lt;br /&gt;
=== -assertions ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| check ASSERTIONS of your machine&lt;br /&gt;
&lt;br /&gt;
If you provide the -t switch, the ASSERTIONS will be checked after executing your trace. Otherwise, they will be checked in an initial state.&lt;br /&gt;
ProB will automatically initialize the machine if you have not provide the -init or -t switch.&lt;br /&gt;
&lt;br /&gt;
You can also use -main_assertions to check only the ASSERTIONS found in the main file.&lt;br /&gt;
&lt;br /&gt;
If your ASSERTIONS are all static (i.e., make no reference to variables), then ProB will remove all CONSTANTS and PROPERTIES from your machine which are not linked (directly or indirectly) to the ASSERTIONS.&lt;br /&gt;
This optimization will only be made if you provide no other switch, such as -mc or -animate which may require the computation of the variables.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -init -assertions&lt;br /&gt;
&lt;br /&gt;
=== -property ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| virtually add predicate to PROPERTIES&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -property &amp;quot;PRED&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== -properties ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| check PROPERTIES&lt;br /&gt;
Note: you should probably first initialise the machine (e.g., with -init).&lt;br /&gt;
If the constants have not yet been set up, probcli will debug the properties.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -init -properties&lt;br /&gt;
&lt;br /&gt;
=== -dot_output &amp;lt;PATH&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| define path for generation of dot files for false properties or assertions&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This option is applicable to -properties and -assertions. It will result in individual dot files being generated for every false or unknown property or assertion. Assertions are numbered A0,A1,... and properties P0,P1,... You can also force to generate dot files for all properties (i.e., also the true ones) using the -dot_all command-line flag.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -init -properties -dot_output somewhere/&lt;br /&gt;
&lt;br /&gt;
This will generate files somewhere/my_P0_false.dot, somewhere/my_P1_false.dot, ...&lt;br /&gt;
&lt;br /&gt;
=== -rc ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| runtime checking of types/pre-/post-conditions&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -ltlfile &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| check LTL formulas in file &amp;lt;FILE&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -ltlassertions ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| check LTL assertions (in DEFINITIONS)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -ltllimit &amp;lt;LIMIT&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| explore at most &amp;lt;LIMIT&amp;gt; states when model-checking LTL&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -save &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| save state space for later refinement check&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -refchk &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| refinement check against previous saved state space&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -mcm_tests &amp;lt;Depth&amp;gt; &amp;lt;MaxStates&amp;gt; &amp;lt;EndPredicate&amp;gt; &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Generate test cases for the given specification. Each test case consists of a sequence of operations resp. events (a so-called trace) that&lt;br /&gt;
* start in a state after an initialisation&lt;br /&gt;
* contain a requested operation/event&lt;br /&gt;
* end in a state where the &amp;lt;EndPredicate&amp;gt; is fulfilled&lt;br /&gt;
&lt;br /&gt;
The user can specify what requested operations/events are with the&lt;br /&gt;
option [[#-mcm_cover &amp;lt;Operation(s)&amp;gt;|-mcm_cover]].&lt;br /&gt;
&lt;br /&gt;
ProB uses a &amp;quot;breadth-first&amp;quot; approach to search for test cases. When all requested operations/events are covered by test cases within maximum length M, the algorithm will explore the complete state space with that maximum distance M from the initialisation. It outputs all found traces that satisfy the requirements above.&lt;br /&gt;
&lt;br /&gt;
The algorithm stops if either&lt;br /&gt;
* it has covered all required operations/events with the current search depth&lt;br /&gt;
* or it has reached the maximum search depth or maximum number of explored states.&lt;br /&gt;
&lt;br /&gt;
The required parameters are:&lt;br /&gt;
;Depth&lt;br /&gt;
: The maximum length of traces that the algorithm searches for test until it stops without covering all required operations/events.&lt;br /&gt;
;MaxStates&lt;br /&gt;
: The maximum number of explored states until the algorithm stops without covering all required operations/events.&lt;br /&gt;
;EndPredicate&lt;br /&gt;
: A predicate in B syntax that the last state of a trace must fulfil. If you do not have any restrictions on that state, use a trivially true predicate like &#039;&#039;&#039;1=1&#039;&#039;&#039;&lt;br /&gt;
;FILE&lt;br /&gt;
: The found test cases a written to the XML file &amp;lt;FILE&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mcm_tests 10 2000 &amp;quot;EndStateVar=TRUE&amp;quot; testcases.xml -mcm_cover op1,op2&lt;br /&gt;
&lt;br /&gt;
generates test cases for the operations &#039;&#039;&#039;op1&#039;&#039;&#039; and &#039;&#039;&#039;op2&#039;&#039;&#039; of the specification &#039;&#039;&#039;my.mch&#039;&#039;&#039;. The maximum length of traces is 10, at most 2000 states are explored. Each test case ends in a state where the predicate &#039;&#039;&#039;EndStateVar=TRUE&#039;&#039;&#039; holds. The found test cases are written to a file &#039;&#039;&#039;testcases.xml&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
As of version 1.6.0, the operation arguments are also written to the XML file.&lt;br /&gt;
The preference &amp;lt;tt&amp;gt;INTERNAL_ARGUMENT_PREFIX&amp;lt;/tt&amp;gt; can be used to provide a prefix for internal operation arguments; any argument/parameter whose name starts with that prefix is considered an internal parameter and not shown in the trace file.&lt;br /&gt;
Also, as of version 1.6.0, the non-deterministic initialisations are shown in the XML trace file: all variables and constants where more than one possible initialisation exists are written into the trace file, as argument of an INITIALISATION event.&lt;br /&gt;
&lt;br /&gt;
=== -mcm_cover &amp;lt;Operation(s)&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Specify an operation or event that should be covered when generating test cases with the &#039;&#039;&#039;-mcm_test&#039;&#039;&#039; option. Multiple operations/events can be specified by seperating them by comma or by using &#039;&#039;&#039;-mcm_cover&#039;&#039;&#039; several times.&lt;br /&gt;
&lt;br /&gt;
See [[#-mcm_tests &amp;lt;Depth&amp;gt; &amp;lt;MaxStates&amp;gt; &amp;lt;EndPredicate&amp;gt; &amp;lt;FILE&amp;gt;|-mcm-tests]] for further details.&lt;br /&gt;
&lt;br /&gt;
=== -spdot &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Write graph of the state space to a dot &amp;lt;FILE&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 100 -spdot my_statespace.dot&lt;br /&gt;
&lt;br /&gt;
=== -cbc_tests &amp;lt;Depth&amp;gt; &amp;lt;EndPredicate&amp;gt; &amp;lt;File&amp;gt; ===&lt;br /&gt;
Generate test cases by constraint solving with maximum&lt;br /&gt;
length &#039;&#039;&#039;Depth&#039;&#039;&#039;, the last state satisfies &#039;&#039;&#039;EndPredicate&#039;&#039;&#039;&lt;br /&gt;
and the test cases are written to &#039;&#039;&#039;File&#039;&#039;&#039;. If the predicate is the empty string we assume truth. If the filename is the empty string no file is generated. See also the page on [[Test_Case_Generation]].&lt;br /&gt;
&lt;br /&gt;
=== -cbc_cover &amp;lt;Operation&amp;gt; ===&lt;br /&gt;
When generating CB test cases, &#039;&#039;&#039;Operation&#039;&#039;&#039; should be covered.&lt;br /&gt;
The option can be given multiple times to specify several operations.&lt;br /&gt;
Alternatively, multiple operations can be separated by a comma. You can also use the option &amp;lt;pre&amp;gt;-cbc_cover_match PartialName&amp;lt;/pre&amp;gt; to match all operations whose name contains PartialName. See also the page about [[Test_Case_Generation]].&lt;br /&gt;
&lt;br /&gt;
=== -test_description &amp;lt;File&amp;gt; ===&lt;br /&gt;
Read the options for constraint based test case generation from &#039;&#039;&#039;File&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== -bmc &amp;lt;Depth&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Run the [[Bounded_Model_Checking|bounded model checker]] until maximum trace depth &amp;lt;Depth&amp;gt; specified. Looks for invariant violations using the constraint-based test case generation algorithm.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -bmc 20&lt;br /&gt;
&lt;br /&gt;
=== -csp-guide &amp;lt;File&amp;gt; ===&lt;br /&gt;
Use the CSP File &#039;&#039;&#039;File&#039;&#039;&#039; to guide the B Machine (&amp;quot;CSP||B&amp;quot;).&lt;br /&gt;
(This feature is included since version 1.3.5-beta7.)&lt;br /&gt;
&lt;br /&gt;
=== -rule_report &amp;lt;File&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Generates rule validation report for rules machines (.rmch) at the specified location &amp;lt;File&amp;gt; for the current animation state. Depending on the file extension an HTML or an XML version of the report is generated (.html/.xml).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Useful in combination with &amp;lt;tt&amp;gt;-execute&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;-execute_all&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli myrules.rmch -execute_all -rule_report my_report.html&lt;br /&gt;
&lt;br /&gt;
== Environment Variables ==&lt;br /&gt;
&lt;br /&gt;
Set NO_COLOR environment variable to disable terminal colors.&lt;br /&gt;
See [https://no-color.org https://no-color.org].&lt;br /&gt;
&lt;br /&gt;
== Preferences ==&lt;br /&gt;
&lt;br /&gt;
You can use these preferences within the command:&lt;br /&gt;
&lt;br /&gt;
 -p &amp;lt;PREFERENCE&amp;gt; &amp;lt;VALUE&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;1&amp;quot; width=&amp;quot;100%&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!style=&amp;quot;background-color:lightgrey;&amp;quot; | &amp;lt;PREFERENCE&amp;gt;&lt;br /&gt;
!style=&amp;quot;background-color:lightgrey;&amp;quot; | &amp;lt;VALUE&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| MAXINT&lt;br /&gt;
| nat ==&amp;gt; MaxInt, used for expressions such as xx::NAT (2147483647 for 4 byte ints)&lt;br /&gt;
|-&lt;br /&gt;
| MININT&lt;br /&gt;
| neg ==&amp;gt; MinInt, used for expressions such as xx::INT (-2147483648 for 4 byte ints)&lt;br /&gt;
|-&lt;br /&gt;
| DEFAULT_SETSIZE&lt;br /&gt;
| nat ==&amp;gt; Size of unspecified deferred sets in SETS section. Will be used if a set s is neither enumerated, has no no card(s)=nr predicate in the PROPERTIES and has no scope_s == Nr DEFINITION.&lt;br /&gt;
|-&lt;br /&gt;
| MAX_INITIALISATIONS&lt;br /&gt;
| nat ==&amp;gt; Max Number of Initialisations and ways to setup constants computed&lt;br /&gt;
|-&lt;br /&gt;
| MAX_OPERATIONS&lt;br /&gt;
| nat ==&amp;gt; Max Number of Enablings per Operation Computed&lt;br /&gt;
|-&lt;br /&gt;
| ANIMATE_SKIP_OPERATIONS&lt;br /&gt;
| bool ==&amp;gt; Animate operations which are skip or PRE C THEN skip&lt;br /&gt;
|-&lt;br /&gt;
| COMPRESSION&lt;br /&gt;
| bool ==&amp;gt; Use more aggressive COMPRESSION when storing states&lt;br /&gt;
|-&lt;br /&gt;
| EXPAND_CLOSURES_FOR_STATE&lt;br /&gt;
| bool ==&amp;gt; Convert lazy form back into explicit form for Variables, Constants, Operation Arguments. ProB will sometimes try to keep certain sets symbolic. If this preference is TRUE then ProB will try to expand those sets for variables and constants after an operation has been executed.&lt;br /&gt;
|-&lt;br /&gt;
| SYMBOLIC&lt;br /&gt;
| bool ==&amp;gt; Lazy expansion of lambdas and set comprehensions. By default ProB will keep certain sets symbolic (e.g., sets it knows are infinite). When this preference is set to TRUE then all set comprehensions and lambda abstractions will at first be kept symbolic and only expanded into explicit form if needed.&lt;br /&gt;
|-&lt;br /&gt;
| CLPFD&lt;br /&gt;
| bool ==&amp;gt; Use CLP(FD) solver for B integers (restricts range to -2^28..2^28-1 on 32 bit computers). Setting this preference to TRUE should substantially improve ProB&#039;s ability to solve complicated predicates involving integers. However, it may cause CLP(FD) overflows in certain circumstances.&lt;br /&gt;
|-&lt;br /&gt;
| SMT&lt;br /&gt;
| bool ==&amp;gt; Enable SMT-Mode (aggressive treatment of : and /: inside predicates). With this predicate set to TRUE ProB will be better at solving certain constraint solving tasks. It should be enabled when doing constraint-based invariant or deadlock checking. ProB Tcl/Tk will turn this preference on automatically for those checks.&lt;br /&gt;
|-&lt;br /&gt;
| STATIC_ORDERING&lt;br /&gt;
| bool ==&amp;gt; Use static ordering to enumerate constants which occur in most PROPERTIES first&lt;br /&gt;
|-&lt;br /&gt;
| SYMMETRY_MODE&lt;br /&gt;
| [off,flood,nauty,hash] ==&amp;gt; Symmetry Mode: off,flood,canon,nauty,hash&lt;br /&gt;
|-&lt;br /&gt;
| TIME_OUT&lt;br /&gt;
| nat1 ==&amp;gt; Time out for computing enabled transitions (in ms, is multiplied by a factor for other computations)&lt;br /&gt;
|-&lt;br /&gt;
| PROOF_INFO&lt;br /&gt;
| bool ==&amp;gt; Use Proof Information to restrict invariant checking to affected unproven clauses. Most useful in EventB for models exported from Rodin.&lt;br /&gt;
|-&lt;br /&gt;
| TRY_FIND_ABORT&lt;br /&gt;
| bool ==&amp;gt; Try more aggressively to detect ill-defined expressions (e.g. applying function outside of domain), may slow down animator&lt;br /&gt;
|-&lt;br /&gt;
| NUMBER_OF_ANIMATED_ABSTRACTIONS&lt;br /&gt;
| nat ==&amp;gt; How many levels of refined models are animated by default&lt;br /&gt;
|-&lt;br /&gt;
| ALLOW_INCOMPLETE_SETUP_CONSTANTS&lt;br /&gt;
| bool ==&amp;gt; Allow ProB to proceed even if only part of the CONSTANTS have been found.&lt;br /&gt;
|-&lt;br /&gt;
| PARTITION_PROPERTIES&lt;br /&gt;
| bool ==&amp;gt; Partition predicates (PROPERTIES) into components&lt;br /&gt;
|-&lt;br /&gt;
| USE_RECORD_CONSTRUCTION&lt;br /&gt;
| bool ==&amp;gt; Records: Check if axioms/properties describe a record pattern&lt;br /&gt;
|-&lt;br /&gt;
| OPERATION_REUSE&lt;br /&gt;
| bool ==&amp;gt; Try and reuse previously computed operation effects in B/Event-B&lt;br /&gt;
|-&lt;br /&gt;
| SHOW_EVENTB_ANY_VALUES&lt;br /&gt;
| bool ==&amp;gt; Show top-level ANY variable values of B Operations without parameters as parameters&lt;br /&gt;
|-&lt;br /&gt;
| RANDOMISE_OPERATION_ORDER&lt;br /&gt;
| bool ==&amp;gt; Randomise order of operations when computing successor states&lt;br /&gt;
|-&lt;br /&gt;
| EXPAND_FORALL_UPTO&lt;br /&gt;
| nat ==&amp;gt; When analysing predicates: max. domain size for expansion of forall (use 0 to disable expansion)&lt;br /&gt;
|-&lt;br /&gt;
| MAX_DISPLAY_SET&lt;br /&gt;
| int ==&amp;gt; Max size for pretty-printing sets (-1 means no limit)&lt;br /&gt;
|-&lt;br /&gt;
| CSP_STRIP_SOURCE_LOC&lt;br /&gt;
| bool ==&amp;gt; Strip source location for CSP; will speed up model checking&lt;br /&gt;
|-&lt;br /&gt;
| WARN_WHEN_EXPANDING_INFINITE_CLOSURES&lt;br /&gt;
| int ==&amp;gt; Warn when expanding infinite closures if MAXINT larger than:&lt;br /&gt;
|-&lt;br /&gt;
| TRACE_INFO&lt;br /&gt;
| bool ==&amp;gt; Provide various tracing information on the terminal/console.&lt;br /&gt;
|-&lt;br /&gt;
| DOUBLE_EVALUATION&lt;br /&gt;
| bool ==&amp;gt; Evaluate PREDICATES positively and negatively when analyzing assertions or properties&lt;br /&gt;
|-&lt;br /&gt;
| RECURSIVE&lt;br /&gt;
| bool ==&amp;gt; Lazy expansion of *Recursive* set Comprehensions and lambdas&lt;br /&gt;
|-&lt;br /&gt;
| IGNORE_HASH_COLLISIONS&lt;br /&gt;
| bool ==&amp;gt; Ignore Hash Collisions (if true not all states may be computed, visited states are not memorised !)&lt;br /&gt;
|-&lt;br /&gt;
| FORGET_STATE_SPACE&lt;br /&gt;
| bool ==&amp;gt; Do not remember state space (mainly useful in conjunction with Ignore Hash Collisions)&lt;br /&gt;
|-&lt;br /&gt;
| NEGATED_INVARIANT_CHECKING&lt;br /&gt;
| bool ==&amp;gt; Perform double evaluation (positive and negative) when checking invariants&lt;br /&gt;
|-&lt;br /&gt;
| CSE&lt;br /&gt;
| bool ==&amp;gt; Perform common-sub-expression elimination&lt;br /&gt;
|-&lt;br /&gt;
| CSE_SUBST&lt;br /&gt;
| bool ==&amp;gt; Perform common-sub-expression elimination also for B substitutions&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -p TIME_OUT 5000 -p CLPFD TRUE -p SYMMETRY_MODE hash -mc 1000&lt;br /&gt;
&lt;br /&gt;
== Some probcli examples ==&lt;br /&gt;
&lt;br /&gt;
To load a file My.mch, setup the constants and initialize it do:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
probcli -init My.mch&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
To load a file M.mch, setup the constants, initialize and then check all assertions with Atelier-B&#039;s default values for MININT and MAXINT and an increased timeout of 5 seconds do:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
probcli -init -assertions -p MAXINT 2147483647 -p MININT -2147483647 -p TIME_OUT 5000 M.mch&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To fully model check a specification M.mch while tryining to minimize memory consumption do:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
probcli -model_check -p COMPRESSION TRUE M.mch&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To model check a specification M.mch while trying to minimize memory consumption further by not storing processed stats and using symmetry reduction (and accepting hash collisions) do:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
probcli -p COMPRESSION -p IGNORE_HASH_COLLISIONS TRUE -p FORGET_STATE_SPACE TRUE -p SYMMETRY_MODE hash -model_check M.mch &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Command-line Arguments for ProB Tcl/Tk ==&lt;br /&gt;
&lt;br /&gt;
Note that the stand-alone Tcl/Tk version also supports a limited form of command-line preferences:&lt;br /&gt;
* &#039;&#039;&#039;FILE&#039;&#039;&#039; (the name/path of the file to be loaded)&lt;br /&gt;
* &#039;&#039;&#039;-prefs PREF_FILE&#039;&#039;&#039;  (to use a specific preferences file, rather than the default ProB_Preferences.pl in your home folder)&lt;br /&gt;
* &#039;&#039;&#039;-batch&#039;&#039;&#039; (to instruct ProB not to try to bring up windows, but to print information only to the terminal)&lt;br /&gt;
* &#039;&#039;&#039;-selfcheck&#039;&#039;&#039; (to run the standard unit tests)&lt;br /&gt;
* &#039;&#039;&#039;-t&#039;&#039;&#039; (to perform the Trace Check on the default trace file associated with the specification)&lt;br /&gt;
* &#039;&#039;&#039;-tcl TCL_Command&#039;&#039;&#039; (to run a particular pre-defined Tcl command)&lt;br /&gt;
* &#039;&#039;&#039;-mc&#039;&#039;&#039; (to perform model checking)&lt;br /&gt;
* &#039;&#039;&#039;-c&#039;&#039;&#039; (to compute the coverage)&lt;br /&gt;
* &#039;&#039;&#039;-ref&#039;&#039;&#039; (to perform the default trace refinment check)&lt;br /&gt;
&lt;br /&gt;
However, the comand-line version of ProB, called &#039;&#039;&#039;probcli&#039;&#039;&#039;, provides more features. It also does not depend on Tcl/Tk and can therefore be run on systems without Tcl/Tk.&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=VisB&amp;diff=5951</id>
		<title>VisB</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=VisB&amp;diff=5951"/>
		<updated>2025-04-04T09:10:06Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* VisB DEFINITIONS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;VisB&#039;&#039;&#039; is a visualisation feature of ProB based on SVG graphics and HTML.&lt;br /&gt;
&lt;br /&gt;
Initially VisB was developed for [[ProB2-UI]], the new user interface of ProB based on JavaFX and the ProB2-Java-API.&lt;br /&gt;
It is included in ProB2-UI version 1.1.0 and later, which [[Download#ProB2-UI using Java FX|can be downloaded here]].&lt;br /&gt;
Users of ProB2-UI version 1.0.0 can [[#Installing the VisB plugin for older ProB2-UI versions|install VisB as a plugin]].&lt;br /&gt;
We, however, recommend you use the latest ProB2-UI snapshot.&lt;br /&gt;
VisB is constantly being improved and the latest version contains several useful new features.&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2UI_VisB_View.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
ProB Tcl/Tk and probcli version 1.11.0 and later also support VisB visualisations:&lt;br /&gt;
&lt;br /&gt;
* with &amp;lt;tt&amp;gt;probcli File.mch ... -visb VISBJSONFILE HTMLFILE&amp;lt;/tt&amp;gt; you can export the animator&#039;s history to a self-contained HTML file including a visualisation of the states in the history&lt;br /&gt;
* in ProB Tcl/Tk you can visualise the current state or the history using a VisB visualisation file (it is shown in an external browser) by right clicking in the &amp;quot;State Properties&amp;quot; or the &amp;quot;History&amp;quot; pane.&lt;br /&gt;
Hovers work in both cases, but unlike in ProB2-UI, you cannot click to perform events.&lt;br /&gt;
&lt;br /&gt;
An article about VisB has been [https://rdcu.be/b4rqh published in the ABZ&#039;2020 proceedings].&lt;br /&gt;
&lt;br /&gt;
== Using VisB ==&lt;br /&gt;
&lt;br /&gt;
In current versions of [[ProB2-UI]] the VisB view is automatically shown in the center pane below the state view.&lt;br /&gt;
To start VisB in older versions of [[ProB2-UI]], choose the &amp;quot;Open VisB&amp;quot; command in the Visualisation menu,&lt;br /&gt;
or right-click in the &amp;quot;State Properties&amp;quot; pane of ProB Tcl/Tk and select &amp;quot;View Current State in VisB&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can now choose a JSON file which builds on top of  a SVG graphics file (more recent versions of VisB can also load visualisations from [[VisB#VisB_DEFINITIONS|definitions]].&lt;br /&gt;
The JSON file contains a reference to a SVG file, along with entries to modify attributes based on the current state of a B model and entries which specify how VisB should react to clicks on the SVG. The SVG file should contain object ids which are referenced in the JSON file.&lt;br /&gt;
&lt;br /&gt;
Here is a sample file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;svg&amp;quot;:&amp;quot;Train2.svg&amp;quot;,&lt;br /&gt;
  &amp;quot;items&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;Train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;visibility&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;IF 1:TRAIN THEN \&amp;quot;visible\&amp;quot; ELSE \&amp;quot;hidden\&amp;quot; END&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;Train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;fill&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;IF train_speed(1)&amp;gt;0 THEN \&amp;quot;blue\&amp;quot; ELSE \&amp;quot;orange\&amp;quot; END&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;Train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;x&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;train_back_loc(1)*10+20&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;Train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;width&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;train_length(1)*10&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
    ],&lt;br /&gt;
  &amp;quot;events&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;Train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;:&amp;quot;Train_Move1&amp;quot;,&lt;br /&gt;
      &amp;quot;predicates&amp;quot;:[&lt;br /&gt;
        &amp;quot;1=1&amp;quot;&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== VisB Attributes ==&lt;br /&gt;
&lt;br /&gt;
At the top-level a VisB JSON file contains these attributes:&lt;br /&gt;
* svg&lt;br /&gt;
* model-name&lt;br /&gt;
* include&lt;br /&gt;
* svg_objects&lt;br /&gt;
* definitions&lt;br /&gt;
* items&lt;br /&gt;
* events&lt;br /&gt;
&lt;br /&gt;
Below we explain them in more detail.&lt;br /&gt;
&lt;br /&gt;
=== SVG file and inclusion ===&lt;br /&gt;
&lt;br /&gt;
The main VisB Json file should contain an &amp;lt;tt&amp;gt;svg&amp;lt;/tt&amp;gt; attribute with a&lt;br /&gt;
relative or absolute path to the SVG file to be shown.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;model-name&amp;lt;/tt&amp;gt; attribute is optional; if set ProB will emit&lt;br /&gt;
a warning if the B model&#039;s name does not match the value of this attribute.&lt;br /&gt;
&lt;br /&gt;
One can also include subsidiary VisB Json files using the &amp;lt;tt&amp;gt;include&amp;lt;/tt&amp;gt;&lt;br /&gt;
attribute with again a relative or absolut path to another Json file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;svg&amp;quot;:&amp;quot;my_svg_file.svg&amp;quot;,&lt;br /&gt;
  &amp;quot;include&amp;quot;:&amp;quot;subsidiary_visb_file.json&amp;quot;,&lt;br /&gt;
  &amp;quot;items&amp;quot;:[&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The svg attribute in subsidiary files will be ignored.&lt;br /&gt;
You can override the VisB items in the included file (i.e., a VisB item for an id and attribute in the top-level file will override items for the same id and attribute in the included files).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Items and Events ===&lt;br /&gt;
&lt;br /&gt;
For VisB &amp;lt;tt&amp;gt;items&amp;lt;/tt&amp;gt; every entry needs&lt;br /&gt;
* &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, this is the identifier of an object in the associated SVG file&lt;br /&gt;
* &amp;lt;tt&amp;gt;attr&amp;lt;/tt&amp;gt; a valid SVG attribute&lt;br /&gt;
* &amp;lt;tt&amp;gt;value&amp;lt;/tt&amp;gt; a B formula which will be evaluated in the current state of a model and yields a new value for the above attribute.&lt;br /&gt;
&lt;br /&gt;
Note that the formula can  make use of the [[Summary_of_B_Syntax#Reals |REAL datatype]]  and also use many of the [[External_Functions|external functions]] e.g. from LibraryStrings or LibraySVG.&lt;br /&gt;
Here is an example VisB Item:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;items&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;: &amp;quot;x&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;100.0 + train_left(train1)&amp;quot;&lt;br /&gt;
    } ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As of version 1.12.2, ProB allows you to use a single attribute whose name is the SVG attribute being set, rather than two attributes (attr, value).&lt;br /&gt;
With this you can set multiple SVG attributes in one VisB item.&lt;br /&gt;
For example, you can now write:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;items&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;x&amp;quot;:&amp;quot;100.0 + train_left(train1)&amp;quot;,&lt;br /&gt;
      &amp;quot;y&amp;quot;:&amp;quot;20.0 + train_bottom(train1)&amp;quot;&lt;br /&gt;
    } ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For VisB &amp;lt;tt&amp;gt;events&amp;lt;/tt&amp;gt; every entry needs&lt;br /&gt;
* &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, this is the identifier of an object in the associated SVG file&lt;br /&gt;
* &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; a valid B operation or event of the loaded formal model&lt;br /&gt;
* &amp;lt;tt&amp;gt;predicates&amp;lt;/tt&amp;gt; an optional list of B predicates, which can be used to set parameters of the B operation that is executed upon a click&lt;br /&gt;
&lt;br /&gt;
Additionally VisB now recognises for both items and events:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;ignore&amp;lt;/tt&amp;gt;, if this attribute is present the item will be ignored&lt;br /&gt;
* &amp;lt;tt&amp;gt;repeat&amp;lt;/tt&amp;gt;, if this attribute is present the item will be replicated (see below). This construct requires a list of strings.&lt;br /&gt;
* &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, if this attribute is present the item will be replicated (see below). The for construct requires &amp;lt;tt&amp;gt;from&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;to&amp;lt;/tt&amp;gt; with integer values as sub arguments. As of version 1.11.1 you can also use constant B integer expressions accessing just the sets.&lt;br /&gt;
* &amp;lt;tt&amp;gt;optional&amp;lt;/tt&amp;gt;, if this boolean attribute is &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt; an event will be ignored if the event name is not a valid top-level event/operation in the model. An item will be ignored if the identifiers in the formula do not exists (i.e., errors during type checking will be ignored)&lt;br /&gt;
* &amp;lt;tt&amp;gt;override&amp;lt;/tt&amp;gt;, if this boolean attribute is &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt; no warnings will be generated if another VisB item for the same attribute and id is overriden (as of version 1.11.1)&lt;br /&gt;
&lt;br /&gt;
Other attributes will be ignored. E.g, one can use a &amp;lt;tt&amp;gt;comment&amp;lt;/tt&amp;gt; attribute to add comments to the VisB items.&lt;br /&gt;
&lt;br /&gt;
When executing an event, VisB now performs the following replacements within the predicates of the event:&lt;br /&gt;
* &amp;lt;tt&amp;gt;%shiftKey&amp;lt;/tt&amp;gt; is replaced by TRUE if the shift key was pressed during the click, FALSE otherwise&lt;br /&gt;
* &amp;lt;tt&amp;gt;%metaKey&amp;lt;/tt&amp;gt; is replaced by TRUE if the shift key was pressed during the click, FALSE otherwise&lt;br /&gt;
* &amp;lt;tt&amp;gt;%pageX&amp;lt;/tt&amp;gt; is replaced by the x coordinate of the click relative to the top-left of the entire VisB SVG&lt;br /&gt;
* &amp;lt;tt&amp;gt;%pageY&amp;lt;/tt&amp;gt; is replaced by the y coordinate of the click relative to the top-left of the entire VisB SVG&lt;br /&gt;
&lt;br /&gt;
Finally, VisB events can be associated with mouse hover actions.&lt;br /&gt;
For this you just need to add an attribute &amp;lt;tt&amp;gt;hovers&amp;lt;/tt&amp;gt; which contains a list of JSON objects with the following attributes:&lt;br /&gt;
* &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, this is the identifier of an object in the associated SVG file; this attribute is optional; if it is not present the id specified in the VisB event will be used.&lt;br /&gt;
* &amp;lt;tt&amp;gt;attr&amp;lt;/tt&amp;gt; a valid SVG attribute&lt;br /&gt;
* &amp;lt;tt&amp;gt;enter&amp;lt;/tt&amp;gt; a value which will be used when the mouse enters the area of the object&lt;br /&gt;
* &amp;lt;tt&amp;gt;leave&amp;lt;/tt&amp;gt; a value which will be used to restore the attribute when the mouse leaves the area&lt;br /&gt;
Note that the enter and leave values have to be static at the moment; in future we plan to allow B formulas here and also apply the repetition/replacement mechanism specified above.&lt;br /&gt;
If you just wish to attach a hover to an SVG object (and no B operation/event) you can set the event field of the VisB event to the empty string (&amp;lt;tt&amp;gt;&amp;quot;event&amp;quot;:&amp;quot;&amp;quot;&amp;lt;/tt&amp;gt;).&lt;br /&gt;
You should not use attributes for the hover which are set by VisB items.&lt;br /&gt;
&lt;br /&gt;
Here is an example VisB event with hovers:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;button&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;: &amp;quot;toggle_button&amp;quot;,&lt;br /&gt;
      &amp;quot;hovers&amp;quot;: [{ &amp;quot;attr&amp;quot;:&amp;quot;stroke-width&amp;quot;, &amp;quot;enter&amp;quot;:&amp;quot;6&amp;quot;, &amp;quot;leave&amp;quot;:&amp;quot;1&amp;quot;},&lt;br /&gt;
                 { &amp;quot;attr&amp;quot;:&amp;quot;opacity&amp;quot;, &amp;quot;enter&amp;quot;:&amp;quot;0.8&amp;quot;, &amp;quot;leave&amp;quot;:&amp;quot;1.0&amp;quot;}]&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A VisB event can now also contain an list of items with the attributes &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;attr&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;enabled&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;disabled&amp;lt;/tt&amp;gt;.&lt;br /&gt;
When the associated event is enabled, the attribute of the SVG object with the given id is set to the  value provided in the enabled attribute, otherwise the disabled attribute value is used.&lt;br /&gt;
As above the item id is optional and defaults to the id of the VisB event.&lt;br /&gt;
Here is an example VisB event with hovers and an items list:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;button&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;: &amp;quot;press_button&amp;quot;,&lt;br /&gt;
      &amp;quot;hovers&amp;quot;: [{ &amp;quot;attr&amp;quot;:&amp;quot;stroke-width&amp;quot;, &amp;quot;enter&amp;quot;:&amp;quot;6&amp;quot;, &amp;quot;leave&amp;quot;:&amp;quot;1&amp;quot;}],&lt;br /&gt;
      &amp;quot;items&amp;quot;: [{&amp;quot;attr&amp;quot;:&amp;quot;fill&amp;quot;, &amp;quot;disabled&amp;quot;:&amp;quot;\&amp;quot;green\&amp;quot;&amp;quot;, &amp;quot;enabled&amp;quot;:&amp;quot;\&amp;quot;red\&amp;quot;&amp;quot;}]&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Replication / Loops ==&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;repeat&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; attributes to replicate a VisB&lt;br /&gt;
item or event.&lt;br /&gt;
Replication consists in duplicating the item or event, and replacing &amp;lt;tt&amp;gt;%0&amp;lt;/tt&amp;gt; within the identifier and value attributes of the time with the repeated string or integer.&lt;br /&gt;
&lt;br /&gt;
For example, the repeat instruction below will result in the creation of three VisB items, one for id &amp;lt;tt&amp;gt;txt_ttd1&amp;lt;/tt&amp;gt;,  for &amp;lt;tt&amp;gt;txt_ttd2&amp;lt;/tt&amp;gt;,  and one for &amp;lt;tt&amp;gt;txt_ttd3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The value formula for &amp;lt;tt&amp;gt;txt_ttd1&amp;lt;/tt&amp;gt; is &amp;lt;tt&amp;gt;&amp;quot;IF 1: dom(TTD) THEN visb_ttd_back(%0) ELSE -1000 END&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
     &amp;quot;repeat&amp;quot;: [&amp;quot;1&amp;quot;,&amp;quot;2&amp;quot;,&amp;quot;3&amp;quot;],&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;txt_ttd%0&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;x&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;IF %0: dom(TTD) THEN visb_ttd_back(%0) ELSE -1000 END&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A for loop can be used instead for the above example as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
     &amp;quot;for&amp;quot;: {&amp;quot;from&amp;quot;:1, &amp;quot;to&amp;quot;:3},&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;txt_ttd%0&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;x&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;IF %0: dom(TTD) THEN visb_ttd_back(%0) ELSE -1000 END&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The for loop also allows an optional &amp;lt;tt&amp;gt;step&amp;lt;/tt&amp;gt; attribute.&lt;br /&gt;
&lt;br /&gt;
It is possible to apply both &amp;lt;tt&amp;gt;repeat&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; attributes at the same time, as this example shows.&lt;br /&gt;
(The exact details of multiple iterations for a VisB item might change in future.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
     &amp;quot;repeat&amp;quot;: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],&lt;br /&gt;
     &amp;quot;for&amp;quot;: {&amp;quot;from&amp;quot;:1, &amp;quot;to&amp;quot;:20},&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;tile%1x%0&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;: &amp;quot;TryQueen&amp;quot;,&lt;br /&gt;
      &amp;quot;hovers&amp;quot;: [{ &amp;quot;attr&amp;quot;:&amp;quot;opacity&amp;quot;, &amp;quot;enter&amp;quot;:&amp;quot;0.5&amp;quot;, &amp;quot;leave&amp;quot;:&amp;quot;1&amp;quot;}],&lt;br /&gt;
      &amp;quot;predicates&amp;quot; : [&amp;quot;i=%1&amp;quot;,&amp;quot;j=%0&amp;quot;] &lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 1.11.0 you can also use nested for loops.&lt;br /&gt;
As of version 1.11.1 of ProB you can also use B expressions for the &amp;lt;tt&amp;gt;from&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;to&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;step&amp;lt;/tt&amp;gt; attributes of a for loop.&lt;br /&gt;
However, these expressions must be evaluable without having access to any constants or variables. Indeed, the for and repeat loops are processed once when loading a VisB file, independently of any given state.&lt;br /&gt;
So, you can only access identifiers of &amp;lt;tt&amp;gt;SETS&amp;lt;/tt&amp;gt; section of a B machine.&lt;br /&gt;
It may still be useful, e.g., to iterate over an enumerated or deferred set (TRAINS below):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
     &amp;quot;for&amp;quot;: {&amp;quot;from&amp;quot;:1, &amp;quot;to&amp;quot;:&amp;quot;card(TRAINS)&amp;quot;},&lt;br /&gt;
...&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;INT_TO_ENUM&amp;lt;/tt&amp;gt; external function available as of ProB 1.11.1 can be useful in expressions here to convert the iteration variable back to an enumerated or deferred set element.&lt;br /&gt;
For example, &amp;lt;tt&amp;gt;INT_TO_ENUM(TRAINS,1)&amp;lt;/tt&amp;gt; refers to the first element of the set &amp;lt;tt&amp;gt;TRAINS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== VisB Definitions (in JSON file) ==&lt;br /&gt;
&lt;br /&gt;
As of ProB Tcl/Tk 1.11.0 it is possible to include local definitions in the VisB JSON  file.&lt;br /&gt;
Each definition has a name and a value formula.&lt;br /&gt;
Definitions are evaluated in order of appearance (a later definition can thus refer to an ealier one) and are evaluated in a state before evaluating VisB items.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;definitions&amp;quot;:[&lt;br /&gt;
    { &amp;quot;name&amp;quot;:&amp;quot;xscale&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot; : &amp;quot;(100.0 / real(NrOfTrackElements))&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    { &amp;quot;name&amp;quot;:&amp;quot;visb_train_rear&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot; : &amp;quot;%x.(x:dom(train_rear)|xscale * real(train_rear(x)))&amp;quot;&lt;br /&gt;
    }]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The VisB definitions are particularly useful for Event-B models (as you can use [[Summary_of_B_Syntax#Reals |REAL numbers]]  and also have access to [[External_Functions|external functions]] such as LibraryStrings or LibraySVG).&lt;br /&gt;
But they are &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; yet available for events in ProB2-UI.&lt;br /&gt;
&lt;br /&gt;
== VisB Additional SVG Objects ==&lt;br /&gt;
&lt;br /&gt;
As of version 1.12.0 of ProB Tcl/Tk you can add new SVG objects to your SVG file.&lt;br /&gt;
You can use for and repeat loops (see above) to create an arbitrary number of objects.&lt;br /&gt;
This is useful for making flexible visualisations which work with an arbitrary number&lt;br /&gt;
of objects.&lt;br /&gt;
The same rules and limitations for for/repeat loops apply as for items above.&lt;br /&gt;
&lt;br /&gt;
Every entry in the svg_objects list &lt;br /&gt;
* an &amp;lt;tt&amp;gt;svg_class&amp;lt;/tt&amp;gt; attribute, which can be, e.g., line, circle, rect, ...&lt;br /&gt;
* an object &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; attribute&lt;br /&gt;
* an optional &amp;lt;tt&amp;gt;comment&amp;lt;/tt&amp;gt; attribute&lt;br /&gt;
* any other attribute will be used to create the SVG object and should be valid for the specified svg_class&lt;br /&gt;
&lt;br /&gt;
Here is an example (taken from [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples/-/blob/master/Physics/n_bodies_visb.json here]) where NOBJS is a DEFINITION inside a B machine:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;svg_objects&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;for&amp;quot;:{&amp;quot;from&amp;quot;:1,&amp;quot;to&amp;quot;:&amp;quot;NOBJS&amp;quot;}, &lt;br /&gt;
      &amp;quot;svg_class&amp;quot;:&amp;quot;circle&amp;quot;,&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;body%0&amp;quot;,&lt;br /&gt;
      &amp;quot;cx&amp;quot;:&amp;quot;45&amp;quot;,&lt;br /&gt;
      &amp;quot;cy&amp;quot;:&amp;quot;15&amp;quot;,&lt;br /&gt;
      &amp;quot;r&amp;quot;:&amp;quot;10&amp;quot;,&lt;br /&gt;
      &amp;quot;stroke&amp;quot;:&amp;quot;black&amp;quot;,&lt;br /&gt;
      &amp;quot;stroke-width&amp;quot;:&amp;quot;0.5&amp;quot;,&lt;br /&gt;
      &amp;quot;fill&amp;quot;:&amp;quot;green&amp;quot;&lt;br /&gt;
    } ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is another example where TRAINS is a deferred or enumerated set of the B model being visualised:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;svg_objects&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;for&amp;quot;:{&amp;quot;from&amp;quot;:1,&amp;quot;to&amp;quot;:&amp;quot;card(TRAINS)&amp;quot;}, &lt;br /&gt;
      &amp;quot;svg_class&amp;quot;:&amp;quot;rect&amp;quot;,&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;fresh_train_rect%0&amp;quot;,&lt;br /&gt;
      &amp;quot;x&amp;quot;:&amp;quot;0&amp;quot;,&lt;br /&gt;
      &amp;quot;y&amp;quot;:&amp;quot;0&amp;quot;,&lt;br /&gt;
      &amp;quot;height&amp;quot;:&amp;quot;10&amp;quot;,&lt;br /&gt;
      &amp;quot;width&amp;quot;:&amp;quot;20&amp;quot;,&lt;br /&gt;
      &amp;quot;comment&amp;quot;:&amp;quot;train current position rectangle&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== VisB DEFINITIONS ==&lt;br /&gt;
As of version 1.12 you can also provide many of the VisB annotations via B DEFINITIONS.&lt;br /&gt;
This can be done in addition to a VisB JSON file or completely replacing the JSON file.&lt;br /&gt;
&lt;br /&gt;
By adding this definition to your B machine you specify that you wish to use an empty&lt;br /&gt;
SVG file as base:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With a VISB_SVG_BOX definition you can set the size of the generated empty SVG file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_SVG_BOX == rec(height:floor(vscale)*25+20, width:1800);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: you can also provide an optional &amp;lt;tt&amp;gt;viewBox&amp;lt;/tt&amp;gt; attribute as a B string.&lt;br /&gt;
&lt;br /&gt;
Via VISB_SVG_CONTENTS definitions you can add new textual content to the base SVG file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   VISB_SVG_CONTENTS == &#039;&#039;&#039;&lt;br /&gt;
   &amp;lt;defs&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
```;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With definitions starting with with VISB_SVG_OBJECTS you can add new SVG objects:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_SVG_OBJECTS1 == rec(`svg_class`:&amp;quot;rect&amp;quot;,`id`:&amp;quot;i1&amp;quot;,x:20,y:20,height:20,width:20,fill:&amp;quot;blue&amp;quot;);&lt;br /&gt;
  VISB_SVG_OBJECTS2 == rec(`svg_class`:&amp;quot;circle&amp;quot;,`id`:&amp;quot;i2&amp;quot;,cx:30,cy:30,r:20,fill:&amp;quot;red&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Each definition can either add a single record or add a set of records in one go.&lt;br /&gt;
The definition should only depend on base sets or constants of the model (see, however, notes for ProB 1.13.0 or later below).&lt;br /&gt;
In addition the constants used in the above definitions should only have one possible value.&lt;br /&gt;
For example, suppose that the constant P has 5 elements then this will create 5 SVG lines.&lt;br /&gt;
Observe that we use the new Event-B-style set comprehension for convenience and that tuples can be used for the &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; field..&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_SVG_OBJECTS3 == {i•i:P|rec(`svg_class`:&amp;quot;line&amp;quot;,`id`:(&amp;quot;line&amp;quot;,i),x1:0,y1:i,x2:i,y2:i)};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, you can use VISB_SVG_UPDATES definitions to specify attributes that depend on the&lt;br /&gt;
value of constants and variables of the animated B model:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_SVG_UPDATES1== rec(`id`:&amp;quot;i2&amp;quot;,fill: IF x&amp;gt;0 THEN &amp;quot;red&amp;quot; ELSE &amp;quot;green&amp;quot; END);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hovers can be defined using VISB_SVG_HOVER definitions (only for objects that have been created with VISB_SVG_OBJECTS) and click events can be defined using&lt;br /&gt;
VISB_SVG_EVENTS definitions with attributes &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; and optionally &amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Here is a minimal example that just uses the VisB DEFINITIONS without any external JSON or SVG file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE button_def&lt;br /&gt;
// An example that uses VisB DEFINITIONS instead of a JSON and SVG file&lt;br /&gt;
DEFINITIONS &lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;&amp;quot;;&lt;br /&gt;
  VISB_SVG_BOX == rec(height:200, width:240);&lt;br /&gt;
  VISB_SVG_OBJECTS == rec(`id`:&amp;quot;button&amp;quot;, svg_class:&amp;quot;circle&amp;quot;,&lt;br /&gt;
     cx:&amp;quot;100&amp;quot;,cy:&amp;quot;100&amp;quot;, r:&amp;quot;80&amp;quot;, stroke:&amp;quot;black&amp;quot;, `stroke-width`:&amp;quot;3&amp;quot;);&lt;br /&gt;
  VISB_SVG_UPDATES == rec(`id`:&amp;quot;button&amp;quot;,&lt;br /&gt;
     fill: IF button=TRUE THEN &amp;quot;green&amp;quot; ELSE &amp;quot;red&amp;quot; END);&lt;br /&gt;
  VISB_SVG_HOVERS == rec(`id`:&amp;quot;button&amp;quot;,&lt;br /&gt;
     stroke:&amp;quot;gray&amp;quot;, `stroke-width`:&amp;quot;5&amp;quot;);&lt;br /&gt;
  VISB_SVG_EVENTS == rec(`id`:&amp;quot;button&amp;quot;, event:&amp;quot;toggle_button&amp;quot;, predicate:&amp;quot;btrue&amp;quot;)&lt;br /&gt;
VARIABLES button&lt;br /&gt;
INVARIANT button:BOOL&lt;br /&gt;
INITIALISATION button := FALSE&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  toggle_button = BEGIN&lt;br /&gt;
    button:= bool(button=FALSE)&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 1.13.0 of ProB you can also use dynamic expressions in object definitions; the above definitions can thus be written more compactly:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_SVG_OBJECTS == rec(`id`:&amp;quot;button&amp;quot;, svg_class:&amp;quot;circle&amp;quot;,&lt;br /&gt;
     cx:100,cy:100, r:80, stroke:&amp;quot;black&amp;quot;, `stroke-width`:3,&lt;br /&gt;
     fill: IF button=TRUE THEN &amp;quot;green&amp;quot; ELSE &amp;quot;red&amp;quot; END,&lt;br /&gt;
    event:&amp;quot;toggle_button&amp;quot;,&lt;br /&gt;
    hovers: rec(stroke:&amp;quot;gray&amp;quot;, `stroke-width`:&amp;quot;5&amp;quot;));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In 1.13.0 you can also use a &amp;quot;children&amp;quot; attribute to specify groups.&lt;br /&gt;
The children attribute should evaluate to a set of strings pointing to ids of SVG objects.&lt;br /&gt;
The following example shows this for for defining the children of &amp;quot;mygroup&amp;quot;.&lt;br /&gt;
Also observe the use of the new [[Summary_of_B_Syntax#Strings:|template string syntax]] for the transform attribute.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    VISB_SVG_FILE == &amp;quot;&amp;quot;;&lt;br /&gt;
    VISB_SVG_BOX == rec(height:400, width:450);&lt;br /&gt;
    VISB_SVG_OBJECTS1 == {i•i:0..9|rec(`id`:(&amp;quot;r&amp;quot;,i), svg_class:&amp;quot;rect&amp;quot;,&lt;br /&gt;
                                   fill:IF i=x THEN &amp;quot;red&amp;quot; ELSE &amp;quot;green&amp;quot; END,&lt;br /&gt;
                                   x:10+10*i, y:100, height:20, width:4)};&lt;br /&gt;
    VISB_SVG_OBJECTS2 == rec(`id`:&amp;quot;mygroup&amp;quot;, svg_class:&amp;quot;g&amp;quot;,&lt;br /&gt;
                             children: {i•i:0..9|(&amp;quot;r&amp;quot;,i)},&lt;br /&gt;
                             transform:```rotate(${x*40},50,100)```&lt;br /&gt;
                            )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Version 1.13.1 also adds a new virtual &amp;lt;tt&amp;gt;title&amp;lt;/tt&amp;gt; attribute that can be set in such SVG_OBJECTS.&lt;br /&gt;
This will create a tooltip box displaying the value of the attribute. (Internally this gets transformed into children SVG title objects.) These tooltips are independent of the other VisB hovers (and in contrast to these hovers the value of the title attribute can be dynamic, i.e., depend on the model&#039;s variables).&lt;br /&gt;
&lt;br /&gt;
In VisB event predicates, the local identifier &amp;lt;tt&amp;gt;VISB_CLICK_META_INFOS&amp;lt;/tt&amp;gt; can be used to access information like shift or command key presses and mouse positions during a click. It represents a record of the following type:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   struct(altKey:   BOOL,&lt;br /&gt;
          ctrlKey:  BOOL,&lt;br /&gt;
          jsVars:   STRING &amp;lt;-&amp;gt; STRING,&lt;br /&gt;
          metaKey:  BOOL,&lt;br /&gt;
          pageX:    INTEGER,&lt;br /&gt;
          pageY:    INTEGER,&lt;br /&gt;
          shiftKey: BOOL&lt;br /&gt;
   )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It also enables usage of JavaScript values: &amp;lt;tt&amp;gt;VISB_CLICK_META_INFOS&#039;jsVars(&amp;quot;MYID&amp;quot;)&amp;lt;/tt&amp;gt;. The value must first be assigned in a &amp;lt;tt&amp;gt;script&amp;lt;/tt&amp;gt; tag in the SVG using &amp;lt;tt&amp;gt;visb_vars[&amp;quot;MYID&amp;quot;]&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
Some examples can be found in the  [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples visb-visualisation-examples] repository.&lt;br /&gt;
We have a small [https://gitlab.cs.uni-duesseldorf.de/general/stups/prob2-jupyter-kernel/-/blob/master/notebooks/manual/VisB_Features.ipynb Jupyter notebook manual] on the DEFINITION features of VisB.&lt;br /&gt;
More details and examples will be added later.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
&lt;br /&gt;
* Beware that you need to escape quotation marks and slashes in the JSON file for fields containing B expressions. Also, you cannot use newline.&lt;br /&gt;
* Hovers are currently evaluated once statically and cannot make use of B expressions. To make hover information dependent on the state, use the visibility attribute to make hidden SVG objects (which can be adapted depending on the state using VisB items) visible. The [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples/-/tree/master/Train train VisB example] illustrates this idea.&lt;br /&gt;
&lt;br /&gt;
== Tips and Tricks ==&lt;br /&gt;
&lt;br /&gt;
It is sometimes useful to use simple coordinates for your VisB items and B expressions, e.g. x coordinates of 0..100.&lt;br /&gt;
You can quite often do this and use the SVG  &amp;lt;b&amp;gt;transform&amp;lt;/b&amp;gt; attribute to scale and move the SVG object to the right place.&lt;br /&gt;
The simple  [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples/-/tree/master/Train train VisB example] shows how to do this.&lt;br /&gt;
In essence your SVG file can contain this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;polygon id = &amp;quot;ttd_polyline&amp;quot;&lt;br /&gt;
       points=&amp;quot;0,0 100,0&amp;quot;&lt;br /&gt;
       stroke=&amp;quot;gray&amp;quot; fill=&amp;quot;none&amp;quot;&lt;br /&gt;
       transform=&amp;quot;translate(10,22.5)&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
and the VisB JSON file contains this, making use of LibrarySVG.def (automatically available) external function &amp;lt;b&amp;gt;svg_axis&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;ttd_polyline&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;points&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;svg_axis({0} \\/ ran(%tt.(tt:TTDS|1+max(TTD_TrackElements(tt)))),100.0/real(TrackElementNumber+1),100.0,2.0)&amp;quot;,&lt;br /&gt;
      &amp;quot;comment&amp;quot;:&amp;quot;show ticks for TTD Limits&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Observe that we had to escape the slash of the union operator.&lt;br /&gt;
Also observe, that we are able to use [[Summary_of_B_Syntax#Reals:|floating numbers]] in the new version of ProB, which is very useful for VisB visualisations.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It can be useful to use style and class to make it easier to change your color scheme or other styling attributes within your visualisation consistently.&lt;br /&gt;
Again, the simple  [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples/-/tree/master/Train train VisB example] shows how to do this.&lt;br /&gt;
E.g., your SVG file could contain towards the top this definition:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;style id=&amp;quot;style_ttd_ts_mp&amp;quot;&amp;gt;&lt;br /&gt;
        .ttd {&lt;br /&gt;
            stroke : none;&lt;br /&gt;
            stroke-width: 0.2;&lt;br /&gt;
            opacity: 0.7&lt;br /&gt;
        }&lt;br /&gt;
        .red-occupied-ttd {&lt;br /&gt;
            fill : red&lt;br /&gt;
        }&lt;br /&gt;
   &amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Later you can then use it to style your objects:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;polygon id = &amp;quot;occupied_ttd_polygon&amp;quot;&lt;br /&gt;
       points=&amp;quot;0,0 0,2 10,2 10,0 70,0 70,1 90,1 90,0&amp;quot;&lt;br /&gt;
       class = &amp;quot;ttd red-occupied-ttd&amp;quot;&lt;br /&gt;
       transform=&amp;quot;translate(10,23)&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then modify the class using VisB items. Classes can also be useful for hovers, by simply exchanging one style for another when the mouse is over an objects (again, see [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples/-/tree/master/Train the train example]).&lt;br /&gt;
Recent versions of ProB also support adding and removing a class, which is useful for hovers when the class is modified by VisB items:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;train_polygon_tr1&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;:&amp;quot;TrainMoveForward&amp;quot;,&lt;br /&gt;
      &amp;quot;hovers&amp;quot;: [{ &amp;quot;attr&amp;quot;:&amp;quot;class&amp;quot;, &amp;quot;enter&amp;quot;:&amp;quot;+train-hover&amp;quot;, &amp;quot;leave&amp;quot;:&amp;quot;-train-hover&amp;quot;}]&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Debugging and HTML Export ==&lt;br /&gt;
&lt;br /&gt;
In classical B models you can store your default VisB visualisation in the DEFINITIONS section:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  DEFINITIONS&lt;br /&gt;
    VISB_JSON_FILE == &amp;quot;TwoTrains.json&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For debugging it can be useful to use VisB within ProB Tcl/Tk: if you choose to visualise the current state with VisB, ProB will generate a stand-alone HTML file which is opened in a browser.&lt;br /&gt;
In the browser you can open the (Javascript) developer console and you will be alerted to warnings and errors (which unfortunately, are currently not shown in ProB2-UI).&lt;br /&gt;
Upon changing the state in the animator, the HTML file will be regenerated and the VisB file re-loaded if necessary.&lt;br /&gt;
The HTML export also displays hovers, but cannot react to clicks.&lt;br /&gt;
The HTML export is also available in ProB2-UI (in the export menu in the top-right corner).&lt;br /&gt;
&lt;br /&gt;
ProB can also export the entire animation history to a standalone HTML file that can be passed to other persons (without requiring access to the B model or to ProB).&lt;br /&gt;
In ProB Tcl/Tk you can right-click on the history pane and choose &amp;quot;View History in VisB&amp;quot;.&lt;br /&gt;
In probcli you can use the command &amp;lt;tt&amp;gt;-visb JSONFILE HTMLFILE&amp;lt;/tt&amp;gt; to export the history.&lt;br /&gt;
In ProB2-UI you can click on the export icon in the upper right hand corner:&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2UI_VisB_View_Export.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The ProB2-UI table visualisation view (Visualisation menu) also contains tables to help debug VisB items and events:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2UI_VisB_Debug_Table_View.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
This view is also available in ProB Tcl/Tk in the Visualize menu (States submenu).&lt;br /&gt;
ProB2-UI also has another inspection view that can be obtained by clicking on the &amp;quot;i&amp;quot; (info) icon in the the VisB toolbar.&lt;br /&gt;
&lt;br /&gt;
=== Using the VisB exported HTML file ===&lt;br /&gt;
&lt;br /&gt;
You should be able to open the exported HTML using a regular browser.&lt;br /&gt;
Within the web page (see the image below) you can then do the following:&lt;br /&gt;
* single step through the trace by clicking the &amp;quot;Forward&amp;quot; and &amp;quot;Backward&amp;quot; buttons, or clicking on individual steps of the trace&lt;br /&gt;
* execute the entire trace nd see changes to the visualisation by clicking one of the &amp;quot;Run Trace&amp;quot; buttons&lt;br /&gt;
* you can inspect the value of the sets, constants and variables at every step by expanding the corresponding tabs&lt;br /&gt;
Some meta information can be found at the bottom of the trace.&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2UI_VisB_View_ExportedHTML.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
== Citing VisB ==&lt;br /&gt;
This is the Bibtex entry for an article about VisB  [https://rdcu.be/b4rqh in the ABZ&#039;2020 proceedings]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@inproceedings{WerthLeuschel:abz2020,&lt;br /&gt;
  author    = {Michelle Werth and Michael Leuschel},&lt;br /&gt;
  title     = {{VisB}: A Lightweight Tool to Visualize Formal Models with {SVG} Graphics},&lt;br /&gt;
  booktitle = {Proceedings ABZ 2020},&lt;br /&gt;
  editor=&amp;quot;Raschke, Alexander and M{\&#039;e}ry, Dominique and Houdek, Frank&amp;quot;,&lt;br /&gt;
  year      = {2020},&lt;br /&gt;
  series = {LNCS 12071},&lt;br /&gt;
  pages = &amp;quot;260--265&amp;quot;,&lt;br /&gt;
  isbn=&amp;quot;978-3-030-48077-6&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing the VisB plugin for older ProB2-UI versions ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The following instructions are for ProB2-UI version 1.0.0 &#039;&#039;&#039;only&#039;&#039;&#039;. On current versions of ProB2-UI (1.1.0 and later), VisB is included by default and &#039;&#039;&#039;does not need to be installed separately&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
To install the VisB plugin in ProB2-UI 1.0.0 you need to:&lt;br /&gt;
&lt;br /&gt;
# [https://www3.hhu.de/stups/downloads/prob2/plugins/VisB-1.0.0.jar Download the VisB plugin jar file].&lt;br /&gt;
# In the &amp;quot;Advanced&amp;quot; menu of ProB2-UI, choose &amp;quot;Plugin Menu&amp;quot;.&lt;br /&gt;
# Click on the &amp;quot;Add Plugin...&amp;quot; button.&lt;br /&gt;
# Select the VisB jar file that you have downloaded.&lt;br /&gt;
# Choose the &amp;quot;Open VisB&amp;quot; command in the Advanced menu to start VisB.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=VisB&amp;diff=5950</id>
		<title>VisB</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=VisB&amp;diff=5950"/>
		<updated>2025-04-04T07:35:03Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* VisB DEFINITIONS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;VisB&#039;&#039;&#039; is a visualisation feature of ProB based on SVG graphics and HTML.&lt;br /&gt;
&lt;br /&gt;
Initially VisB was developed for [[ProB2-UI]], the new user interface of ProB based on JavaFX and the ProB2-Java-API.&lt;br /&gt;
It is included in ProB2-UI version 1.1.0 and later, which [[Download#ProB2-UI using Java FX|can be downloaded here]].&lt;br /&gt;
Users of ProB2-UI version 1.0.0 can [[#Installing the VisB plugin for older ProB2-UI versions|install VisB as a plugin]].&lt;br /&gt;
We, however, recommend you use the latest ProB2-UI snapshot.&lt;br /&gt;
VisB is constantly being improved and the latest version contains several useful new features.&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2UI_VisB_View.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
ProB Tcl/Tk and probcli version 1.11.0 and later also support VisB visualisations:&lt;br /&gt;
&lt;br /&gt;
* with &amp;lt;tt&amp;gt;probcli File.mch ... -visb VISBJSONFILE HTMLFILE&amp;lt;/tt&amp;gt; you can export the animator&#039;s history to a self-contained HTML file including a visualisation of the states in the history&lt;br /&gt;
* in ProB Tcl/Tk you can visualise the current state or the history using a VisB visualisation file (it is shown in an external browser) by right clicking in the &amp;quot;State Properties&amp;quot; or the &amp;quot;History&amp;quot; pane.&lt;br /&gt;
Hovers work in both cases, but unlike in ProB2-UI, you cannot click to perform events.&lt;br /&gt;
&lt;br /&gt;
An article about VisB has been [https://rdcu.be/b4rqh published in the ABZ&#039;2020 proceedings].&lt;br /&gt;
&lt;br /&gt;
== Using VisB ==&lt;br /&gt;
&lt;br /&gt;
In current versions of [[ProB2-UI]] the VisB view is automatically shown in the center pane below the state view.&lt;br /&gt;
To start VisB in older versions of [[ProB2-UI]], choose the &amp;quot;Open VisB&amp;quot; command in the Visualisation menu,&lt;br /&gt;
or right-click in the &amp;quot;State Properties&amp;quot; pane of ProB Tcl/Tk and select &amp;quot;View Current State in VisB&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can now choose a JSON file which builds on top of  a SVG graphics file (more recent versions of VisB can also load visualisations from [[VisB#VisB_DEFINITIONS|definitions]].&lt;br /&gt;
The JSON file contains a reference to a SVG file, along with entries to modify attributes based on the current state of a B model and entries which specify how VisB should react to clicks on the SVG. The SVG file should contain object ids which are referenced in the JSON file.&lt;br /&gt;
&lt;br /&gt;
Here is a sample file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;svg&amp;quot;:&amp;quot;Train2.svg&amp;quot;,&lt;br /&gt;
  &amp;quot;items&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;Train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;visibility&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;IF 1:TRAIN THEN \&amp;quot;visible\&amp;quot; ELSE \&amp;quot;hidden\&amp;quot; END&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;Train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;fill&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;IF train_speed(1)&amp;gt;0 THEN \&amp;quot;blue\&amp;quot; ELSE \&amp;quot;orange\&amp;quot; END&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;Train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;x&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;train_back_loc(1)*10+20&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;Train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;width&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;train_length(1)*10&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
    ],&lt;br /&gt;
  &amp;quot;events&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;Train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;:&amp;quot;Train_Move1&amp;quot;,&lt;br /&gt;
      &amp;quot;predicates&amp;quot;:[&lt;br /&gt;
        &amp;quot;1=1&amp;quot;&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== VisB Attributes ==&lt;br /&gt;
&lt;br /&gt;
At the top-level a VisB JSON file contains these attributes:&lt;br /&gt;
* svg&lt;br /&gt;
* model-name&lt;br /&gt;
* include&lt;br /&gt;
* svg_objects&lt;br /&gt;
* definitions&lt;br /&gt;
* items&lt;br /&gt;
* events&lt;br /&gt;
&lt;br /&gt;
Below we explain them in more detail.&lt;br /&gt;
&lt;br /&gt;
=== SVG file and inclusion ===&lt;br /&gt;
&lt;br /&gt;
The main VisB Json file should contain an &amp;lt;tt&amp;gt;svg&amp;lt;/tt&amp;gt; attribute with a&lt;br /&gt;
relative or absolute path to the SVG file to be shown.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;model-name&amp;lt;/tt&amp;gt; attribute is optional; if set ProB will emit&lt;br /&gt;
a warning if the B model&#039;s name does not match the value of this attribute.&lt;br /&gt;
&lt;br /&gt;
One can also include subsidiary VisB Json files using the &amp;lt;tt&amp;gt;include&amp;lt;/tt&amp;gt;&lt;br /&gt;
attribute with again a relative or absolut path to another Json file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;svg&amp;quot;:&amp;quot;my_svg_file.svg&amp;quot;,&lt;br /&gt;
  &amp;quot;include&amp;quot;:&amp;quot;subsidiary_visb_file.json&amp;quot;,&lt;br /&gt;
  &amp;quot;items&amp;quot;:[&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The svg attribute in subsidiary files will be ignored.&lt;br /&gt;
You can override the VisB items in the included file (i.e., a VisB item for an id and attribute in the top-level file will override items for the same id and attribute in the included files).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Items and Events ===&lt;br /&gt;
&lt;br /&gt;
For VisB &amp;lt;tt&amp;gt;items&amp;lt;/tt&amp;gt; every entry needs&lt;br /&gt;
* &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, this is the identifier of an object in the associated SVG file&lt;br /&gt;
* &amp;lt;tt&amp;gt;attr&amp;lt;/tt&amp;gt; a valid SVG attribute&lt;br /&gt;
* &amp;lt;tt&amp;gt;value&amp;lt;/tt&amp;gt; a B formula which will be evaluated in the current state of a model and yields a new value for the above attribute.&lt;br /&gt;
&lt;br /&gt;
Note that the formula can  make use of the [[Summary_of_B_Syntax#Reals |REAL datatype]]  and also use many of the [[External_Functions|external functions]] e.g. from LibraryStrings or LibraySVG.&lt;br /&gt;
Here is an example VisB Item:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;items&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;: &amp;quot;x&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;100.0 + train_left(train1)&amp;quot;&lt;br /&gt;
    } ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As of version 1.12.2, ProB allows you to use a single attribute whose name is the SVG attribute being set, rather than two attributes (attr, value).&lt;br /&gt;
With this you can set multiple SVG attributes in one VisB item.&lt;br /&gt;
For example, you can now write:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;items&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;x&amp;quot;:&amp;quot;100.0 + train_left(train1)&amp;quot;,&lt;br /&gt;
      &amp;quot;y&amp;quot;:&amp;quot;20.0 + train_bottom(train1)&amp;quot;&lt;br /&gt;
    } ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For VisB &amp;lt;tt&amp;gt;events&amp;lt;/tt&amp;gt; every entry needs&lt;br /&gt;
* &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, this is the identifier of an object in the associated SVG file&lt;br /&gt;
* &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; a valid B operation or event of the loaded formal model&lt;br /&gt;
* &amp;lt;tt&amp;gt;predicates&amp;lt;/tt&amp;gt; an optional list of B predicates, which can be used to set parameters of the B operation that is executed upon a click&lt;br /&gt;
&lt;br /&gt;
Additionally VisB now recognises for both items and events:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;ignore&amp;lt;/tt&amp;gt;, if this attribute is present the item will be ignored&lt;br /&gt;
* &amp;lt;tt&amp;gt;repeat&amp;lt;/tt&amp;gt;, if this attribute is present the item will be replicated (see below). This construct requires a list of strings.&lt;br /&gt;
* &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, if this attribute is present the item will be replicated (see below). The for construct requires &amp;lt;tt&amp;gt;from&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;to&amp;lt;/tt&amp;gt; with integer values as sub arguments. As of version 1.11.1 you can also use constant B integer expressions accessing just the sets.&lt;br /&gt;
* &amp;lt;tt&amp;gt;optional&amp;lt;/tt&amp;gt;, if this boolean attribute is &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt; an event will be ignored if the event name is not a valid top-level event/operation in the model. An item will be ignored if the identifiers in the formula do not exists (i.e., errors during type checking will be ignored)&lt;br /&gt;
* &amp;lt;tt&amp;gt;override&amp;lt;/tt&amp;gt;, if this boolean attribute is &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt; no warnings will be generated if another VisB item for the same attribute and id is overriden (as of version 1.11.1)&lt;br /&gt;
&lt;br /&gt;
Other attributes will be ignored. E.g, one can use a &amp;lt;tt&amp;gt;comment&amp;lt;/tt&amp;gt; attribute to add comments to the VisB items.&lt;br /&gt;
&lt;br /&gt;
When executing an event, VisB now performs the following replacements within the predicates of the event:&lt;br /&gt;
* &amp;lt;tt&amp;gt;%shiftKey&amp;lt;/tt&amp;gt; is replaced by TRUE if the shift key was pressed during the click, FALSE otherwise&lt;br /&gt;
* &amp;lt;tt&amp;gt;%metaKey&amp;lt;/tt&amp;gt; is replaced by TRUE if the shift key was pressed during the click, FALSE otherwise&lt;br /&gt;
* &amp;lt;tt&amp;gt;%pageX&amp;lt;/tt&amp;gt; is replaced by the x coordinate of the click relative to the top-left of the entire VisB SVG&lt;br /&gt;
* &amp;lt;tt&amp;gt;%pageY&amp;lt;/tt&amp;gt; is replaced by the y coordinate of the click relative to the top-left of the entire VisB SVG&lt;br /&gt;
&lt;br /&gt;
Finally, VisB events can be associated with mouse hover actions.&lt;br /&gt;
For this you just need to add an attribute &amp;lt;tt&amp;gt;hovers&amp;lt;/tt&amp;gt; which contains a list of JSON objects with the following attributes:&lt;br /&gt;
* &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, this is the identifier of an object in the associated SVG file; this attribute is optional; if it is not present the id specified in the VisB event will be used.&lt;br /&gt;
* &amp;lt;tt&amp;gt;attr&amp;lt;/tt&amp;gt; a valid SVG attribute&lt;br /&gt;
* &amp;lt;tt&amp;gt;enter&amp;lt;/tt&amp;gt; a value which will be used when the mouse enters the area of the object&lt;br /&gt;
* &amp;lt;tt&amp;gt;leave&amp;lt;/tt&amp;gt; a value which will be used to restore the attribute when the mouse leaves the area&lt;br /&gt;
Note that the enter and leave values have to be static at the moment; in future we plan to allow B formulas here and also apply the repetition/replacement mechanism specified above.&lt;br /&gt;
If you just wish to attach a hover to an SVG object (and no B operation/event) you can set the event field of the VisB event to the empty string (&amp;lt;tt&amp;gt;&amp;quot;event&amp;quot;:&amp;quot;&amp;quot;&amp;lt;/tt&amp;gt;).&lt;br /&gt;
You should not use attributes for the hover which are set by VisB items.&lt;br /&gt;
&lt;br /&gt;
Here is an example VisB event with hovers:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;button&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;: &amp;quot;toggle_button&amp;quot;,&lt;br /&gt;
      &amp;quot;hovers&amp;quot;: [{ &amp;quot;attr&amp;quot;:&amp;quot;stroke-width&amp;quot;, &amp;quot;enter&amp;quot;:&amp;quot;6&amp;quot;, &amp;quot;leave&amp;quot;:&amp;quot;1&amp;quot;},&lt;br /&gt;
                 { &amp;quot;attr&amp;quot;:&amp;quot;opacity&amp;quot;, &amp;quot;enter&amp;quot;:&amp;quot;0.8&amp;quot;, &amp;quot;leave&amp;quot;:&amp;quot;1.0&amp;quot;}]&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A VisB event can now also contain an list of items with the attributes &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;attr&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;enabled&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;disabled&amp;lt;/tt&amp;gt;.&lt;br /&gt;
When the associated event is enabled, the attribute of the SVG object with the given id is set to the  value provided in the enabled attribute, otherwise the disabled attribute value is used.&lt;br /&gt;
As above the item id is optional and defaults to the id of the VisB event.&lt;br /&gt;
Here is an example VisB event with hovers and an items list:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;button&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;: &amp;quot;press_button&amp;quot;,&lt;br /&gt;
      &amp;quot;hovers&amp;quot;: [{ &amp;quot;attr&amp;quot;:&amp;quot;stroke-width&amp;quot;, &amp;quot;enter&amp;quot;:&amp;quot;6&amp;quot;, &amp;quot;leave&amp;quot;:&amp;quot;1&amp;quot;}],&lt;br /&gt;
      &amp;quot;items&amp;quot;: [{&amp;quot;attr&amp;quot;:&amp;quot;fill&amp;quot;, &amp;quot;disabled&amp;quot;:&amp;quot;\&amp;quot;green\&amp;quot;&amp;quot;, &amp;quot;enabled&amp;quot;:&amp;quot;\&amp;quot;red\&amp;quot;&amp;quot;}]&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Replication / Loops ==&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;repeat&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; attributes to replicate a VisB&lt;br /&gt;
item or event.&lt;br /&gt;
Replication consists in duplicating the item or event, and replacing &amp;lt;tt&amp;gt;%0&amp;lt;/tt&amp;gt; within the identifier and value attributes of the time with the repeated string or integer.&lt;br /&gt;
&lt;br /&gt;
For example, the repeat instruction below will result in the creation of three VisB items, one for id &amp;lt;tt&amp;gt;txt_ttd1&amp;lt;/tt&amp;gt;,  for &amp;lt;tt&amp;gt;txt_ttd2&amp;lt;/tt&amp;gt;,  and one for &amp;lt;tt&amp;gt;txt_ttd3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The value formula for &amp;lt;tt&amp;gt;txt_ttd1&amp;lt;/tt&amp;gt; is &amp;lt;tt&amp;gt;&amp;quot;IF 1: dom(TTD) THEN visb_ttd_back(%0) ELSE -1000 END&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
     &amp;quot;repeat&amp;quot;: [&amp;quot;1&amp;quot;,&amp;quot;2&amp;quot;,&amp;quot;3&amp;quot;],&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;txt_ttd%0&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;x&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;IF %0: dom(TTD) THEN visb_ttd_back(%0) ELSE -1000 END&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A for loop can be used instead for the above example as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
     &amp;quot;for&amp;quot;: {&amp;quot;from&amp;quot;:1, &amp;quot;to&amp;quot;:3},&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;txt_ttd%0&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;x&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;IF %0: dom(TTD) THEN visb_ttd_back(%0) ELSE -1000 END&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The for loop also allows an optional &amp;lt;tt&amp;gt;step&amp;lt;/tt&amp;gt; attribute.&lt;br /&gt;
&lt;br /&gt;
It is possible to apply both &amp;lt;tt&amp;gt;repeat&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; attributes at the same time, as this example shows.&lt;br /&gt;
(The exact details of multiple iterations for a VisB item might change in future.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
     &amp;quot;repeat&amp;quot;: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],&lt;br /&gt;
     &amp;quot;for&amp;quot;: {&amp;quot;from&amp;quot;:1, &amp;quot;to&amp;quot;:20},&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;tile%1x%0&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;: &amp;quot;TryQueen&amp;quot;,&lt;br /&gt;
      &amp;quot;hovers&amp;quot;: [{ &amp;quot;attr&amp;quot;:&amp;quot;opacity&amp;quot;, &amp;quot;enter&amp;quot;:&amp;quot;0.5&amp;quot;, &amp;quot;leave&amp;quot;:&amp;quot;1&amp;quot;}],&lt;br /&gt;
      &amp;quot;predicates&amp;quot; : [&amp;quot;i=%1&amp;quot;,&amp;quot;j=%0&amp;quot;] &lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 1.11.0 you can also use nested for loops.&lt;br /&gt;
As of version 1.11.1 of ProB you can also use B expressions for the &amp;lt;tt&amp;gt;from&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;to&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;step&amp;lt;/tt&amp;gt; attributes of a for loop.&lt;br /&gt;
However, these expressions must be evaluable without having access to any constants or variables. Indeed, the for and repeat loops are processed once when loading a VisB file, independently of any given state.&lt;br /&gt;
So, you can only access identifiers of &amp;lt;tt&amp;gt;SETS&amp;lt;/tt&amp;gt; section of a B machine.&lt;br /&gt;
It may still be useful, e.g., to iterate over an enumerated or deferred set (TRAINS below):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
     &amp;quot;for&amp;quot;: {&amp;quot;from&amp;quot;:1, &amp;quot;to&amp;quot;:&amp;quot;card(TRAINS)&amp;quot;},&lt;br /&gt;
...&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;INT_TO_ENUM&amp;lt;/tt&amp;gt; external function available as of ProB 1.11.1 can be useful in expressions here to convert the iteration variable back to an enumerated or deferred set element.&lt;br /&gt;
For example, &amp;lt;tt&amp;gt;INT_TO_ENUM(TRAINS,1)&amp;lt;/tt&amp;gt; refers to the first element of the set &amp;lt;tt&amp;gt;TRAINS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== VisB Definitions (in JSON file) ==&lt;br /&gt;
&lt;br /&gt;
As of ProB Tcl/Tk 1.11.0 it is possible to include local definitions in the VisB JSON  file.&lt;br /&gt;
Each definition has a name and a value formula.&lt;br /&gt;
Definitions are evaluated in order of appearance (a later definition can thus refer to an ealier one) and are evaluated in a state before evaluating VisB items.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;definitions&amp;quot;:[&lt;br /&gt;
    { &amp;quot;name&amp;quot;:&amp;quot;xscale&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot; : &amp;quot;(100.0 / real(NrOfTrackElements))&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    { &amp;quot;name&amp;quot;:&amp;quot;visb_train_rear&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot; : &amp;quot;%x.(x:dom(train_rear)|xscale * real(train_rear(x)))&amp;quot;&lt;br /&gt;
    }]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The VisB definitions are particularly useful for Event-B models (as you can use [[Summary_of_B_Syntax#Reals |REAL numbers]]  and also have access to [[External_Functions|external functions]] such as LibraryStrings or LibraySVG).&lt;br /&gt;
But they are &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; yet available for events in ProB2-UI.&lt;br /&gt;
&lt;br /&gt;
== VisB Additional SVG Objects ==&lt;br /&gt;
&lt;br /&gt;
As of version 1.12.0 of ProB Tcl/Tk you can add new SVG objects to your SVG file.&lt;br /&gt;
You can use for and repeat loops (see above) to create an arbitrary number of objects.&lt;br /&gt;
This is useful for making flexible visualisations which work with an arbitrary number&lt;br /&gt;
of objects.&lt;br /&gt;
The same rules and limitations for for/repeat loops apply as for items above.&lt;br /&gt;
&lt;br /&gt;
Every entry in the svg_objects list &lt;br /&gt;
* an &amp;lt;tt&amp;gt;svg_class&amp;lt;/tt&amp;gt; attribute, which can be, e.g., line, circle, rect, ...&lt;br /&gt;
* an object &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; attribute&lt;br /&gt;
* an optional &amp;lt;tt&amp;gt;comment&amp;lt;/tt&amp;gt; attribute&lt;br /&gt;
* any other attribute will be used to create the SVG object and should be valid for the specified svg_class&lt;br /&gt;
&lt;br /&gt;
Here is an example (taken from [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples/-/blob/master/Physics/n_bodies_visb.json here]) where NOBJS is a DEFINITION inside a B machine:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;svg_objects&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;for&amp;quot;:{&amp;quot;from&amp;quot;:1,&amp;quot;to&amp;quot;:&amp;quot;NOBJS&amp;quot;}, &lt;br /&gt;
      &amp;quot;svg_class&amp;quot;:&amp;quot;circle&amp;quot;,&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;body%0&amp;quot;,&lt;br /&gt;
      &amp;quot;cx&amp;quot;:&amp;quot;45&amp;quot;,&lt;br /&gt;
      &amp;quot;cy&amp;quot;:&amp;quot;15&amp;quot;,&lt;br /&gt;
      &amp;quot;r&amp;quot;:&amp;quot;10&amp;quot;,&lt;br /&gt;
      &amp;quot;stroke&amp;quot;:&amp;quot;black&amp;quot;,&lt;br /&gt;
      &amp;quot;stroke-width&amp;quot;:&amp;quot;0.5&amp;quot;,&lt;br /&gt;
      &amp;quot;fill&amp;quot;:&amp;quot;green&amp;quot;&lt;br /&gt;
    } ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is another example where TRAINS is a deferred or enumerated set of the B model being visualised:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;svg_objects&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;for&amp;quot;:{&amp;quot;from&amp;quot;:1,&amp;quot;to&amp;quot;:&amp;quot;card(TRAINS)&amp;quot;}, &lt;br /&gt;
      &amp;quot;svg_class&amp;quot;:&amp;quot;rect&amp;quot;,&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;fresh_train_rect%0&amp;quot;,&lt;br /&gt;
      &amp;quot;x&amp;quot;:&amp;quot;0&amp;quot;,&lt;br /&gt;
      &amp;quot;y&amp;quot;:&amp;quot;0&amp;quot;,&lt;br /&gt;
      &amp;quot;height&amp;quot;:&amp;quot;10&amp;quot;,&lt;br /&gt;
      &amp;quot;width&amp;quot;:&amp;quot;20&amp;quot;,&lt;br /&gt;
      &amp;quot;comment&amp;quot;:&amp;quot;train current position rectangle&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== VisB DEFINITIONS ==&lt;br /&gt;
As of version 1.12 you can also provide many of the VisB annotations via B DEFINITIONS.&lt;br /&gt;
This can be done in addition to a VisB JSON file or completely replacing the JSON file.&lt;br /&gt;
&lt;br /&gt;
By adding this definition to your B machine you specify that you wish to use an empty&lt;br /&gt;
SVG file as base:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With a VISB_SVG_BOX definition you can set the size of the generated empty SVG file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_SVG_BOX == rec(height:floor(vscale)*25+20, width:1800);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: you can also provide an optional &amp;lt;tt&amp;gt;viewBox&amp;lt;/tt&amp;gt; attribute as a B string.&lt;br /&gt;
&lt;br /&gt;
Via VISB_SVG_CONTENTS definitions you can add new textual content to the base SVG file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   VISB_SVG_CONTENTS == &#039;&#039;&#039;&lt;br /&gt;
   &amp;lt;defs&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
```;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With definitions starting with with VISB_SVG_OBJECTS you can add new SVG objects:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_SVG_OBJECTS1 == rec(`svg_class`:&amp;quot;rect&amp;quot;,`id`:&amp;quot;i1&amp;quot;,x:20,y:20,height:20,width:20,fill:&amp;quot;blue&amp;quot;);&lt;br /&gt;
  VISB_SVG_OBJECTS2 == rec(`svg_class`:&amp;quot;circle&amp;quot;,`id`:&amp;quot;i2&amp;quot;,cx:30,cy:30,r:20,fill:&amp;quot;red&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Each definition can either add a single record or add a set of records in one go.&lt;br /&gt;
The definition should only depend on base sets or constants of the model (see, however, notes for ProB 1.13.0 or later below).&lt;br /&gt;
In addition the constants used in the above definitions should only have one possible value.&lt;br /&gt;
For example, suppose that the constant P has 5 elements then this will create 5 SVG lines.&lt;br /&gt;
Observe that we use the new Event-B-style set comprehension for convenience and that tuples can be used for the &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; field..&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_SVG_OBJECTS3 == {i•i:P|rec(`svg_class`:&amp;quot;line&amp;quot;,`id`:(&amp;quot;line&amp;quot;,i),x1:0,y1:i,x2:i,y2:i)};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, you can use VISB_SVG_UPDATES definitions to specify attributes that depend on the&lt;br /&gt;
value of constants and variables of the animated B model:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_SVG_UPDATES1== rec(`id`:&amp;quot;i2&amp;quot;,fill: IF x&amp;gt;0 THEN &amp;quot;red&amp;quot; ELSE &amp;quot;green&amp;quot; END);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hovers can be defined using VISB_SVG_HOVER definitions (only for objects that have been created with VISB_SVG_OBJECTS) and click events can be defined using&lt;br /&gt;
VISB_SVG_EVENTS definitions with attributes &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; and optionally &amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Here is a minimal example that just uses the VisB DEFINITIONS without any external JSON or SVG file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE button_def&lt;br /&gt;
// An example that uses VisB DEFINITIONS instead of a JSON and SVG file&lt;br /&gt;
DEFINITIONS &lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;&amp;quot;;&lt;br /&gt;
  VISB_SVG_BOX == rec(height:200, width:240);&lt;br /&gt;
  VISB_SVG_OBJECTS == rec(`id`:&amp;quot;button&amp;quot;, svg_class:&amp;quot;circle&amp;quot;,&lt;br /&gt;
     cx:&amp;quot;100&amp;quot;,cy:&amp;quot;100&amp;quot;, r:&amp;quot;80&amp;quot;, stroke:&amp;quot;black&amp;quot;, `stroke-width`:&amp;quot;3&amp;quot;);&lt;br /&gt;
  VISB_SVG_UPDATES == rec(`id`:&amp;quot;button&amp;quot;,&lt;br /&gt;
     fill: IF button=TRUE THEN &amp;quot;green&amp;quot; ELSE &amp;quot;red&amp;quot; END);&lt;br /&gt;
  VISB_SVG_HOVERS == rec(`id`:&amp;quot;button&amp;quot;,&lt;br /&gt;
     stroke:&amp;quot;gray&amp;quot;, `stroke-width`:&amp;quot;5&amp;quot;);&lt;br /&gt;
  VISB_SVG_EVENTS == rec(`id`:&amp;quot;button&amp;quot;, event:&amp;quot;toggle_button&amp;quot;, predicate:&amp;quot;btrue&amp;quot;)&lt;br /&gt;
VARIABLES button&lt;br /&gt;
INVARIANT button:BOOL&lt;br /&gt;
INITIALISATION button := FALSE&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  toggle_button = BEGIN&lt;br /&gt;
    button:= bool(button=FALSE)&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 1.13.0 of ProB you can also use dynamic expressions in object definitions; the above definitions can thus be written more compactly:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_SVG_OBJECTS == rec(`id`:&amp;quot;button&amp;quot;, svg_class:&amp;quot;circle&amp;quot;,&lt;br /&gt;
     cx:100,cy:100, r:80, stroke:&amp;quot;black&amp;quot;, `stroke-width`:3,&lt;br /&gt;
     fill: IF button=TRUE THEN &amp;quot;green&amp;quot; ELSE &amp;quot;red&amp;quot; END,&lt;br /&gt;
    event:&amp;quot;toggle_button&amp;quot;,&lt;br /&gt;
    hovers: rec(stroke:&amp;quot;gray&amp;quot;, `stroke-width`:&amp;quot;5&amp;quot;));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In 1.13.0 you can also use a &amp;quot;children&amp;quot; attribute to specify groups.&lt;br /&gt;
The children attribute should evaluate to a set of strings pointing to ids of SVG objects.&lt;br /&gt;
The following example shows this for for defining the children of &amp;quot;mygroup&amp;quot;.&lt;br /&gt;
Also observe the use of the new [[Summary_of_B_Syntax#Strings:|template string syntax]] for the transform attribute.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    VISB_SVG_FILE == &amp;quot;&amp;quot;;&lt;br /&gt;
    VISB_SVG_BOX == rec(height:400, width:450);&lt;br /&gt;
    VISB_SVG_OBJECTS1 == {i•i:0..9|rec(`id`:(&amp;quot;r&amp;quot;,i), svg_class:&amp;quot;rect&amp;quot;,&lt;br /&gt;
                                   fill:IF i=x THEN &amp;quot;red&amp;quot; ELSE &amp;quot;green&amp;quot; END,&lt;br /&gt;
                                   x:10+10*i, y:100, height:20, width:4)};&lt;br /&gt;
    VISB_SVG_OBJECTS2 == rec(`id`:&amp;quot;mygroup&amp;quot;, svg_class:&amp;quot;g&amp;quot;,&lt;br /&gt;
                             children: {i•i:0..9|(&amp;quot;r&amp;quot;,i)},&lt;br /&gt;
                             transform:```rotate(${x*40},50,100)```&lt;br /&gt;
                            )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Version 1.13.1 also adds a new virtual &amp;lt;tt&amp;gt;title&amp;lt;/tt&amp;gt; attribute that can be set in such SVG_OBJECTS.&lt;br /&gt;
This will create a tooltip box displaying the value of the attribute. (Internally this gets transformed into children SVG title objects.) These tooltips are independent of the other VisB hovers (and in contrast to these hovers the value of the title attribute can be dynamic, i.e., depend on the model&#039;s variables).&lt;br /&gt;
&lt;br /&gt;
In VisB event predicates, the local identifier &amp;lt;tt&amp;gt;VISB_CLICK_META_INFOS&amp;lt;/tt&amp;gt; can be used to access information like shift or command key presses and mouse positions during a click. It represents a record of the following type:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   rec(altKey:    BOOL,&lt;br /&gt;
       ctrlKey:   BOOL,&lt;br /&gt;
       jsVars:    STRING &amp;lt;-&amp;gt; STRING,&lt;br /&gt;
       metaKey:   BOOL,&lt;br /&gt;
       pageX:     INTEGER,&lt;br /&gt;
       pageY:     INTEGER,&lt;br /&gt;
       shiftKey:  BOOL&lt;br /&gt;
   )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It also enables usage of JavaScript values: &amp;lt;tt&amp;gt;VISB_CLICK_META_INFOS&#039;jsVars(&amp;quot;MYID&amp;quot;)&amp;lt;/tt&amp;gt;. The value must first be assigned in a &amp;lt;tt&amp;gt;script&amp;lt;/tt&amp;gt; tag in the SVG using &amp;lt;tt&amp;gt;visb_vars[&amp;quot;MYID&amp;quot;]&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
Some examples can be found in the  [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples visb-visualisation-examples] repository.&lt;br /&gt;
We have a small [https://gitlab.cs.uni-duesseldorf.de/general/stups/prob2-jupyter-kernel/-/blob/master/notebooks/manual/VisB_Features.ipynb Jupyter notebook manual] on the DEFINITION features of VisB.&lt;br /&gt;
More details and examples will be added later.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
&lt;br /&gt;
* Beware that you need to escape quotation marks and slashes in the JSON file for fields containing B expressions. Also, you cannot use newline.&lt;br /&gt;
* Hovers are currently evaluated once statically and cannot make use of B expressions. To make hover information dependent on the state, use the visibility attribute to make hidden SVG objects (which can be adapted depending on the state using VisB items) visible. The [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples/-/tree/master/Train train VisB example] illustrates this idea.&lt;br /&gt;
&lt;br /&gt;
== Tips and Tricks ==&lt;br /&gt;
&lt;br /&gt;
It is sometimes useful to use simple coordinates for your VisB items and B expressions, e.g. x coordinates of 0..100.&lt;br /&gt;
You can quite often do this and use the SVG  &amp;lt;b&amp;gt;transform&amp;lt;/b&amp;gt; attribute to scale and move the SVG object to the right place.&lt;br /&gt;
The simple  [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples/-/tree/master/Train train VisB example] shows how to do this.&lt;br /&gt;
In essence your SVG file can contain this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;polygon id = &amp;quot;ttd_polyline&amp;quot;&lt;br /&gt;
       points=&amp;quot;0,0 100,0&amp;quot;&lt;br /&gt;
       stroke=&amp;quot;gray&amp;quot; fill=&amp;quot;none&amp;quot;&lt;br /&gt;
       transform=&amp;quot;translate(10,22.5)&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
and the VisB JSON file contains this, making use of LibrarySVG.def (automatically available) external function &amp;lt;b&amp;gt;svg_axis&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;ttd_polyline&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;points&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;svg_axis({0} \\/ ran(%tt.(tt:TTDS|1+max(TTD_TrackElements(tt)))),100.0/real(TrackElementNumber+1),100.0,2.0)&amp;quot;,&lt;br /&gt;
      &amp;quot;comment&amp;quot;:&amp;quot;show ticks for TTD Limits&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Observe that we had to escape the slash of the union operator.&lt;br /&gt;
Also observe, that we are able to use [[Summary_of_B_Syntax#Reals:|floating numbers]] in the new version of ProB, which is very useful for VisB visualisations.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It can be useful to use style and class to make it easier to change your color scheme or other styling attributes within your visualisation consistently.&lt;br /&gt;
Again, the simple  [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples/-/tree/master/Train train VisB example] shows how to do this.&lt;br /&gt;
E.g., your SVG file could contain towards the top this definition:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;style id=&amp;quot;style_ttd_ts_mp&amp;quot;&amp;gt;&lt;br /&gt;
        .ttd {&lt;br /&gt;
            stroke : none;&lt;br /&gt;
            stroke-width: 0.2;&lt;br /&gt;
            opacity: 0.7&lt;br /&gt;
        }&lt;br /&gt;
        .red-occupied-ttd {&lt;br /&gt;
            fill : red&lt;br /&gt;
        }&lt;br /&gt;
   &amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Later you can then use it to style your objects:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;polygon id = &amp;quot;occupied_ttd_polygon&amp;quot;&lt;br /&gt;
       points=&amp;quot;0,0 0,2 10,2 10,0 70,0 70,1 90,1 90,0&amp;quot;&lt;br /&gt;
       class = &amp;quot;ttd red-occupied-ttd&amp;quot;&lt;br /&gt;
       transform=&amp;quot;translate(10,23)&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then modify the class using VisB items. Classes can also be useful for hovers, by simply exchanging one style for another when the mouse is over an objects (again, see [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples/-/tree/master/Train the train example]).&lt;br /&gt;
Recent versions of ProB also support adding and removing a class, which is useful for hovers when the class is modified by VisB items:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;train_polygon_tr1&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;:&amp;quot;TrainMoveForward&amp;quot;,&lt;br /&gt;
      &amp;quot;hovers&amp;quot;: [{ &amp;quot;attr&amp;quot;:&amp;quot;class&amp;quot;, &amp;quot;enter&amp;quot;:&amp;quot;+train-hover&amp;quot;, &amp;quot;leave&amp;quot;:&amp;quot;-train-hover&amp;quot;}]&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Debugging and HTML Export ==&lt;br /&gt;
&lt;br /&gt;
In classical B models you can store your default VisB visualisation in the DEFINITIONS section:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  DEFINITIONS&lt;br /&gt;
    VISB_JSON_FILE == &amp;quot;TwoTrains.json&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For debugging it can be useful to use VisB within ProB Tcl/Tk: if you choose to visualise the current state with VisB, ProB will generate a stand-alone HTML file which is opened in a browser.&lt;br /&gt;
In the browser you can open the (Javascript) developer console and you will be alerted to warnings and errors (which unfortunately, are currently not shown in ProB2-UI).&lt;br /&gt;
Upon changing the state in the animator, the HTML file will be regenerated and the VisB file re-loaded if necessary.&lt;br /&gt;
The HTML export also displays hovers, but cannot react to clicks.&lt;br /&gt;
The HTML export is also available in ProB2-UI (in the export menu in the top-right corner).&lt;br /&gt;
&lt;br /&gt;
ProB can also export the entire animation history to a standalone HTML file that can be passed to other persons (without requiring access to the B model or to ProB).&lt;br /&gt;
In ProB Tcl/Tk you can right-click on the history pane and choose &amp;quot;View History in VisB&amp;quot;.&lt;br /&gt;
In probcli you can use the command &amp;lt;tt&amp;gt;-visb JSONFILE HTMLFILE&amp;lt;/tt&amp;gt; to export the history.&lt;br /&gt;
In ProB2-UI you can click on the export icon in the upper right hand corner:&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2UI_VisB_View_Export.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The ProB2-UI table visualisation view (Visualisation menu) also contains tables to help debug VisB items and events:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2UI_VisB_Debug_Table_View.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
This view is also available in ProB Tcl/Tk in the Visualize menu (States submenu).&lt;br /&gt;
ProB2-UI also has another inspection view that can be obtained by clicking on the &amp;quot;i&amp;quot; (info) icon in the the VisB toolbar.&lt;br /&gt;
&lt;br /&gt;
=== Using the VisB exported HTML file ===&lt;br /&gt;
&lt;br /&gt;
You should be able to open the exported HTML using a regular browser.&lt;br /&gt;
Within the web page (see the image below) you can then do the following:&lt;br /&gt;
* single step through the trace by clicking the &amp;quot;Forward&amp;quot; and &amp;quot;Backward&amp;quot; buttons, or clicking on individual steps of the trace&lt;br /&gt;
* execute the entire trace nd see changes to the visualisation by clicking one of the &amp;quot;Run Trace&amp;quot; buttons&lt;br /&gt;
* you can inspect the value of the sets, constants and variables at every step by expanding the corresponding tabs&lt;br /&gt;
Some meta information can be found at the bottom of the trace.&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2UI_VisB_View_ExportedHTML.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
== Citing VisB ==&lt;br /&gt;
This is the Bibtex entry for an article about VisB  [https://rdcu.be/b4rqh in the ABZ&#039;2020 proceedings]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@inproceedings{WerthLeuschel:abz2020,&lt;br /&gt;
  author    = {Michelle Werth and Michael Leuschel},&lt;br /&gt;
  title     = {{VisB}: A Lightweight Tool to Visualize Formal Models with {SVG} Graphics},&lt;br /&gt;
  booktitle = {Proceedings ABZ 2020},&lt;br /&gt;
  editor=&amp;quot;Raschke, Alexander and M{\&#039;e}ry, Dominique and Houdek, Frank&amp;quot;,&lt;br /&gt;
  year      = {2020},&lt;br /&gt;
  series = {LNCS 12071},&lt;br /&gt;
  pages = &amp;quot;260--265&amp;quot;,&lt;br /&gt;
  isbn=&amp;quot;978-3-030-48077-6&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing the VisB plugin for older ProB2-UI versions ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The following instructions are for ProB2-UI version 1.0.0 &#039;&#039;&#039;only&#039;&#039;&#039;. On current versions of ProB2-UI (1.1.0 and later), VisB is included by default and &#039;&#039;&#039;does not need to be installed separately&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
To install the VisB plugin in ProB2-UI 1.0.0 you need to:&lt;br /&gt;
&lt;br /&gt;
# [https://www3.hhu.de/stups/downloads/prob2/plugins/VisB-1.0.0.jar Download the VisB plugin jar file].&lt;br /&gt;
# In the &amp;quot;Advanced&amp;quot; menu of ProB2-UI, choose &amp;quot;Plugin Menu&amp;quot;.&lt;br /&gt;
# Click on the &amp;quot;Add Plugin...&amp;quot; button.&lt;br /&gt;
# Select the VisB jar file that you have downloaded.&lt;br /&gt;
# Choose the &amp;quot;Open VisB&amp;quot; command in the Advanced menu to start VisB.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=VisB&amp;diff=5949</id>
		<title>VisB</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=VisB&amp;diff=5949"/>
		<updated>2025-04-04T07:29:37Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* VisB DEFINITIONS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;VisB&#039;&#039;&#039; is a visualisation feature of ProB based on SVG graphics and HTML.&lt;br /&gt;
&lt;br /&gt;
Initially VisB was developed for [[ProB2-UI]], the new user interface of ProB based on JavaFX and the ProB2-Java-API.&lt;br /&gt;
It is included in ProB2-UI version 1.1.0 and later, which [[Download#ProB2-UI using Java FX|can be downloaded here]].&lt;br /&gt;
Users of ProB2-UI version 1.0.0 can [[#Installing the VisB plugin for older ProB2-UI versions|install VisB as a plugin]].&lt;br /&gt;
We, however, recommend you use the latest ProB2-UI snapshot.&lt;br /&gt;
VisB is constantly being improved and the latest version contains several useful new features.&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2UI_VisB_View.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
ProB Tcl/Tk and probcli version 1.11.0 and later also support VisB visualisations:&lt;br /&gt;
&lt;br /&gt;
* with &amp;lt;tt&amp;gt;probcli File.mch ... -visb VISBJSONFILE HTMLFILE&amp;lt;/tt&amp;gt; you can export the animator&#039;s history to a self-contained HTML file including a visualisation of the states in the history&lt;br /&gt;
* in ProB Tcl/Tk you can visualise the current state or the history using a VisB visualisation file (it is shown in an external browser) by right clicking in the &amp;quot;State Properties&amp;quot; or the &amp;quot;History&amp;quot; pane.&lt;br /&gt;
Hovers work in both cases, but unlike in ProB2-UI, you cannot click to perform events.&lt;br /&gt;
&lt;br /&gt;
An article about VisB has been [https://rdcu.be/b4rqh published in the ABZ&#039;2020 proceedings].&lt;br /&gt;
&lt;br /&gt;
== Using VisB ==&lt;br /&gt;
&lt;br /&gt;
In current versions of [[ProB2-UI]] the VisB view is automatically shown in the center pane below the state view.&lt;br /&gt;
To start VisB in older versions of [[ProB2-UI]], choose the &amp;quot;Open VisB&amp;quot; command in the Visualisation menu,&lt;br /&gt;
or right-click in the &amp;quot;State Properties&amp;quot; pane of ProB Tcl/Tk and select &amp;quot;View Current State in VisB&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can now choose a JSON file which builds on top of  a SVG graphics file (more recent versions of VisB can also load visualisations from [[VisB#VisB_DEFINITIONS|definitions]].&lt;br /&gt;
The JSON file contains a reference to a SVG file, along with entries to modify attributes based on the current state of a B model and entries which specify how VisB should react to clicks on the SVG. The SVG file should contain object ids which are referenced in the JSON file.&lt;br /&gt;
&lt;br /&gt;
Here is a sample file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;svg&amp;quot;:&amp;quot;Train2.svg&amp;quot;,&lt;br /&gt;
  &amp;quot;items&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;Train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;visibility&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;IF 1:TRAIN THEN \&amp;quot;visible\&amp;quot; ELSE \&amp;quot;hidden\&amp;quot; END&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;Train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;fill&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;IF train_speed(1)&amp;gt;0 THEN \&amp;quot;blue\&amp;quot; ELSE \&amp;quot;orange\&amp;quot; END&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;Train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;x&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;train_back_loc(1)*10+20&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;Train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;width&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;train_length(1)*10&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
    ],&lt;br /&gt;
  &amp;quot;events&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;Train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;:&amp;quot;Train_Move1&amp;quot;,&lt;br /&gt;
      &amp;quot;predicates&amp;quot;:[&lt;br /&gt;
        &amp;quot;1=1&amp;quot;&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== VisB Attributes ==&lt;br /&gt;
&lt;br /&gt;
At the top-level a VisB JSON file contains these attributes:&lt;br /&gt;
* svg&lt;br /&gt;
* model-name&lt;br /&gt;
* include&lt;br /&gt;
* svg_objects&lt;br /&gt;
* definitions&lt;br /&gt;
* items&lt;br /&gt;
* events&lt;br /&gt;
&lt;br /&gt;
Below we explain them in more detail.&lt;br /&gt;
&lt;br /&gt;
=== SVG file and inclusion ===&lt;br /&gt;
&lt;br /&gt;
The main VisB Json file should contain an &amp;lt;tt&amp;gt;svg&amp;lt;/tt&amp;gt; attribute with a&lt;br /&gt;
relative or absolute path to the SVG file to be shown.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;model-name&amp;lt;/tt&amp;gt; attribute is optional; if set ProB will emit&lt;br /&gt;
a warning if the B model&#039;s name does not match the value of this attribute.&lt;br /&gt;
&lt;br /&gt;
One can also include subsidiary VisB Json files using the &amp;lt;tt&amp;gt;include&amp;lt;/tt&amp;gt;&lt;br /&gt;
attribute with again a relative or absolut path to another Json file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;svg&amp;quot;:&amp;quot;my_svg_file.svg&amp;quot;,&lt;br /&gt;
  &amp;quot;include&amp;quot;:&amp;quot;subsidiary_visb_file.json&amp;quot;,&lt;br /&gt;
  &amp;quot;items&amp;quot;:[&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The svg attribute in subsidiary files will be ignored.&lt;br /&gt;
You can override the VisB items in the included file (i.e., a VisB item for an id and attribute in the top-level file will override items for the same id and attribute in the included files).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Items and Events ===&lt;br /&gt;
&lt;br /&gt;
For VisB &amp;lt;tt&amp;gt;items&amp;lt;/tt&amp;gt; every entry needs&lt;br /&gt;
* &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, this is the identifier of an object in the associated SVG file&lt;br /&gt;
* &amp;lt;tt&amp;gt;attr&amp;lt;/tt&amp;gt; a valid SVG attribute&lt;br /&gt;
* &amp;lt;tt&amp;gt;value&amp;lt;/tt&amp;gt; a B formula which will be evaluated in the current state of a model and yields a new value for the above attribute.&lt;br /&gt;
&lt;br /&gt;
Note that the formula can  make use of the [[Summary_of_B_Syntax#Reals |REAL datatype]]  and also use many of the [[External_Functions|external functions]] e.g. from LibraryStrings or LibraySVG.&lt;br /&gt;
Here is an example VisB Item:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;items&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;: &amp;quot;x&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;100.0 + train_left(train1)&amp;quot;&lt;br /&gt;
    } ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As of version 1.12.2, ProB allows you to use a single attribute whose name is the SVG attribute being set, rather than two attributes (attr, value).&lt;br /&gt;
With this you can set multiple SVG attributes in one VisB item.&lt;br /&gt;
For example, you can now write:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;items&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;x&amp;quot;:&amp;quot;100.0 + train_left(train1)&amp;quot;,&lt;br /&gt;
      &amp;quot;y&amp;quot;:&amp;quot;20.0 + train_bottom(train1)&amp;quot;&lt;br /&gt;
    } ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For VisB &amp;lt;tt&amp;gt;events&amp;lt;/tt&amp;gt; every entry needs&lt;br /&gt;
* &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, this is the identifier of an object in the associated SVG file&lt;br /&gt;
* &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; a valid B operation or event of the loaded formal model&lt;br /&gt;
* &amp;lt;tt&amp;gt;predicates&amp;lt;/tt&amp;gt; an optional list of B predicates, which can be used to set parameters of the B operation that is executed upon a click&lt;br /&gt;
&lt;br /&gt;
Additionally VisB now recognises for both items and events:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;ignore&amp;lt;/tt&amp;gt;, if this attribute is present the item will be ignored&lt;br /&gt;
* &amp;lt;tt&amp;gt;repeat&amp;lt;/tt&amp;gt;, if this attribute is present the item will be replicated (see below). This construct requires a list of strings.&lt;br /&gt;
* &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, if this attribute is present the item will be replicated (see below). The for construct requires &amp;lt;tt&amp;gt;from&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;to&amp;lt;/tt&amp;gt; with integer values as sub arguments. As of version 1.11.1 you can also use constant B integer expressions accessing just the sets.&lt;br /&gt;
* &amp;lt;tt&amp;gt;optional&amp;lt;/tt&amp;gt;, if this boolean attribute is &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt; an event will be ignored if the event name is not a valid top-level event/operation in the model. An item will be ignored if the identifiers in the formula do not exists (i.e., errors during type checking will be ignored)&lt;br /&gt;
* &amp;lt;tt&amp;gt;override&amp;lt;/tt&amp;gt;, if this boolean attribute is &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt; no warnings will be generated if another VisB item for the same attribute and id is overriden (as of version 1.11.1)&lt;br /&gt;
&lt;br /&gt;
Other attributes will be ignored. E.g, one can use a &amp;lt;tt&amp;gt;comment&amp;lt;/tt&amp;gt; attribute to add comments to the VisB items.&lt;br /&gt;
&lt;br /&gt;
When executing an event, VisB now performs the following replacements within the predicates of the event:&lt;br /&gt;
* &amp;lt;tt&amp;gt;%shiftKey&amp;lt;/tt&amp;gt; is replaced by TRUE if the shift key was pressed during the click, FALSE otherwise&lt;br /&gt;
* &amp;lt;tt&amp;gt;%metaKey&amp;lt;/tt&amp;gt; is replaced by TRUE if the shift key was pressed during the click, FALSE otherwise&lt;br /&gt;
* &amp;lt;tt&amp;gt;%pageX&amp;lt;/tt&amp;gt; is replaced by the x coordinate of the click relative to the top-left of the entire VisB SVG&lt;br /&gt;
* &amp;lt;tt&amp;gt;%pageY&amp;lt;/tt&amp;gt; is replaced by the y coordinate of the click relative to the top-left of the entire VisB SVG&lt;br /&gt;
&lt;br /&gt;
Finally, VisB events can be associated with mouse hover actions.&lt;br /&gt;
For this you just need to add an attribute &amp;lt;tt&amp;gt;hovers&amp;lt;/tt&amp;gt; which contains a list of JSON objects with the following attributes:&lt;br /&gt;
* &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, this is the identifier of an object in the associated SVG file; this attribute is optional; if it is not present the id specified in the VisB event will be used.&lt;br /&gt;
* &amp;lt;tt&amp;gt;attr&amp;lt;/tt&amp;gt; a valid SVG attribute&lt;br /&gt;
* &amp;lt;tt&amp;gt;enter&amp;lt;/tt&amp;gt; a value which will be used when the mouse enters the area of the object&lt;br /&gt;
* &amp;lt;tt&amp;gt;leave&amp;lt;/tt&amp;gt; a value which will be used to restore the attribute when the mouse leaves the area&lt;br /&gt;
Note that the enter and leave values have to be static at the moment; in future we plan to allow B formulas here and also apply the repetition/replacement mechanism specified above.&lt;br /&gt;
If you just wish to attach a hover to an SVG object (and no B operation/event) you can set the event field of the VisB event to the empty string (&amp;lt;tt&amp;gt;&amp;quot;event&amp;quot;:&amp;quot;&amp;quot;&amp;lt;/tt&amp;gt;).&lt;br /&gt;
You should not use attributes for the hover which are set by VisB items.&lt;br /&gt;
&lt;br /&gt;
Here is an example VisB event with hovers:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;button&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;: &amp;quot;toggle_button&amp;quot;,&lt;br /&gt;
      &amp;quot;hovers&amp;quot;: [{ &amp;quot;attr&amp;quot;:&amp;quot;stroke-width&amp;quot;, &amp;quot;enter&amp;quot;:&amp;quot;6&amp;quot;, &amp;quot;leave&amp;quot;:&amp;quot;1&amp;quot;},&lt;br /&gt;
                 { &amp;quot;attr&amp;quot;:&amp;quot;opacity&amp;quot;, &amp;quot;enter&amp;quot;:&amp;quot;0.8&amp;quot;, &amp;quot;leave&amp;quot;:&amp;quot;1.0&amp;quot;}]&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A VisB event can now also contain an list of items with the attributes &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;attr&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;enabled&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;disabled&amp;lt;/tt&amp;gt;.&lt;br /&gt;
When the associated event is enabled, the attribute of the SVG object with the given id is set to the  value provided in the enabled attribute, otherwise the disabled attribute value is used.&lt;br /&gt;
As above the item id is optional and defaults to the id of the VisB event.&lt;br /&gt;
Here is an example VisB event with hovers and an items list:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;button&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;: &amp;quot;press_button&amp;quot;,&lt;br /&gt;
      &amp;quot;hovers&amp;quot;: [{ &amp;quot;attr&amp;quot;:&amp;quot;stroke-width&amp;quot;, &amp;quot;enter&amp;quot;:&amp;quot;6&amp;quot;, &amp;quot;leave&amp;quot;:&amp;quot;1&amp;quot;}],&lt;br /&gt;
      &amp;quot;items&amp;quot;: [{&amp;quot;attr&amp;quot;:&amp;quot;fill&amp;quot;, &amp;quot;disabled&amp;quot;:&amp;quot;\&amp;quot;green\&amp;quot;&amp;quot;, &amp;quot;enabled&amp;quot;:&amp;quot;\&amp;quot;red\&amp;quot;&amp;quot;}]&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Replication / Loops ==&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;repeat&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; attributes to replicate a VisB&lt;br /&gt;
item or event.&lt;br /&gt;
Replication consists in duplicating the item or event, and replacing &amp;lt;tt&amp;gt;%0&amp;lt;/tt&amp;gt; within the identifier and value attributes of the time with the repeated string or integer.&lt;br /&gt;
&lt;br /&gt;
For example, the repeat instruction below will result in the creation of three VisB items, one for id &amp;lt;tt&amp;gt;txt_ttd1&amp;lt;/tt&amp;gt;,  for &amp;lt;tt&amp;gt;txt_ttd2&amp;lt;/tt&amp;gt;,  and one for &amp;lt;tt&amp;gt;txt_ttd3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The value formula for &amp;lt;tt&amp;gt;txt_ttd1&amp;lt;/tt&amp;gt; is &amp;lt;tt&amp;gt;&amp;quot;IF 1: dom(TTD) THEN visb_ttd_back(%0) ELSE -1000 END&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
     &amp;quot;repeat&amp;quot;: [&amp;quot;1&amp;quot;,&amp;quot;2&amp;quot;,&amp;quot;3&amp;quot;],&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;txt_ttd%0&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;x&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;IF %0: dom(TTD) THEN visb_ttd_back(%0) ELSE -1000 END&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A for loop can be used instead for the above example as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
     &amp;quot;for&amp;quot;: {&amp;quot;from&amp;quot;:1, &amp;quot;to&amp;quot;:3},&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;txt_ttd%0&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;x&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;IF %0: dom(TTD) THEN visb_ttd_back(%0) ELSE -1000 END&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The for loop also allows an optional &amp;lt;tt&amp;gt;step&amp;lt;/tt&amp;gt; attribute.&lt;br /&gt;
&lt;br /&gt;
It is possible to apply both &amp;lt;tt&amp;gt;repeat&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; attributes at the same time, as this example shows.&lt;br /&gt;
(The exact details of multiple iterations for a VisB item might change in future.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
     &amp;quot;repeat&amp;quot;: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],&lt;br /&gt;
     &amp;quot;for&amp;quot;: {&amp;quot;from&amp;quot;:1, &amp;quot;to&amp;quot;:20},&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;tile%1x%0&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;: &amp;quot;TryQueen&amp;quot;,&lt;br /&gt;
      &amp;quot;hovers&amp;quot;: [{ &amp;quot;attr&amp;quot;:&amp;quot;opacity&amp;quot;, &amp;quot;enter&amp;quot;:&amp;quot;0.5&amp;quot;, &amp;quot;leave&amp;quot;:&amp;quot;1&amp;quot;}],&lt;br /&gt;
      &amp;quot;predicates&amp;quot; : [&amp;quot;i=%1&amp;quot;,&amp;quot;j=%0&amp;quot;] &lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 1.11.0 you can also use nested for loops.&lt;br /&gt;
As of version 1.11.1 of ProB you can also use B expressions for the &amp;lt;tt&amp;gt;from&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;to&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;step&amp;lt;/tt&amp;gt; attributes of a for loop.&lt;br /&gt;
However, these expressions must be evaluable without having access to any constants or variables. Indeed, the for and repeat loops are processed once when loading a VisB file, independently of any given state.&lt;br /&gt;
So, you can only access identifiers of &amp;lt;tt&amp;gt;SETS&amp;lt;/tt&amp;gt; section of a B machine.&lt;br /&gt;
It may still be useful, e.g., to iterate over an enumerated or deferred set (TRAINS below):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
     &amp;quot;for&amp;quot;: {&amp;quot;from&amp;quot;:1, &amp;quot;to&amp;quot;:&amp;quot;card(TRAINS)&amp;quot;},&lt;br /&gt;
...&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;INT_TO_ENUM&amp;lt;/tt&amp;gt; external function available as of ProB 1.11.1 can be useful in expressions here to convert the iteration variable back to an enumerated or deferred set element.&lt;br /&gt;
For example, &amp;lt;tt&amp;gt;INT_TO_ENUM(TRAINS,1)&amp;lt;/tt&amp;gt; refers to the first element of the set &amp;lt;tt&amp;gt;TRAINS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== VisB Definitions (in JSON file) ==&lt;br /&gt;
&lt;br /&gt;
As of ProB Tcl/Tk 1.11.0 it is possible to include local definitions in the VisB JSON  file.&lt;br /&gt;
Each definition has a name and a value formula.&lt;br /&gt;
Definitions are evaluated in order of appearance (a later definition can thus refer to an ealier one) and are evaluated in a state before evaluating VisB items.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;definitions&amp;quot;:[&lt;br /&gt;
    { &amp;quot;name&amp;quot;:&amp;quot;xscale&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot; : &amp;quot;(100.0 / real(NrOfTrackElements))&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    { &amp;quot;name&amp;quot;:&amp;quot;visb_train_rear&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot; : &amp;quot;%x.(x:dom(train_rear)|xscale * real(train_rear(x)))&amp;quot;&lt;br /&gt;
    }]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The VisB definitions are particularly useful for Event-B models (as you can use [[Summary_of_B_Syntax#Reals |REAL numbers]]  and also have access to [[External_Functions|external functions]] such as LibraryStrings or LibraySVG).&lt;br /&gt;
But they are &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; yet available for events in ProB2-UI.&lt;br /&gt;
&lt;br /&gt;
== VisB Additional SVG Objects ==&lt;br /&gt;
&lt;br /&gt;
As of version 1.12.0 of ProB Tcl/Tk you can add new SVG objects to your SVG file.&lt;br /&gt;
You can use for and repeat loops (see above) to create an arbitrary number of objects.&lt;br /&gt;
This is useful for making flexible visualisations which work with an arbitrary number&lt;br /&gt;
of objects.&lt;br /&gt;
The same rules and limitations for for/repeat loops apply as for items above.&lt;br /&gt;
&lt;br /&gt;
Every entry in the svg_objects list &lt;br /&gt;
* an &amp;lt;tt&amp;gt;svg_class&amp;lt;/tt&amp;gt; attribute, which can be, e.g., line, circle, rect, ...&lt;br /&gt;
* an object &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; attribute&lt;br /&gt;
* an optional &amp;lt;tt&amp;gt;comment&amp;lt;/tt&amp;gt; attribute&lt;br /&gt;
* any other attribute will be used to create the SVG object and should be valid for the specified svg_class&lt;br /&gt;
&lt;br /&gt;
Here is an example (taken from [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples/-/blob/master/Physics/n_bodies_visb.json here]) where NOBJS is a DEFINITION inside a B machine:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;svg_objects&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;for&amp;quot;:{&amp;quot;from&amp;quot;:1,&amp;quot;to&amp;quot;:&amp;quot;NOBJS&amp;quot;}, &lt;br /&gt;
      &amp;quot;svg_class&amp;quot;:&amp;quot;circle&amp;quot;,&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;body%0&amp;quot;,&lt;br /&gt;
      &amp;quot;cx&amp;quot;:&amp;quot;45&amp;quot;,&lt;br /&gt;
      &amp;quot;cy&amp;quot;:&amp;quot;15&amp;quot;,&lt;br /&gt;
      &amp;quot;r&amp;quot;:&amp;quot;10&amp;quot;,&lt;br /&gt;
      &amp;quot;stroke&amp;quot;:&amp;quot;black&amp;quot;,&lt;br /&gt;
      &amp;quot;stroke-width&amp;quot;:&amp;quot;0.5&amp;quot;,&lt;br /&gt;
      &amp;quot;fill&amp;quot;:&amp;quot;green&amp;quot;&lt;br /&gt;
    } ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is another example where TRAINS is a deferred or enumerated set of the B model being visualised:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;svg_objects&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;for&amp;quot;:{&amp;quot;from&amp;quot;:1,&amp;quot;to&amp;quot;:&amp;quot;card(TRAINS)&amp;quot;}, &lt;br /&gt;
      &amp;quot;svg_class&amp;quot;:&amp;quot;rect&amp;quot;,&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;fresh_train_rect%0&amp;quot;,&lt;br /&gt;
      &amp;quot;x&amp;quot;:&amp;quot;0&amp;quot;,&lt;br /&gt;
      &amp;quot;y&amp;quot;:&amp;quot;0&amp;quot;,&lt;br /&gt;
      &amp;quot;height&amp;quot;:&amp;quot;10&amp;quot;,&lt;br /&gt;
      &amp;quot;width&amp;quot;:&amp;quot;20&amp;quot;,&lt;br /&gt;
      &amp;quot;comment&amp;quot;:&amp;quot;train current position rectangle&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== VisB DEFINITIONS ==&lt;br /&gt;
As of version 1.12 you can also provide many of the VisB annotations via B DEFINITIONS.&lt;br /&gt;
This can be done in addition to a VisB JSON file or completely replacing the JSON file.&lt;br /&gt;
&lt;br /&gt;
By adding this definition to your B machine you specify that you wish to use an empty&lt;br /&gt;
SVG file as base:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With a VISB_SVG_BOX definition you can set the size of the generated empty SVG file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_SVG_BOX == rec(height:floor(vscale)*25+20, width:1800);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: you can also provide an optional &amp;lt;tt&amp;gt;viewBox&amp;lt;/tt&amp;gt; attribute as a B string.&lt;br /&gt;
&lt;br /&gt;
Via VISB_SVG_CONTENTS definitions you can add new textual content to the base SVG file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   VISB_SVG_CONTENTS == &#039;&#039;&#039;&lt;br /&gt;
   &amp;lt;defs&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
```;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With definitions starting with with VISB_SVG_OBJECTS you can add new SVG objects:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_SVG_OBJECTS1 == rec(`svg_class`:&amp;quot;rect&amp;quot;,`id`:&amp;quot;i1&amp;quot;,x:20,y:20,height:20,width:20,fill:&amp;quot;blue&amp;quot;);&lt;br /&gt;
  VISB_SVG_OBJECTS2 == rec(`svg_class`:&amp;quot;circle&amp;quot;,`id`:&amp;quot;i2&amp;quot;,cx:30,cy:30,r:20,fill:&amp;quot;red&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Each definition can either add a single record or add a set of records in one go.&lt;br /&gt;
The definition should only depend on base sets or constants of the model (see, however, notes for ProB 1.13.0 or later below).&lt;br /&gt;
In addition the constants used in the above definitions should only have one possible value.&lt;br /&gt;
For example, suppose that the constant P has 5 elements then this will create 5 SVG lines.&lt;br /&gt;
Observe that we use the new Event-B-style set comprehension for convenience and that tuples can be used for the &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; field..&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_SVG_OBJECTS3 == {i•i:P|rec(`svg_class`:&amp;quot;line&amp;quot;,`id`:(&amp;quot;line&amp;quot;,i),x1:0,y1:i,x2:i,y2:i)};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, you can use VISB_SVG_UPDATES definitions to specify attributes that depend on the&lt;br /&gt;
value of constants and variables of the animated B model:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_SVG_UPDATES1== rec(`id`:&amp;quot;i2&amp;quot;,fill: IF x&amp;gt;0 THEN &amp;quot;red&amp;quot; ELSE &amp;quot;green&amp;quot; END);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hovers can be defined using VISB_SVG_HOVER definitions (only for objects that have been created with VISB_SVG_OBJECTS) and click events can be defined using&lt;br /&gt;
VISB_SVG_EVENTS definitions with attributes &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; and optionally &amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Here is a minimal example that just uses the VisB DEFINITIONS without any external JSON or SVG file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE button_def&lt;br /&gt;
// An example that uses VisB DEFINITIONS instead of a JSON and SVG file&lt;br /&gt;
DEFINITIONS &lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;&amp;quot;;&lt;br /&gt;
  VISB_SVG_BOX == rec(height:200, width:240);&lt;br /&gt;
  VISB_SVG_OBJECTS == rec(`id`:&amp;quot;button&amp;quot;, svg_class:&amp;quot;circle&amp;quot;,&lt;br /&gt;
     cx:&amp;quot;100&amp;quot;,cy:&amp;quot;100&amp;quot;, r:&amp;quot;80&amp;quot;, stroke:&amp;quot;black&amp;quot;, `stroke-width`:&amp;quot;3&amp;quot;);&lt;br /&gt;
  VISB_SVG_UPDATES == rec(`id`:&amp;quot;button&amp;quot;,&lt;br /&gt;
     fill: IF button=TRUE THEN &amp;quot;green&amp;quot; ELSE &amp;quot;red&amp;quot; END);&lt;br /&gt;
  VISB_SVG_HOVERS == rec(`id`:&amp;quot;button&amp;quot;,&lt;br /&gt;
     stroke:&amp;quot;gray&amp;quot;, `stroke-width`:&amp;quot;5&amp;quot;);&lt;br /&gt;
  VISB_SVG_EVENTS == rec(`id`:&amp;quot;button&amp;quot;, event:&amp;quot;toggle_button&amp;quot;, predicate:&amp;quot;btrue&amp;quot;)&lt;br /&gt;
VARIABLES button&lt;br /&gt;
INVARIANT button:BOOL&lt;br /&gt;
INITIALISATION button := FALSE&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  toggle_button = BEGIN&lt;br /&gt;
    button:= bool(button=FALSE)&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 1.13.0 of ProB you can also use dynamic expressions in object definitions; the above definitions can thus be written more compactly:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_SVG_OBJECTS == rec(`id`:&amp;quot;button&amp;quot;, svg_class:&amp;quot;circle&amp;quot;,&lt;br /&gt;
     cx:100,cy:100, r:80, stroke:&amp;quot;black&amp;quot;, `stroke-width`:3,&lt;br /&gt;
     fill: IF button=TRUE THEN &amp;quot;green&amp;quot; ELSE &amp;quot;red&amp;quot; END,&lt;br /&gt;
    event:&amp;quot;toggle_button&amp;quot;,&lt;br /&gt;
    hovers: rec(stroke:&amp;quot;gray&amp;quot;, `stroke-width`:&amp;quot;5&amp;quot;));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In 1.13.0 you can also use a &amp;quot;children&amp;quot; attribute to specify groups.&lt;br /&gt;
The children attribute should evaluate to a set of strings pointing to ids of SVG objects.&lt;br /&gt;
The following example shows this for for defining the children of &amp;quot;mygroup&amp;quot;.&lt;br /&gt;
Also observe the use of the new [[Summary_of_B_Syntax#Strings:|template string syntax]] for the transform attribute.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    VISB_SVG_FILE == &amp;quot;&amp;quot;;&lt;br /&gt;
    VISB_SVG_BOX == rec(height:400, width:450);&lt;br /&gt;
    VISB_SVG_OBJECTS1 == {i•i:0..9|rec(`id`:(&amp;quot;r&amp;quot;,i), svg_class:&amp;quot;rect&amp;quot;,&lt;br /&gt;
                                   fill:IF i=x THEN &amp;quot;red&amp;quot; ELSE &amp;quot;green&amp;quot; END,&lt;br /&gt;
                                   x:10+10*i, y:100, height:20, width:4)};&lt;br /&gt;
    VISB_SVG_OBJECTS2 == rec(`id`:&amp;quot;mygroup&amp;quot;, svg_class:&amp;quot;g&amp;quot;,&lt;br /&gt;
                             children: {i•i:0..9|(&amp;quot;r&amp;quot;,i)},&lt;br /&gt;
                             transform:```rotate(${x*40},50,100)```&lt;br /&gt;
                            )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Version 1.13.1 also adds a new virtual &amp;lt;tt&amp;gt;title&amp;lt;/tt&amp;gt; attribute that can be set in such SVG_OBJECTS.&lt;br /&gt;
This will create a tooltip box displaying the value of the attribute. (Internally this gets transformed into children SVG title objects.) These tooltips are independent of the other VisB hovers (and in contrast to these hovers the value of the title attribute can be dynamic, i.e., depend on the model&#039;s variables).&lt;br /&gt;
&lt;br /&gt;
In VisB event predicates, the local identifier &amp;lt;tt&amp;gt;VISB_CLICK_META_INFOS&amp;lt;/tt&amp;gt; can be used to access information like shift or command key presses and mouse positions during a click. It represents a record of the following type:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   rec(altKey:    BOOL,&lt;br /&gt;
       ctrlKey:   BOOL,&lt;br /&gt;
       jsVars:    STRING &amp;lt;-&amp;gt; STRING,&lt;br /&gt;
       metaKey:   BOOL,&lt;br /&gt;
       pageX:     INTEGER,&lt;br /&gt;
       pageY:     INTEGER,&lt;br /&gt;
       shiftKey:  BOOL&lt;br /&gt;
   )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It also enables usage of JavaScript values: &amp;lt;tt&amp;gt;VISB_CLICK_META_INFOS&#039;jsVars(&amp;quot;MYID&amp;quot;)&amp;lt;/tt&amp;gt;. The value must first be assigned in a &amp;lt;tt&amp;gt;script&amp;lt;/tt&amp;gt; tag in the SVG using &amp;lt;tt&amp;gt;visb_vars[&amp;quot;${MYID}&amp;quot;]&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
Some examples can be found in the  [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples visb-visualisation-examples] repository.&lt;br /&gt;
We have a small [https://gitlab.cs.uni-duesseldorf.de/general/stups/prob2-jupyter-kernel/-/blob/master/notebooks/manual/VisB_Features.ipynb Jupyter notebook manual] on the DEFINITION features of VisB.&lt;br /&gt;
More details and examples will be added later.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
&lt;br /&gt;
* Beware that you need to escape quotation marks and slashes in the JSON file for fields containing B expressions. Also, you cannot use newline.&lt;br /&gt;
* Hovers are currently evaluated once statically and cannot make use of B expressions. To make hover information dependent on the state, use the visibility attribute to make hidden SVG objects (which can be adapted depending on the state using VisB items) visible. The [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples/-/tree/master/Train train VisB example] illustrates this idea.&lt;br /&gt;
&lt;br /&gt;
== Tips and Tricks ==&lt;br /&gt;
&lt;br /&gt;
It is sometimes useful to use simple coordinates for your VisB items and B expressions, e.g. x coordinates of 0..100.&lt;br /&gt;
You can quite often do this and use the SVG  &amp;lt;b&amp;gt;transform&amp;lt;/b&amp;gt; attribute to scale and move the SVG object to the right place.&lt;br /&gt;
The simple  [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples/-/tree/master/Train train VisB example] shows how to do this.&lt;br /&gt;
In essence your SVG file can contain this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;polygon id = &amp;quot;ttd_polyline&amp;quot;&lt;br /&gt;
       points=&amp;quot;0,0 100,0&amp;quot;&lt;br /&gt;
       stroke=&amp;quot;gray&amp;quot; fill=&amp;quot;none&amp;quot;&lt;br /&gt;
       transform=&amp;quot;translate(10,22.5)&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
and the VisB JSON file contains this, making use of LibrarySVG.def (automatically available) external function &amp;lt;b&amp;gt;svg_axis&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;ttd_polyline&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;points&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;svg_axis({0} \\/ ran(%tt.(tt:TTDS|1+max(TTD_TrackElements(tt)))),100.0/real(TrackElementNumber+1),100.0,2.0)&amp;quot;,&lt;br /&gt;
      &amp;quot;comment&amp;quot;:&amp;quot;show ticks for TTD Limits&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Observe that we had to escape the slash of the union operator.&lt;br /&gt;
Also observe, that we are able to use [[Summary_of_B_Syntax#Reals:|floating numbers]] in the new version of ProB, which is very useful for VisB visualisations.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It can be useful to use style and class to make it easier to change your color scheme or other styling attributes within your visualisation consistently.&lt;br /&gt;
Again, the simple  [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples/-/tree/master/Train train VisB example] shows how to do this.&lt;br /&gt;
E.g., your SVG file could contain towards the top this definition:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;style id=&amp;quot;style_ttd_ts_mp&amp;quot;&amp;gt;&lt;br /&gt;
        .ttd {&lt;br /&gt;
            stroke : none;&lt;br /&gt;
            stroke-width: 0.2;&lt;br /&gt;
            opacity: 0.7&lt;br /&gt;
        }&lt;br /&gt;
        .red-occupied-ttd {&lt;br /&gt;
            fill : red&lt;br /&gt;
        }&lt;br /&gt;
   &amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Later you can then use it to style your objects:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;polygon id = &amp;quot;occupied_ttd_polygon&amp;quot;&lt;br /&gt;
       points=&amp;quot;0,0 0,2 10,2 10,0 70,0 70,1 90,1 90,0&amp;quot;&lt;br /&gt;
       class = &amp;quot;ttd red-occupied-ttd&amp;quot;&lt;br /&gt;
       transform=&amp;quot;translate(10,23)&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then modify the class using VisB items. Classes can also be useful for hovers, by simply exchanging one style for another when the mouse is over an objects (again, see [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples/-/tree/master/Train the train example]).&lt;br /&gt;
Recent versions of ProB also support adding and removing a class, which is useful for hovers when the class is modified by VisB items:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;train_polygon_tr1&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;:&amp;quot;TrainMoveForward&amp;quot;,&lt;br /&gt;
      &amp;quot;hovers&amp;quot;: [{ &amp;quot;attr&amp;quot;:&amp;quot;class&amp;quot;, &amp;quot;enter&amp;quot;:&amp;quot;+train-hover&amp;quot;, &amp;quot;leave&amp;quot;:&amp;quot;-train-hover&amp;quot;}]&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Debugging and HTML Export ==&lt;br /&gt;
&lt;br /&gt;
In classical B models you can store your default VisB visualisation in the DEFINITIONS section:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  DEFINITIONS&lt;br /&gt;
    VISB_JSON_FILE == &amp;quot;TwoTrains.json&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For debugging it can be useful to use VisB within ProB Tcl/Tk: if you choose to visualise the current state with VisB, ProB will generate a stand-alone HTML file which is opened in a browser.&lt;br /&gt;
In the browser you can open the (Javascript) developer console and you will be alerted to warnings and errors (which unfortunately, are currently not shown in ProB2-UI).&lt;br /&gt;
Upon changing the state in the animator, the HTML file will be regenerated and the VisB file re-loaded if necessary.&lt;br /&gt;
The HTML export also displays hovers, but cannot react to clicks.&lt;br /&gt;
The HTML export is also available in ProB2-UI (in the export menu in the top-right corner).&lt;br /&gt;
&lt;br /&gt;
ProB can also export the entire animation history to a standalone HTML file that can be passed to other persons (without requiring access to the B model or to ProB).&lt;br /&gt;
In ProB Tcl/Tk you can right-click on the history pane and choose &amp;quot;View History in VisB&amp;quot;.&lt;br /&gt;
In probcli you can use the command &amp;lt;tt&amp;gt;-visb JSONFILE HTMLFILE&amp;lt;/tt&amp;gt; to export the history.&lt;br /&gt;
In ProB2-UI you can click on the export icon in the upper right hand corner:&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2UI_VisB_View_Export.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The ProB2-UI table visualisation view (Visualisation menu) also contains tables to help debug VisB items and events:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2UI_VisB_Debug_Table_View.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
This view is also available in ProB Tcl/Tk in the Visualize menu (States submenu).&lt;br /&gt;
ProB2-UI also has another inspection view that can be obtained by clicking on the &amp;quot;i&amp;quot; (info) icon in the the VisB toolbar.&lt;br /&gt;
&lt;br /&gt;
=== Using the VisB exported HTML file ===&lt;br /&gt;
&lt;br /&gt;
You should be able to open the exported HTML using a regular browser.&lt;br /&gt;
Within the web page (see the image below) you can then do the following:&lt;br /&gt;
* single step through the trace by clicking the &amp;quot;Forward&amp;quot; and &amp;quot;Backward&amp;quot; buttons, or clicking on individual steps of the trace&lt;br /&gt;
* execute the entire trace nd see changes to the visualisation by clicking one of the &amp;quot;Run Trace&amp;quot; buttons&lt;br /&gt;
* you can inspect the value of the sets, constants and variables at every step by expanding the corresponding tabs&lt;br /&gt;
Some meta information can be found at the bottom of the trace.&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2UI_VisB_View_ExportedHTML.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
== Citing VisB ==&lt;br /&gt;
This is the Bibtex entry for an article about VisB  [https://rdcu.be/b4rqh in the ABZ&#039;2020 proceedings]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@inproceedings{WerthLeuschel:abz2020,&lt;br /&gt;
  author    = {Michelle Werth and Michael Leuschel},&lt;br /&gt;
  title     = {{VisB}: A Lightweight Tool to Visualize Formal Models with {SVG} Graphics},&lt;br /&gt;
  booktitle = {Proceedings ABZ 2020},&lt;br /&gt;
  editor=&amp;quot;Raschke, Alexander and M{\&#039;e}ry, Dominique and Houdek, Frank&amp;quot;,&lt;br /&gt;
  year      = {2020},&lt;br /&gt;
  series = {LNCS 12071},&lt;br /&gt;
  pages = &amp;quot;260--265&amp;quot;,&lt;br /&gt;
  isbn=&amp;quot;978-3-030-48077-6&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing the VisB plugin for older ProB2-UI versions ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The following instructions are for ProB2-UI version 1.0.0 &#039;&#039;&#039;only&#039;&#039;&#039;. On current versions of ProB2-UI (1.1.0 and later), VisB is included by default and &#039;&#039;&#039;does not need to be installed separately&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
To install the VisB plugin in ProB2-UI 1.0.0 you need to:&lt;br /&gt;
&lt;br /&gt;
# [https://www3.hhu.de/stups/downloads/prob2/plugins/VisB-1.0.0.jar Download the VisB plugin jar file].&lt;br /&gt;
# In the &amp;quot;Advanced&amp;quot; menu of ProB2-UI, choose &amp;quot;Plugin Menu&amp;quot;.&lt;br /&gt;
# Click on the &amp;quot;Add Plugin...&amp;quot; button.&lt;br /&gt;
# Select the VisB jar file that you have downloaded.&lt;br /&gt;
# Choose the &amp;quot;Open VisB&amp;quot; command in the Advanced menu to start VisB.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=VisB&amp;diff=5948</id>
		<title>VisB</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=VisB&amp;diff=5948"/>
		<updated>2025-04-04T07:28:30Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* VisB DEFINITIONS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;VisB&#039;&#039;&#039; is a visualisation feature of ProB based on SVG graphics and HTML.&lt;br /&gt;
&lt;br /&gt;
Initially VisB was developed for [[ProB2-UI]], the new user interface of ProB based on JavaFX and the ProB2-Java-API.&lt;br /&gt;
It is included in ProB2-UI version 1.1.0 and later, which [[Download#ProB2-UI using Java FX|can be downloaded here]].&lt;br /&gt;
Users of ProB2-UI version 1.0.0 can [[#Installing the VisB plugin for older ProB2-UI versions|install VisB as a plugin]].&lt;br /&gt;
We, however, recommend you use the latest ProB2-UI snapshot.&lt;br /&gt;
VisB is constantly being improved and the latest version contains several useful new features.&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2UI_VisB_View.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
ProB Tcl/Tk and probcli version 1.11.0 and later also support VisB visualisations:&lt;br /&gt;
&lt;br /&gt;
* with &amp;lt;tt&amp;gt;probcli File.mch ... -visb VISBJSONFILE HTMLFILE&amp;lt;/tt&amp;gt; you can export the animator&#039;s history to a self-contained HTML file including a visualisation of the states in the history&lt;br /&gt;
* in ProB Tcl/Tk you can visualise the current state or the history using a VisB visualisation file (it is shown in an external browser) by right clicking in the &amp;quot;State Properties&amp;quot; or the &amp;quot;History&amp;quot; pane.&lt;br /&gt;
Hovers work in both cases, but unlike in ProB2-UI, you cannot click to perform events.&lt;br /&gt;
&lt;br /&gt;
An article about VisB has been [https://rdcu.be/b4rqh published in the ABZ&#039;2020 proceedings].&lt;br /&gt;
&lt;br /&gt;
== Using VisB ==&lt;br /&gt;
&lt;br /&gt;
In current versions of [[ProB2-UI]] the VisB view is automatically shown in the center pane below the state view.&lt;br /&gt;
To start VisB in older versions of [[ProB2-UI]], choose the &amp;quot;Open VisB&amp;quot; command in the Visualisation menu,&lt;br /&gt;
or right-click in the &amp;quot;State Properties&amp;quot; pane of ProB Tcl/Tk and select &amp;quot;View Current State in VisB&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can now choose a JSON file which builds on top of  a SVG graphics file (more recent versions of VisB can also load visualisations from [[VisB#VisB_DEFINITIONS|definitions]].&lt;br /&gt;
The JSON file contains a reference to a SVG file, along with entries to modify attributes based on the current state of a B model and entries which specify how VisB should react to clicks on the SVG. The SVG file should contain object ids which are referenced in the JSON file.&lt;br /&gt;
&lt;br /&gt;
Here is a sample file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;svg&amp;quot;:&amp;quot;Train2.svg&amp;quot;,&lt;br /&gt;
  &amp;quot;items&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;Train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;visibility&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;IF 1:TRAIN THEN \&amp;quot;visible\&amp;quot; ELSE \&amp;quot;hidden\&amp;quot; END&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;Train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;fill&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;IF train_speed(1)&amp;gt;0 THEN \&amp;quot;blue\&amp;quot; ELSE \&amp;quot;orange\&amp;quot; END&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;Train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;x&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;train_back_loc(1)*10+20&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;Train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;width&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;train_length(1)*10&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
    ],&lt;br /&gt;
  &amp;quot;events&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;Train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;:&amp;quot;Train_Move1&amp;quot;,&lt;br /&gt;
      &amp;quot;predicates&amp;quot;:[&lt;br /&gt;
        &amp;quot;1=1&amp;quot;&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== VisB Attributes ==&lt;br /&gt;
&lt;br /&gt;
At the top-level a VisB JSON file contains these attributes:&lt;br /&gt;
* svg&lt;br /&gt;
* model-name&lt;br /&gt;
* include&lt;br /&gt;
* svg_objects&lt;br /&gt;
* definitions&lt;br /&gt;
* items&lt;br /&gt;
* events&lt;br /&gt;
&lt;br /&gt;
Below we explain them in more detail.&lt;br /&gt;
&lt;br /&gt;
=== SVG file and inclusion ===&lt;br /&gt;
&lt;br /&gt;
The main VisB Json file should contain an &amp;lt;tt&amp;gt;svg&amp;lt;/tt&amp;gt; attribute with a&lt;br /&gt;
relative or absolute path to the SVG file to be shown.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;model-name&amp;lt;/tt&amp;gt; attribute is optional; if set ProB will emit&lt;br /&gt;
a warning if the B model&#039;s name does not match the value of this attribute.&lt;br /&gt;
&lt;br /&gt;
One can also include subsidiary VisB Json files using the &amp;lt;tt&amp;gt;include&amp;lt;/tt&amp;gt;&lt;br /&gt;
attribute with again a relative or absolut path to another Json file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;svg&amp;quot;:&amp;quot;my_svg_file.svg&amp;quot;,&lt;br /&gt;
  &amp;quot;include&amp;quot;:&amp;quot;subsidiary_visb_file.json&amp;quot;,&lt;br /&gt;
  &amp;quot;items&amp;quot;:[&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The svg attribute in subsidiary files will be ignored.&lt;br /&gt;
You can override the VisB items in the included file (i.e., a VisB item for an id and attribute in the top-level file will override items for the same id and attribute in the included files).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Items and Events ===&lt;br /&gt;
&lt;br /&gt;
For VisB &amp;lt;tt&amp;gt;items&amp;lt;/tt&amp;gt; every entry needs&lt;br /&gt;
* &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, this is the identifier of an object in the associated SVG file&lt;br /&gt;
* &amp;lt;tt&amp;gt;attr&amp;lt;/tt&amp;gt; a valid SVG attribute&lt;br /&gt;
* &amp;lt;tt&amp;gt;value&amp;lt;/tt&amp;gt; a B formula which will be evaluated in the current state of a model and yields a new value for the above attribute.&lt;br /&gt;
&lt;br /&gt;
Note that the formula can  make use of the [[Summary_of_B_Syntax#Reals |REAL datatype]]  and also use many of the [[External_Functions|external functions]] e.g. from LibraryStrings or LibraySVG.&lt;br /&gt;
Here is an example VisB Item:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;items&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;: &amp;quot;x&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;100.0 + train_left(train1)&amp;quot;&lt;br /&gt;
    } ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As of version 1.12.2, ProB allows you to use a single attribute whose name is the SVG attribute being set, rather than two attributes (attr, value).&lt;br /&gt;
With this you can set multiple SVG attributes in one VisB item.&lt;br /&gt;
For example, you can now write:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;items&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;train1_rect&amp;quot;,&lt;br /&gt;
      &amp;quot;x&amp;quot;:&amp;quot;100.0 + train_left(train1)&amp;quot;,&lt;br /&gt;
      &amp;quot;y&amp;quot;:&amp;quot;20.0 + train_bottom(train1)&amp;quot;&lt;br /&gt;
    } ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For VisB &amp;lt;tt&amp;gt;events&amp;lt;/tt&amp;gt; every entry needs&lt;br /&gt;
* &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, this is the identifier of an object in the associated SVG file&lt;br /&gt;
* &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; a valid B operation or event of the loaded formal model&lt;br /&gt;
* &amp;lt;tt&amp;gt;predicates&amp;lt;/tt&amp;gt; an optional list of B predicates, which can be used to set parameters of the B operation that is executed upon a click&lt;br /&gt;
&lt;br /&gt;
Additionally VisB now recognises for both items and events:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;ignore&amp;lt;/tt&amp;gt;, if this attribute is present the item will be ignored&lt;br /&gt;
* &amp;lt;tt&amp;gt;repeat&amp;lt;/tt&amp;gt;, if this attribute is present the item will be replicated (see below). This construct requires a list of strings.&lt;br /&gt;
* &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, if this attribute is present the item will be replicated (see below). The for construct requires &amp;lt;tt&amp;gt;from&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;to&amp;lt;/tt&amp;gt; with integer values as sub arguments. As of version 1.11.1 you can also use constant B integer expressions accessing just the sets.&lt;br /&gt;
* &amp;lt;tt&amp;gt;optional&amp;lt;/tt&amp;gt;, if this boolean attribute is &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt; an event will be ignored if the event name is not a valid top-level event/operation in the model. An item will be ignored if the identifiers in the formula do not exists (i.e., errors during type checking will be ignored)&lt;br /&gt;
* &amp;lt;tt&amp;gt;override&amp;lt;/tt&amp;gt;, if this boolean attribute is &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt; no warnings will be generated if another VisB item for the same attribute and id is overriden (as of version 1.11.1)&lt;br /&gt;
&lt;br /&gt;
Other attributes will be ignored. E.g, one can use a &amp;lt;tt&amp;gt;comment&amp;lt;/tt&amp;gt; attribute to add comments to the VisB items.&lt;br /&gt;
&lt;br /&gt;
When executing an event, VisB now performs the following replacements within the predicates of the event:&lt;br /&gt;
* &amp;lt;tt&amp;gt;%shiftKey&amp;lt;/tt&amp;gt; is replaced by TRUE if the shift key was pressed during the click, FALSE otherwise&lt;br /&gt;
* &amp;lt;tt&amp;gt;%metaKey&amp;lt;/tt&amp;gt; is replaced by TRUE if the shift key was pressed during the click, FALSE otherwise&lt;br /&gt;
* &amp;lt;tt&amp;gt;%pageX&amp;lt;/tt&amp;gt; is replaced by the x coordinate of the click relative to the top-left of the entire VisB SVG&lt;br /&gt;
* &amp;lt;tt&amp;gt;%pageY&amp;lt;/tt&amp;gt; is replaced by the y coordinate of the click relative to the top-left of the entire VisB SVG&lt;br /&gt;
&lt;br /&gt;
Finally, VisB events can be associated with mouse hover actions.&lt;br /&gt;
For this you just need to add an attribute &amp;lt;tt&amp;gt;hovers&amp;lt;/tt&amp;gt; which contains a list of JSON objects with the following attributes:&lt;br /&gt;
* &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, this is the identifier of an object in the associated SVG file; this attribute is optional; if it is not present the id specified in the VisB event will be used.&lt;br /&gt;
* &amp;lt;tt&amp;gt;attr&amp;lt;/tt&amp;gt; a valid SVG attribute&lt;br /&gt;
* &amp;lt;tt&amp;gt;enter&amp;lt;/tt&amp;gt; a value which will be used when the mouse enters the area of the object&lt;br /&gt;
* &amp;lt;tt&amp;gt;leave&amp;lt;/tt&amp;gt; a value which will be used to restore the attribute when the mouse leaves the area&lt;br /&gt;
Note that the enter and leave values have to be static at the moment; in future we plan to allow B formulas here and also apply the repetition/replacement mechanism specified above.&lt;br /&gt;
If you just wish to attach a hover to an SVG object (and no B operation/event) you can set the event field of the VisB event to the empty string (&amp;lt;tt&amp;gt;&amp;quot;event&amp;quot;:&amp;quot;&amp;quot;&amp;lt;/tt&amp;gt;).&lt;br /&gt;
You should not use attributes for the hover which are set by VisB items.&lt;br /&gt;
&lt;br /&gt;
Here is an example VisB event with hovers:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;button&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;: &amp;quot;toggle_button&amp;quot;,&lt;br /&gt;
      &amp;quot;hovers&amp;quot;: [{ &amp;quot;attr&amp;quot;:&amp;quot;stroke-width&amp;quot;, &amp;quot;enter&amp;quot;:&amp;quot;6&amp;quot;, &amp;quot;leave&amp;quot;:&amp;quot;1&amp;quot;},&lt;br /&gt;
                 { &amp;quot;attr&amp;quot;:&amp;quot;opacity&amp;quot;, &amp;quot;enter&amp;quot;:&amp;quot;0.8&amp;quot;, &amp;quot;leave&amp;quot;:&amp;quot;1.0&amp;quot;}]&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A VisB event can now also contain an list of items with the attributes &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;attr&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;enabled&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;disabled&amp;lt;/tt&amp;gt;.&lt;br /&gt;
When the associated event is enabled, the attribute of the SVG object with the given id is set to the  value provided in the enabled attribute, otherwise the disabled attribute value is used.&lt;br /&gt;
As above the item id is optional and defaults to the id of the VisB event.&lt;br /&gt;
Here is an example VisB event with hovers and an items list:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;button&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;: &amp;quot;press_button&amp;quot;,&lt;br /&gt;
      &amp;quot;hovers&amp;quot;: [{ &amp;quot;attr&amp;quot;:&amp;quot;stroke-width&amp;quot;, &amp;quot;enter&amp;quot;:&amp;quot;6&amp;quot;, &amp;quot;leave&amp;quot;:&amp;quot;1&amp;quot;}],&lt;br /&gt;
      &amp;quot;items&amp;quot;: [{&amp;quot;attr&amp;quot;:&amp;quot;fill&amp;quot;, &amp;quot;disabled&amp;quot;:&amp;quot;\&amp;quot;green\&amp;quot;&amp;quot;, &amp;quot;enabled&amp;quot;:&amp;quot;\&amp;quot;red\&amp;quot;&amp;quot;}]&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Replication / Loops ==&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;repeat&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; attributes to replicate a VisB&lt;br /&gt;
item or event.&lt;br /&gt;
Replication consists in duplicating the item or event, and replacing &amp;lt;tt&amp;gt;%0&amp;lt;/tt&amp;gt; within the identifier and value attributes of the time with the repeated string or integer.&lt;br /&gt;
&lt;br /&gt;
For example, the repeat instruction below will result in the creation of three VisB items, one for id &amp;lt;tt&amp;gt;txt_ttd1&amp;lt;/tt&amp;gt;,  for &amp;lt;tt&amp;gt;txt_ttd2&amp;lt;/tt&amp;gt;,  and one for &amp;lt;tt&amp;gt;txt_ttd3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The value formula for &amp;lt;tt&amp;gt;txt_ttd1&amp;lt;/tt&amp;gt; is &amp;lt;tt&amp;gt;&amp;quot;IF 1: dom(TTD) THEN visb_ttd_back(%0) ELSE -1000 END&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
     &amp;quot;repeat&amp;quot;: [&amp;quot;1&amp;quot;,&amp;quot;2&amp;quot;,&amp;quot;3&amp;quot;],&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;txt_ttd%0&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;x&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;IF %0: dom(TTD) THEN visb_ttd_back(%0) ELSE -1000 END&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A for loop can be used instead for the above example as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
     &amp;quot;for&amp;quot;: {&amp;quot;from&amp;quot;:1, &amp;quot;to&amp;quot;:3},&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;txt_ttd%0&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;x&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;IF %0: dom(TTD) THEN visb_ttd_back(%0) ELSE -1000 END&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The for loop also allows an optional &amp;lt;tt&amp;gt;step&amp;lt;/tt&amp;gt; attribute.&lt;br /&gt;
&lt;br /&gt;
It is possible to apply both &amp;lt;tt&amp;gt;repeat&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; attributes at the same time, as this example shows.&lt;br /&gt;
(The exact details of multiple iterations for a VisB item might change in future.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
     &amp;quot;repeat&amp;quot;: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],&lt;br /&gt;
     &amp;quot;for&amp;quot;: {&amp;quot;from&amp;quot;:1, &amp;quot;to&amp;quot;:20},&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;tile%1x%0&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;: &amp;quot;TryQueen&amp;quot;,&lt;br /&gt;
      &amp;quot;hovers&amp;quot;: [{ &amp;quot;attr&amp;quot;:&amp;quot;opacity&amp;quot;, &amp;quot;enter&amp;quot;:&amp;quot;0.5&amp;quot;, &amp;quot;leave&amp;quot;:&amp;quot;1&amp;quot;}],&lt;br /&gt;
      &amp;quot;predicates&amp;quot; : [&amp;quot;i=%1&amp;quot;,&amp;quot;j=%0&amp;quot;] &lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 1.11.0 you can also use nested for loops.&lt;br /&gt;
As of version 1.11.1 of ProB you can also use B expressions for the &amp;lt;tt&amp;gt;from&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;to&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;step&amp;lt;/tt&amp;gt; attributes of a for loop.&lt;br /&gt;
However, these expressions must be evaluable without having access to any constants or variables. Indeed, the for and repeat loops are processed once when loading a VisB file, independently of any given state.&lt;br /&gt;
So, you can only access identifiers of &amp;lt;tt&amp;gt;SETS&amp;lt;/tt&amp;gt; section of a B machine.&lt;br /&gt;
It may still be useful, e.g., to iterate over an enumerated or deferred set (TRAINS below):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
     &amp;quot;for&amp;quot;: {&amp;quot;from&amp;quot;:1, &amp;quot;to&amp;quot;:&amp;quot;card(TRAINS)&amp;quot;},&lt;br /&gt;
...&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;INT_TO_ENUM&amp;lt;/tt&amp;gt; external function available as of ProB 1.11.1 can be useful in expressions here to convert the iteration variable back to an enumerated or deferred set element.&lt;br /&gt;
For example, &amp;lt;tt&amp;gt;INT_TO_ENUM(TRAINS,1)&amp;lt;/tt&amp;gt; refers to the first element of the set &amp;lt;tt&amp;gt;TRAINS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== VisB Definitions (in JSON file) ==&lt;br /&gt;
&lt;br /&gt;
As of ProB Tcl/Tk 1.11.0 it is possible to include local definitions in the VisB JSON  file.&lt;br /&gt;
Each definition has a name and a value formula.&lt;br /&gt;
Definitions are evaluated in order of appearance (a later definition can thus refer to an ealier one) and are evaluated in a state before evaluating VisB items.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;definitions&amp;quot;:[&lt;br /&gt;
    { &amp;quot;name&amp;quot;:&amp;quot;xscale&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot; : &amp;quot;(100.0 / real(NrOfTrackElements))&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    { &amp;quot;name&amp;quot;:&amp;quot;visb_train_rear&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot; : &amp;quot;%x.(x:dom(train_rear)|xscale * real(train_rear(x)))&amp;quot;&lt;br /&gt;
    }]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The VisB definitions are particularly useful for Event-B models (as you can use [[Summary_of_B_Syntax#Reals |REAL numbers]]  and also have access to [[External_Functions|external functions]] such as LibraryStrings or LibraySVG).&lt;br /&gt;
But they are &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; yet available for events in ProB2-UI.&lt;br /&gt;
&lt;br /&gt;
== VisB Additional SVG Objects ==&lt;br /&gt;
&lt;br /&gt;
As of version 1.12.0 of ProB Tcl/Tk you can add new SVG objects to your SVG file.&lt;br /&gt;
You can use for and repeat loops (see above) to create an arbitrary number of objects.&lt;br /&gt;
This is useful for making flexible visualisations which work with an arbitrary number&lt;br /&gt;
of objects.&lt;br /&gt;
The same rules and limitations for for/repeat loops apply as for items above.&lt;br /&gt;
&lt;br /&gt;
Every entry in the svg_objects list &lt;br /&gt;
* an &amp;lt;tt&amp;gt;svg_class&amp;lt;/tt&amp;gt; attribute, which can be, e.g., line, circle, rect, ...&lt;br /&gt;
* an object &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; attribute&lt;br /&gt;
* an optional &amp;lt;tt&amp;gt;comment&amp;lt;/tt&amp;gt; attribute&lt;br /&gt;
* any other attribute will be used to create the SVG object and should be valid for the specified svg_class&lt;br /&gt;
&lt;br /&gt;
Here is an example (taken from [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples/-/blob/master/Physics/n_bodies_visb.json here]) where NOBJS is a DEFINITION inside a B machine:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;svg_objects&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;for&amp;quot;:{&amp;quot;from&amp;quot;:1,&amp;quot;to&amp;quot;:&amp;quot;NOBJS&amp;quot;}, &lt;br /&gt;
      &amp;quot;svg_class&amp;quot;:&amp;quot;circle&amp;quot;,&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;body%0&amp;quot;,&lt;br /&gt;
      &amp;quot;cx&amp;quot;:&amp;quot;45&amp;quot;,&lt;br /&gt;
      &amp;quot;cy&amp;quot;:&amp;quot;15&amp;quot;,&lt;br /&gt;
      &amp;quot;r&amp;quot;:&amp;quot;10&amp;quot;,&lt;br /&gt;
      &amp;quot;stroke&amp;quot;:&amp;quot;black&amp;quot;,&lt;br /&gt;
      &amp;quot;stroke-width&amp;quot;:&amp;quot;0.5&amp;quot;,&lt;br /&gt;
      &amp;quot;fill&amp;quot;:&amp;quot;green&amp;quot;&lt;br /&gt;
    } ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is another example where TRAINS is a deferred or enumerated set of the B model being visualised:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;svg_objects&amp;quot;:[&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;for&amp;quot;:{&amp;quot;from&amp;quot;:1,&amp;quot;to&amp;quot;:&amp;quot;card(TRAINS)&amp;quot;}, &lt;br /&gt;
      &amp;quot;svg_class&amp;quot;:&amp;quot;rect&amp;quot;,&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;fresh_train_rect%0&amp;quot;,&lt;br /&gt;
      &amp;quot;x&amp;quot;:&amp;quot;0&amp;quot;,&lt;br /&gt;
      &amp;quot;y&amp;quot;:&amp;quot;0&amp;quot;,&lt;br /&gt;
      &amp;quot;height&amp;quot;:&amp;quot;10&amp;quot;,&lt;br /&gt;
      &amp;quot;width&amp;quot;:&amp;quot;20&amp;quot;,&lt;br /&gt;
      &amp;quot;comment&amp;quot;:&amp;quot;train current position rectangle&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== VisB DEFINITIONS ==&lt;br /&gt;
As of version 1.12 you can also provide many of the VisB annotations via B DEFINITIONS.&lt;br /&gt;
This can be done in addition to a VisB JSON file or completely replacing the JSON file.&lt;br /&gt;
&lt;br /&gt;
By adding this definition to your B machine you specify that you wish to use an empty&lt;br /&gt;
SVG file as base:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With a VISB_SVG_BOX definition you can set the size of the generated empty SVG file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_SVG_BOX == rec(height:floor(vscale)*25+20, width:1800);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: you can also provide an optional &amp;lt;tt&amp;gt;viewBox&amp;lt;/tt&amp;gt; attribute as a B string.&lt;br /&gt;
&lt;br /&gt;
Via VISB_SVG_CONTENTS definitions you can add new textual content to the base SVG file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   VISB_SVG_CONTENTS == &#039;&#039;&#039;&lt;br /&gt;
   &amp;lt;defs&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
```;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With definitions starting with with VISB_SVG_OBJECTS you can add new SVG objects:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_SVG_OBJECTS1 == rec(`svg_class`:&amp;quot;rect&amp;quot;,`id`:&amp;quot;i1&amp;quot;,x:20,y:20,height:20,width:20,fill:&amp;quot;blue&amp;quot;);&lt;br /&gt;
  VISB_SVG_OBJECTS2 == rec(`svg_class`:&amp;quot;circle&amp;quot;,`id`:&amp;quot;i2&amp;quot;,cx:30,cy:30,r:20,fill:&amp;quot;red&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Each definition can either add a single record or add a set of records in one go.&lt;br /&gt;
The definition should only depend on base sets or constants of the model (see, however, notes for ProB 1.13.0 or later below).&lt;br /&gt;
In addition the constants used in the above definitions should only have one possible value.&lt;br /&gt;
For example, suppose that the constant P has 5 elements then this will create 5 SVG lines.&lt;br /&gt;
Observe that we use the new Event-B-style set comprehension for convenience and that tuples can be used for the &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; field..&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_SVG_OBJECTS3 == {i•i:P|rec(`svg_class`:&amp;quot;line&amp;quot;,`id`:(&amp;quot;line&amp;quot;,i),x1:0,y1:i,x2:i,y2:i)};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, you can use VISB_SVG_UPDATES definitions to specify attributes that depend on the&lt;br /&gt;
value of constants and variables of the animated B model:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_SVG_UPDATES1== rec(`id`:&amp;quot;i2&amp;quot;,fill: IF x&amp;gt;0 THEN &amp;quot;red&amp;quot; ELSE &amp;quot;green&amp;quot; END);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hovers can be defined using VISB_SVG_HOVER definitions (only for objects that have been created with VISB_SVG_OBJECTS) and click events can be defined using&lt;br /&gt;
VISB_SVG_EVENTS definitions with attributes &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; and optionally &amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Here is a minimal example that just uses the VisB DEFINITIONS without any external JSON or SVG file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE button_def&lt;br /&gt;
// An example that uses VisB DEFINITIONS instead of a JSON and SVG file&lt;br /&gt;
DEFINITIONS &lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;&amp;quot;;&lt;br /&gt;
  VISB_SVG_BOX == rec(height:200, width:240);&lt;br /&gt;
  VISB_SVG_OBJECTS == rec(`id`:&amp;quot;button&amp;quot;, svg_class:&amp;quot;circle&amp;quot;,&lt;br /&gt;
     cx:&amp;quot;100&amp;quot;,cy:&amp;quot;100&amp;quot;, r:&amp;quot;80&amp;quot;, stroke:&amp;quot;black&amp;quot;, `stroke-width`:&amp;quot;3&amp;quot;);&lt;br /&gt;
  VISB_SVG_UPDATES == rec(`id`:&amp;quot;button&amp;quot;,&lt;br /&gt;
     fill: IF button=TRUE THEN &amp;quot;green&amp;quot; ELSE &amp;quot;red&amp;quot; END);&lt;br /&gt;
  VISB_SVG_HOVERS == rec(`id`:&amp;quot;button&amp;quot;,&lt;br /&gt;
     stroke:&amp;quot;gray&amp;quot;, `stroke-width`:&amp;quot;5&amp;quot;);&lt;br /&gt;
  VISB_SVG_EVENTS == rec(`id`:&amp;quot;button&amp;quot;, event:&amp;quot;toggle_button&amp;quot;, predicate:&amp;quot;btrue&amp;quot;)&lt;br /&gt;
VARIABLES button&lt;br /&gt;
INVARIANT button:BOOL&lt;br /&gt;
INITIALISATION button := FALSE&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  toggle_button = BEGIN&lt;br /&gt;
    button:= bool(button=FALSE)&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 1.13.0 of ProB you can also use dynamic expressions in object definitions; the above definitions can thus be written more compactly:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_SVG_OBJECTS == rec(`id`:&amp;quot;button&amp;quot;, svg_class:&amp;quot;circle&amp;quot;,&lt;br /&gt;
     cx:100,cy:100, r:80, stroke:&amp;quot;black&amp;quot;, `stroke-width`:3,&lt;br /&gt;
     fill: IF button=TRUE THEN &amp;quot;green&amp;quot; ELSE &amp;quot;red&amp;quot; END,&lt;br /&gt;
    event:&amp;quot;toggle_button&amp;quot;,&lt;br /&gt;
    hovers: rec(stroke:&amp;quot;gray&amp;quot;, `stroke-width`:&amp;quot;5&amp;quot;));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In 1.13.0 you can also use a &amp;quot;children&amp;quot; attribute to specify groups.&lt;br /&gt;
The children attribute should evaluate to a set of strings pointing to ids of SVG objects.&lt;br /&gt;
The following example shows this for for defining the children of &amp;quot;mygroup&amp;quot;.&lt;br /&gt;
Also observe the use of the new [[Summary_of_B_Syntax#Strings:|template string syntax]] for the transform attribute.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    VISB_SVG_FILE == &amp;quot;&amp;quot;;&lt;br /&gt;
    VISB_SVG_BOX == rec(height:400, width:450);&lt;br /&gt;
    VISB_SVG_OBJECTS1 == {i•i:0..9|rec(`id`:(&amp;quot;r&amp;quot;,i), svg_class:&amp;quot;rect&amp;quot;,&lt;br /&gt;
                                   fill:IF i=x THEN &amp;quot;red&amp;quot; ELSE &amp;quot;green&amp;quot; END,&lt;br /&gt;
                                   x:10+10*i, y:100, height:20, width:4)};&lt;br /&gt;
    VISB_SVG_OBJECTS2 == rec(`id`:&amp;quot;mygroup&amp;quot;, svg_class:&amp;quot;g&amp;quot;,&lt;br /&gt;
                             children: {i•i:0..9|(&amp;quot;r&amp;quot;,i)},&lt;br /&gt;
                             transform:```rotate(${x*40},50,100)```&lt;br /&gt;
                            )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Version 1.13.1 also adds a new virtual &amp;lt;tt&amp;gt;title&amp;lt;/tt&amp;gt; attribute that can be set in such SVG_OBJECTS.&lt;br /&gt;
This will create a tooltip box displaying the value of the attribute. (Internally this gets transformed into children SVG title objects.) These tooltips are independent of the other VisB hovers (and in contrast to these hovers the value of the title attribute can be dynamic, i.e., depend on the model&#039;s variables).&lt;br /&gt;
&lt;br /&gt;
In VisB event predicates, the local identifier VISB_CLICK_META_INFOS can be used to access information like shift or command key presses and mouse positions during a click. It represents a record of the following type:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   rec(altKey:     BOOL,&lt;br /&gt;
       ctrlKey:    BOOL,&lt;br /&gt;
       jsVars:     STRING &amp;lt;-&amp;gt; STRING,&lt;br /&gt;
       metaKey:    BOOL,&lt;br /&gt;
       pageX:      INTEGER,&lt;br /&gt;
       pageY:      INTEGER,&lt;br /&gt;
       shiftKey:   BOOL&lt;br /&gt;
   )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It also enables usage of JavaScript values: &amp;lt;tt&amp;gt;VISB_CLICK_META_INFOS&#039;jsVars(&amp;quot;MYID&amp;quot;)&amp;lt;/tt&amp;gt;. The value must first be assigned in a &amp;lt;tt&amp;gt;script&amp;lt;/tt&amp;gt; tag in the SVG using &amp;lt;tt&amp;gt;visb_vars[&amp;quot;${MYID}&amp;quot;]&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
Some examples can be found in the  [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples visb-visualisation-examples] repository.&lt;br /&gt;
We have a small [https://gitlab.cs.uni-duesseldorf.de/general/stups/prob2-jupyter-kernel/-/blob/master/notebooks/manual/VisB_Features.ipynb Jupyter notebook manual] on the DEFINITION features of VisB.&lt;br /&gt;
More details and examples will be added later.&lt;br /&gt;
&lt;br /&gt;
== Caveats ==&lt;br /&gt;
&lt;br /&gt;
* Beware that you need to escape quotation marks and slashes in the JSON file for fields containing B expressions. Also, you cannot use newline.&lt;br /&gt;
* Hovers are currently evaluated once statically and cannot make use of B expressions. To make hover information dependent on the state, use the visibility attribute to make hidden SVG objects (which can be adapted depending on the state using VisB items) visible. The [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples/-/tree/master/Train train VisB example] illustrates this idea.&lt;br /&gt;
&lt;br /&gt;
== Tips and Tricks ==&lt;br /&gt;
&lt;br /&gt;
It is sometimes useful to use simple coordinates for your VisB items and B expressions, e.g. x coordinates of 0..100.&lt;br /&gt;
You can quite often do this and use the SVG  &amp;lt;b&amp;gt;transform&amp;lt;/b&amp;gt; attribute to scale and move the SVG object to the right place.&lt;br /&gt;
The simple  [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples/-/tree/master/Train train VisB example] shows how to do this.&lt;br /&gt;
In essence your SVG file can contain this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;polygon id = &amp;quot;ttd_polyline&amp;quot;&lt;br /&gt;
       points=&amp;quot;0,0 100,0&amp;quot;&lt;br /&gt;
       stroke=&amp;quot;gray&amp;quot; fill=&amp;quot;none&amp;quot;&lt;br /&gt;
       transform=&amp;quot;translate(10,22.5)&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
and the VisB JSON file contains this, making use of LibrarySVG.def (automatically available) external function &amp;lt;b&amp;gt;svg_axis&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;ttd_polyline&amp;quot;,&lt;br /&gt;
      &amp;quot;attr&amp;quot;:&amp;quot;points&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;:&amp;quot;svg_axis({0} \\/ ran(%tt.(tt:TTDS|1+max(TTD_TrackElements(tt)))),100.0/real(TrackElementNumber+1),100.0,2.0)&amp;quot;,&lt;br /&gt;
      &amp;quot;comment&amp;quot;:&amp;quot;show ticks for TTD Limits&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Observe that we had to escape the slash of the union operator.&lt;br /&gt;
Also observe, that we are able to use [[Summary_of_B_Syntax#Reals:|floating numbers]] in the new version of ProB, which is very useful for VisB visualisations.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It can be useful to use style and class to make it easier to change your color scheme or other styling attributes within your visualisation consistently.&lt;br /&gt;
Again, the simple  [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples/-/tree/master/Train train VisB example] shows how to do this.&lt;br /&gt;
E.g., your SVG file could contain towards the top this definition:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;style id=&amp;quot;style_ttd_ts_mp&amp;quot;&amp;gt;&lt;br /&gt;
        .ttd {&lt;br /&gt;
            stroke : none;&lt;br /&gt;
            stroke-width: 0.2;&lt;br /&gt;
            opacity: 0.7&lt;br /&gt;
        }&lt;br /&gt;
        .red-occupied-ttd {&lt;br /&gt;
            fill : red&lt;br /&gt;
        }&lt;br /&gt;
   &amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Later you can then use it to style your objects:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;polygon id = &amp;quot;occupied_ttd_polygon&amp;quot;&lt;br /&gt;
       points=&amp;quot;0,0 0,2 10,2 10,0 70,0 70,1 90,1 90,0&amp;quot;&lt;br /&gt;
       class = &amp;quot;ttd red-occupied-ttd&amp;quot;&lt;br /&gt;
       transform=&amp;quot;translate(10,23)&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then modify the class using VisB items. Classes can also be useful for hovers, by simply exchanging one style for another when the mouse is over an objects (again, see [https://gitlab.cs.uni-duesseldorf.de/general/stups/visb-visualisation-examples/-/tree/master/Train the train example]).&lt;br /&gt;
Recent versions of ProB also support adding and removing a class, which is useful for hovers when the class is modified by VisB items:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   {&lt;br /&gt;
      &amp;quot;id&amp;quot;:&amp;quot;train_polygon_tr1&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;:&amp;quot;TrainMoveForward&amp;quot;,&lt;br /&gt;
      &amp;quot;hovers&amp;quot;: [{ &amp;quot;attr&amp;quot;:&amp;quot;class&amp;quot;, &amp;quot;enter&amp;quot;:&amp;quot;+train-hover&amp;quot;, &amp;quot;leave&amp;quot;:&amp;quot;-train-hover&amp;quot;}]&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Debugging and HTML Export ==&lt;br /&gt;
&lt;br /&gt;
In classical B models you can store your default VisB visualisation in the DEFINITIONS section:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  DEFINITIONS&lt;br /&gt;
    VISB_JSON_FILE == &amp;quot;TwoTrains.json&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For debugging it can be useful to use VisB within ProB Tcl/Tk: if you choose to visualise the current state with VisB, ProB will generate a stand-alone HTML file which is opened in a browser.&lt;br /&gt;
In the browser you can open the (Javascript) developer console and you will be alerted to warnings and errors (which unfortunately, are currently not shown in ProB2-UI).&lt;br /&gt;
Upon changing the state in the animator, the HTML file will be regenerated and the VisB file re-loaded if necessary.&lt;br /&gt;
The HTML export also displays hovers, but cannot react to clicks.&lt;br /&gt;
The HTML export is also available in ProB2-UI (in the export menu in the top-right corner).&lt;br /&gt;
&lt;br /&gt;
ProB can also export the entire animation history to a standalone HTML file that can be passed to other persons (without requiring access to the B model or to ProB).&lt;br /&gt;
In ProB Tcl/Tk you can right-click on the history pane and choose &amp;quot;View History in VisB&amp;quot;.&lt;br /&gt;
In probcli you can use the command &amp;lt;tt&amp;gt;-visb JSONFILE HTMLFILE&amp;lt;/tt&amp;gt; to export the history.&lt;br /&gt;
In ProB2-UI you can click on the export icon in the upper right hand corner:&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2UI_VisB_View_Export.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The ProB2-UI table visualisation view (Visualisation menu) also contains tables to help debug VisB items and events:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2UI_VisB_Debug_Table_View.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
This view is also available in ProB Tcl/Tk in the Visualize menu (States submenu).&lt;br /&gt;
ProB2-UI also has another inspection view that can be obtained by clicking on the &amp;quot;i&amp;quot; (info) icon in the the VisB toolbar.&lt;br /&gt;
&lt;br /&gt;
=== Using the VisB exported HTML file ===&lt;br /&gt;
&lt;br /&gt;
You should be able to open the exported HTML using a regular browser.&lt;br /&gt;
Within the web page (see the image below) you can then do the following:&lt;br /&gt;
* single step through the trace by clicking the &amp;quot;Forward&amp;quot; and &amp;quot;Backward&amp;quot; buttons, or clicking on individual steps of the trace&lt;br /&gt;
* execute the entire trace nd see changes to the visualisation by clicking one of the &amp;quot;Run Trace&amp;quot; buttons&lt;br /&gt;
* you can inspect the value of the sets, constants and variables at every step by expanding the corresponding tabs&lt;br /&gt;
Some meta information can be found at the bottom of the trace.&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2UI_VisB_View_ExportedHTML.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
== Citing VisB ==&lt;br /&gt;
This is the Bibtex entry for an article about VisB  [https://rdcu.be/b4rqh in the ABZ&#039;2020 proceedings]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@inproceedings{WerthLeuschel:abz2020,&lt;br /&gt;
  author    = {Michelle Werth and Michael Leuschel},&lt;br /&gt;
  title     = {{VisB}: A Lightweight Tool to Visualize Formal Models with {SVG} Graphics},&lt;br /&gt;
  booktitle = {Proceedings ABZ 2020},&lt;br /&gt;
  editor=&amp;quot;Raschke, Alexander and M{\&#039;e}ry, Dominique and Houdek, Frank&amp;quot;,&lt;br /&gt;
  year      = {2020},&lt;br /&gt;
  series = {LNCS 12071},&lt;br /&gt;
  pages = &amp;quot;260--265&amp;quot;,&lt;br /&gt;
  isbn=&amp;quot;978-3-030-48077-6&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing the VisB plugin for older ProB2-UI versions ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The following instructions are for ProB2-UI version 1.0.0 &#039;&#039;&#039;only&#039;&#039;&#039;. On current versions of ProB2-UI (1.1.0 and later), VisB is included by default and &#039;&#039;&#039;does not need to be installed separately&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
To install the VisB plugin in ProB2-UI 1.0.0 you need to:&lt;br /&gt;
&lt;br /&gt;
# [https://www3.hhu.de/stups/downloads/prob2/plugins/VisB-1.0.0.jar Download the VisB plugin jar file].&lt;br /&gt;
# In the &amp;quot;Advanced&amp;quot; menu of ProB2-UI, choose &amp;quot;Plugin Menu&amp;quot;.&lt;br /&gt;
# Click on the &amp;quot;Add Plugin...&amp;quot; button.&lt;br /&gt;
# Select the VisB jar file that you have downloaded.&lt;br /&gt;
# Choose the &amp;quot;Open VisB&amp;quot; command in the Advanced menu to start VisB.&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=External_Functions&amp;diff=5946</id>
		<title>External Functions</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=External_Functions&amp;diff=5946"/>
		<updated>2025-04-02T05:36:28Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* Standard Libraries provided by ProB */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]&lt;br /&gt;
[[Category: Advanced Feature]]&lt;br /&gt;
&lt;br /&gt;
As of version 1.3.5-beta7 ProB can make use of externally defined functions.&lt;br /&gt;
These functions must currently be written in Prolog (in principle C, Java, Tcl or even other languages can be used via the SICStus Prolog external function interfaces).&lt;br /&gt;
These functions can be used to write &amp;lt;em&amp;gt;expression&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;predicates&amp;lt;/em&amp;gt;, or &amp;lt;em&amp;gt;substitutions&amp;lt;/em&amp;gt;.&lt;br /&gt;
The general mechanism that is used is to mark certain DEFINITIONS as external, in which case ProB will make use of external Prolog code rather than using the right-hand-side of the DEFINITION whenever it is used. However, these DEFINITIONS can often (unless they are polymorphic) be wrapped into B (constant) functions. If you just want to use the standard external functions already defined by ProB, then you don&#039;t have to understand this mechanism in detail (or at all).&lt;br /&gt;
&lt;br /&gt;
We have a PDF describing the external functions generated from a  [https://gitlab.cs.uni-duesseldorf.de/general/stups/prob2-jupyter-kernel ProB-Jupyter] notebook:&lt;br /&gt;
[[File:ExternalFunctions.pdf]]&lt;br /&gt;
The Notebook [https://gitlab.cs.uni-duesseldorf.de/general/stups/prob2-jupyter-notebooks is available] and can now be [https://mybinder.org/v2/git/https%3A%2F%2Fgitlab.cs.uni-duesseldorf.de%2Fgeneral%2Fstups%2Fprob2-jupyter-notebooks/master?filepath=manual%2FExternalFunctions.ipynb launched via binder].&lt;br /&gt;
&lt;br /&gt;
== Standard Libraries provided by ProB ==&lt;br /&gt;
In a first instance we have predefined a series of external functions and grouped them in various library machines and definition files:&lt;br /&gt;
* &amp;lt;tt&amp;gt;LibraryMath.mch&amp;lt;/tt&amp;gt;: defining sin, cos, tan, sinx, cosx, tanx, logx, gcd, msb, random as well as access to all other Prolog built-in arithmetic functions.&lt;br /&gt;
* &amp;lt;tt&amp;gt;LibraryStrings.mch&amp;lt;/tt&amp;gt;: functions manipulating B STRING objects by providing &amp;lt;tt&amp;gt;length&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;append&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;split&amp;lt;/tt&amp;gt; and conversion functions &amp;lt;tt&amp;gt;chars&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;codes&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* &amp;lt;tt&amp;gt;LibraryStrings.def&amp;lt;/tt&amp;gt; used by &amp;lt;tt&amp;gt;LibraryStrings.mch&amp;lt;/tt&amp;gt;: providing direct access to various operators on strings (&amp;lt;tt&amp;gt;STRING_LENGTH&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_APPEND&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;INT_TO_STRING&amp;lt;/tt&amp;gt;,...)&lt;br /&gt;
* &amp;lt;tt&amp;gt;LibraryFiles.mch&amp;lt;/tt&amp;gt;: various functions to obtain information about files and directories in the underlying file system&lt;br /&gt;
* &amp;lt;tt&amp;gt;LibraryIO.def&amp;lt;/tt&amp;gt;: providing functions to write information to screen or file. Note: these external functions are polymorphic and as such cannot be defined as B constants: you have to use the DEFINITIONS provided in &amp;lt;tt&amp;gt;LibraryIO.def&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* &amp;lt;tt&amp;gt;CHOOSE.def&amp;lt;/tt&amp;gt;: providing the [http://planetmath.org/encyclopedia/HilbertsEpsilonOperator.html Hilbert choice operator] for choosing a designated element from each set. Again, this function is polymorphic and thus cannot be defined as a B function. This function is useful for defining [[Recursively_Defined_Functions|recursive functions]] over sets (see also [[TLA]]). Note that it in ProB it is undefined for the empty set.&lt;br /&gt;
* &amp;lt;tt&amp;gt;LibraryMeta.def&amp;lt;/tt&amp;gt;: providing access to meta-information about the loaded model (&amp;lt;tt&amp;gt;PROJECT_INFO&amp;lt;/tt&amp;gt;), about the state space (&amp;lt;tt&amp;gt;HISTORY&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STATE_TRANS&amp;lt;/tt&amp;gt;, ...) and about ProB itself (&amp;lt;tt&amp;gt;GET_PREF&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;PROB_INFO_STR&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;PROB_INFO_INT&amp;lt;/tt&amp;gt;,..).&lt;br /&gt;
* &amp;lt;tt&amp;gt;LibraryReals.def&amp;lt;/tt&amp;gt;: providing access to operators on [[Reals and Floats]] (&amp;lt;tt&amp;gt;RSIN&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RCOS&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RTAN&amp;lt;/tt&amp;gt;,  &amp;lt;tt&amp;gt;REXP&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;ROUND&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RLOG&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;RSQRT&amp;lt;/tt&amp;gt;,...).&lt;br /&gt;
* &amp;lt;tt&amp;gt;LibraryRegex.def&amp;lt;/tt&amp;gt;: providing access to regular expression operators on strings (&amp;lt;tt&amp;gt;REGEX_MATCH&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;REGEX_REPLACE&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;REGEX_SEARCH&amp;lt;/tt&amp;gt;,...)&lt;br /&gt;
* &amp;lt;tt&amp;gt;LibraryCSV.def&amp;lt;/tt&amp;gt;: contains a &amp;lt;tt&amp;gt;READ_CSV&amp;lt;/tt&amp;gt; external function to read in CSV files or strings and convert them to a B data structure&lt;br /&gt;
* &amp;lt;tt&amp;gt;LibrarySVG.def&amp;lt;/tt&amp;gt;: providing utility functions for VisB (&amp;lt;tt&amp;gt;svg_points&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;svg_axis&amp;lt;/tt&amp;gt;,...)&lt;br /&gt;
* &amp;lt;tt&amp;gt;LibraryXML.def&amp;lt;/tt&amp;gt;: contains a &amp;lt;tt&amp;gt;READ_XML&amp;lt;/tt&amp;gt; external function to read in XML files or strings and convert them to a B data structure with strings and records. Also contains &amp;lt;tt&amp;gt;READ_JSON_AS_XML&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;READ_JSON_FROM_STRING_AS_XML&amp;lt;/tt&amp;gt; to read JSON files and converting them to the same B format.&lt;br /&gt;
* &amp;lt;tt&amp;gt;LibraryBits.def&amp;lt;/tt&amp;gt;: contains bit-manipulation functions on integers (&amp;lt;tt&amp;gt;BNOT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BAND&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;BXOR&amp;lt;/tt&amp;gt;,...).&lt;br /&gt;
* &amp;lt;tt&amp;gt;SORT.def&amp;lt;/tt&amp;gt;: providing sorting related functions (&amp;lt;tt&amp;gt;SORT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;SQUASH&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;REPLACE&amp;lt;/tt&amp;gt;). &lt;br /&gt;
* &amp;lt;tt&amp;gt;SCCS.def&amp;lt;/tt&amp;gt;: providing access to &amp;lt;tt&amp;gt;SCCS&amp;lt;/tt&amp;gt; to compute the strongly connected components of a relation and &amp;lt;tt&amp;gt;CLOSURE1&amp;lt;/tt&amp;gt; an alternative algorithm for compting the transitive closure of a relation.&lt;br /&gt;
* &amp;lt;tt&amp;gt;LibraryJSON.def&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;LibraryJSON.mch&amp;lt;/tt&amp;gt; providing the functions &amp;lt;tt&amp;gt;READ_JSON&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;READ_JSON_FROM_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;WRITE_JSON&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;WRITE_JSON_TO_STRING&amp;lt;/tt&amp;gt; and the freetype &amp;lt;tt&amp;gt;JsonValue&amp;lt;/tt&amp;gt; to read and write JSON data.&lt;br /&gt;
* &amp;lt;tt&amp;gt;LibraryZMQ_RPC.def&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;LibraryZMQ_RPC.mch&amp;lt;/tt&amp;gt;: providing access to a JSON RPC (Remote Procedure Call) library either over regular sockets or ZMQ sockets. More information is available on [[JSON and Sockets]].&lt;br /&gt;
&lt;br /&gt;
Since version 1.5 the standard library is shipped with ProB  and references to machines and DEFINITION-files in the standard library are resolved automatically when referenced (see [[PROBPATH]] for information about how to customize the lookup path).&lt;br /&gt;
&lt;br /&gt;
To use a library machine you can use the &amp;lt;tt&amp;gt;SEES&amp;lt;/tt&amp;gt; mechanism:&lt;br /&gt;
 SEES LibraryMath&lt;br /&gt;
Note that for rules machines (.rmch) you have to use &amp;lt;tt&amp;gt;REFERENCES&amp;lt;/tt&amp;gt; instead.&lt;br /&gt;
&lt;br /&gt;
In general you can do the following with an external function, such as &amp;lt;tt&amp;gt;sin&amp;lt;/tt&amp;gt;, wrapped into a constant:&lt;br /&gt;
* apply the function: &amp;lt;tt&amp;gt;sin(x)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* compute the image of the function: &amp;lt;tt&amp;gt;sin[1..100]&amp;lt;/tt&amp;gt;&lt;br /&gt;
* compose the function with a finite relation on the left: &amp;lt;tt&amp;gt;([1..100] ; sin)&amp;lt;/tt&amp;gt;&lt;br /&gt;
* compute the domain of the function: &amp;lt;tt&amp;gt;dom(sin)&amp;lt;/tt&amp;gt;&lt;br /&gt;
To use a library definition file, you need to include the file in the DEFINITIONS clause:&lt;br /&gt;
 DEFINITIONS&lt;br /&gt;
   &amp;quot;LibraryIO.def&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Overview of the External Function DEFINITION Mechanism ==&lt;br /&gt;
&lt;br /&gt;
Currently, external functions are linked to classical B machines using B DEFINITIONS as follows:&lt;br /&gt;
* one definition, which defines the function as it is seen by tools other than ProB (e.g., Atelier-B). Suppose we want to declare an external cosinus function named &amp;lt;tt&amp;gt;COS&amp;lt;/tt&amp;gt;, then this definition could be &amp;lt;tt&amp;gt;COS(x) == cos(x)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* one definition declaring the type of the function. For &amp;lt;tt&amp;gt;COS&amp;lt;/tt&amp;gt; this would be &amp;lt;tt&amp;gt;EXTERNAL_FUNCTION_COS == INTEGER --&amp;gt; INTEGER&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* Prolog code which gets called by ProB in place of the right-hand-side of the first definition&lt;br /&gt;
Usually, it is also a good idea to encapsulate the external function inside a CONSTANT which is defined as a lambda abstraction with as body simply the call to the first DEFINITION. For &amp;lt;tt&amp;gt;COS&amp;lt;/tt&amp;gt; this would be &amp;lt;tt&amp;gt;cos = %x.(x:NATURAL|COS(x))&amp;lt;/tt&amp;gt;. Observe that for Atelier-B this is a tautology.&lt;br /&gt;
For ProB, the use of such a constant allows one to have a real B function representing the external function, for which we can compute the domain, range, etc.&lt;br /&gt;
&lt;br /&gt;
For the typing of an external function &amp;lt;tt&amp;gt;NAME&amp;lt;/tt&amp;gt; with type &amp;lt;tt&amp;gt;TYPE&amp;lt;/tt&amp;gt; there are three possibilities, depending on whether the function is a function, a predicate or a substitution:&lt;br /&gt;
* &amp;lt;tt&amp;gt;EXTERNAL_FUNCTION_NAME == TYPE&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;EXTERNAL_PREDICATE_NAME == TYPE&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;EXTERNAL_SUBSTITUTION_NAME == TYPE&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In case the external function is polymorphic, the &amp;lt;tt&amp;gt;DEFINITION&amp;lt;/tt&amp;gt; can take extra arguments: each argument is treated like a type variable.&lt;br /&gt;
For example, the following is used in &amp;lt;tt&amp;gt;CHOOSE.def&amp;lt;/tt&amp;gt; to declare the [http://planetmath.org/encyclopedia/HilbertsEpsilonOperator.html Hilbert choice operator]:&lt;br /&gt;
* &amp;lt;tt&amp;gt;EXTERNAL_FUNCTION_CHOOSE(T) == (POW(T)--&amp;gt;T) &amp;lt;/tt&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Rules-DSL&amp;diff=5945</id>
		<title>Rules-DSL</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Rules-DSL&amp;diff=5945"/>
		<updated>2025-03-31T10:29:44Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* Rule Validation with probcli */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== B-Rules DSL ==&lt;br /&gt;
&lt;br /&gt;
The B-Rules domain-specific language (B-Rules DSL) mainly provides operations for data validation. &amp;lt;em&amp;gt;Rules&amp;lt;/em&amp;gt; allow checking for expected properties, while &amp;lt;em&amp;gt;computations&amp;lt;/em&amp;gt; can be used to define and compute variables based on the successful execution of certain rules. Furthermore you can use &amp;lt;em&amp;gt;functions&amp;lt;/em&amp;gt; to compute values multiple times depending on different inputs.&lt;br /&gt;
&lt;br /&gt;
===Setting up a Rules Machine===&lt;br /&gt;
Rules machines are stored in &amp;lt;code&amp;gt;.rmch&amp;lt;/code&amp;gt;-files. The general setup for the machine header is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULES_MACHINE machine_name&lt;br /&gt;
REFERENCES list of rules machines&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The latter allows the inclusion of other rules machines and ordinary B machines that contain only constants, but not yet any other B machines. Below, &amp;lt;code&amp;gt;SETS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;DEFINITIONS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;PROPERTIES&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;CONSTANTS&amp;lt;/code&amp;gt; can be used as in a normal B machine. Note that &amp;lt;code&amp;gt;VARIABLES&amp;lt;/code&amp;gt; are not allowed as they are set by rule based computations.&lt;br /&gt;
&lt;br /&gt;
====Rules====&lt;br /&gt;
Rules can be defined in the &amp;lt;code&amp;gt;OPERATIONS&amp;lt;/code&amp;gt;-section of a rules machine. Depending on whether the expectations are met, a rule returns &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;FAIL&amp;lt;/code&amp;gt;. If a rule fails, additionally provided string messages are returned as counterexamples.&lt;br /&gt;
In the B Rules-DSL a rule has the following structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE rule_name // will be the name of the operation and variable storing the result&lt;br /&gt;
DEPENDS_ON_RULE list of rules&lt;br /&gt;
DEPENDS_ON_COMPUTATION list of computations&lt;br /&gt;
ACTIVATION predicate&lt;br /&gt;
ERROR_TYPES positive number of error types&lt;br /&gt;
BODY&lt;br /&gt;
    arbitrarily many rule bodys (see below)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The specified &amp;lt;code&amp;gt;rule_name&amp;lt;/code&amp;gt; will be the name of the operation and variable storing the result.&lt;br /&gt;
If a rule depends on other rules, it can only be executed if the specified rules have been successfully checked, i.e. their corresponding variables &amp;lt;code&amp;gt;rule_name&amp;lt;/code&amp;gt; have the value &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt;. In addition, rules can depend on computations. In this case, a rule is enabled when the specified computations have been executed. If a rule uses variables that are defined by computations, the corresponding computations are added implicitly as dependencies and do not have to be declared explicitly. Any other preconditions can be specified as an &amp;lt;code&amp;gt;ACTIVATION&amp;lt;/code&amp;gt; predicate. An important note is that the activation predicate is evaluated statically at initialisation and disables the rule if the predicate is false. Activation predicates and dependencies can be omitted if they are not needed.&lt;br /&gt;
&lt;br /&gt;
To use different error types (for example, if a rule has multiple bodies and it is necessary to distinguish between them), the number of error types has to be declared in the rule header.&lt;br /&gt;
Error types are also optional.&lt;br /&gt;
&lt;br /&gt;
The actual rule conditions are specified within the body of a rule, which contains the name and the preconditions.&lt;br /&gt;
A rule succeeds if and only if all rule conditions in its body are satisfied.&lt;br /&gt;
There are two constructs for rule bodies that can be used arbitrarily often in the body of a rule.&lt;br /&gt;
The following is formulated in a positive way, i.e. the execution of the rule leads to &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt; if the conditions in the &amp;lt;code&amp;gt;EXPECT&amp;lt;/code&amp;gt;-part are fulfilled.&lt;br /&gt;
In contrast to the &amp;lt;code&amp;gt;RULE_FAIL&amp;lt;/code&amp;gt; body (see below), in &amp;lt;code&amp;gt;RULE_FORALL&amp;lt;/code&amp;gt; you can obtain success messages (such as counter examples) for successful applications of the rule.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    RULE_FORALL&lt;br /&gt;
        list of identifiers&lt;br /&gt;
    WHERE &lt;br /&gt;
        conditions on identifiers&lt;br /&gt;
    EXPECT&lt;br /&gt;
        conditions that must be fulfilled for this rule&lt;br /&gt;
    ERROR_TYPE&lt;br /&gt;
        number encoding error type, must be in range of error types&lt;br /&gt;
    ON_SUCCESS &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list) or&lt;br /&gt;
        ```${identifier from list}``` (template string)&lt;br /&gt;
    COUNTEREXAMPLE &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list) or&lt;br /&gt;
        ```${identifier from list}``` (template string)&lt;br /&gt;
    END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, a negated rule can be formulated. Here the execution of the rule results in &amp;lt;code&amp;gt;FAIL&amp;lt;/code&amp;gt; if the conditions in the &amp;lt;code&amp;gt;WHEN&amp;lt;/code&amp;gt;-part are fulfilled.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    RULE_FAIL &lt;br /&gt;
        list of identifiers&lt;br /&gt;
    WHEN &lt;br /&gt;
        conditions on identifiers for a failing rule&lt;br /&gt;
    ERROR_TYPE&lt;br /&gt;
        number encoding error type, must be in range of error types&lt;br /&gt;
    COUNTEREXAMPLE &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list)&lt;br /&gt;
    END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Counterexamples are of the type &amp;lt;code&amp;gt;INTEGER &amp;lt;-&amp;gt; STRING&amp;lt;/code&amp;gt;. The integer contains the error type, while the string contains the message of the counterexample.&lt;br /&gt;
&lt;br /&gt;
Also valid for the rules header are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULEID id&lt;br /&gt;
CLASSIFICATION identifier&lt;br /&gt;
TAGS identifier&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;CLASSIFICATION&amp;lt;/code&amp;gt; keyword can be used to group the rules in the [[#Rule_Validation_in_ProB2-UI|HTML validation report]] according to their classification.&lt;br /&gt;
&lt;br /&gt;
====Computations====&lt;br /&gt;
Computations can be used to define variables. As for rules, their activation can depend on further rules, computations or any other predicate specified as an activation condition. Again, the activation condition is evaluated at initialisation and sets the computation status variable to &amp;lt;code&amp;gt;COMPUTATION_DISABLED&amp;lt;/code&amp;gt; if the predicate is false. Furthermore, a &amp;lt;code&amp;gt;DUMMY_VALUE&amp;lt;/code&amp;gt; can be set, which initialises the variable with the specified value instead of the empty set before execution of the computation. This mechanism implies that each variable defined by a computation must be a set of type &amp;lt;code&amp;gt;POW(S)&amp;lt;/code&amp;gt; for any &amp;lt;code&amp;gt;TYPE&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;S&amp;lt;/code&amp;gt;. A computation can be replaced by a previously defined computation if it sets the same variable (of the same type) by using &amp;lt;code&amp;gt;REPLACES&amp;lt;/code&amp;gt;. The general syntax for computations is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
COMPUTATION computation_name&lt;br /&gt;
DEPENDS_ON_RULE list of rules&lt;br /&gt;
DEPENDS_ON_COMPUTATION list of computations&lt;br /&gt;
ACTIVATION predicate&lt;br /&gt;
REPLACES identifier of exactly one computation&lt;br /&gt;
BODY&lt;br /&gt;
    DEFINE variable_name&lt;br /&gt;
        TYPE type of variable&lt;br /&gt;
        DUMMY_VALUE value of variable before execution (initialisation)&lt;br /&gt;
        VALUE value of variable after execution&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Activation predicates, dependencies, and also the dummy value can be omitted if they are not needed. After the execution of a computation, the value of the corresponding variable &amp;lt;code&amp;gt;computation_name&amp;lt;/code&amp;gt; is changed from &amp;lt;code&amp;gt;NOT_EXECUTED&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;EXECUTED&amp;lt;/code&amp;gt;  and the variable &amp;lt;code&amp;gt;variable_name&amp;lt;/code&amp;gt; has the value \texttt{VALUE}. For related computations, it may be useful to use multiple &amp;lt;code&amp;gt;DEFINE&amp;lt;/code&amp;gt; blocks in one computation.&lt;br /&gt;
Separated by &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt;, the body of a computation can contain any number of variable definitions.&lt;br /&gt;
&lt;br /&gt;
====Functions====&lt;br /&gt;
Functions can be called from any rules machine that references the machine containing the function. Depending on input parameters that must fulfil specified preconditions, the functions returns output value(s) that must fulfil optional postconditions. In the body, any B statement can be used to (sequentially) compute the output value.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FUNCTION output &amp;lt;-- function_name(list of input parameters)&lt;br /&gt;
PRECONDITION&lt;br /&gt;
    predicate&lt;br /&gt;
POSTCONDITION&lt;br /&gt;
    predicate&lt;br /&gt;
BODY&lt;br /&gt;
   some B statements&lt;br /&gt;
   output := ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Additional Syntax====&lt;br /&gt;
There are some useful predicates available in rules machines that can be used to check the success or failure of rules. It is also possible to check whether a certain error type was returned by a rule. These are:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SUCCEEDED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 succeeded&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SUCCEEDED_RULE_ERROR_TYPE(rule1,1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 did not fail with error type 1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;GET_RULE_COUNTEREXAMPLES(rule1)&amp;lt;/code&amp;gt;: set of counterexamples of rule1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 failed&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE_ERROR_TYPE(rule1,2)&amp;lt;/code&amp;gt;: TRUE, if check of rule1 failed with error type 2&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE_ALL_ERROR_TYPES(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 failed with all possible error types for rule1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;NOT_CHECKED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if rule1 has not yet been checked&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;DISABLED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if rule1 is disabled (its preconditions are not fulfilled)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another functionality of rules machines are FOR-loops. Their syntax is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FOR variable(s) IN set&lt;br /&gt;
DO&lt;br /&gt;
    operation(s)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
An example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE example_rule&lt;br /&gt;
BODY&lt;br /&gt;
    FOR x,y IN {1 |-&amp;gt; TRUE, 2 |-&amp;gt; FALSE, 3 |-&amp;gt; FALSE} DO &lt;br /&gt;
        RULE_FAIL &lt;br /&gt;
        WHEN y = FALSE&lt;br /&gt;
        COUNTEREXAMPLE STRING_FORMAT(&amp;quot;example_rule_fail: ~w&amp;quot;, x)&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This rule always fails and returns &amp;lt;code&amp;gt;{1 |-&amp;gt; &amp;quot;example_rule_fail: 2&amp;quot;, 1 |-&amp;gt; &amp;quot;example_rule_fail: 3&amp;quot;}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Rule Validation in ProB2-UI===&lt;br /&gt;
Rule validation has been integrated into the ProB2-UI since version 1.2.2 (not yet released).&lt;br /&gt;
It allows convenient execution of rules and computations together with a graphical representation of the results.&lt;br /&gt;
Rules are grouped by their classification and can be additionally filtered by their name, ID, or tags.&lt;br /&gt;
The results can also be exported as an HTML report.&lt;br /&gt;
In addition, dependencies of rules and computations can be visualised as a graph either for all operations or for just one operation (the HTML report and the dependency graph are generated by the ProB Java API and can also be created without ProB2-UI).&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2 UI Rules View.png|500px|ProB2-UI Rules View]]&lt;br /&gt;
&lt;br /&gt;
===Rule Validation with probcli===&lt;br /&gt;
The probcli recognises the option &amp;lt;code&amp;gt;-rule_report &amp;lt;file&amp;gt;&amp;lt;/code&amp;gt; which generates the same HTML validation report as in ProB2-UI for the current animation state.&lt;br /&gt;
To validate all rules, use this option in combination with &amp;lt;code&amp;gt;-execute_all&amp;lt;/code&amp;gt;.&lt;br /&gt;
The HTML report option is also available in ProB Tcl/Tk via the visualization menu.&lt;br /&gt;
Using the special definition &amp;lt;code&amp;gt;RULE_REPORT_CONTEXT&amp;lt;/code&amp;gt; you can include context information about the check in the report (of the type &amp;lt;tt&amp;gt;STRING&amp;lt;/tt&amp;gt;), e.g. the file name of a validated XML file.&lt;br /&gt;
&lt;br /&gt;
===Use Rules for Data Validation===&lt;br /&gt;
The concept of rule validation can be used to validate data from external sources such as CSV or XML files and load the validated data into ProB by successive computations.&lt;br /&gt;
For an XML file, this could look as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULES_MACHINE XML_import&lt;br /&gt;
DEFINITIONS&lt;br /&gt;
    &amp;quot;LibraryXML.def&amp;quot;&lt;br /&gt;
CONSTANTS&lt;br /&gt;
    xml_data&lt;br /&gt;
PROPERTIES&lt;br /&gt;
    xml_data = READ_XML(&amp;quot;xml_file.xml&amp;quot;, &amp;quot;auto&amp;quot;)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now some properties can be validated. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE is_supported_version_of_type_xyz&lt;br /&gt;
ERROR_TYPES 2&lt;br /&gt;
BODY&lt;br /&gt;
    RULE_FAIL e&lt;br /&gt;
    WHEN&lt;br /&gt;
        1 : dom(xml_data) &amp;amp; e = data(1)&#039;element &amp;amp; e /= &amp;quot;xyz&amp;quot;&lt;br /&gt;
    ERROR_TYPE 1 // optional: 1 is standard type&lt;br /&gt;
    COUNTEREXAMPLE&lt;br /&gt;
        STRING_FORMAT(&amp;quot;Error: could not find element &#039;xyz&#039;, was &#039;&amp;quot;^e^&amp;quot;&#039;&amp;quot;)&lt;br /&gt;
    END;&lt;br /&gt;
    RULE_FAIL v&lt;br /&gt;
    WHEN&lt;br /&gt;
        v = xml_data(1)&#039;attributes(&amp;quot;version&amp;quot;) &amp;amp; v /: supported_versions&lt;br /&gt;
    ERROR_TYPE 2&lt;br /&gt;
    COUNTEREXAMPLE&lt;br /&gt;
        &amp;quot;xyz of version &amp;quot;^v^&amp;quot; is currently not supported&amp;quot;&lt;br /&gt;
    END&lt;br /&gt;
END;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Internal Representation===&lt;br /&gt;
Each rules machine is internally translated to an ordinary B machine, which can be accessed as its internal representation.&lt;br /&gt;
Consider the following example rule:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE rule1 BODY RULE_FAIL WHEN bfalse COUNTEREXAMPLE &amp;quot;&amp;quot; END END;&lt;br /&gt;
&lt;br /&gt;
COMPUTATION comp1&lt;br /&gt;
BODY&lt;br /&gt;
    DEFINE x&lt;br /&gt;
    TYPE POW(INTEGER)&lt;br /&gt;
    VALUE 1..10&lt;br /&gt;
    END&lt;br /&gt;
END;&lt;br /&gt;
&lt;br /&gt;
RULE rule2&lt;br /&gt;
DEPENDS_ON_RULE rule1&lt;br /&gt;
// DEPENDS_ON_COMPUTATION comp1&lt;br /&gt;
BODY&lt;br /&gt;
    RULE_FORALL i&lt;br /&gt;
        WHERE i : 1..10&lt;br /&gt;
        EXPECT i &amp;gt; 5&lt;br /&gt;
        COUNTEREXAMPLE STRING_FORMAT(&amp;quot;~w &amp;lt;= 5&amp;quot;, i)&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Its internal representation in classical B is the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
`$RESULT`,`$COUNTEREXAMPLES` &amp;lt;-- rule1 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        rule1 = &amp;quot;NOT_CHECKED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
      rule1,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;SUCCESS&amp;quot;,&amp;quot;SUCCESS&amp;quot;,{}&lt;br /&gt;
    END;&lt;br /&gt;
  &lt;br /&gt;
  comp1 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        comp1 = &amp;quot;NOT_EXECUTED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
      x,comp1 := FORCE(1 .. 10),&amp;quot;EXECUTED&amp;quot;&lt;br /&gt;
    END;&lt;br /&gt;
  &lt;br /&gt;
  `$RESULT`,`$COUNTEREXAMPLES` &amp;lt;-- rule2 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        rule2 = &amp;quot;NOT_CHECKED&amp;quot;&lt;br /&gt;
      &amp;amp; rule1 = &amp;quot;SUCCESS&amp;quot;&lt;br /&gt;
      &amp;amp; comp1 = &amp;quot;EXECUTED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
        rule2,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;SUCCESS&amp;quot;,&amp;quot;SUCCESS&amp;quot;,{} ;&lt;br /&gt;
        VAR `$ResultTuple`,`$ResultStrings`&lt;br /&gt;
        IN&lt;br /&gt;
            `$ResultTuple` := FORCE({i|i : x &amp;amp; not(i &amp;gt; 5)}) ;&lt;br /&gt;
            `$ResultStrings` := FORCE({`$String`|`$String` : STRING &amp;amp; #i.(i : `$ResultTuple` &amp;amp; `$String` = FORMAT_TO_STRING(&amp;quot;~w &amp;lt;= 5&amp;quot;,[TO_STRING(i)]))});&lt;br /&gt;
              rule2_Counterexamples := rule2_Counterexamples \/ {1} * `$ResultStrings` ;&lt;br /&gt;
          IF `$ResultTuple` /= {} THEN&lt;br /&gt;
              rule2,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;FAIL&amp;quot;,&amp;quot;FAIL&amp;quot;,rule2_Counterexamples&lt;br /&gt;
          END&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Observe that the implicit dependency of rule2 on comp1 (rule2 uses its variable x) is detected automatically without explicit declaration.&lt;br /&gt;
&lt;br /&gt;
===Include Rules Machines into other Projects===&lt;br /&gt;
Currently, it is not possible to include rules machines directly into any other machines. Instead, use the rules machine at the top of the hierarchy (of the rules project) and save the internal generated machine as &amp;lt;code&amp;gt;.mch&amp;lt;/code&amp;gt;-file. After changing the machine name accordingly, the rules can be included and used via this machine.&lt;br /&gt;
Note that in this case it is not possible to perform Rules-DSL specific methods of the ProB Java API (like detailed information about rule results).&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Rules-DSL&amp;diff=5944</id>
		<title>Rules-DSL</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Rules-DSL&amp;diff=5944"/>
		<updated>2025-03-31T10:29:18Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* Rule Validation with probcli */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== B-Rules DSL ==&lt;br /&gt;
&lt;br /&gt;
The B-Rules domain-specific language (B-Rules DSL) mainly provides operations for data validation. &amp;lt;em&amp;gt;Rules&amp;lt;/em&amp;gt; allow checking for expected properties, while &amp;lt;em&amp;gt;computations&amp;lt;/em&amp;gt; can be used to define and compute variables based on the successful execution of certain rules. Furthermore you can use &amp;lt;em&amp;gt;functions&amp;lt;/em&amp;gt; to compute values multiple times depending on different inputs.&lt;br /&gt;
&lt;br /&gt;
===Setting up a Rules Machine===&lt;br /&gt;
Rules machines are stored in &amp;lt;code&amp;gt;.rmch&amp;lt;/code&amp;gt;-files. The general setup for the machine header is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULES_MACHINE machine_name&lt;br /&gt;
REFERENCES list of rules machines&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The latter allows the inclusion of other rules machines and ordinary B machines that contain only constants, but not yet any other B machines. Below, &amp;lt;code&amp;gt;SETS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;DEFINITIONS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;PROPERTIES&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;CONSTANTS&amp;lt;/code&amp;gt; can be used as in a normal B machine. Note that &amp;lt;code&amp;gt;VARIABLES&amp;lt;/code&amp;gt; are not allowed as they are set by rule based computations.&lt;br /&gt;
&lt;br /&gt;
====Rules====&lt;br /&gt;
Rules can be defined in the &amp;lt;code&amp;gt;OPERATIONS&amp;lt;/code&amp;gt;-section of a rules machine. Depending on whether the expectations are met, a rule returns &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;FAIL&amp;lt;/code&amp;gt;. If a rule fails, additionally provided string messages are returned as counterexamples.&lt;br /&gt;
In the B Rules-DSL a rule has the following structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE rule_name // will be the name of the operation and variable storing the result&lt;br /&gt;
DEPENDS_ON_RULE list of rules&lt;br /&gt;
DEPENDS_ON_COMPUTATION list of computations&lt;br /&gt;
ACTIVATION predicate&lt;br /&gt;
ERROR_TYPES positive number of error types&lt;br /&gt;
BODY&lt;br /&gt;
    arbitrarily many rule bodys (see below)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The specified &amp;lt;code&amp;gt;rule_name&amp;lt;/code&amp;gt; will be the name of the operation and variable storing the result.&lt;br /&gt;
If a rule depends on other rules, it can only be executed if the specified rules have been successfully checked, i.e. their corresponding variables &amp;lt;code&amp;gt;rule_name&amp;lt;/code&amp;gt; have the value &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt;. In addition, rules can depend on computations. In this case, a rule is enabled when the specified computations have been executed. If a rule uses variables that are defined by computations, the corresponding computations are added implicitly as dependencies and do not have to be declared explicitly. Any other preconditions can be specified as an &amp;lt;code&amp;gt;ACTIVATION&amp;lt;/code&amp;gt; predicate. An important note is that the activation predicate is evaluated statically at initialisation and disables the rule if the predicate is false. Activation predicates and dependencies can be omitted if they are not needed.&lt;br /&gt;
&lt;br /&gt;
To use different error types (for example, if a rule has multiple bodies and it is necessary to distinguish between them), the number of error types has to be declared in the rule header.&lt;br /&gt;
Error types are also optional.&lt;br /&gt;
&lt;br /&gt;
The actual rule conditions are specified within the body of a rule, which contains the name and the preconditions.&lt;br /&gt;
A rule succeeds if and only if all rule conditions in its body are satisfied.&lt;br /&gt;
There are two constructs for rule bodies that can be used arbitrarily often in the body of a rule.&lt;br /&gt;
The following is formulated in a positive way, i.e. the execution of the rule leads to &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt; if the conditions in the &amp;lt;code&amp;gt;EXPECT&amp;lt;/code&amp;gt;-part are fulfilled.&lt;br /&gt;
In contrast to the &amp;lt;code&amp;gt;RULE_FAIL&amp;lt;/code&amp;gt; body (see below), in &amp;lt;code&amp;gt;RULE_FORALL&amp;lt;/code&amp;gt; you can obtain success messages (such as counter examples) for successful applications of the rule.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    RULE_FORALL&lt;br /&gt;
        list of identifiers&lt;br /&gt;
    WHERE &lt;br /&gt;
        conditions on identifiers&lt;br /&gt;
    EXPECT&lt;br /&gt;
        conditions that must be fulfilled for this rule&lt;br /&gt;
    ERROR_TYPE&lt;br /&gt;
        number encoding error type, must be in range of error types&lt;br /&gt;
    ON_SUCCESS &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list) or&lt;br /&gt;
        ```${identifier from list}``` (template string)&lt;br /&gt;
    COUNTEREXAMPLE &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list) or&lt;br /&gt;
        ```${identifier from list}``` (template string)&lt;br /&gt;
    END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, a negated rule can be formulated. Here the execution of the rule results in &amp;lt;code&amp;gt;FAIL&amp;lt;/code&amp;gt; if the conditions in the &amp;lt;code&amp;gt;WHEN&amp;lt;/code&amp;gt;-part are fulfilled.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    RULE_FAIL &lt;br /&gt;
        list of identifiers&lt;br /&gt;
    WHEN &lt;br /&gt;
        conditions on identifiers for a failing rule&lt;br /&gt;
    ERROR_TYPE&lt;br /&gt;
        number encoding error type, must be in range of error types&lt;br /&gt;
    COUNTEREXAMPLE &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list)&lt;br /&gt;
    END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Counterexamples are of the type &amp;lt;code&amp;gt;INTEGER &amp;lt;-&amp;gt; STRING&amp;lt;/code&amp;gt;. The integer contains the error type, while the string contains the message of the counterexample.&lt;br /&gt;
&lt;br /&gt;
Also valid for the rules header are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULEID id&lt;br /&gt;
CLASSIFICATION identifier&lt;br /&gt;
TAGS identifier&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;CLASSIFICATION&amp;lt;/code&amp;gt; keyword can be used to group the rules in the [[#Rule_Validation_in_ProB2-UI|HTML validation report]] according to their classification.&lt;br /&gt;
&lt;br /&gt;
====Computations====&lt;br /&gt;
Computations can be used to define variables. As for rules, their activation can depend on further rules, computations or any other predicate specified as an activation condition. Again, the activation condition is evaluated at initialisation and sets the computation status variable to &amp;lt;code&amp;gt;COMPUTATION_DISABLED&amp;lt;/code&amp;gt; if the predicate is false. Furthermore, a &amp;lt;code&amp;gt;DUMMY_VALUE&amp;lt;/code&amp;gt; can be set, which initialises the variable with the specified value instead of the empty set before execution of the computation. This mechanism implies that each variable defined by a computation must be a set of type &amp;lt;code&amp;gt;POW(S)&amp;lt;/code&amp;gt; for any &amp;lt;code&amp;gt;TYPE&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;S&amp;lt;/code&amp;gt;. A computation can be replaced by a previously defined computation if it sets the same variable (of the same type) by using &amp;lt;code&amp;gt;REPLACES&amp;lt;/code&amp;gt;. The general syntax for computations is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
COMPUTATION computation_name&lt;br /&gt;
DEPENDS_ON_RULE list of rules&lt;br /&gt;
DEPENDS_ON_COMPUTATION list of computations&lt;br /&gt;
ACTIVATION predicate&lt;br /&gt;
REPLACES identifier of exactly one computation&lt;br /&gt;
BODY&lt;br /&gt;
    DEFINE variable_name&lt;br /&gt;
        TYPE type of variable&lt;br /&gt;
        DUMMY_VALUE value of variable before execution (initialisation)&lt;br /&gt;
        VALUE value of variable after execution&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Activation predicates, dependencies, and also the dummy value can be omitted if they are not needed. After the execution of a computation, the value of the corresponding variable &amp;lt;code&amp;gt;computation_name&amp;lt;/code&amp;gt; is changed from &amp;lt;code&amp;gt;NOT_EXECUTED&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;EXECUTED&amp;lt;/code&amp;gt;  and the variable &amp;lt;code&amp;gt;variable_name&amp;lt;/code&amp;gt; has the value \texttt{VALUE}. For related computations, it may be useful to use multiple &amp;lt;code&amp;gt;DEFINE&amp;lt;/code&amp;gt; blocks in one computation.&lt;br /&gt;
Separated by &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt;, the body of a computation can contain any number of variable definitions.&lt;br /&gt;
&lt;br /&gt;
====Functions====&lt;br /&gt;
Functions can be called from any rules machine that references the machine containing the function. Depending on input parameters that must fulfil specified preconditions, the functions returns output value(s) that must fulfil optional postconditions. In the body, any B statement can be used to (sequentially) compute the output value.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FUNCTION output &amp;lt;-- function_name(list of input parameters)&lt;br /&gt;
PRECONDITION&lt;br /&gt;
    predicate&lt;br /&gt;
POSTCONDITION&lt;br /&gt;
    predicate&lt;br /&gt;
BODY&lt;br /&gt;
   some B statements&lt;br /&gt;
   output := ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Additional Syntax====&lt;br /&gt;
There are some useful predicates available in rules machines that can be used to check the success or failure of rules. It is also possible to check whether a certain error type was returned by a rule. These are:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SUCCEEDED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 succeeded&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SUCCEEDED_RULE_ERROR_TYPE(rule1,1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 did not fail with error type 1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;GET_RULE_COUNTEREXAMPLES(rule1)&amp;lt;/code&amp;gt;: set of counterexamples of rule1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 failed&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE_ERROR_TYPE(rule1,2)&amp;lt;/code&amp;gt;: TRUE, if check of rule1 failed with error type 2&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE_ALL_ERROR_TYPES(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 failed with all possible error types for rule1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;NOT_CHECKED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if rule1 has not yet been checked&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;DISABLED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if rule1 is disabled (its preconditions are not fulfilled)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another functionality of rules machines are FOR-loops. Their syntax is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FOR variable(s) IN set&lt;br /&gt;
DO&lt;br /&gt;
    operation(s)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
An example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE example_rule&lt;br /&gt;
BODY&lt;br /&gt;
    FOR x,y IN {1 |-&amp;gt; TRUE, 2 |-&amp;gt; FALSE, 3 |-&amp;gt; FALSE} DO &lt;br /&gt;
        RULE_FAIL &lt;br /&gt;
        WHEN y = FALSE&lt;br /&gt;
        COUNTEREXAMPLE STRING_FORMAT(&amp;quot;example_rule_fail: ~w&amp;quot;, x)&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This rule always fails and returns &amp;lt;code&amp;gt;{1 |-&amp;gt; &amp;quot;example_rule_fail: 2&amp;quot;, 1 |-&amp;gt; &amp;quot;example_rule_fail: 3&amp;quot;}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Rule Validation in ProB2-UI===&lt;br /&gt;
Rule validation has been integrated into the ProB2-UI since version 1.2.2 (not yet released).&lt;br /&gt;
It allows convenient execution of rules and computations together with a graphical representation of the results.&lt;br /&gt;
Rules are grouped by their classification and can be additionally filtered by their name, ID, or tags.&lt;br /&gt;
The results can also be exported as an HTML report.&lt;br /&gt;
In addition, dependencies of rules and computations can be visualised as a graph either for all operations or for just one operation (the HTML report and the dependency graph are generated by the ProB Java API and can also be created without ProB2-UI).&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2 UI Rules View.png|500px|ProB2-UI Rules View]]&lt;br /&gt;
&lt;br /&gt;
===Rule Validation with probcli===&lt;br /&gt;
The probcli recognises the option &amp;lt;code&amp;gt;-rule_report &amp;lt;file&amp;gt;&amp;lt;/code&amp;gt; which generates the same HTML validation report as in ProB2-UI for the current animation state.&lt;br /&gt;
To validate all rules, use this option in combination with &amp;lt;code&amp;gt;-execute_all&amp;lt;/code&amp;gt;.&lt;br /&gt;
The HTML report option is also available in ProB Tcl/Tk via the visualization menu.&lt;br /&gt;
Using the special definition &amp;lt;code&amp;gt;RULE_REPORT_CONTEXT&amp;lt;/code&amp;gt; you can include context information about the check in the report, e.g. the file name of a validated XML file.&lt;br /&gt;
&lt;br /&gt;
===Use Rules for Data Validation===&lt;br /&gt;
The concept of rule validation can be used to validate data from external sources such as CSV or XML files and load the validated data into ProB by successive computations.&lt;br /&gt;
For an XML file, this could look as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULES_MACHINE XML_import&lt;br /&gt;
DEFINITIONS&lt;br /&gt;
    &amp;quot;LibraryXML.def&amp;quot;&lt;br /&gt;
CONSTANTS&lt;br /&gt;
    xml_data&lt;br /&gt;
PROPERTIES&lt;br /&gt;
    xml_data = READ_XML(&amp;quot;xml_file.xml&amp;quot;, &amp;quot;auto&amp;quot;)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now some properties can be validated. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE is_supported_version_of_type_xyz&lt;br /&gt;
ERROR_TYPES 2&lt;br /&gt;
BODY&lt;br /&gt;
    RULE_FAIL e&lt;br /&gt;
    WHEN&lt;br /&gt;
        1 : dom(xml_data) &amp;amp; e = data(1)&#039;element &amp;amp; e /= &amp;quot;xyz&amp;quot;&lt;br /&gt;
    ERROR_TYPE 1 // optional: 1 is standard type&lt;br /&gt;
    COUNTEREXAMPLE&lt;br /&gt;
        STRING_FORMAT(&amp;quot;Error: could not find element &#039;xyz&#039;, was &#039;&amp;quot;^e^&amp;quot;&#039;&amp;quot;)&lt;br /&gt;
    END;&lt;br /&gt;
    RULE_FAIL v&lt;br /&gt;
    WHEN&lt;br /&gt;
        v = xml_data(1)&#039;attributes(&amp;quot;version&amp;quot;) &amp;amp; v /: supported_versions&lt;br /&gt;
    ERROR_TYPE 2&lt;br /&gt;
    COUNTEREXAMPLE&lt;br /&gt;
        &amp;quot;xyz of version &amp;quot;^v^&amp;quot; is currently not supported&amp;quot;&lt;br /&gt;
    END&lt;br /&gt;
END;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Internal Representation===&lt;br /&gt;
Each rules machine is internally translated to an ordinary B machine, which can be accessed as its internal representation.&lt;br /&gt;
Consider the following example rule:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE rule1 BODY RULE_FAIL WHEN bfalse COUNTEREXAMPLE &amp;quot;&amp;quot; END END;&lt;br /&gt;
&lt;br /&gt;
COMPUTATION comp1&lt;br /&gt;
BODY&lt;br /&gt;
    DEFINE x&lt;br /&gt;
    TYPE POW(INTEGER)&lt;br /&gt;
    VALUE 1..10&lt;br /&gt;
    END&lt;br /&gt;
END;&lt;br /&gt;
&lt;br /&gt;
RULE rule2&lt;br /&gt;
DEPENDS_ON_RULE rule1&lt;br /&gt;
// DEPENDS_ON_COMPUTATION comp1&lt;br /&gt;
BODY&lt;br /&gt;
    RULE_FORALL i&lt;br /&gt;
        WHERE i : 1..10&lt;br /&gt;
        EXPECT i &amp;gt; 5&lt;br /&gt;
        COUNTEREXAMPLE STRING_FORMAT(&amp;quot;~w &amp;lt;= 5&amp;quot;, i)&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Its internal representation in classical B is the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
`$RESULT`,`$COUNTEREXAMPLES` &amp;lt;-- rule1 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        rule1 = &amp;quot;NOT_CHECKED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
      rule1,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;SUCCESS&amp;quot;,&amp;quot;SUCCESS&amp;quot;,{}&lt;br /&gt;
    END;&lt;br /&gt;
  &lt;br /&gt;
  comp1 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        comp1 = &amp;quot;NOT_EXECUTED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
      x,comp1 := FORCE(1 .. 10),&amp;quot;EXECUTED&amp;quot;&lt;br /&gt;
    END;&lt;br /&gt;
  &lt;br /&gt;
  `$RESULT`,`$COUNTEREXAMPLES` &amp;lt;-- rule2 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        rule2 = &amp;quot;NOT_CHECKED&amp;quot;&lt;br /&gt;
      &amp;amp; rule1 = &amp;quot;SUCCESS&amp;quot;&lt;br /&gt;
      &amp;amp; comp1 = &amp;quot;EXECUTED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
        rule2,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;SUCCESS&amp;quot;,&amp;quot;SUCCESS&amp;quot;,{} ;&lt;br /&gt;
        VAR `$ResultTuple`,`$ResultStrings`&lt;br /&gt;
        IN&lt;br /&gt;
            `$ResultTuple` := FORCE({i|i : x &amp;amp; not(i &amp;gt; 5)}) ;&lt;br /&gt;
            `$ResultStrings` := FORCE({`$String`|`$String` : STRING &amp;amp; #i.(i : `$ResultTuple` &amp;amp; `$String` = FORMAT_TO_STRING(&amp;quot;~w &amp;lt;= 5&amp;quot;,[TO_STRING(i)]))});&lt;br /&gt;
              rule2_Counterexamples := rule2_Counterexamples \/ {1} * `$ResultStrings` ;&lt;br /&gt;
          IF `$ResultTuple` /= {} THEN&lt;br /&gt;
              rule2,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;FAIL&amp;quot;,&amp;quot;FAIL&amp;quot;,rule2_Counterexamples&lt;br /&gt;
          END&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Observe that the implicit dependency of rule2 on comp1 (rule2 uses its variable x) is detected automatically without explicit declaration.&lt;br /&gt;
&lt;br /&gt;
===Include Rules Machines into other Projects===&lt;br /&gt;
Currently, it is not possible to include rules machines directly into any other machines. Instead, use the rules machine at the top of the hierarchy (of the rules project) and save the internal generated machine as &amp;lt;code&amp;gt;.mch&amp;lt;/code&amp;gt;-file. After changing the machine name accordingly, the rules can be included and used via this machine.&lt;br /&gt;
Note that in this case it is not possible to perform Rules-DSL specific methods of the ProB Java API (like detailed information about rule results).&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Rules-DSL&amp;diff=5943</id>
		<title>Rules-DSL</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Rules-DSL&amp;diff=5943"/>
		<updated>2025-03-31T10:29:04Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* Rule Validation with probcli */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== B-Rules DSL ==&lt;br /&gt;
&lt;br /&gt;
The B-Rules domain-specific language (B-Rules DSL) mainly provides operations for data validation. &amp;lt;em&amp;gt;Rules&amp;lt;/em&amp;gt; allow checking for expected properties, while &amp;lt;em&amp;gt;computations&amp;lt;/em&amp;gt; can be used to define and compute variables based on the successful execution of certain rules. Furthermore you can use &amp;lt;em&amp;gt;functions&amp;lt;/em&amp;gt; to compute values multiple times depending on different inputs.&lt;br /&gt;
&lt;br /&gt;
===Setting up a Rules Machine===&lt;br /&gt;
Rules machines are stored in &amp;lt;code&amp;gt;.rmch&amp;lt;/code&amp;gt;-files. The general setup for the machine header is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULES_MACHINE machine_name&lt;br /&gt;
REFERENCES list of rules machines&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The latter allows the inclusion of other rules machines and ordinary B machines that contain only constants, but not yet any other B machines. Below, &amp;lt;code&amp;gt;SETS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;DEFINITIONS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;PROPERTIES&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;CONSTANTS&amp;lt;/code&amp;gt; can be used as in a normal B machine. Note that &amp;lt;code&amp;gt;VARIABLES&amp;lt;/code&amp;gt; are not allowed as they are set by rule based computations.&lt;br /&gt;
&lt;br /&gt;
====Rules====&lt;br /&gt;
Rules can be defined in the &amp;lt;code&amp;gt;OPERATIONS&amp;lt;/code&amp;gt;-section of a rules machine. Depending on whether the expectations are met, a rule returns &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;FAIL&amp;lt;/code&amp;gt;. If a rule fails, additionally provided string messages are returned as counterexamples.&lt;br /&gt;
In the B Rules-DSL a rule has the following structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE rule_name // will be the name of the operation and variable storing the result&lt;br /&gt;
DEPENDS_ON_RULE list of rules&lt;br /&gt;
DEPENDS_ON_COMPUTATION list of computations&lt;br /&gt;
ACTIVATION predicate&lt;br /&gt;
ERROR_TYPES positive number of error types&lt;br /&gt;
BODY&lt;br /&gt;
    arbitrarily many rule bodys (see below)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The specified &amp;lt;code&amp;gt;rule_name&amp;lt;/code&amp;gt; will be the name of the operation and variable storing the result.&lt;br /&gt;
If a rule depends on other rules, it can only be executed if the specified rules have been successfully checked, i.e. their corresponding variables &amp;lt;code&amp;gt;rule_name&amp;lt;/code&amp;gt; have the value &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt;. In addition, rules can depend on computations. In this case, a rule is enabled when the specified computations have been executed. If a rule uses variables that are defined by computations, the corresponding computations are added implicitly as dependencies and do not have to be declared explicitly. Any other preconditions can be specified as an &amp;lt;code&amp;gt;ACTIVATION&amp;lt;/code&amp;gt; predicate. An important note is that the activation predicate is evaluated statically at initialisation and disables the rule if the predicate is false. Activation predicates and dependencies can be omitted if they are not needed.&lt;br /&gt;
&lt;br /&gt;
To use different error types (for example, if a rule has multiple bodies and it is necessary to distinguish between them), the number of error types has to be declared in the rule header.&lt;br /&gt;
Error types are also optional.&lt;br /&gt;
&lt;br /&gt;
The actual rule conditions are specified within the body of a rule, which contains the name and the preconditions.&lt;br /&gt;
A rule succeeds if and only if all rule conditions in its body are satisfied.&lt;br /&gt;
There are two constructs for rule bodies that can be used arbitrarily often in the body of a rule.&lt;br /&gt;
The following is formulated in a positive way, i.e. the execution of the rule leads to &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt; if the conditions in the &amp;lt;code&amp;gt;EXPECT&amp;lt;/code&amp;gt;-part are fulfilled.&lt;br /&gt;
In contrast to the &amp;lt;code&amp;gt;RULE_FAIL&amp;lt;/code&amp;gt; body (see below), in &amp;lt;code&amp;gt;RULE_FORALL&amp;lt;/code&amp;gt; you can obtain success messages (such as counter examples) for successful applications of the rule.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    RULE_FORALL&lt;br /&gt;
        list of identifiers&lt;br /&gt;
    WHERE &lt;br /&gt;
        conditions on identifiers&lt;br /&gt;
    EXPECT&lt;br /&gt;
        conditions that must be fulfilled for this rule&lt;br /&gt;
    ERROR_TYPE&lt;br /&gt;
        number encoding error type, must be in range of error types&lt;br /&gt;
    ON_SUCCESS &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list) or&lt;br /&gt;
        ```${identifier from list}``` (template string)&lt;br /&gt;
    COUNTEREXAMPLE &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list) or&lt;br /&gt;
        ```${identifier from list}``` (template string)&lt;br /&gt;
    END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, a negated rule can be formulated. Here the execution of the rule results in &amp;lt;code&amp;gt;FAIL&amp;lt;/code&amp;gt; if the conditions in the &amp;lt;code&amp;gt;WHEN&amp;lt;/code&amp;gt;-part are fulfilled.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    RULE_FAIL &lt;br /&gt;
        list of identifiers&lt;br /&gt;
    WHEN &lt;br /&gt;
        conditions on identifiers for a failing rule&lt;br /&gt;
    ERROR_TYPE&lt;br /&gt;
        number encoding error type, must be in range of error types&lt;br /&gt;
    COUNTEREXAMPLE &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list)&lt;br /&gt;
    END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Counterexamples are of the type &amp;lt;code&amp;gt;INTEGER &amp;lt;-&amp;gt; STRING&amp;lt;/code&amp;gt;. The integer contains the error type, while the string contains the message of the counterexample.&lt;br /&gt;
&lt;br /&gt;
Also valid for the rules header are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULEID id&lt;br /&gt;
CLASSIFICATION identifier&lt;br /&gt;
TAGS identifier&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;CLASSIFICATION&amp;lt;/code&amp;gt; keyword can be used to group the rules in the [[#Rule_Validation_in_ProB2-UI|HTML validation report]] according to their classification.&lt;br /&gt;
&lt;br /&gt;
====Computations====&lt;br /&gt;
Computations can be used to define variables. As for rules, their activation can depend on further rules, computations or any other predicate specified as an activation condition. Again, the activation condition is evaluated at initialisation and sets the computation status variable to &amp;lt;code&amp;gt;COMPUTATION_DISABLED&amp;lt;/code&amp;gt; if the predicate is false. Furthermore, a &amp;lt;code&amp;gt;DUMMY_VALUE&amp;lt;/code&amp;gt; can be set, which initialises the variable with the specified value instead of the empty set before execution of the computation. This mechanism implies that each variable defined by a computation must be a set of type &amp;lt;code&amp;gt;POW(S)&amp;lt;/code&amp;gt; for any &amp;lt;code&amp;gt;TYPE&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;S&amp;lt;/code&amp;gt;. A computation can be replaced by a previously defined computation if it sets the same variable (of the same type) by using &amp;lt;code&amp;gt;REPLACES&amp;lt;/code&amp;gt;. The general syntax for computations is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
COMPUTATION computation_name&lt;br /&gt;
DEPENDS_ON_RULE list of rules&lt;br /&gt;
DEPENDS_ON_COMPUTATION list of computations&lt;br /&gt;
ACTIVATION predicate&lt;br /&gt;
REPLACES identifier of exactly one computation&lt;br /&gt;
BODY&lt;br /&gt;
    DEFINE variable_name&lt;br /&gt;
        TYPE type of variable&lt;br /&gt;
        DUMMY_VALUE value of variable before execution (initialisation)&lt;br /&gt;
        VALUE value of variable after execution&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Activation predicates, dependencies, and also the dummy value can be omitted if they are not needed. After the execution of a computation, the value of the corresponding variable &amp;lt;code&amp;gt;computation_name&amp;lt;/code&amp;gt; is changed from &amp;lt;code&amp;gt;NOT_EXECUTED&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;EXECUTED&amp;lt;/code&amp;gt;  and the variable &amp;lt;code&amp;gt;variable_name&amp;lt;/code&amp;gt; has the value \texttt{VALUE}. For related computations, it may be useful to use multiple &amp;lt;code&amp;gt;DEFINE&amp;lt;/code&amp;gt; blocks in one computation.&lt;br /&gt;
Separated by &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt;, the body of a computation can contain any number of variable definitions.&lt;br /&gt;
&lt;br /&gt;
====Functions====&lt;br /&gt;
Functions can be called from any rules machine that references the machine containing the function. Depending on input parameters that must fulfil specified preconditions, the functions returns output value(s) that must fulfil optional postconditions. In the body, any B statement can be used to (sequentially) compute the output value.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FUNCTION output &amp;lt;-- function_name(list of input parameters)&lt;br /&gt;
PRECONDITION&lt;br /&gt;
    predicate&lt;br /&gt;
POSTCONDITION&lt;br /&gt;
    predicate&lt;br /&gt;
BODY&lt;br /&gt;
   some B statements&lt;br /&gt;
   output := ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Additional Syntax====&lt;br /&gt;
There are some useful predicates available in rules machines that can be used to check the success or failure of rules. It is also possible to check whether a certain error type was returned by a rule. These are:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SUCCEEDED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 succeeded&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SUCCEEDED_RULE_ERROR_TYPE(rule1,1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 did not fail with error type 1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;GET_RULE_COUNTEREXAMPLES(rule1)&amp;lt;/code&amp;gt;: set of counterexamples of rule1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 failed&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE_ERROR_TYPE(rule1,2)&amp;lt;/code&amp;gt;: TRUE, if check of rule1 failed with error type 2&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE_ALL_ERROR_TYPES(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 failed with all possible error types for rule1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;NOT_CHECKED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if rule1 has not yet been checked&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;DISABLED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if rule1 is disabled (its preconditions are not fulfilled)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another functionality of rules machines are FOR-loops. Their syntax is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FOR variable(s) IN set&lt;br /&gt;
DO&lt;br /&gt;
    operation(s)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
An example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE example_rule&lt;br /&gt;
BODY&lt;br /&gt;
    FOR x,y IN {1 |-&amp;gt; TRUE, 2 |-&amp;gt; FALSE, 3 |-&amp;gt; FALSE} DO &lt;br /&gt;
        RULE_FAIL &lt;br /&gt;
        WHEN y = FALSE&lt;br /&gt;
        COUNTEREXAMPLE STRING_FORMAT(&amp;quot;example_rule_fail: ~w&amp;quot;, x)&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This rule always fails and returns &amp;lt;code&amp;gt;{1 |-&amp;gt; &amp;quot;example_rule_fail: 2&amp;quot;, 1 |-&amp;gt; &amp;quot;example_rule_fail: 3&amp;quot;}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Rule Validation in ProB2-UI===&lt;br /&gt;
Rule validation has been integrated into the ProB2-UI since version 1.2.2 (not yet released).&lt;br /&gt;
It allows convenient execution of rules and computations together with a graphical representation of the results.&lt;br /&gt;
Rules are grouped by their classification and can be additionally filtered by their name, ID, or tags.&lt;br /&gt;
The results can also be exported as an HTML report.&lt;br /&gt;
In addition, dependencies of rules and computations can be visualised as a graph either for all operations or for just one operation (the HTML report and the dependency graph are generated by the ProB Java API and can also be created without ProB2-UI).&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2 UI Rules View.png|500px|ProB2-UI Rules View]]&lt;br /&gt;
&lt;br /&gt;
===Rule Validation with probcli===&lt;br /&gt;
The probcli recognises the option &amp;lt;code&amp;gt;-rule_report &amp;lt;file&amp;gt;&amp;lt;/code&amp;gt; which generates the same HTML validation report as in ProB2-UI for the current animation state.&lt;br /&gt;
To validate all rules, use this option in combination with &amp;lt;code&amp;gt;-execute_all&amp;lt;/code&amp;gt;.&lt;br /&gt;
The HTML report option is also available in ProB Tcl/Tk via the visualization menu.&lt;br /&gt;
Using the special definition &amp;lt;code&amp;gt;RULE_REPORT_CONTEXT&amp;lt;/code&amp;gt; you can include context information about the check run in the report, e.g. the file name of a validated XML file.&lt;br /&gt;
&lt;br /&gt;
===Use Rules for Data Validation===&lt;br /&gt;
The concept of rule validation can be used to validate data from external sources such as CSV or XML files and load the validated data into ProB by successive computations.&lt;br /&gt;
For an XML file, this could look as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULES_MACHINE XML_import&lt;br /&gt;
DEFINITIONS&lt;br /&gt;
    &amp;quot;LibraryXML.def&amp;quot;&lt;br /&gt;
CONSTANTS&lt;br /&gt;
    xml_data&lt;br /&gt;
PROPERTIES&lt;br /&gt;
    xml_data = READ_XML(&amp;quot;xml_file.xml&amp;quot;, &amp;quot;auto&amp;quot;)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now some properties can be validated. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE is_supported_version_of_type_xyz&lt;br /&gt;
ERROR_TYPES 2&lt;br /&gt;
BODY&lt;br /&gt;
    RULE_FAIL e&lt;br /&gt;
    WHEN&lt;br /&gt;
        1 : dom(xml_data) &amp;amp; e = data(1)&#039;element &amp;amp; e /= &amp;quot;xyz&amp;quot;&lt;br /&gt;
    ERROR_TYPE 1 // optional: 1 is standard type&lt;br /&gt;
    COUNTEREXAMPLE&lt;br /&gt;
        STRING_FORMAT(&amp;quot;Error: could not find element &#039;xyz&#039;, was &#039;&amp;quot;^e^&amp;quot;&#039;&amp;quot;)&lt;br /&gt;
    END;&lt;br /&gt;
    RULE_FAIL v&lt;br /&gt;
    WHEN&lt;br /&gt;
        v = xml_data(1)&#039;attributes(&amp;quot;version&amp;quot;) &amp;amp; v /: supported_versions&lt;br /&gt;
    ERROR_TYPE 2&lt;br /&gt;
    COUNTEREXAMPLE&lt;br /&gt;
        &amp;quot;xyz of version &amp;quot;^v^&amp;quot; is currently not supported&amp;quot;&lt;br /&gt;
    END&lt;br /&gt;
END;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Internal Representation===&lt;br /&gt;
Each rules machine is internally translated to an ordinary B machine, which can be accessed as its internal representation.&lt;br /&gt;
Consider the following example rule:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE rule1 BODY RULE_FAIL WHEN bfalse COUNTEREXAMPLE &amp;quot;&amp;quot; END END;&lt;br /&gt;
&lt;br /&gt;
COMPUTATION comp1&lt;br /&gt;
BODY&lt;br /&gt;
    DEFINE x&lt;br /&gt;
    TYPE POW(INTEGER)&lt;br /&gt;
    VALUE 1..10&lt;br /&gt;
    END&lt;br /&gt;
END;&lt;br /&gt;
&lt;br /&gt;
RULE rule2&lt;br /&gt;
DEPENDS_ON_RULE rule1&lt;br /&gt;
// DEPENDS_ON_COMPUTATION comp1&lt;br /&gt;
BODY&lt;br /&gt;
    RULE_FORALL i&lt;br /&gt;
        WHERE i : 1..10&lt;br /&gt;
        EXPECT i &amp;gt; 5&lt;br /&gt;
        COUNTEREXAMPLE STRING_FORMAT(&amp;quot;~w &amp;lt;= 5&amp;quot;, i)&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Its internal representation in classical B is the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
`$RESULT`,`$COUNTEREXAMPLES` &amp;lt;-- rule1 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        rule1 = &amp;quot;NOT_CHECKED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
      rule1,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;SUCCESS&amp;quot;,&amp;quot;SUCCESS&amp;quot;,{}&lt;br /&gt;
    END;&lt;br /&gt;
  &lt;br /&gt;
  comp1 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        comp1 = &amp;quot;NOT_EXECUTED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
      x,comp1 := FORCE(1 .. 10),&amp;quot;EXECUTED&amp;quot;&lt;br /&gt;
    END;&lt;br /&gt;
  &lt;br /&gt;
  `$RESULT`,`$COUNTEREXAMPLES` &amp;lt;-- rule2 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        rule2 = &amp;quot;NOT_CHECKED&amp;quot;&lt;br /&gt;
      &amp;amp; rule1 = &amp;quot;SUCCESS&amp;quot;&lt;br /&gt;
      &amp;amp; comp1 = &amp;quot;EXECUTED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
        rule2,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;SUCCESS&amp;quot;,&amp;quot;SUCCESS&amp;quot;,{} ;&lt;br /&gt;
        VAR `$ResultTuple`,`$ResultStrings`&lt;br /&gt;
        IN&lt;br /&gt;
            `$ResultTuple` := FORCE({i|i : x &amp;amp; not(i &amp;gt; 5)}) ;&lt;br /&gt;
            `$ResultStrings` := FORCE({`$String`|`$String` : STRING &amp;amp; #i.(i : `$ResultTuple` &amp;amp; `$String` = FORMAT_TO_STRING(&amp;quot;~w &amp;lt;= 5&amp;quot;,[TO_STRING(i)]))});&lt;br /&gt;
              rule2_Counterexamples := rule2_Counterexamples \/ {1} * `$ResultStrings` ;&lt;br /&gt;
          IF `$ResultTuple` /= {} THEN&lt;br /&gt;
              rule2,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;FAIL&amp;quot;,&amp;quot;FAIL&amp;quot;,rule2_Counterexamples&lt;br /&gt;
          END&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Observe that the implicit dependency of rule2 on comp1 (rule2 uses its variable x) is detected automatically without explicit declaration.&lt;br /&gt;
&lt;br /&gt;
===Include Rules Machines into other Projects===&lt;br /&gt;
Currently, it is not possible to include rules machines directly into any other machines. Instead, use the rules machine at the top of the hierarchy (of the rules project) and save the internal generated machine as &amp;lt;code&amp;gt;.mch&amp;lt;/code&amp;gt;-file. After changing the machine name accordingly, the rules can be included and used via this machine.&lt;br /&gt;
Note that in this case it is not possible to perform Rules-DSL specific methods of the ProB Java API (like detailed information about rule results).&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Rules-DSL&amp;diff=5942</id>
		<title>Rules-DSL</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Rules-DSL&amp;diff=5942"/>
		<updated>2025-03-31T10:28:52Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* Rule Validation with probcli */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== B-Rules DSL ==&lt;br /&gt;
&lt;br /&gt;
The B-Rules domain-specific language (B-Rules DSL) mainly provides operations for data validation. &amp;lt;em&amp;gt;Rules&amp;lt;/em&amp;gt; allow checking for expected properties, while &amp;lt;em&amp;gt;computations&amp;lt;/em&amp;gt; can be used to define and compute variables based on the successful execution of certain rules. Furthermore you can use &amp;lt;em&amp;gt;functions&amp;lt;/em&amp;gt; to compute values multiple times depending on different inputs.&lt;br /&gt;
&lt;br /&gt;
===Setting up a Rules Machine===&lt;br /&gt;
Rules machines are stored in &amp;lt;code&amp;gt;.rmch&amp;lt;/code&amp;gt;-files. The general setup for the machine header is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULES_MACHINE machine_name&lt;br /&gt;
REFERENCES list of rules machines&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The latter allows the inclusion of other rules machines and ordinary B machines that contain only constants, but not yet any other B machines. Below, &amp;lt;code&amp;gt;SETS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;DEFINITIONS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;PROPERTIES&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;CONSTANTS&amp;lt;/code&amp;gt; can be used as in a normal B machine. Note that &amp;lt;code&amp;gt;VARIABLES&amp;lt;/code&amp;gt; are not allowed as they are set by rule based computations.&lt;br /&gt;
&lt;br /&gt;
====Rules====&lt;br /&gt;
Rules can be defined in the &amp;lt;code&amp;gt;OPERATIONS&amp;lt;/code&amp;gt;-section of a rules machine. Depending on whether the expectations are met, a rule returns &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;FAIL&amp;lt;/code&amp;gt;. If a rule fails, additionally provided string messages are returned as counterexamples.&lt;br /&gt;
In the B Rules-DSL a rule has the following structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE rule_name // will be the name of the operation and variable storing the result&lt;br /&gt;
DEPENDS_ON_RULE list of rules&lt;br /&gt;
DEPENDS_ON_COMPUTATION list of computations&lt;br /&gt;
ACTIVATION predicate&lt;br /&gt;
ERROR_TYPES positive number of error types&lt;br /&gt;
BODY&lt;br /&gt;
    arbitrarily many rule bodys (see below)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The specified &amp;lt;code&amp;gt;rule_name&amp;lt;/code&amp;gt; will be the name of the operation and variable storing the result.&lt;br /&gt;
If a rule depends on other rules, it can only be executed if the specified rules have been successfully checked, i.e. their corresponding variables &amp;lt;code&amp;gt;rule_name&amp;lt;/code&amp;gt; have the value &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt;. In addition, rules can depend on computations. In this case, a rule is enabled when the specified computations have been executed. If a rule uses variables that are defined by computations, the corresponding computations are added implicitly as dependencies and do not have to be declared explicitly. Any other preconditions can be specified as an &amp;lt;code&amp;gt;ACTIVATION&amp;lt;/code&amp;gt; predicate. An important note is that the activation predicate is evaluated statically at initialisation and disables the rule if the predicate is false. Activation predicates and dependencies can be omitted if they are not needed.&lt;br /&gt;
&lt;br /&gt;
To use different error types (for example, if a rule has multiple bodies and it is necessary to distinguish between them), the number of error types has to be declared in the rule header.&lt;br /&gt;
Error types are also optional.&lt;br /&gt;
&lt;br /&gt;
The actual rule conditions are specified within the body of a rule, which contains the name and the preconditions.&lt;br /&gt;
A rule succeeds if and only if all rule conditions in its body are satisfied.&lt;br /&gt;
There are two constructs for rule bodies that can be used arbitrarily often in the body of a rule.&lt;br /&gt;
The following is formulated in a positive way, i.e. the execution of the rule leads to &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt; if the conditions in the &amp;lt;code&amp;gt;EXPECT&amp;lt;/code&amp;gt;-part are fulfilled.&lt;br /&gt;
In contrast to the &amp;lt;code&amp;gt;RULE_FAIL&amp;lt;/code&amp;gt; body (see below), in &amp;lt;code&amp;gt;RULE_FORALL&amp;lt;/code&amp;gt; you can obtain success messages (such as counter examples) for successful applications of the rule.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    RULE_FORALL&lt;br /&gt;
        list of identifiers&lt;br /&gt;
    WHERE &lt;br /&gt;
        conditions on identifiers&lt;br /&gt;
    EXPECT&lt;br /&gt;
        conditions that must be fulfilled for this rule&lt;br /&gt;
    ERROR_TYPE&lt;br /&gt;
        number encoding error type, must be in range of error types&lt;br /&gt;
    ON_SUCCESS &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list) or&lt;br /&gt;
        ```${identifier from list}``` (template string)&lt;br /&gt;
    COUNTEREXAMPLE &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list) or&lt;br /&gt;
        ```${identifier from list}``` (template string)&lt;br /&gt;
    END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, a negated rule can be formulated. Here the execution of the rule results in &amp;lt;code&amp;gt;FAIL&amp;lt;/code&amp;gt; if the conditions in the &amp;lt;code&amp;gt;WHEN&amp;lt;/code&amp;gt;-part are fulfilled.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    RULE_FAIL &lt;br /&gt;
        list of identifiers&lt;br /&gt;
    WHEN &lt;br /&gt;
        conditions on identifiers for a failing rule&lt;br /&gt;
    ERROR_TYPE&lt;br /&gt;
        number encoding error type, must be in range of error types&lt;br /&gt;
    COUNTEREXAMPLE &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list)&lt;br /&gt;
    END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Counterexamples are of the type &amp;lt;code&amp;gt;INTEGER &amp;lt;-&amp;gt; STRING&amp;lt;/code&amp;gt;. The integer contains the error type, while the string contains the message of the counterexample.&lt;br /&gt;
&lt;br /&gt;
Also valid for the rules header are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULEID id&lt;br /&gt;
CLASSIFICATION identifier&lt;br /&gt;
TAGS identifier&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;CLASSIFICATION&amp;lt;/code&amp;gt; keyword can be used to group the rules in the [[#Rule_Validation_in_ProB2-UI|HTML validation report]] according to their classification.&lt;br /&gt;
&lt;br /&gt;
====Computations====&lt;br /&gt;
Computations can be used to define variables. As for rules, their activation can depend on further rules, computations or any other predicate specified as an activation condition. Again, the activation condition is evaluated at initialisation and sets the computation status variable to &amp;lt;code&amp;gt;COMPUTATION_DISABLED&amp;lt;/code&amp;gt; if the predicate is false. Furthermore, a &amp;lt;code&amp;gt;DUMMY_VALUE&amp;lt;/code&amp;gt; can be set, which initialises the variable with the specified value instead of the empty set before execution of the computation. This mechanism implies that each variable defined by a computation must be a set of type &amp;lt;code&amp;gt;POW(S)&amp;lt;/code&amp;gt; for any &amp;lt;code&amp;gt;TYPE&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;S&amp;lt;/code&amp;gt;. A computation can be replaced by a previously defined computation if it sets the same variable (of the same type) by using &amp;lt;code&amp;gt;REPLACES&amp;lt;/code&amp;gt;. The general syntax for computations is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
COMPUTATION computation_name&lt;br /&gt;
DEPENDS_ON_RULE list of rules&lt;br /&gt;
DEPENDS_ON_COMPUTATION list of computations&lt;br /&gt;
ACTIVATION predicate&lt;br /&gt;
REPLACES identifier of exactly one computation&lt;br /&gt;
BODY&lt;br /&gt;
    DEFINE variable_name&lt;br /&gt;
        TYPE type of variable&lt;br /&gt;
        DUMMY_VALUE value of variable before execution (initialisation)&lt;br /&gt;
        VALUE value of variable after execution&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Activation predicates, dependencies, and also the dummy value can be omitted if they are not needed. After the execution of a computation, the value of the corresponding variable &amp;lt;code&amp;gt;computation_name&amp;lt;/code&amp;gt; is changed from &amp;lt;code&amp;gt;NOT_EXECUTED&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;EXECUTED&amp;lt;/code&amp;gt;  and the variable &amp;lt;code&amp;gt;variable_name&amp;lt;/code&amp;gt; has the value \texttt{VALUE}. For related computations, it may be useful to use multiple &amp;lt;code&amp;gt;DEFINE&amp;lt;/code&amp;gt; blocks in one computation.&lt;br /&gt;
Separated by &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt;, the body of a computation can contain any number of variable definitions.&lt;br /&gt;
&lt;br /&gt;
====Functions====&lt;br /&gt;
Functions can be called from any rules machine that references the machine containing the function. Depending on input parameters that must fulfil specified preconditions, the functions returns output value(s) that must fulfil optional postconditions. In the body, any B statement can be used to (sequentially) compute the output value.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FUNCTION output &amp;lt;-- function_name(list of input parameters)&lt;br /&gt;
PRECONDITION&lt;br /&gt;
    predicate&lt;br /&gt;
POSTCONDITION&lt;br /&gt;
    predicate&lt;br /&gt;
BODY&lt;br /&gt;
   some B statements&lt;br /&gt;
   output := ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Additional Syntax====&lt;br /&gt;
There are some useful predicates available in rules machines that can be used to check the success or failure of rules. It is also possible to check whether a certain error type was returned by a rule. These are:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SUCCEEDED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 succeeded&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SUCCEEDED_RULE_ERROR_TYPE(rule1,1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 did not fail with error type 1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;GET_RULE_COUNTEREXAMPLES(rule1)&amp;lt;/code&amp;gt;: set of counterexamples of rule1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 failed&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE_ERROR_TYPE(rule1,2)&amp;lt;/code&amp;gt;: TRUE, if check of rule1 failed with error type 2&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE_ALL_ERROR_TYPES(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 failed with all possible error types for rule1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;NOT_CHECKED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if rule1 has not yet been checked&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;DISABLED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if rule1 is disabled (its preconditions are not fulfilled)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another functionality of rules machines are FOR-loops. Their syntax is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FOR variable(s) IN set&lt;br /&gt;
DO&lt;br /&gt;
    operation(s)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
An example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE example_rule&lt;br /&gt;
BODY&lt;br /&gt;
    FOR x,y IN {1 |-&amp;gt; TRUE, 2 |-&amp;gt; FALSE, 3 |-&amp;gt; FALSE} DO &lt;br /&gt;
        RULE_FAIL &lt;br /&gt;
        WHEN y = FALSE&lt;br /&gt;
        COUNTEREXAMPLE STRING_FORMAT(&amp;quot;example_rule_fail: ~w&amp;quot;, x)&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This rule always fails and returns &amp;lt;code&amp;gt;{1 |-&amp;gt; &amp;quot;example_rule_fail: 2&amp;quot;, 1 |-&amp;gt; &amp;quot;example_rule_fail: 3&amp;quot;}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Rule Validation in ProB2-UI===&lt;br /&gt;
Rule validation has been integrated into the ProB2-UI since version 1.2.2 (not yet released).&lt;br /&gt;
It allows convenient execution of rules and computations together with a graphical representation of the results.&lt;br /&gt;
Rules are grouped by their classification and can be additionally filtered by their name, ID, or tags.&lt;br /&gt;
The results can also be exported as an HTML report.&lt;br /&gt;
In addition, dependencies of rules and computations can be visualised as a graph either for all operations or for just one operation (the HTML report and the dependency graph are generated by the ProB Java API and can also be created without ProB2-UI).&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2 UI Rules View.png|500px|ProB2-UI Rules View]]&lt;br /&gt;
&lt;br /&gt;
===Rule Validation with probcli===&lt;br /&gt;
The probcli recognises the option &amp;lt;code&amp;gt;-rule_report &amp;lt;file&amp;gt;&amp;lt;/code&amp;gt; which generates the same HTML validation report as in ProB2-UI for the current animation state.&lt;br /&gt;
To validate all rules, use this option in combination with &amp;lt;code&amp;gt;-execute_all&amp;lt;/code&amp;gt;.&lt;br /&gt;
The HTML report option is also available in ProB Tcl/Tk via the visualization menu.&lt;br /&gt;
Using the special definition &amp;lt;tt&amp;gt;RULE_REPORT_CONTEXT&amp;lt;/tt&amp;gt; you can include context information about the check run in the report, e.g. the file name of a validated XML file.&lt;br /&gt;
&lt;br /&gt;
===Use Rules for Data Validation===&lt;br /&gt;
The concept of rule validation can be used to validate data from external sources such as CSV or XML files and load the validated data into ProB by successive computations.&lt;br /&gt;
For an XML file, this could look as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULES_MACHINE XML_import&lt;br /&gt;
DEFINITIONS&lt;br /&gt;
    &amp;quot;LibraryXML.def&amp;quot;&lt;br /&gt;
CONSTANTS&lt;br /&gt;
    xml_data&lt;br /&gt;
PROPERTIES&lt;br /&gt;
    xml_data = READ_XML(&amp;quot;xml_file.xml&amp;quot;, &amp;quot;auto&amp;quot;)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now some properties can be validated. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE is_supported_version_of_type_xyz&lt;br /&gt;
ERROR_TYPES 2&lt;br /&gt;
BODY&lt;br /&gt;
    RULE_FAIL e&lt;br /&gt;
    WHEN&lt;br /&gt;
        1 : dom(xml_data) &amp;amp; e = data(1)&#039;element &amp;amp; e /= &amp;quot;xyz&amp;quot;&lt;br /&gt;
    ERROR_TYPE 1 // optional: 1 is standard type&lt;br /&gt;
    COUNTEREXAMPLE&lt;br /&gt;
        STRING_FORMAT(&amp;quot;Error: could not find element &#039;xyz&#039;, was &#039;&amp;quot;^e^&amp;quot;&#039;&amp;quot;)&lt;br /&gt;
    END;&lt;br /&gt;
    RULE_FAIL v&lt;br /&gt;
    WHEN&lt;br /&gt;
        v = xml_data(1)&#039;attributes(&amp;quot;version&amp;quot;) &amp;amp; v /: supported_versions&lt;br /&gt;
    ERROR_TYPE 2&lt;br /&gt;
    COUNTEREXAMPLE&lt;br /&gt;
        &amp;quot;xyz of version &amp;quot;^v^&amp;quot; is currently not supported&amp;quot;&lt;br /&gt;
    END&lt;br /&gt;
END;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Internal Representation===&lt;br /&gt;
Each rules machine is internally translated to an ordinary B machine, which can be accessed as its internal representation.&lt;br /&gt;
Consider the following example rule:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE rule1 BODY RULE_FAIL WHEN bfalse COUNTEREXAMPLE &amp;quot;&amp;quot; END END;&lt;br /&gt;
&lt;br /&gt;
COMPUTATION comp1&lt;br /&gt;
BODY&lt;br /&gt;
    DEFINE x&lt;br /&gt;
    TYPE POW(INTEGER)&lt;br /&gt;
    VALUE 1..10&lt;br /&gt;
    END&lt;br /&gt;
END;&lt;br /&gt;
&lt;br /&gt;
RULE rule2&lt;br /&gt;
DEPENDS_ON_RULE rule1&lt;br /&gt;
// DEPENDS_ON_COMPUTATION comp1&lt;br /&gt;
BODY&lt;br /&gt;
    RULE_FORALL i&lt;br /&gt;
        WHERE i : 1..10&lt;br /&gt;
        EXPECT i &amp;gt; 5&lt;br /&gt;
        COUNTEREXAMPLE STRING_FORMAT(&amp;quot;~w &amp;lt;= 5&amp;quot;, i)&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Its internal representation in classical B is the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
`$RESULT`,`$COUNTEREXAMPLES` &amp;lt;-- rule1 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        rule1 = &amp;quot;NOT_CHECKED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
      rule1,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;SUCCESS&amp;quot;,&amp;quot;SUCCESS&amp;quot;,{}&lt;br /&gt;
    END;&lt;br /&gt;
  &lt;br /&gt;
  comp1 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        comp1 = &amp;quot;NOT_EXECUTED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
      x,comp1 := FORCE(1 .. 10),&amp;quot;EXECUTED&amp;quot;&lt;br /&gt;
    END;&lt;br /&gt;
  &lt;br /&gt;
  `$RESULT`,`$COUNTEREXAMPLES` &amp;lt;-- rule2 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        rule2 = &amp;quot;NOT_CHECKED&amp;quot;&lt;br /&gt;
      &amp;amp; rule1 = &amp;quot;SUCCESS&amp;quot;&lt;br /&gt;
      &amp;amp; comp1 = &amp;quot;EXECUTED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
        rule2,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;SUCCESS&amp;quot;,&amp;quot;SUCCESS&amp;quot;,{} ;&lt;br /&gt;
        VAR `$ResultTuple`,`$ResultStrings`&lt;br /&gt;
        IN&lt;br /&gt;
            `$ResultTuple` := FORCE({i|i : x &amp;amp; not(i &amp;gt; 5)}) ;&lt;br /&gt;
            `$ResultStrings` := FORCE({`$String`|`$String` : STRING &amp;amp; #i.(i : `$ResultTuple` &amp;amp; `$String` = FORMAT_TO_STRING(&amp;quot;~w &amp;lt;= 5&amp;quot;,[TO_STRING(i)]))});&lt;br /&gt;
              rule2_Counterexamples := rule2_Counterexamples \/ {1} * `$ResultStrings` ;&lt;br /&gt;
          IF `$ResultTuple` /= {} THEN&lt;br /&gt;
              rule2,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;FAIL&amp;quot;,&amp;quot;FAIL&amp;quot;,rule2_Counterexamples&lt;br /&gt;
          END&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Observe that the implicit dependency of rule2 on comp1 (rule2 uses its variable x) is detected automatically without explicit declaration.&lt;br /&gt;
&lt;br /&gt;
===Include Rules Machines into other Projects===&lt;br /&gt;
Currently, it is not possible to include rules machines directly into any other machines. Instead, use the rules machine at the top of the hierarchy (of the rules project) and save the internal generated machine as &amp;lt;code&amp;gt;.mch&amp;lt;/code&amp;gt;-file. After changing the machine name accordingly, the rules can be included and used via this machine.&lt;br /&gt;
Note that in this case it is not possible to perform Rules-DSL specific methods of the ProB Java API (like detailed information about rule results).&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Using_the_Command-Line_Version_of_ProB&amp;diff=5941</id>
		<title>Using the Command-Line Version of ProB</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Using_the_Command-Line_Version_of_ProB&amp;diff=5941"/>
		<updated>2025-03-31T07:56:57Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
[[Category:ProB Cli]]&lt;br /&gt;
&lt;br /&gt;
The command-line version of ProB, called &amp;lt;b&amp;gt;probcli&amp;lt;/b&amp;gt;, offers many of the features of the standalone Tcl/Tk Version via the command-line. As such, you can run ProB from your shell scripts or in your Makefiles.&lt;br /&gt;
These pages refer to version 1.6 of ProB. Some features are only available in the nightly build of ProB. You can run &amp;lt;tt&amp;gt;probcli –help&amp;lt;/tt&amp;gt; to find out which commands are supported by your version of ProB. For Bash users we provide [[Bash Completion|command completion]] support.&lt;br /&gt;
&lt;br /&gt;
Note: the order of commands is not relevant for &amp;lt;tt&amp;gt;probcli&amp;lt;/tt&amp;gt; (except within groups of commands such as &amp;lt;tt&amp;gt;-p MAXINT 127&amp;lt;/tt&amp;gt;). Any argument that is not recognised by &amp;lt;tt&amp;gt;probcli&amp;lt;/tt&amp;gt; is treated as a filename to be analysed.&lt;br /&gt;
&lt;br /&gt;
[[file:ProBTerminalizerDemo.gif|center||600px]]&lt;br /&gt;
&lt;br /&gt;
== Conventions used ==&lt;br /&gt;
&lt;br /&gt;
The following conventions are used in this guide:&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;10&amp;quot;&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &amp;lt;replaceme&amp;gt;&lt;br /&gt;
| All values that should be replaced with some value are shown withing &amp;lt; &amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | line breaks&lt;br /&gt;
| Command synopsis for command may be broken up on several lines. When typing commands enter all option on the same line.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;probcli [--help]&lt;br /&gt;
&amp;lt;filename&amp;gt; [ &amp;lt;options&amp;gt; ]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The underscore within all options can as of version 1.5.1-beta7 be replaced with dashes. Also, all commands can either be typed with single leading dashes or double leading dashes.&lt;br /&gt;
For example, all of the following commands have the same effect:&lt;br /&gt;
 probcli M.mch -model_check&lt;br /&gt;
 probcli M.mch -model-check&lt;br /&gt;
 probcli M.mch --model_check&lt;br /&gt;
 probcli M.mch --model-check&lt;br /&gt;
&lt;br /&gt;
== Options ==&lt;br /&gt;
&lt;br /&gt;
=== -mc &amp;lt;nr&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| model check; checking at most &amp;lt;nr&amp;gt; states&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
  probcli my.mch -mc 100&lt;br /&gt;
&lt;br /&gt;
Note: with a value of nr=1 ProB will only inspect the &amp;quot;virtual&amp;quot; root node (and compute its outgoing transitions).&lt;br /&gt;
Also see the related options &amp;lt;tt&amp;gt;-nodead, -noinv, -nogoal, -noass&amp;lt;/tt&amp;gt; to influence which kinds of errors are reported by &amp;lt;tt&amp;gt;-mc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
You can also set a target goal predicate using the &amp;lt;tt&amp;gt;-goal &amp;quot;PRED&amp;quot;&amp;lt;/tt&amp;gt; command and limit the scope of the model checking using the &amp;lt;tt&amp;gt;-scope &amp;quot;PRED&amp;quot;&amp;lt;/tt&amp;gt; command. &lt;br /&gt;
&lt;br /&gt;
=== -model_check ===&lt;br /&gt;
&lt;br /&gt;
The same as &amp;lt;tt&amp;gt;-mc&amp;lt;/tt&amp;gt; but without a limit on the number of nodes checked.&lt;br /&gt;
ProB will run until the entire state space is explored.&lt;br /&gt;
&lt;br /&gt;
=== -no&amp;lt;x&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| restrict errors reported by model checking (-mc), TLC model checking (-mc_with_tlc), animation (-animate) and execution (-execute) with &amp;lt;x&amp;gt;=dead,inv,goal,ass&lt;br /&gt;
* -nodead : do not report deadlocks&lt;br /&gt;
* -noinv : do not report invariant violations&lt;br /&gt;
* -nogoal : do not stop if a state satisfying the GOAL predicate has been found&lt;br /&gt;
* -noass : do not report assertion violations&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
  probcli my.mch -mc 1000 -nodead -nogoal&lt;br /&gt;
&lt;br /&gt;
=== -disable_timeout ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| turn off ProB&#039;s timeout mechanism, e.g., for computing enabled operations and invariant checking; this can sometimes speed up model checking (-mc or -model_check) and animation (-animate). Available as of version 1.5.1-beta7.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
  probcli my.mch -model-check -disable-timeout&lt;br /&gt;
&lt;br /&gt;
=== -bf ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| proceed breadth-first during model checking&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
  probcli my.mch -bf -mc 1000&lt;br /&gt;
&lt;br /&gt;
=== -df ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| proceed depth-first during model checking&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
  probcli my.mch -df -mc 1000&lt;br /&gt;
&lt;br /&gt;
=== -mc_mode &amp;lt;M&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| influence how the model checker proceeds. Available as of version 1.5.1. Supersedes the &amp;lt;tt&amp;gt;-df&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;-bf&amp;lt;/tt&amp;gt; switches.&lt;br /&gt;
Possible values for the mode &amp;lt;M&amp;gt; are: &amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;df&amp;lt;/tt&amp;gt; (depth-first traversal),&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;bf&amp;lt;/tt&amp;gt; (breadth-first traversal),&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;mixed&amp;lt;/tt&amp;gt; (mixed depth-first / breadth-first traversal with random choice; currently the default),&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;random&amp;lt;/tt&amp;gt; (choosing next node to process completely at random), &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;hash&amp;lt;/tt&amp;gt; (similar to random, but uses the Prolog hash function of a node instead of a random number generator),&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;heuristic&amp;lt;/tt&amp;gt; (try and use &amp;lt;tt&amp;gt;HEURISTIC_FUNCTION&amp;lt;/tt&amp;gt; provided by user in &amp;lt;tt&amp;gt;DEFINITIONS&amp;lt;/tt&amp;gt; clause). Some explanations can be found [[Blocks_World_(Directed_Model_Checking)|in an example about directed model checking]].&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;out_degree_hash&amp;lt;/tt&amp;gt; (prioritise nodes with fewer outgoing transitions; mainly useful for deadlock checking)&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
  probcli my.mch -model_check -mc_mode random&lt;br /&gt;
&lt;br /&gt;
=== --timeout &amp;lt;N&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Global timeout in ms for model checking and refinement checking. &lt;br /&gt;
This does not influence the timeout used for computing individual transitions/operations.&lt;br /&gt;
This has to be set with the -p TIME_OUT &amp;lt;N&amp;gt;. Note that the &amp;lt;tt&amp;gt;TIME_OUT&amp;lt;/tt&amp;gt; preference also influences other computations, such as invariant checking or static assertion checking, where it is multiplied by a factor. See the description of the -p option.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -timeout 10000&lt;br /&gt;
&lt;br /&gt;
=== -t ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| trace check (associated .trace file must exist)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -t&lt;br /&gt;
&lt;br /&gt;
=== -init ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| initialise specification&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -init&lt;br /&gt;
 nr_of_components(1)&lt;br /&gt;
 % checking_component_properties(1,[])&lt;br /&gt;
 % enumerating_constants_without_constraints([typedval(fd(_24428,ID),global(ID),iv)])&lt;br /&gt;
 % grounding_wait_flags&lt;br /&gt;
 grounding_component(1)&lt;br /&gt;
 grounding_component(2)&lt;br /&gt;
 % found_enumeration_of_constants(0,2)&lt;br /&gt;
 % backtrack(found_enumeration_of_constants(0,2))&lt;br /&gt;
 % found_enumeration_of_constants(0,1)&lt;br /&gt;
 % backtrack(found_enumeration_of_constants(0,1))&lt;br /&gt;
 &amp;lt;- 0: SETUP_CONSTANTS :: root&lt;br /&gt;
 % Could not set up constants with parameters from trace file.&lt;br /&gt;
 % Will attempt any possible initialisation of constants.&lt;br /&gt;
  | 0: SETUP_CONSTANTS success --&amp;gt;0&lt;br /&gt;
  - &amp;lt;- 1: INITIALISATION :: 0&lt;br /&gt;
 % Could not initialise with parameters from trace file.&lt;br /&gt;
 % Will attempt any possible initialisation.&lt;br /&gt;
 ALL OPERATIONS COVERED&lt;br /&gt;
  -  | 1: INITIALISATION success --&amp;gt;2&lt;br /&gt;
  -  - SUCCESS&lt;br /&gt;
&lt;br /&gt;
=== -cbc &amp;lt;OPNAME&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| constraint-based invariant checking for an operation (also use &amp;lt;OPNAME&amp;gt;=all)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -cbc all&lt;br /&gt;
&lt;br /&gt;
=== -cbc_deadlock ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Perform constraint-based deadlock checking (also use -cbc_deadlock_pred PRED)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This will try to find a state which satisfies the invariant and properties and where no operation/event is enabled.&lt;br /&gt;
Note: if ProB finds a counter example then the machine cannot be proven to be deadlock free. However, the particular state may not be reachable from the initial state(s). If you want to find a reachable deadlock you have to use the model checker.&lt;br /&gt;
&lt;br /&gt;
=== -cbc_deadlock_pred &amp;lt;PRED&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Constraint-based deadlock finding given a predicate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is like -cbc_deadlock but you provide an additional predicate. ProB will only find deadlocks which also make this predicate true.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch  -cbc_deadlock_pred &amp;quot;n=15&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== -cbc_assertions ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Constraint-based checking of assertions on constants&lt;br /&gt;
|}&lt;br /&gt;
This will try and find a solution for the constants which make an assertion (on constants) false.&lt;br /&gt;
&lt;br /&gt;
You can use the extra command &amp;lt;tt&amp;gt;-cbc_output_file FILE&amp;lt;/tt&amp;gt; to write the result of this check to a file.&lt;br /&gt;
You can also use the extra command &amp;lt;tt&amp;gt;-cbc_option contradiction_check&amp;lt;/tt&amp;gt; to ask ProB to check if there is a contradiction in the properties (in case the check did not find a counter-example to the assertions). The extra command &amp;lt;tt&amp;gt;-cbc_option unsat_core&amp;lt;/tt&amp;gt; tells ProB to compute the unsatisfiable core in case a proof the assertions was found.&lt;br /&gt;
Note that the &amp;lt;tt&amp;gt;TIME_OUT&amp;lt;/tt&amp;gt; preference is multiplied by 10 for this command.&lt;br /&gt;
&lt;br /&gt;
There are various variations of this command:&lt;br /&gt;
 -cbc_assertions_proof&lt;br /&gt;
 -cbc_assertions_tautology_proof &lt;br /&gt;
Both commands do not allow enumeration warnings to occur.&lt;br /&gt;
The latter command  ignores the PROPERTIES and tries to check whether the ASSERTION(s) are tautologies.&lt;br /&gt;
Both commands can be useful to use ProB as a Prover/Disprover (as is done in Atelier-B 4.3).&lt;br /&gt;
&lt;br /&gt;
=== -cbc_sequence &amp;lt;SEQ&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Constraint-based searching for a sequence of operation names (separated by semicolons)&lt;br /&gt;
|}&lt;br /&gt;
This will try and find a solution for the constants, initial variable values and parameters which make execution of the given sequence of operations possible.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch  -cbc_sequence &amp;quot;op1;op2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== -strict ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| raise error and stop probcli if anything unexpected happens, e.g., if model checking finds a counter example or trace checking fails or any unexpected error happens&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -t -strict&lt;br /&gt;
&lt;br /&gt;
=== -expcterr &amp;lt;ERR&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| expect error to occur (&amp;lt;ERR&amp;gt;=cbc,mc,ltl,...)&lt;br /&gt;
Tell ProB that you expect a certain error to occur. Mainly useful for regression tests (in conjunction with the -strict option).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli examples/B/Benchmarks/CarlaTravelAgencyErr.mch -mc 1000 -expcterr invariant_violation -strict&lt;br /&gt;
&lt;br /&gt;
=== -animate &amp;lt;Nr&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| random animation (max Nr steps)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Animates the machine randomly, maximally Nr of steps. It will stop if a deadlock is reached and report an error. You can also use the command &amp;lt;tt&amp;gt;-animate_all&amp;lt;/tt&amp;gt;, which will only stop at a deadlock (and not report an error). Be careful: &amp;lt;tt&amp;gt;-animate_all&amp;lt;/tt&amp;gt; could run forever.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -animate 100&lt;br /&gt;
&lt;br /&gt;
=== -execute &amp;lt;Nr&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| execution (max Nr steps)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Executes the &amp;quot;first&amp;quot; enabled operation of a machine, maximally Nr of steps. It will stop if a deadlock is reached and report an error. You can also use the command &amp;lt;tt&amp;gt;-execute_all&amp;lt;/tt&amp;gt;, which will only stop at a deadlock (and not report an error). Be careful: &amp;lt;tt&amp;gt;-execute_all&amp;lt;/tt&amp;gt; could run forever.&lt;br /&gt;
&lt;br /&gt;
In contrast to -animate, -execute will&lt;br /&gt;
* always choose the first enabled operation it finds and stop searching for further enabled operations in that state (-animate will compute all enabled operations up to the limit set by the &amp;lt;tt&amp;gt;MAX_OPERATIONS&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;MAX_INITIALISATIONS&amp;lt;/tt&amp;gt; preference and then choose randomly); the order of operations in the B machine is thus important for -execute&lt;br /&gt;
* not store intermediate states in the state space; as such -execute is faster but after execution one only has access to the first state and the final state of execution&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -execute 100&lt;br /&gt;
&lt;br /&gt;
=== -execute_all===&lt;br /&gt;
&lt;br /&gt;
See &amp;lt;tt&amp;gt;-execute &amp;lt;Nr&amp;gt;&amp;lt;/tt&amp;gt; above.&lt;br /&gt;
&lt;br /&gt;
=== -det_check ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| check if animation steps are deterministic&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Checks if every step of the animation is deterministic (i.e., only one operation is possible, and it can only be executed in one possible way as far as parameters and result is concerned).&lt;br /&gt;
Currently this option has only an effect for the -animate &amp;lt;Nr&amp;gt; and the -init commands.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -animate 100 -det_check&lt;br /&gt;
&lt;br /&gt;
=== -det_constants ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| check if animation steps are deterministic&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Checks if the SETUP_CONSTANTS step is deterministic (i.e., only one way to set up the constants is possible).&lt;br /&gt;
Currently this option has only an effect for the -animate &amp;lt;Nr&amp;gt; and the -init commands.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -init -det_constants&lt;br /&gt;
=== -his &amp;lt;FILE&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| save animation history to a file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save the animation (or model checking) history to a text file. Operations are separated by semicolons.&lt;br /&gt;
The output can be adapted using the -his_option command. With -his_option show_states the -his command will also write out all states to the file (in the form of comments before and after operations). With -his_option show_init only the initial state is written out.&lt;br /&gt;
The -his command is executed after the -init, -animate, -t or -mc commands.&lt;br /&gt;
See also the -sptxt command to only write the current values of variables and constants to a file.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli -animate 5 -his history.txt  supersimple.mch&lt;br /&gt;
&lt;br /&gt;
Additionally we can have the initialised variables and constants:&lt;br /&gt;
&lt;br /&gt;
 probcli -animate 5 -his history.txt -his_option show_init supersimple.mch&lt;br /&gt;
&lt;br /&gt;
And we can have in addition the values of the variables in between (and at the end):&lt;br /&gt;
&lt;br /&gt;
 probcli -animate 5 -his history.txt -his_option show_states supersimple.mch&lt;br /&gt;
&lt;br /&gt;
With -his_option trace_file as only option, probcli will write the history in Prolog format, which can later be used by the -t command.&lt;br /&gt;
&lt;br /&gt;
=== -i ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| interactive animation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After performing the other commands, ProB stays in interactive mode and allows the user to manually animate the loaded specification.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -i&lt;br /&gt;
&lt;br /&gt;
=== -repl ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| start interactive read-eval-print-loop&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -p CLPFD TRUE -repl&lt;br /&gt;
&lt;br /&gt;
A list of commands can be obtained by typing &amp;lt;tt&amp;gt;:help&amp;lt;/tt&amp;gt; (just help for versions 1.3.x of probcli). The interactive read-eval-print-loop can be exited using &amp;lt;tt&amp;gt;:q&amp;lt;/tt&amp;gt; (just typing a return on a blank line for versions 1.3.x of probcli)..&lt;br /&gt;
If in addition you want see a graphical representation of the solutions found you can use the following command and open the &amp;lt;tt&amp;gt;out.dot&amp;lt;/tt&amp;gt; file using dotty or GraphViz:&lt;br /&gt;
 probcli -repl -evaldot ~/out.dot&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also use the &amp;lt;tt&amp;gt;-eval&amp;lt;/tt&amp;gt; command to evaluate specific formulas or expressions:&lt;br /&gt;
 probcli -eval &amp;quot;1+2&amp;quot;&lt;br /&gt;
For convenience, these formulas can also be put into a separate file:&lt;br /&gt;
 probcli -eval_file MyFormula.txt&lt;br /&gt;
&lt;br /&gt;
=== -c ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| print coverage statistics&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 -c&lt;br /&gt;
&lt;br /&gt;
You can also use the longer name for the command:&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 --coverage&lt;br /&gt;
&lt;br /&gt;
There is also a version which prints a shorter summary (and which is much faster for large state spaces):&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 --coverage_summary&lt;br /&gt;
&lt;br /&gt;
=== -cc &amp;lt;Nr&amp;gt; &amp;lt;Nr&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| print and check coverage statistics&lt;br /&gt;
Print coverage statistics and check that the given number of nodes and transitions have been computed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 -cc 10 25&lt;br /&gt;
&lt;br /&gt;
=== -p &amp;lt;PREFERENCE&amp;gt; &amp;lt;VALUE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Set &amp;lt;PREFERENCE&amp;gt; to &amp;lt;VALUE&amp;gt;. For more information about preferences please have a look at [[Using_the_Command-Line_Version_of_ProB#Preferences | Preferences]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
You can also use --pref instead of -p.&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -p TIME_OUT 8000 -p CLPFD TRUE -mc 10000&lt;br /&gt;
&lt;br /&gt;
=== -pref_group &amp;lt;PREFGROUP&amp;gt; &amp;lt;SETTING&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| set to the group of preferences &amp;lt;PREFGROUP&amp;gt; to a predefined setting &amp;lt;SETTING&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -pref_group model_check unlimited&lt;br /&gt;
&lt;br /&gt;
Available groups and settings are:&lt;br /&gt;
&lt;br /&gt;
* PREFERENCE GROUP integer : SETTINGS [int32] : Values for MAXINT and MININT&lt;br /&gt;
* PREFERENCE GROUP time_out : SETTINGS [disable_time_out] : To disable TIME_OUT&lt;br /&gt;
* PREFERENCE GROUP model_check : SETTINGS [disable_max,unlimited] : Model Checking Limits&lt;br /&gt;
* PREFERENCE GROUP dot_colors : SETTINGS [classic,dreams,winter] : Colours for Dot graphs&lt;br /&gt;
&lt;br /&gt;
=== -prefs &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Set preferences from preference file &amp;lt;FILE&amp;gt;. The file should be created by the Tcl/Tk version of ProB; this version automatically creates a file called ProB_Preferences.pl. For more information about preferences please have a look at [[Using_the_Command-Line_Version_of_ProB#Preferences | Preferences]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -prefs ProB_Preferences.pl&lt;br /&gt;
&lt;br /&gt;
=== -card &amp;lt;GS&amp;gt; &amp;lt;VAL&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| set cardinality (scope in Alloy terminology) of a B deferred set. This overrides the default cardinality (which can be set using &amp;lt;tt&amp;gt;-p DEFAULT_SETSIZE &amp;lt;VAL&amp;gt;&amp;lt;/tt&amp;gt;).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -card PID 5&lt;br /&gt;
&lt;br /&gt;
=== -goal &amp;lt;PRED&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| set GOAL predicate for model checker&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 10000000 -goal &amp;quot;n=18&amp;quot;  -strict -expcterr goal_found&lt;br /&gt;
&lt;br /&gt;
=== -scope &amp;lt;PRED&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| set SCOPE predicate for model checker; states which do not satisfy the SCOPE predicate will be ignored (invariant will not be checked and no outgoing transitions will be computed)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 10000000 -scope &amp;quot;n&amp;lt;18&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
=== -s &amp;lt;PORT&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| start socket server on given port&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -ss ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| start socket server on port 9000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -sf ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| start socket server on some free port&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -sptxt &amp;lt;FILE&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| save constants and variables to a file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save the values of constants and variables to a text file in classical B syntax.&lt;br /&gt;
The -sptxt command is executed after the -init, -animate, -t or -mc commands.&lt;br /&gt;
The values are fully written out (some sets, e.g., infinite sets may be written out symbolically).&lt;br /&gt;
&lt;br /&gt;
See also the -his command.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli -animate 5 -sptxt state.txt  supersimple.mch&lt;br /&gt;
&lt;br /&gt;
This will write the values of all variables and constants to the file state.txt after animating the machine 5 steps.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== -cache &amp;lt;DIRECTORY&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| save constants (and in future also variables) to a file to avoid recomputation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This commands saves the values of constants for the current B machine and puts those values into files in the specified directory. The command will also tell ProB to try and reuse constants saved for subsidiary machines (included using SEES for example) whenever possible.&lt;br /&gt;
The purpose of the command is to avoid recomputing constants as much as possible, as this can be very time consuming.&lt;br /&gt;
This also works for values of variables computed in the initialisation or even using operations.&lt;br /&gt;
However, we do not support refinements at the moment.&lt;br /&gt;
&lt;br /&gt;
Note: this command can also be used when starting up the ProB Tcl/Tk version.&lt;br /&gt;
&lt;br /&gt;
=== -logxml &amp;lt;LogFile&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| log activities and results of probcli in XML format in &amp;lt;LogFile&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A schema declaration file (xsd) can be found at &amp;lt;tt&amp;gt;doc/logxml_xsd.xml&amp;lt;/tt&amp;gt; in the ProB [[Download#Sourcecode|Prolog sources]].&lt;br /&gt;
The log file contains information about the various commands performed by probcli.&lt;br /&gt;
It also contains version information, the parameters provided to probcli and details about the errors that occured.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 -logxml log.xml&lt;br /&gt;
&lt;br /&gt;
=== -logxml_write_vars &amp;lt;PREFIX&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| after processing other commands (such as -execute) write values of variables having prefix PREFIX in their name into the XML log file (if XML logging has been activated using the -logxml command)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -execute 1000 -logxml log.xml -logxml_write_vars out&lt;br /&gt;
&lt;br /&gt;
=== -l &amp;lt;LogFile&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| log activities in &amp;lt;LogFile&amp;gt; using Prolog format&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 -l my.log&lt;br /&gt;
&lt;br /&gt;
=== -ll ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| log activities in /tmp/prob_cli_debug.log&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 -ll&lt;br /&gt;
&lt;br /&gt;
=== -lg &amp;lt;LogFile&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| analyse &amp;lt;LogFile&amp;gt; using gnuplot&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -pp &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| pretty-print internal representation to &amp;lt;FILE&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -pp my_pp.mch&lt;br /&gt;
&lt;br /&gt;
=== -ppf &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| pretty-print internal representation to &amp;lt;FILE&amp;gt;, force printing of all type infos&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -ppf my_ppf.mch&lt;br /&gt;
&lt;br /&gt;
=== -v ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| set ProB into verbose mode&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 -v&lt;br /&gt;
&lt;br /&gt;
=== -version ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| print version information&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
There is also an alternate command called -svers which just prints the version number of ProB.&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli -version&lt;br /&gt;
 ProB Command Line Interface&lt;br /&gt;
   VERSION 1.3.4-rc1 (9556:9570M)&lt;br /&gt;
   $LastChangedDate: 2011-11-16 18:36:18 +0100 (Wed, 16 Nov 2011) $&lt;br /&gt;
   Prolog: SICStus 4.2.0 (x86_64-darwin-10.6.0): Mon Mar  7 20:03:36 CET 2011&lt;br /&gt;
   Application Path: /Users/leuschel/svn_root/NewProB&lt;br /&gt;
&lt;br /&gt;
 probcli -svers&lt;br /&gt;
 VERSION 1.3.4-rc1 (9556:9570M)&lt;br /&gt;
&lt;br /&gt;
You can use &amp;lt;tt&amp;gt;probcli -version -v&amp;lt;/tt&amp;gt; to obtain more information about your version of probcli.&lt;br /&gt;
&lt;br /&gt;
=== -check_java_version ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| check Java and B parser version information&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This command is available as of ProB version 1.5.1-beta5 or higher. It can be useful to check that your Java is correctly installed and that the ProB B parser can operate correctly&lt;br /&gt;
&lt;br /&gt;
 probcli -check_java_version&lt;br /&gt;
 Result of checking Java version:&lt;br /&gt;
  Java is correctly installed and version 1.7.0_55-b13 is compatible with ProB requirements (&amp;gt;= 1.7).&lt;br /&gt;
  ProB B Java Parser available in version: 2016-02-25 15:27:18.55.&lt;br /&gt;
&lt;br /&gt;
=== -assertions ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| check ASSERTIONS of your machine&lt;br /&gt;
&lt;br /&gt;
If you provide the -t switch, the ASSERTIONS will be checked after executing your trace. Otherwise, they will be checked in an initial state.&lt;br /&gt;
ProB will automatically initialize the machine if you have not provide the -init or -t switch.&lt;br /&gt;
&lt;br /&gt;
You can also use -main_assertions to check only the ASSERTIONS found in the main file.&lt;br /&gt;
&lt;br /&gt;
If your ASSERTIONS are all static (i.e., make no reference to variables), then ProB will remove all CONSTANTS and PROPERTIES from your machine which are not linked (directly or indirectly) to the ASSERTIONS.&lt;br /&gt;
This optimization will only be made if you provide no other switch, such as -mc or -animate which may require the computation of the variables.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -init -assertions&lt;br /&gt;
&lt;br /&gt;
=== -property ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| virtually add predicate to PROPERTIES&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -property &amp;quot;PRED&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== -properties ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| check PROPERTIES&lt;br /&gt;
Note: you should probably first initialise the machine (e.g., with -init).&lt;br /&gt;
If the constants have not yet been set up, probcli will debug the properties.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -init -properties&lt;br /&gt;
&lt;br /&gt;
=== -dot_output &amp;lt;PATH&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| define path for generation of dot files for false properties or assertions&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This option is applicable to -properties and -assertions. It will result in individual dot files being generated for every false or unknown property or assertion. Assertions are numbered A0,A1,... and properties P0,P1,... You can also force to generate dot files for all properties (i.e., also the true ones) using the -dot_all command-line flag.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -init -properties -dot_output somewhere/&lt;br /&gt;
&lt;br /&gt;
This will generate files somewhere/my_P0_false.dot, somewhere/my_P1_false.dot, ...&lt;br /&gt;
&lt;br /&gt;
=== -rc ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| runtime checking of types/pre-/post-conditions&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -ltlfile &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| check LTL formulas in file &amp;lt;FILE&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -ltlassertions ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| check LTL assertions (in DEFINITIONS)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -ltllimit &amp;lt;LIMIT&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| explore at most &amp;lt;LIMIT&amp;gt; states when model-checking LTL&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -save &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| save state space for later refinement check&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -refchk &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| refinement check against previous saved state space&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -mcm_tests &amp;lt;Depth&amp;gt; &amp;lt;MaxStates&amp;gt; &amp;lt;EndPredicate&amp;gt; &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Generate test cases for the given specification. Each test case consists of a sequence of operations resp. events (a so-called trace) that&lt;br /&gt;
* start in a state after an initialisation&lt;br /&gt;
* contain a requested operation/event&lt;br /&gt;
* end in a state where the &amp;lt;EndPredicate&amp;gt; is fulfilled&lt;br /&gt;
&lt;br /&gt;
The user can specify what requested operations/events are with the&lt;br /&gt;
option [[#-mcm_cover &amp;lt;Operation(s)&amp;gt;|-mcm_cover]].&lt;br /&gt;
&lt;br /&gt;
ProB uses a &amp;quot;breadth-first&amp;quot; approach to search for test cases. When all requested operations/events are covered by test cases within maximum length M, the algorithm will explore the complete state space with that maximum distance M from the initialisation. It outputs all found traces that satisfy the requirements above.&lt;br /&gt;
&lt;br /&gt;
The algorithm stops if either&lt;br /&gt;
* it has covered all required operations/events with the current search depth&lt;br /&gt;
* or it has reached the maximum search depth or maximum number of explored states.&lt;br /&gt;
&lt;br /&gt;
The required parameters are:&lt;br /&gt;
;Depth&lt;br /&gt;
: The maximum length of traces that the algorithm searches for test until it stops without covering all required operations/events.&lt;br /&gt;
;MaxStates&lt;br /&gt;
: The maximum number of explored states until the algorithm stops without covering all required operations/events.&lt;br /&gt;
;EndPredicate&lt;br /&gt;
: A predicate in B syntax that the last state of a trace must fulfil. If you do not have any restrictions on that state, use a trivially true predicate like &#039;&#039;&#039;1=1&#039;&#039;&#039;&lt;br /&gt;
;FILE&lt;br /&gt;
: The found test cases a written to the XML file &amp;lt;FILE&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mcm_tests 10 2000 &amp;quot;EndStateVar=TRUE&amp;quot; testcases.xml -mcm_cover op1,op2&lt;br /&gt;
&lt;br /&gt;
generates test cases for the operations &#039;&#039;&#039;op1&#039;&#039;&#039; and &#039;&#039;&#039;op2&#039;&#039;&#039; of the specification &#039;&#039;&#039;my.mch&#039;&#039;&#039;. The maximum length of traces is 10, at most 2000 states are explored. Each test case ends in a state where the predicate &#039;&#039;&#039;EndStateVar=TRUE&#039;&#039;&#039; holds. The found test cases are written to a file &#039;&#039;&#039;testcases.xml&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
As of version 1.6.0, the operation arguments are also written to the XML file.&lt;br /&gt;
The preference &amp;lt;tt&amp;gt;INTERNAL_ARGUMENT_PREFIX&amp;lt;/tt&amp;gt; can be used to provide a prefix for internal operation arguments; any argument/parameter whose name starts with that prefix is considered an internal parameter and not shown in the trace file.&lt;br /&gt;
Also, as of version 1.6.0, the non-deterministic initialisations are shown in the XML trace file: all variables and constants where more than one possible initialisation exists are written into the trace file, as argument of an INITIALISATION event.&lt;br /&gt;
&lt;br /&gt;
=== -mcm_cover &amp;lt;Operation(s)&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Specify an operation or event that should be covered when generating test cases with the &#039;&#039;&#039;-mcm_test&#039;&#039;&#039; option. Multiple operations/events can be specified by seperating them by comma or by using &#039;&#039;&#039;-mcm_cover&#039;&#039;&#039; several times.&lt;br /&gt;
&lt;br /&gt;
See [[#-mcm_tests &amp;lt;Depth&amp;gt; &amp;lt;MaxStates&amp;gt; &amp;lt;EndPredicate&amp;gt; &amp;lt;FILE&amp;gt;|-mcm-tests]] for further details.&lt;br /&gt;
&lt;br /&gt;
=== -spdot &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Write graph of the state space to a dot &amp;lt;FILE&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 100 -spdot my_statespace.dot&lt;br /&gt;
&lt;br /&gt;
=== -cbc_tests &amp;lt;Depth&amp;gt; &amp;lt;EndPredicate&amp;gt; &amp;lt;File&amp;gt; ===&lt;br /&gt;
Generate test cases by constraint solving with maximum&lt;br /&gt;
length &#039;&#039;&#039;Depth&#039;&#039;&#039;, the last state satisfies &#039;&#039;&#039;EndPredicate&#039;&#039;&#039;&lt;br /&gt;
and the test cases are written to &#039;&#039;&#039;File&#039;&#039;&#039;. If the predicate is the empty string we assume truth. If the filename is the empty string no file is generated. See also the page on [[Test_Case_Generation]].&lt;br /&gt;
&lt;br /&gt;
=== -cbc_cover &amp;lt;Operation&amp;gt; ===&lt;br /&gt;
When generating CB test cases, &#039;&#039;&#039;Operation&#039;&#039;&#039; should be covered.&lt;br /&gt;
The option can be given multiple times to specify several operations.&lt;br /&gt;
Alternatively, multiple operations can be separated by a comma. You can also use the option &amp;lt;pre&amp;gt;-cbc_cover_match PartialName&amp;lt;/pre&amp;gt; to match all operations whose name contains PartialName. See also the page about [[Test_Case_Generation]].&lt;br /&gt;
&lt;br /&gt;
=== -test_description &amp;lt;File&amp;gt; ===&lt;br /&gt;
Read the options for constraint based test case generation from &#039;&#039;&#039;File&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== -bmc &amp;lt;Depth&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Run the [[Bounded_Model_Checking|bounded model checker]] until maximum trace depth &amp;lt;Depth&amp;gt; specified. Looks for invariant violations using the constraint-based test case generation algorithm.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -bmc 20&lt;br /&gt;
&lt;br /&gt;
=== -csp-guide &amp;lt;File&amp;gt; ===&lt;br /&gt;
Use the CSP File &#039;&#039;&#039;File&#039;&#039;&#039; to guide the B Machine (&amp;quot;CSP||B&amp;quot;).&lt;br /&gt;
(This feature is included since version 1.3.5-beta7.)&lt;br /&gt;
&lt;br /&gt;
=== -rule_report &amp;lt;File&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Generates HTML rule validation report for rules machines (.rmch) at the specified location &amp;lt;File&amp;gt; for the current animation state.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Useful in combination with &amp;lt;tt&amp;gt;-execute&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;-execute_all&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli myrules.rmch -execute_all -rule_report my_report.html&lt;br /&gt;
&lt;br /&gt;
== Environment Variables ==&lt;br /&gt;
&lt;br /&gt;
Set NO_COLOR environment variable to disable terminal colors.&lt;br /&gt;
See [https://no-color.org https://no-color.org].&lt;br /&gt;
&lt;br /&gt;
== Preferences ==&lt;br /&gt;
&lt;br /&gt;
You can use these preferences within the command:&lt;br /&gt;
&lt;br /&gt;
 -p &amp;lt;PREFERENCE&amp;gt; &amp;lt;VALUE&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;1&amp;quot; width=&amp;quot;100%&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!style=&amp;quot;background-color:lightgrey;&amp;quot; | &amp;lt;PREFERENCE&amp;gt;&lt;br /&gt;
!style=&amp;quot;background-color:lightgrey;&amp;quot; | &amp;lt;VALUE&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| MAXINT&lt;br /&gt;
| nat ==&amp;gt; MaxInt, used for expressions such as xx::NAT (2147483647 for 4 byte ints)&lt;br /&gt;
|-&lt;br /&gt;
| MININT&lt;br /&gt;
| neg ==&amp;gt; MinInt, used for expressions such as xx::INT (-2147483648 for 4 byte ints)&lt;br /&gt;
|-&lt;br /&gt;
| DEFAULT_SETSIZE&lt;br /&gt;
| nat ==&amp;gt; Size of unspecified deferred sets in SETS section. Will be used if a set s is neither enumerated, has no no card(s)=nr predicate in the PROPERTIES and has no scope_s == Nr DEFINITION.&lt;br /&gt;
|-&lt;br /&gt;
| MAX_INITIALISATIONS&lt;br /&gt;
| nat ==&amp;gt; Max Number of Initialisations and ways to setup constants computed&lt;br /&gt;
|-&lt;br /&gt;
| MAX_OPERATIONS&lt;br /&gt;
| nat ==&amp;gt; Max Number of Enablings per Operation Computed&lt;br /&gt;
|-&lt;br /&gt;
| ANIMATE_SKIP_OPERATIONS&lt;br /&gt;
| bool ==&amp;gt; Animate operations which are skip or PRE C THEN skip&lt;br /&gt;
|-&lt;br /&gt;
| COMPRESSION&lt;br /&gt;
| bool ==&amp;gt; Use more aggressive COMPRESSION when storing states&lt;br /&gt;
|-&lt;br /&gt;
| EXPAND_CLOSURES_FOR_STATE&lt;br /&gt;
| bool ==&amp;gt; Convert lazy form back into explicit form for Variables, Constants, Operation Arguments. ProB will sometimes try to keep certain sets symbolic. If this preference is TRUE then ProB will try to expand those sets for variables and constants after an operation has been executed.&lt;br /&gt;
|-&lt;br /&gt;
| SYMBOLIC&lt;br /&gt;
| bool ==&amp;gt; Lazy expansion of lambdas and set comprehensions. By default ProB will keep certain sets symbolic (e.g., sets it knows are infinite). When this preference is set to TRUE then all set comprehensions and lambda abstractions will at first be kept symbolic and only expanded into explicit form if needed.&lt;br /&gt;
|-&lt;br /&gt;
| CLPFD&lt;br /&gt;
| bool ==&amp;gt; Use CLP(FD) solver for B integers (restricts range to -2^28..2^28-1 on 32 bit computers). Setting this preference to TRUE should substantially improve ProB&#039;s ability to solve complicated predicates involving integers. However, it may cause CLP(FD) overflows in certain circumstances.&lt;br /&gt;
|-&lt;br /&gt;
| SMT&lt;br /&gt;
| bool ==&amp;gt; Enable SMT-Mode (aggressive treatment of : and /: inside predicates). With this predicate set to TRUE ProB will be better at solving certain constraint solving tasks. It should be enabled when doing constraint-based invariant or deadlock checking. ProB Tcl/Tk will turn this preference on automatically for those checks.&lt;br /&gt;
|-&lt;br /&gt;
| STATIC_ORDERING&lt;br /&gt;
| bool ==&amp;gt; Use static ordering to enumerate constants which occur in most PROPERTIES first&lt;br /&gt;
|-&lt;br /&gt;
| SYMMETRY_MODE&lt;br /&gt;
| [off,flood,nauty,hash] ==&amp;gt; Symmetry Mode: off,flood,canon,nauty,hash&lt;br /&gt;
|-&lt;br /&gt;
| TIME_OUT&lt;br /&gt;
| nat1 ==&amp;gt; Time out for computing enabled transitions (in ms, is multiplied by a factor for other computations)&lt;br /&gt;
|-&lt;br /&gt;
| PROOF_INFO&lt;br /&gt;
| bool ==&amp;gt; Use Proof Information to restrict invariant checking to affected unproven clauses. Most useful in EventB for models exported from Rodin.&lt;br /&gt;
|-&lt;br /&gt;
| TRY_FIND_ABORT&lt;br /&gt;
| bool ==&amp;gt; Try more aggressively to detect ill-defined expressions (e.g. applying function outside of domain), may slow down animator&lt;br /&gt;
|-&lt;br /&gt;
| NUMBER_OF_ANIMATED_ABSTRACTIONS&lt;br /&gt;
| nat ==&amp;gt; How many levels of refined models are animated by default&lt;br /&gt;
|-&lt;br /&gt;
| ALLOW_INCOMPLETE_SETUP_CONSTANTS&lt;br /&gt;
| bool ==&amp;gt; Allow ProB to proceed even if only part of the CONSTANTS have been found.&lt;br /&gt;
|-&lt;br /&gt;
| PARTITION_PROPERTIES&lt;br /&gt;
| bool ==&amp;gt; Partition predicates (PROPERTIES) into components&lt;br /&gt;
|-&lt;br /&gt;
| USE_RECORD_CONSTRUCTION&lt;br /&gt;
| bool ==&amp;gt; Records: Check if axioms/properties describe a record pattern&lt;br /&gt;
|-&lt;br /&gt;
| OPERATION_REUSE&lt;br /&gt;
| bool ==&amp;gt; Try and reuse previously computed operation effects in B/Event-B&lt;br /&gt;
|-&lt;br /&gt;
| SHOW_EVENTB_ANY_VALUES&lt;br /&gt;
| bool ==&amp;gt; Show top-level ANY variable values of B Operations without parameters as parameters&lt;br /&gt;
|-&lt;br /&gt;
| RANDOMISE_OPERATION_ORDER&lt;br /&gt;
| bool ==&amp;gt; Randomise order of operations when computing successor states&lt;br /&gt;
|-&lt;br /&gt;
| EXPAND_FORALL_UPTO&lt;br /&gt;
| nat ==&amp;gt; When analysing predicates: max. domain size for expansion of forall (use 0 to disable expansion)&lt;br /&gt;
|-&lt;br /&gt;
| MAX_DISPLAY_SET&lt;br /&gt;
| int ==&amp;gt; Max size for pretty-printing sets (-1 means no limit)&lt;br /&gt;
|-&lt;br /&gt;
| CSP_STRIP_SOURCE_LOC&lt;br /&gt;
| bool ==&amp;gt; Strip source location for CSP; will speed up model checking&lt;br /&gt;
|-&lt;br /&gt;
| WARN_WHEN_EXPANDING_INFINITE_CLOSURES&lt;br /&gt;
| int ==&amp;gt; Warn when expanding infinite closures if MAXINT larger than:&lt;br /&gt;
|-&lt;br /&gt;
| TRACE_INFO&lt;br /&gt;
| bool ==&amp;gt; Provide various tracing information on the terminal/console.&lt;br /&gt;
|-&lt;br /&gt;
| DOUBLE_EVALUATION&lt;br /&gt;
| bool ==&amp;gt; Evaluate PREDICATES positively and negatively when analyzing assertions or properties&lt;br /&gt;
|-&lt;br /&gt;
| RECURSIVE&lt;br /&gt;
| bool ==&amp;gt; Lazy expansion of *Recursive* set Comprehensions and lambdas&lt;br /&gt;
|-&lt;br /&gt;
| IGNORE_HASH_COLLISIONS&lt;br /&gt;
| bool ==&amp;gt; Ignore Hash Collisions (if true not all states may be computed, visited states are not memorised !)&lt;br /&gt;
|-&lt;br /&gt;
| FORGET_STATE_SPACE&lt;br /&gt;
| bool ==&amp;gt; Do not remember state space (mainly useful in conjunction with Ignore Hash Collisions)&lt;br /&gt;
|-&lt;br /&gt;
| NEGATED_INVARIANT_CHECKING&lt;br /&gt;
| bool ==&amp;gt; Perform double evaluation (positive and negative) when checking invariants&lt;br /&gt;
|-&lt;br /&gt;
| CSE&lt;br /&gt;
| bool ==&amp;gt; Perform common-sub-expression elimination&lt;br /&gt;
|-&lt;br /&gt;
| CSE_SUBST&lt;br /&gt;
| bool ==&amp;gt; Perform common-sub-expression elimination also for B substitutions&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -p TIME_OUT 5000 -p CLPFD TRUE -p SYMMETRY_MODE hash -mc 1000&lt;br /&gt;
&lt;br /&gt;
== Some probcli examples ==&lt;br /&gt;
&lt;br /&gt;
To load a file My.mch, setup the constants and initialize it do:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
probcli -init My.mch&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
To load a file M.mch, setup the constants, initialize and then check all assertions with Atelier-B&#039;s default values for MININT and MAXINT and an increased timeout of 5 seconds do:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
probcli -init -assertions -p MAXINT 2147483647 -p MININT -2147483647 -p TIME_OUT 5000 M.mch&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To fully model check a specification M.mch while tryining to minimize memory consumption do:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
probcli -model_check -p COMPRESSION TRUE M.mch&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To model check a specification M.mch while trying to minimize memory consumption further by not storing processed stats and using symmetry reduction (and accepting hash collisions) do:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
probcli -p COMPRESSION -p IGNORE_HASH_COLLISIONS TRUE -p FORGET_STATE_SPACE TRUE -p SYMMETRY_MODE hash -model_check M.mch &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Command-line Arguments for ProB Tcl/Tk ==&lt;br /&gt;
&lt;br /&gt;
Note that the stand-alone Tcl/Tk version also supports a limited form of command-line preferences:&lt;br /&gt;
* &#039;&#039;&#039;FILE&#039;&#039;&#039; (the name/path of the file to be loaded)&lt;br /&gt;
* &#039;&#039;&#039;-prefs PREF_FILE&#039;&#039;&#039;  (to use a specific preferences file, rather than the default ProB_Preferences.pl in your home folder)&lt;br /&gt;
* &#039;&#039;&#039;-batch&#039;&#039;&#039; (to instruct ProB not to try to bring up windows, but to print information only to the terminal)&lt;br /&gt;
* &#039;&#039;&#039;-selfcheck&#039;&#039;&#039; (to run the standard unit tests)&lt;br /&gt;
* &#039;&#039;&#039;-t&#039;&#039;&#039; (to perform the Trace Check on the default trace file associated with the specification)&lt;br /&gt;
* &#039;&#039;&#039;-tcl TCL_Command&#039;&#039;&#039; (to run a particular pre-defined Tcl command)&lt;br /&gt;
* &#039;&#039;&#039;-mc&#039;&#039;&#039; (to perform model checking)&lt;br /&gt;
* &#039;&#039;&#039;-c&#039;&#039;&#039; (to compute the coverage)&lt;br /&gt;
* &#039;&#039;&#039;-ref&#039;&#039;&#039; (to perform the default trace refinment check)&lt;br /&gt;
&lt;br /&gt;
However, the comand-line version of ProB, called &#039;&#039;&#039;probcli&#039;&#039;&#039;, provides more features. It also does not depend on Tcl/Tk and can therefore be run on systems without Tcl/Tk.&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Using_the_Command-Line_Version_of_ProB&amp;diff=5940</id>
		<title>Using the Command-Line Version of ProB</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Using_the_Command-Line_Version_of_ProB&amp;diff=5940"/>
		<updated>2025-03-31T07:37:08Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
[[Category:ProB Cli]]&lt;br /&gt;
&lt;br /&gt;
The command-line version of ProB, called &amp;lt;b&amp;gt;probcli&amp;lt;/b&amp;gt;, offers many of the features of the standalone Tcl/Tk Version via the command-line. As such, you can run ProB from your shell scripts or in your Makefiles.&lt;br /&gt;
These pages refer to version 1.6 of ProB. Some features are only available in the nightly build of ProB. You can run &amp;lt;tt&amp;gt;probcli –help&amp;lt;/tt&amp;gt; to find out which commands are supported by your version of ProB. For Bash users we provide [[Bash Completion|command completion]] support.&lt;br /&gt;
&lt;br /&gt;
Note: the order of commands is not relevant for &amp;lt;tt&amp;gt;probcli&amp;lt;/tt&amp;gt; (except within groups of commands such as &amp;lt;tt&amp;gt;-p MAXINT 127&amp;lt;/tt&amp;gt;). Any argument that is not recognised by &amp;lt;tt&amp;gt;probcli&amp;lt;/tt&amp;gt; is treated as a filename to be analysed.&lt;br /&gt;
&lt;br /&gt;
[[file:ProBTerminalizerDemo.gif|center||600px]]&lt;br /&gt;
&lt;br /&gt;
== Conventions used ==&lt;br /&gt;
&lt;br /&gt;
The following conventions are used in this guide:&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;10&amp;quot;&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &amp;lt;replaceme&amp;gt;&lt;br /&gt;
| All values that should be replaced with some value are shown withing &amp;lt; &amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | line breaks&lt;br /&gt;
| Command synopsis for command may be broken up on several lines. When typing commands enter all option on the same line.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;probcli [--help]&lt;br /&gt;
&amp;lt;filename&amp;gt; [ &amp;lt;options&amp;gt; ]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The underscore within all options can as of version 1.5.1-beta7 be replaced with dashes. Also, all commands can either be typed with single leading dashes or double leading dashes.&lt;br /&gt;
For example, all of the following commands have the same effect:&lt;br /&gt;
 probcli M.mch -model_check&lt;br /&gt;
 probcli M.mch -model-check&lt;br /&gt;
 probcli M.mch --model_check&lt;br /&gt;
 probcli M.mch --model-check&lt;br /&gt;
&lt;br /&gt;
== Options ==&lt;br /&gt;
&lt;br /&gt;
=== -mc &amp;lt;nr&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| model check; checking at most &amp;lt;nr&amp;gt; states&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
  probcli my.mch -mc 100&lt;br /&gt;
&lt;br /&gt;
Note: with a value of nr=1 ProB will only inspect the &amp;quot;virtual&amp;quot; root node (and compute its outgoing transitions).&lt;br /&gt;
Also see the related options &amp;lt;tt&amp;gt;-nodead, -noinv, -nogoal, -noass&amp;lt;/tt&amp;gt; to influence which kinds of errors are reported by &amp;lt;tt&amp;gt;-mc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
You can also set a target goal predicate using the &amp;lt;tt&amp;gt;-goal &amp;quot;PRED&amp;quot;&amp;lt;/tt&amp;gt; command and limit the scope of the model checking using the &amp;lt;tt&amp;gt;-scope &amp;quot;PRED&amp;quot;&amp;lt;/tt&amp;gt; command. &lt;br /&gt;
&lt;br /&gt;
=== -model_check ===&lt;br /&gt;
&lt;br /&gt;
The same as &amp;lt;tt&amp;gt;-mc&amp;lt;/tt&amp;gt; but without a limit on the number of nodes checked.&lt;br /&gt;
ProB will run until the entire state space is explored.&lt;br /&gt;
&lt;br /&gt;
=== -no&amp;lt;x&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| restrict errors reported by model checking (-mc), TLC model checking (-mc_with_tlc), animation (-animate) and execution (-execute) with &amp;lt;x&amp;gt;=dead,inv,goal,ass&lt;br /&gt;
* -nodead : do not report deadlocks&lt;br /&gt;
* -noinv : do not report invariant violations&lt;br /&gt;
* -nogoal : do not stop if a state satisfying the GOAL predicate has been found&lt;br /&gt;
* -noass : do not report assertion violations&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
  probcli my.mch -mc 1000 -nodead -nogoal&lt;br /&gt;
&lt;br /&gt;
=== -disable_timeout ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| turn off ProB&#039;s timeout mechanism, e.g., for computing enabled operations and invariant checking; this can sometimes speed up model checking (-mc or -model_check) and animation (-animate). Available as of version 1.5.1-beta7.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
  probcli my.mch -model-check -disable-timeout&lt;br /&gt;
&lt;br /&gt;
=== -bf ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| proceed breadth-first during model checking&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
  probcli my.mch -bf -mc 1000&lt;br /&gt;
&lt;br /&gt;
=== -df ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| proceed depth-first during model checking&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
  probcli my.mch -df -mc 1000&lt;br /&gt;
&lt;br /&gt;
=== -mc_mode &amp;lt;M&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| influence how the model checker proceeds. Available as of version 1.5.1. Supersedes the &amp;lt;tt&amp;gt;-df&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;-bf&amp;lt;/tt&amp;gt; switches.&lt;br /&gt;
Possible values for the mode &amp;lt;M&amp;gt; are: &amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;df&amp;lt;/tt&amp;gt; (depth-first traversal),&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;bf&amp;lt;/tt&amp;gt; (breadth-first traversal),&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;mixed&amp;lt;/tt&amp;gt; (mixed depth-first / breadth-first traversal with random choice; currently the default),&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;random&amp;lt;/tt&amp;gt; (choosing next node to process completely at random), &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;hash&amp;lt;/tt&amp;gt; (similar to random, but uses the Prolog hash function of a node instead of a random number generator),&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;heuristic&amp;lt;/tt&amp;gt; (try and use &amp;lt;tt&amp;gt;HEURISTIC_FUNCTION&amp;lt;/tt&amp;gt; provided by user in &amp;lt;tt&amp;gt;DEFINITIONS&amp;lt;/tt&amp;gt; clause). Some explanations can be found [[Blocks_World_(Directed_Model_Checking)|in an example about directed model checking]].&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;out_degree_hash&amp;lt;/tt&amp;gt; (prioritise nodes with fewer outgoing transitions; mainly useful for deadlock checking)&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
  probcli my.mch -model_check -mc_mode random&lt;br /&gt;
&lt;br /&gt;
=== --timeout &amp;lt;N&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Global timeout in ms for model checking and refinement checking. &lt;br /&gt;
This does not influence the timeout used for computing individual transitions/operations.&lt;br /&gt;
This has to be set with the -p TIME_OUT &amp;lt;N&amp;gt;. Note that the &amp;lt;tt&amp;gt;TIME_OUT&amp;lt;/tt&amp;gt; preference also influences other computations, such as invariant checking or static assertion checking, where it is multiplied by a factor. See the description of the -p option.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -timeout 10000&lt;br /&gt;
&lt;br /&gt;
=== -t ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| trace check (associated .trace file must exist)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -t&lt;br /&gt;
&lt;br /&gt;
=== -init ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| initialise specification&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -init&lt;br /&gt;
 nr_of_components(1)&lt;br /&gt;
 % checking_component_properties(1,[])&lt;br /&gt;
 % enumerating_constants_without_constraints([typedval(fd(_24428,ID),global(ID),iv)])&lt;br /&gt;
 % grounding_wait_flags&lt;br /&gt;
 grounding_component(1)&lt;br /&gt;
 grounding_component(2)&lt;br /&gt;
 % found_enumeration_of_constants(0,2)&lt;br /&gt;
 % backtrack(found_enumeration_of_constants(0,2))&lt;br /&gt;
 % found_enumeration_of_constants(0,1)&lt;br /&gt;
 % backtrack(found_enumeration_of_constants(0,1))&lt;br /&gt;
 &amp;lt;- 0: SETUP_CONSTANTS :: root&lt;br /&gt;
 % Could not set up constants with parameters from trace file.&lt;br /&gt;
 % Will attempt any possible initialisation of constants.&lt;br /&gt;
  | 0: SETUP_CONSTANTS success --&amp;gt;0&lt;br /&gt;
  - &amp;lt;- 1: INITIALISATION :: 0&lt;br /&gt;
 % Could not initialise with parameters from trace file.&lt;br /&gt;
 % Will attempt any possible initialisation.&lt;br /&gt;
 ALL OPERATIONS COVERED&lt;br /&gt;
  -  | 1: INITIALISATION success --&amp;gt;2&lt;br /&gt;
  -  - SUCCESS&lt;br /&gt;
&lt;br /&gt;
=== -cbc &amp;lt;OPNAME&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| constraint-based invariant checking for an operation (also use &amp;lt;OPNAME&amp;gt;=all)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -cbc all&lt;br /&gt;
&lt;br /&gt;
=== -cbc_deadlock ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Perform constraint-based deadlock checking (also use -cbc_deadlock_pred PRED)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This will try to find a state which satisfies the invariant and properties and where no operation/event is enabled.&lt;br /&gt;
Note: if ProB finds a counter example then the machine cannot be proven to be deadlock free. However, the particular state may not be reachable from the initial state(s). If you want to find a reachable deadlock you have to use the model checker.&lt;br /&gt;
&lt;br /&gt;
=== -cbc_deadlock_pred &amp;lt;PRED&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Constraint-based deadlock finding given a predicate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is like -cbc_deadlock but you provide an additional predicate. ProB will only find deadlocks which also make this predicate true.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch  -cbc_deadlock_pred &amp;quot;n=15&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== -cbc_assertions ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Constraint-based checking of assertions on constants&lt;br /&gt;
|}&lt;br /&gt;
This will try and find a solution for the constants which make an assertion (on constants) false.&lt;br /&gt;
&lt;br /&gt;
You can use the extra command &amp;lt;tt&amp;gt;-cbc_output_file FILE&amp;lt;/tt&amp;gt; to write the result of this check to a file.&lt;br /&gt;
You can also use the extra command &amp;lt;tt&amp;gt;-cbc_option contradiction_check&amp;lt;/tt&amp;gt; to ask ProB to check if there is a contradiction in the properties (in case the check did not find a counter-example to the assertions). The extra command &amp;lt;tt&amp;gt;-cbc_option unsat_core&amp;lt;/tt&amp;gt; tells ProB to compute the unsatisfiable core in case a proof the assertions was found.&lt;br /&gt;
Note that the &amp;lt;tt&amp;gt;TIME_OUT&amp;lt;/tt&amp;gt; preference is multiplied by 10 for this command.&lt;br /&gt;
&lt;br /&gt;
There are various variations of this command:&lt;br /&gt;
 -cbc_assertions_proof&lt;br /&gt;
 -cbc_assertions_tautology_proof &lt;br /&gt;
Both commands do not allow enumeration warnings to occur.&lt;br /&gt;
The latter command  ignores the PROPERTIES and tries to check whether the ASSERTION(s) are tautologies.&lt;br /&gt;
Both commands can be useful to use ProB as a Prover/Disprover (as is done in Atelier-B 4.3).&lt;br /&gt;
&lt;br /&gt;
=== -cbc_sequence &amp;lt;SEQ&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Constraint-based searching for a sequence of operation names (separated by semicolons)&lt;br /&gt;
|}&lt;br /&gt;
This will try and find a solution for the constants, initial variable values and parameters which make execution of the given sequence of operations possible.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch  -cbc_sequence &amp;quot;op1;op2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== -strict ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| raise error and stop probcli if anything unexpected happens, e.g., if model checking finds a counter example or trace checking fails or any unexpected error happens&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -t -strict&lt;br /&gt;
&lt;br /&gt;
=== -expcterr &amp;lt;ERR&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| expect error to occur (&amp;lt;ERR&amp;gt;=cbc,mc,ltl,...)&lt;br /&gt;
Tell ProB that you expect a certain error to occur. Mainly useful for regression tests (in conjunction with the -strict option).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli examples/B/Benchmarks/CarlaTravelAgencyErr.mch -mc 1000 -expcterr invariant_violation -strict&lt;br /&gt;
&lt;br /&gt;
=== -animate &amp;lt;Nr&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| random animation (max Nr steps)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Animates the machine randomly, maximally Nr of steps. It will stop if a deadlock is reached and report an error. You can also use the command &amp;lt;tt&amp;gt;-animate_all&amp;lt;/tt&amp;gt;, which will only stop at a deadlock (and not report an error). Be careful: &amp;lt;tt&amp;gt;-animate_all&amp;lt;/tt&amp;gt; could run forever.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -animate 100&lt;br /&gt;
&lt;br /&gt;
=== -execute &amp;lt;Nr&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| execution (max Nr steps)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Executes the &amp;quot;first&amp;quot; enabled operation of a machine, maximally Nr of steps. It will stop if a deadlock is reached and report an error. You can also use the command &amp;lt;tt&amp;gt;-execute_all&amp;lt;/tt&amp;gt;, which will only stop at a deadlock (and not report an error). Be careful: &amp;lt;tt&amp;gt;-execute_all&amp;lt;/tt&amp;gt; could run forever.&lt;br /&gt;
&lt;br /&gt;
In contrast to -animate, -execute will&lt;br /&gt;
* always choose the first enabled operation it finds and stop searching for further enabled operations in that state (-animate will compute all enabled operations up to the limit set by the &amp;lt;tt&amp;gt;MAX_OPERATIONS&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;MAX_INITIALISATIONS&amp;lt;/tt&amp;gt; preference and then choose randomly); the order of operations in the B machine is thus important for -execute&lt;br /&gt;
* not store intermediate states in the state space; as such -execute is faster but after execution one only has access to the first state and the final state of execution&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -execute 100&lt;br /&gt;
&lt;br /&gt;
=== -execute_all===&lt;br /&gt;
&lt;br /&gt;
See &amp;lt;tt&amp;gt;-execute &amp;lt;Nr&amp;gt;&amp;lt;/tt&amp;gt; above.&lt;br /&gt;
&lt;br /&gt;
=== -det_check ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| check if animation steps are deterministic&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Checks if every step of the animation is deterministic (i.e., only one operation is possible, and it can only be executed in one possible way as far as parameters and result is concerned).&lt;br /&gt;
Currently this option has only an effect for the -animate &amp;lt;Nr&amp;gt; and the -init commands.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -animate 100 -det_check&lt;br /&gt;
&lt;br /&gt;
=== -det_constants ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| check if animation steps are deterministic&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Checks if the SETUP_CONSTANTS step is deterministic (i.e., only one way to set up the constants is possible).&lt;br /&gt;
Currently this option has only an effect for the -animate &amp;lt;Nr&amp;gt; and the -init commands.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -init -det_constants&lt;br /&gt;
=== -his &amp;lt;FILE&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| save animation history to a file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save the animation (or model checking) history to a text file. Operations are separated by semicolons.&lt;br /&gt;
The output can be adapted using the -his_option command. With -his_option show_states the -his command will also write out all states to the file (in the form of comments before and after operations). With -his_option show_init only the initial state is written out.&lt;br /&gt;
The -his command is executed after the -init, -animate, -t or -mc commands.&lt;br /&gt;
See also the -sptxt command to only write the current values of variables and constants to a file.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli -animate 5 -his history.txt  supersimple.mch&lt;br /&gt;
&lt;br /&gt;
Additionally we can have the initialised variables and constants:&lt;br /&gt;
&lt;br /&gt;
 probcli -animate 5 -his history.txt -his_option show_init supersimple.mch&lt;br /&gt;
&lt;br /&gt;
And we can have in addition the values of the variables in between (and at the end):&lt;br /&gt;
&lt;br /&gt;
 probcli -animate 5 -his history.txt -his_option show_states supersimple.mch&lt;br /&gt;
&lt;br /&gt;
With -his_option trace_file as only option, probcli will write the history in Prolog format, which can later be used by the -t command.&lt;br /&gt;
&lt;br /&gt;
=== -i ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| interactive animation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After performing the other commands, ProB stays in interactive mode and allows the user to manually animate the loaded specification.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -i&lt;br /&gt;
&lt;br /&gt;
=== -repl ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| start interactive read-eval-print-loop&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -p CLPFD TRUE -repl&lt;br /&gt;
&lt;br /&gt;
A list of commands can be obtained by typing &amp;lt;tt&amp;gt;:help&amp;lt;/tt&amp;gt; (just help for versions 1.3.x of probcli). The interactive read-eval-print-loop can be exited using &amp;lt;tt&amp;gt;:q&amp;lt;/tt&amp;gt; (just typing a return on a blank line for versions 1.3.x of probcli)..&lt;br /&gt;
If in addition you want see a graphical representation of the solutions found you can use the following command and open the &amp;lt;tt&amp;gt;out.dot&amp;lt;/tt&amp;gt; file using dotty or GraphViz:&lt;br /&gt;
 probcli -repl -evaldot ~/out.dot&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also use the &amp;lt;tt&amp;gt;-eval&amp;lt;/tt&amp;gt; command to evaluate specific formulas or expressions:&lt;br /&gt;
 probcli -eval &amp;quot;1+2&amp;quot;&lt;br /&gt;
For convenience, these formulas can also be put into a separate file:&lt;br /&gt;
 probcli -eval_file MyFormula.txt&lt;br /&gt;
&lt;br /&gt;
=== -c ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| print coverage statistics&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 -c&lt;br /&gt;
&lt;br /&gt;
You can also use the longer name for the command:&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 --coverage&lt;br /&gt;
&lt;br /&gt;
There is also a version which prints a shorter summary (and which is much faster for large state spaces):&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 --coverage_summary&lt;br /&gt;
&lt;br /&gt;
=== -cc &amp;lt;Nr&amp;gt; &amp;lt;Nr&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| print and check coverage statistics&lt;br /&gt;
Print coverage statistics and check that the given number of nodes and transitions have been computed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 -cc 10 25&lt;br /&gt;
&lt;br /&gt;
=== -p &amp;lt;PREFERENCE&amp;gt; &amp;lt;VALUE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Set &amp;lt;PREFERENCE&amp;gt; to &amp;lt;VALUE&amp;gt;. For more information about preferences please have a look at [[Using_the_Command-Line_Version_of_ProB#Preferences | Preferences]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
You can also use --pref instead of -p.&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -p TIME_OUT 8000 -p CLPFD TRUE -mc 10000&lt;br /&gt;
&lt;br /&gt;
=== -pref_group &amp;lt;PREFGROUP&amp;gt; &amp;lt;SETTING&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| set to the group of preferences &amp;lt;PREFGROUP&amp;gt; to a predefined setting &amp;lt;SETTING&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -pref_group model_check unlimited&lt;br /&gt;
&lt;br /&gt;
Available groups and settings are:&lt;br /&gt;
&lt;br /&gt;
* PREFERENCE GROUP integer : SETTINGS [int32] : Values for MAXINT and MININT&lt;br /&gt;
* PREFERENCE GROUP time_out : SETTINGS [disable_time_out] : To disable TIME_OUT&lt;br /&gt;
* PREFERENCE GROUP model_check : SETTINGS [disable_max,unlimited] : Model Checking Limits&lt;br /&gt;
* PREFERENCE GROUP dot_colors : SETTINGS [classic,dreams,winter] : Colours for Dot graphs&lt;br /&gt;
&lt;br /&gt;
=== -prefs &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Set preferences from preference file &amp;lt;FILE&amp;gt;. The file should be created by the Tcl/Tk version of ProB; this version automatically creates a file called ProB_Preferences.pl. For more information about preferences please have a look at [[Using_the_Command-Line_Version_of_ProB#Preferences | Preferences]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -prefs ProB_Preferences.pl&lt;br /&gt;
&lt;br /&gt;
=== -card &amp;lt;GS&amp;gt; &amp;lt;VAL&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| set cardinality (scope in Alloy terminology) of a B deferred set. This overrides the default cardinality (which can be set using &amp;lt;tt&amp;gt;-p DEFAULT_SETSIZE &amp;lt;VAL&amp;gt;&amp;lt;/tt&amp;gt;).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -card PID 5&lt;br /&gt;
&lt;br /&gt;
=== -goal &amp;lt;PRED&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| set GOAL predicate for model checker&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 10000000 -goal &amp;quot;n=18&amp;quot;  -strict -expcterr goal_found&lt;br /&gt;
&lt;br /&gt;
=== -scope &amp;lt;PRED&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| set SCOPE predicate for model checker; states which do not satisfy the SCOPE predicate will be ignored (invariant will not be checked and no outgoing transitions will be computed)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 10000000 -scope &amp;quot;n&amp;lt;18&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
=== -s &amp;lt;PORT&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| start socket server on given port&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -ss ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| start socket server on port 9000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -sf ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| start socket server on some free port&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -sptxt &amp;lt;FILE&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| save constants and variables to a file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Save the values of constants and variables to a text file in classical B syntax.&lt;br /&gt;
The -sptxt command is executed after the -init, -animate, -t or -mc commands.&lt;br /&gt;
The values are fully written out (some sets, e.g., infinite sets may be written out symbolically).&lt;br /&gt;
&lt;br /&gt;
See also the -his command.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli -animate 5 -sptxt state.txt  supersimple.mch&lt;br /&gt;
&lt;br /&gt;
This will write the values of all variables and constants to the file state.txt after animating the machine 5 steps.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== -cache &amp;lt;DIRECTORY&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| save constants (and in future also variables) to a file to avoid recomputation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This commands saves the values of constants for the current B machine and puts those values into files in the specified directory. The command will also tell ProB to try and reuse constants saved for subsidiary machines (included using SEES for example) whenever possible.&lt;br /&gt;
The purpose of the command is to avoid recomputing constants as much as possible, as this can be very time consuming.&lt;br /&gt;
This also works for values of variables computed in the initialisation or even using operations.&lt;br /&gt;
However, we do not support refinements at the moment.&lt;br /&gt;
&lt;br /&gt;
Note: this command can also be used when starting up the ProB Tcl/Tk version.&lt;br /&gt;
&lt;br /&gt;
=== -logxml &amp;lt;LogFile&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| log activities and results of probcli in XML format in &amp;lt;LogFile&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A schema declaration file (xsd) can be found at &amp;lt;tt&amp;gt;doc/logxml_xsd.xml&amp;lt;/tt&amp;gt; in the ProB [[Download#Sourcecode|Prolog sources]].&lt;br /&gt;
The log file contains information about the various commands performed by probcli.&lt;br /&gt;
It also contains version information, the parameters provided to probcli and details about the errors that occured.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 -logxml log.xml&lt;br /&gt;
&lt;br /&gt;
=== -logxml_write_vars &amp;lt;PREFIX&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| after processing other commands (such as -execute) write values of variables having prefix PREFIX in their name into the XML log file (if XML logging has been activated using the -logxml command)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -execute 1000 -logxml log.xml -logxml_write_vars out&lt;br /&gt;
&lt;br /&gt;
=== -l &amp;lt;LogFile&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| log activities in &amp;lt;LogFile&amp;gt; using Prolog format&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 -l my.log&lt;br /&gt;
&lt;br /&gt;
=== -ll ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| log activities in /tmp/prob_cli_debug.log&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 -ll&lt;br /&gt;
&lt;br /&gt;
=== -lg &amp;lt;LogFile&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| analyse &amp;lt;LogFile&amp;gt; using gnuplot&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -pp &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| pretty-print internal representation to &amp;lt;FILE&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -pp my_pp.mch&lt;br /&gt;
&lt;br /&gt;
=== -ppf &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| pretty-print internal representation to &amp;lt;FILE&amp;gt;, force printing of all type infos&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -ppf my_ppf.mch&lt;br /&gt;
&lt;br /&gt;
=== -v ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| set ProB into verbose mode&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 1000 -v&lt;br /&gt;
&lt;br /&gt;
=== -version ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| print version information&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
There is also an alternate command called -svers which just prints the version number of ProB.&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli -version&lt;br /&gt;
 ProB Command Line Interface&lt;br /&gt;
   VERSION 1.3.4-rc1 (9556:9570M)&lt;br /&gt;
   $LastChangedDate: 2011-11-16 18:36:18 +0100 (Wed, 16 Nov 2011) $&lt;br /&gt;
   Prolog: SICStus 4.2.0 (x86_64-darwin-10.6.0): Mon Mar  7 20:03:36 CET 2011&lt;br /&gt;
   Application Path: /Users/leuschel/svn_root/NewProB&lt;br /&gt;
&lt;br /&gt;
 probcli -svers&lt;br /&gt;
 VERSION 1.3.4-rc1 (9556:9570M)&lt;br /&gt;
&lt;br /&gt;
You can use &amp;lt;tt&amp;gt;probcli -version -v&amp;lt;/tt&amp;gt; to obtain more information about your version of probcli.&lt;br /&gt;
&lt;br /&gt;
=== -check_java_version ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| check Java and B parser version information&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This command is available as of ProB version 1.5.1-beta5 or higher. It can be useful to check that your Java is correctly installed and that the ProB B parser can operate correctly&lt;br /&gt;
&lt;br /&gt;
 probcli -check_java_version&lt;br /&gt;
 Result of checking Java version:&lt;br /&gt;
  Java is correctly installed and version 1.7.0_55-b13 is compatible with ProB requirements (&amp;gt;= 1.7).&lt;br /&gt;
  ProB B Java Parser available in version: 2016-02-25 15:27:18.55.&lt;br /&gt;
&lt;br /&gt;
=== -assertions ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| check ASSERTIONS of your machine&lt;br /&gt;
&lt;br /&gt;
If you provide the -t switch, the ASSERTIONS will be checked after executing your trace. Otherwise, they will be checked in an initial state.&lt;br /&gt;
ProB will automatically initialize the machine if you have not provide the -init or -t switch.&lt;br /&gt;
&lt;br /&gt;
You can also use -main_assertions to check only the ASSERTIONS found in the main file.&lt;br /&gt;
&lt;br /&gt;
If your ASSERTIONS are all static (i.e., make no reference to variables), then ProB will remove all CONSTANTS and PROPERTIES from your machine which are not linked (directly or indirectly) to the ASSERTIONS.&lt;br /&gt;
This optimization will only be made if you provide no other switch, such as -mc or -animate which may require the computation of the variables.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -init -assertions&lt;br /&gt;
&lt;br /&gt;
=== -property ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| virtually add predicate to PROPERTIES&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -property &amp;quot;PRED&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== -properties ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| check PROPERTIES&lt;br /&gt;
Note: you should probably first initialise the machine (e.g., with -init).&lt;br /&gt;
If the constants have not yet been set up, probcli will debug the properties.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -init -properties&lt;br /&gt;
&lt;br /&gt;
=== -dot_output &amp;lt;PATH&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| define path for generation of dot files for false properties or assertions&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This option is applicable to -properties and -assertions. It will result in individual dot files being generated for every false or unknown property or assertion. Assertions are numbered A0,A1,... and properties P0,P1,... You can also force to generate dot files for all properties (i.e., also the true ones) using the -dot_all command-line flag.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -init -properties -dot_output somewhere/&lt;br /&gt;
&lt;br /&gt;
This will generate files somewhere/my_P0_false.dot, somewhere/my_P1_false.dot, ...&lt;br /&gt;
&lt;br /&gt;
=== -rc ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| runtime checking of types/pre-/post-conditions&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -ltlfile &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| check LTL formulas in file &amp;lt;FILE&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -ltlassertions ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| check LTL assertions (in DEFINITIONS)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -ltllimit &amp;lt;LIMIT&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| explore at most &amp;lt;LIMIT&amp;gt; states when model-checking LTL&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -save &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| save state space for later refinement check&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -refchk &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| refinement check against previous saved state space&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch ...&lt;br /&gt;
&lt;br /&gt;
=== -mcm_tests &amp;lt;Depth&amp;gt; &amp;lt;MaxStates&amp;gt; &amp;lt;EndPredicate&amp;gt; &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Generate test cases for the given specification. Each test case consists of a sequence of operations resp. events (a so-called trace) that&lt;br /&gt;
* start in a state after an initialisation&lt;br /&gt;
* contain a requested operation/event&lt;br /&gt;
* end in a state where the &amp;lt;EndPredicate&amp;gt; is fulfilled&lt;br /&gt;
&lt;br /&gt;
The user can specify what requested operations/events are with the&lt;br /&gt;
option [[#-mcm_cover &amp;lt;Operation(s)&amp;gt;|-mcm_cover]].&lt;br /&gt;
&lt;br /&gt;
ProB uses a &amp;quot;breadth-first&amp;quot; approach to search for test cases. When all requested operations/events are covered by test cases within maximum length M, the algorithm will explore the complete state space with that maximum distance M from the initialisation. It outputs all found traces that satisfy the requirements above.&lt;br /&gt;
&lt;br /&gt;
The algorithm stops if either&lt;br /&gt;
* it has covered all required operations/events with the current search depth&lt;br /&gt;
* or it has reached the maximum search depth or maximum number of explored states.&lt;br /&gt;
&lt;br /&gt;
The required parameters are:&lt;br /&gt;
;Depth&lt;br /&gt;
: The maximum length of traces that the algorithm searches for test until it stops without covering all required operations/events.&lt;br /&gt;
;MaxStates&lt;br /&gt;
: The maximum number of explored states until the algorithm stops without covering all required operations/events.&lt;br /&gt;
;EndPredicate&lt;br /&gt;
: A predicate in B syntax that the last state of a trace must fulfil. If you do not have any restrictions on that state, use a trivially true predicate like &#039;&#039;&#039;1=1&#039;&#039;&#039;&lt;br /&gt;
;FILE&lt;br /&gt;
: The found test cases a written to the XML file &amp;lt;FILE&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mcm_tests 10 2000 &amp;quot;EndStateVar=TRUE&amp;quot; testcases.xml -mcm_cover op1,op2&lt;br /&gt;
&lt;br /&gt;
generates test cases for the operations &#039;&#039;&#039;op1&#039;&#039;&#039; and &#039;&#039;&#039;op2&#039;&#039;&#039; of the specification &#039;&#039;&#039;my.mch&#039;&#039;&#039;. The maximum length of traces is 10, at most 2000 states are explored. Each test case ends in a state where the predicate &#039;&#039;&#039;EndStateVar=TRUE&#039;&#039;&#039; holds. The found test cases are written to a file &#039;&#039;&#039;testcases.xml&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
As of version 1.6.0, the operation arguments are also written to the XML file.&lt;br /&gt;
The preference &amp;lt;tt&amp;gt;INTERNAL_ARGUMENT_PREFIX&amp;lt;/tt&amp;gt; can be used to provide a prefix for internal operation arguments; any argument/parameter whose name starts with that prefix is considered an internal parameter and not shown in the trace file.&lt;br /&gt;
Also, as of version 1.6.0, the non-deterministic initialisations are shown in the XML trace file: all variables and constants where more than one possible initialisation exists are written into the trace file, as argument of an INITIALISATION event.&lt;br /&gt;
&lt;br /&gt;
=== -mcm_cover &amp;lt;Operation(s)&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Specify an operation or event that should be covered when generating test cases with the &#039;&#039;&#039;-mcm_test&#039;&#039;&#039; option. Multiple operations/events can be specified by seperating them by comma or by using &#039;&#039;&#039;-mcm_cover&#039;&#039;&#039; several times.&lt;br /&gt;
&lt;br /&gt;
See [[#-mcm_tests &amp;lt;Depth&amp;gt; &amp;lt;MaxStates&amp;gt; &amp;lt;EndPredicate&amp;gt; &amp;lt;FILE&amp;gt;|-mcm-tests]] for further details.&lt;br /&gt;
&lt;br /&gt;
=== -spdot &amp;lt;FILE&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Description&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Write graph of the state space to a dot &amp;lt;FILE&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -mc 100 -spdot my_statespace.dot&lt;br /&gt;
&lt;br /&gt;
=== -cbc_tests &amp;lt;Depth&amp;gt; &amp;lt;EndPredicate&amp;gt; &amp;lt;File&amp;gt; ===&lt;br /&gt;
Generate test cases by constraint solving with maximum&lt;br /&gt;
length &#039;&#039;&#039;Depth&#039;&#039;&#039;, the last state satisfies &#039;&#039;&#039;EndPredicate&#039;&#039;&#039;&lt;br /&gt;
and the test cases are written to &#039;&#039;&#039;File&#039;&#039;&#039;. If the predicate is the empty string we assume truth. If the filename is the empty string no file is generated. See also the page on [[Test_Case_Generation]].&lt;br /&gt;
&lt;br /&gt;
=== -cbc_cover &amp;lt;Operation&amp;gt; ===&lt;br /&gt;
When generating CB test cases, &#039;&#039;&#039;Operation&#039;&#039;&#039; should be covered.&lt;br /&gt;
The option can be given multiple times to specify several operations.&lt;br /&gt;
Alternatively, multiple operations can be separated by a comma. You can also use the option &amp;lt;pre&amp;gt;-cbc_cover_match PartialName&amp;lt;/pre&amp;gt; to match all operations whose name contains PartialName. See also the page about [[Test_Case_Generation]].&lt;br /&gt;
&lt;br /&gt;
=== -test_description &amp;lt;File&amp;gt; ===&lt;br /&gt;
Read the options for constraint based test case generation from &#039;&#039;&#039;File&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== -bmc &amp;lt;Depth&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;color:black; background-color:#FFFFEF; border:1px solid lightgray;&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| Run the [[Bounded_Model_Checking|bounded model checker]] until maximum trace depth &amp;lt;Depth&amp;gt; specified. Looks for invariant violations using the constraint-based test case generation algorithm.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -bmc 20&lt;br /&gt;
&lt;br /&gt;
=== -csp-guide &amp;lt;File&amp;gt; ===&lt;br /&gt;
Use the CSP File &#039;&#039;&#039;File&#039;&#039;&#039; to guide the B Machine (&amp;quot;CSP||B&amp;quot;).&lt;br /&gt;
(This feature is included since version 1.3.5-beta7.)&lt;br /&gt;
&lt;br /&gt;
== Environment Variables ==&lt;br /&gt;
&lt;br /&gt;
Set NO_COLOR environment variable to disable terminal colors.&lt;br /&gt;
See [https://no-color.org https://no-color.org].&lt;br /&gt;
&lt;br /&gt;
== Preferences ==&lt;br /&gt;
&lt;br /&gt;
You can use these preferences within the command:&lt;br /&gt;
&lt;br /&gt;
 -p &amp;lt;PREFERENCE&amp;gt; &amp;lt;VALUE&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;1&amp;quot; width=&amp;quot;100%&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!style=&amp;quot;background-color:lightgrey;&amp;quot; | &amp;lt;PREFERENCE&amp;gt;&lt;br /&gt;
!style=&amp;quot;background-color:lightgrey;&amp;quot; | &amp;lt;VALUE&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| MAXINT&lt;br /&gt;
| nat ==&amp;gt; MaxInt, used for expressions such as xx::NAT (2147483647 for 4 byte ints)&lt;br /&gt;
|-&lt;br /&gt;
| MININT&lt;br /&gt;
| neg ==&amp;gt; MinInt, used for expressions such as xx::INT (-2147483648 for 4 byte ints)&lt;br /&gt;
|-&lt;br /&gt;
| DEFAULT_SETSIZE&lt;br /&gt;
| nat ==&amp;gt; Size of unspecified deferred sets in SETS section. Will be used if a set s is neither enumerated, has no no card(s)=nr predicate in the PROPERTIES and has no scope_s == Nr DEFINITION.&lt;br /&gt;
|-&lt;br /&gt;
| MAX_INITIALISATIONS&lt;br /&gt;
| nat ==&amp;gt; Max Number of Initialisations and ways to setup constants computed&lt;br /&gt;
|-&lt;br /&gt;
| MAX_OPERATIONS&lt;br /&gt;
| nat ==&amp;gt; Max Number of Enablings per Operation Computed&lt;br /&gt;
|-&lt;br /&gt;
| ANIMATE_SKIP_OPERATIONS&lt;br /&gt;
| bool ==&amp;gt; Animate operations which are skip or PRE C THEN skip&lt;br /&gt;
|-&lt;br /&gt;
| COMPRESSION&lt;br /&gt;
| bool ==&amp;gt; Use more aggressive COMPRESSION when storing states&lt;br /&gt;
|-&lt;br /&gt;
| EXPAND_CLOSURES_FOR_STATE&lt;br /&gt;
| bool ==&amp;gt; Convert lazy form back into explicit form for Variables, Constants, Operation Arguments. ProB will sometimes try to keep certain sets symbolic. If this preference is TRUE then ProB will try to expand those sets for variables and constants after an operation has been executed.&lt;br /&gt;
|-&lt;br /&gt;
| SYMBOLIC&lt;br /&gt;
| bool ==&amp;gt; Lazy expansion of lambdas and set comprehensions. By default ProB will keep certain sets symbolic (e.g., sets it knows are infinite). When this preference is set to TRUE then all set comprehensions and lambda abstractions will at first be kept symbolic and only expanded into explicit form if needed.&lt;br /&gt;
|-&lt;br /&gt;
| CLPFD&lt;br /&gt;
| bool ==&amp;gt; Use CLP(FD) solver for B integers (restricts range to -2^28..2^28-1 on 32 bit computers). Setting this preference to TRUE should substantially improve ProB&#039;s ability to solve complicated predicates involving integers. However, it may cause CLP(FD) overflows in certain circumstances.&lt;br /&gt;
|-&lt;br /&gt;
| SMT&lt;br /&gt;
| bool ==&amp;gt; Enable SMT-Mode (aggressive treatment of : and /: inside predicates). With this predicate set to TRUE ProB will be better at solving certain constraint solving tasks. It should be enabled when doing constraint-based invariant or deadlock checking. ProB Tcl/Tk will turn this preference on automatically for those checks.&lt;br /&gt;
|-&lt;br /&gt;
| STATIC_ORDERING&lt;br /&gt;
| bool ==&amp;gt; Use static ordering to enumerate constants which occur in most PROPERTIES first&lt;br /&gt;
|-&lt;br /&gt;
| SYMMETRY_MODE&lt;br /&gt;
| [off,flood,nauty,hash] ==&amp;gt; Symmetry Mode: off,flood,canon,nauty,hash&lt;br /&gt;
|-&lt;br /&gt;
| TIME_OUT&lt;br /&gt;
| nat1 ==&amp;gt; Time out for computing enabled transitions (in ms, is multiplied by a factor for other computations)&lt;br /&gt;
|-&lt;br /&gt;
| PROOF_INFO&lt;br /&gt;
| bool ==&amp;gt; Use Proof Information to restrict invariant checking to affected unproven clauses. Most useful in EventB for models exported from Rodin.&lt;br /&gt;
|-&lt;br /&gt;
| TRY_FIND_ABORT&lt;br /&gt;
| bool ==&amp;gt; Try more aggressively to detect ill-defined expressions (e.g. applying function outside of domain), may slow down animator&lt;br /&gt;
|-&lt;br /&gt;
| NUMBER_OF_ANIMATED_ABSTRACTIONS&lt;br /&gt;
| nat ==&amp;gt; How many levels of refined models are animated by default&lt;br /&gt;
|-&lt;br /&gt;
| ALLOW_INCOMPLETE_SETUP_CONSTANTS&lt;br /&gt;
| bool ==&amp;gt; Allow ProB to proceed even if only part of the CONSTANTS have been found.&lt;br /&gt;
|-&lt;br /&gt;
| PARTITION_PROPERTIES&lt;br /&gt;
| bool ==&amp;gt; Partition predicates (PROPERTIES) into components&lt;br /&gt;
|-&lt;br /&gt;
| USE_RECORD_CONSTRUCTION&lt;br /&gt;
| bool ==&amp;gt; Records: Check if axioms/properties describe a record pattern&lt;br /&gt;
|-&lt;br /&gt;
| OPERATION_REUSE&lt;br /&gt;
| bool ==&amp;gt; Try and reuse previously computed operation effects in B/Event-B&lt;br /&gt;
|-&lt;br /&gt;
| SHOW_EVENTB_ANY_VALUES&lt;br /&gt;
| bool ==&amp;gt; Show top-level ANY variable values of B Operations without parameters as parameters&lt;br /&gt;
|-&lt;br /&gt;
| RANDOMISE_OPERATION_ORDER&lt;br /&gt;
| bool ==&amp;gt; Randomise order of operations when computing successor states&lt;br /&gt;
|-&lt;br /&gt;
| EXPAND_FORALL_UPTO&lt;br /&gt;
| nat ==&amp;gt; When analysing predicates: max. domain size for expansion of forall (use 0 to disable expansion)&lt;br /&gt;
|-&lt;br /&gt;
| MAX_DISPLAY_SET&lt;br /&gt;
| int ==&amp;gt; Max size for pretty-printing sets (-1 means no limit)&lt;br /&gt;
|-&lt;br /&gt;
| CSP_STRIP_SOURCE_LOC&lt;br /&gt;
| bool ==&amp;gt; Strip source location for CSP; will speed up model checking&lt;br /&gt;
|-&lt;br /&gt;
| WARN_WHEN_EXPANDING_INFINITE_CLOSURES&lt;br /&gt;
| int ==&amp;gt; Warn when expanding infinite closures if MAXINT larger than:&lt;br /&gt;
|-&lt;br /&gt;
| TRACE_INFO&lt;br /&gt;
| bool ==&amp;gt; Provide various tracing information on the terminal/console.&lt;br /&gt;
|-&lt;br /&gt;
| DOUBLE_EVALUATION&lt;br /&gt;
| bool ==&amp;gt; Evaluate PREDICATES positively and negatively when analyzing assertions or properties&lt;br /&gt;
|-&lt;br /&gt;
| RECURSIVE&lt;br /&gt;
| bool ==&amp;gt; Lazy expansion of *Recursive* set Comprehensions and lambdas&lt;br /&gt;
|-&lt;br /&gt;
| IGNORE_HASH_COLLISIONS&lt;br /&gt;
| bool ==&amp;gt; Ignore Hash Collisions (if true not all states may be computed, visited states are not memorised !)&lt;br /&gt;
|-&lt;br /&gt;
| FORGET_STATE_SPACE&lt;br /&gt;
| bool ==&amp;gt; Do not remember state space (mainly useful in conjunction with Ignore Hash Collisions)&lt;br /&gt;
|-&lt;br /&gt;
| NEGATED_INVARIANT_CHECKING&lt;br /&gt;
| bool ==&amp;gt; Perform double evaluation (positive and negative) when checking invariants&lt;br /&gt;
|-&lt;br /&gt;
| CSE&lt;br /&gt;
| bool ==&amp;gt; Perform common-sub-expression elimination&lt;br /&gt;
|-&lt;br /&gt;
| CSE_SUBST&lt;br /&gt;
| bool ==&amp;gt; Perform common-sub-expression elimination also for B substitutions&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
 probcli my.mch -p TIME_OUT 5000 -p CLPFD TRUE -p SYMMETRY_MODE hash -mc 1000&lt;br /&gt;
&lt;br /&gt;
== Some probcli examples ==&lt;br /&gt;
&lt;br /&gt;
To load a file My.mch, setup the constants and initialize it do:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
probcli -init My.mch&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
To load a file M.mch, setup the constants, initialize and then check all assertions with Atelier-B&#039;s default values for MININT and MAXINT and an increased timeout of 5 seconds do:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
probcli -init -assertions -p MAXINT 2147483647 -p MININT -2147483647 -p TIME_OUT 5000 M.mch&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To fully model check a specification M.mch while tryining to minimize memory consumption do:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
probcli -model_check -p COMPRESSION TRUE M.mch&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To model check a specification M.mch while trying to minimize memory consumption further by not storing processed stats and using symmetry reduction (and accepting hash collisions) do:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
probcli -p COMPRESSION -p IGNORE_HASH_COLLISIONS TRUE -p FORGET_STATE_SPACE TRUE -p SYMMETRY_MODE hash -model_check M.mch &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Command-line Arguments for ProB Tcl/Tk ==&lt;br /&gt;
&lt;br /&gt;
Note that the stand-alone Tcl/Tk version also supports a limited form of command-line preferences:&lt;br /&gt;
* &#039;&#039;&#039;FILE&#039;&#039;&#039; (the name/path of the file to be loaded)&lt;br /&gt;
* &#039;&#039;&#039;-prefs PREF_FILE&#039;&#039;&#039;  (to use a specific preferences file, rather than the default ProB_Preferences.pl in your home folder)&lt;br /&gt;
* &#039;&#039;&#039;-batch&#039;&#039;&#039; (to instruct ProB not to try to bring up windows, but to print information only to the terminal)&lt;br /&gt;
* &#039;&#039;&#039;-selfcheck&#039;&#039;&#039; (to run the standard unit tests)&lt;br /&gt;
* &#039;&#039;&#039;-t&#039;&#039;&#039; (to perform the Trace Check on the default trace file associated with the specification)&lt;br /&gt;
* &#039;&#039;&#039;-tcl TCL_Command&#039;&#039;&#039; (to run a particular pre-defined Tcl command)&lt;br /&gt;
* &#039;&#039;&#039;-mc&#039;&#039;&#039; (to perform model checking)&lt;br /&gt;
* &#039;&#039;&#039;-c&#039;&#039;&#039; (to compute the coverage)&lt;br /&gt;
* &#039;&#039;&#039;-ref&#039;&#039;&#039; (to perform the default trace refinment check)&lt;br /&gt;
&lt;br /&gt;
However, the comand-line version of ProB, called &#039;&#039;&#039;probcli&#039;&#039;&#039;, provides more features. It also does not depend on Tcl/Tk and can therefore be run on systems without Tcl/Tk.&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Rules-DSL&amp;diff=5939</id>
		<title>Rules-DSL</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Rules-DSL&amp;diff=5939"/>
		<updated>2025-03-31T07:33:43Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* B-Rules DSL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== B-Rules DSL ==&lt;br /&gt;
&lt;br /&gt;
The B-Rules domain-specific language (B-Rules DSL) mainly provides operations for data validation. &amp;lt;em&amp;gt;Rules&amp;lt;/em&amp;gt; allow checking for expected properties, while &amp;lt;em&amp;gt;computations&amp;lt;/em&amp;gt; can be used to define and compute variables based on the successful execution of certain rules. Furthermore you can use &amp;lt;em&amp;gt;functions&amp;lt;/em&amp;gt; to compute values multiple times depending on different inputs.&lt;br /&gt;
&lt;br /&gt;
===Setting up a Rules Machine===&lt;br /&gt;
Rules machines are stored in &amp;lt;code&amp;gt;.rmch&amp;lt;/code&amp;gt;-files. The general setup for the machine header is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULES_MACHINE machine_name&lt;br /&gt;
REFERENCES list of rules machines&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The latter allows the inclusion of other rules machines and ordinary B machines that contain only constants, but not yet any other B machines. Below, &amp;lt;code&amp;gt;SETS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;DEFINITIONS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;PROPERTIES&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;CONSTANTS&amp;lt;/code&amp;gt; can be used as in a normal B machine. Note that &amp;lt;code&amp;gt;VARIABLES&amp;lt;/code&amp;gt; are not allowed as they are set by rule based computations.&lt;br /&gt;
&lt;br /&gt;
====Rules====&lt;br /&gt;
Rules can be defined in the &amp;lt;code&amp;gt;OPERATIONS&amp;lt;/code&amp;gt;-section of a rules machine. Depending on whether the expectations are met, a rule returns &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;FAIL&amp;lt;/code&amp;gt;. If a rule fails, additionally provided string messages are returned as counterexamples.&lt;br /&gt;
In the B Rules-DSL a rule has the following structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE rule_name // will be the name of the operation and variable storing the result&lt;br /&gt;
DEPENDS_ON_RULE list of rules&lt;br /&gt;
DEPENDS_ON_COMPUTATION list of computations&lt;br /&gt;
ACTIVATION predicate&lt;br /&gt;
ERROR_TYPES positive number of error types&lt;br /&gt;
BODY&lt;br /&gt;
    arbitrarily many rule bodys (see below)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The specified &amp;lt;code&amp;gt;rule_name&amp;lt;/code&amp;gt; will be the name of the operation and variable storing the result.&lt;br /&gt;
If a rule depends on other rules, it can only be executed if the specified rules have been successfully checked, i.e. their corresponding variables &amp;lt;code&amp;gt;rule_name&amp;lt;/code&amp;gt; have the value &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt;. In addition, rules can depend on computations. In this case, a rule is enabled when the specified computations have been executed. If a rule uses variables that are defined by computations, the corresponding computations are added implicitly as dependencies and do not have to be declared explicitly. Any other preconditions can be specified as an &amp;lt;code&amp;gt;ACTIVATION&amp;lt;/code&amp;gt; predicate. An important note is that the activation predicate is evaluated statically at initialisation and disables the rule if the predicate is false. Activation predicates and dependencies can be omitted if they are not needed.&lt;br /&gt;
&lt;br /&gt;
To use different error types (for example, if a rule has multiple bodies and it is necessary to distinguish between them), the number of error types has to be declared in the rule header.&lt;br /&gt;
Error types are also optional.&lt;br /&gt;
&lt;br /&gt;
The actual rule conditions are specified within the body of a rule, which contains the name and the preconditions.&lt;br /&gt;
A rule succeeds if and only if all rule conditions in its body are satisfied.&lt;br /&gt;
There are two constructs for rule bodies that can be used arbitrarily often in the body of a rule.&lt;br /&gt;
The following is formulated in a positive way, i.e. the execution of the rule leads to &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt; if the conditions in the &amp;lt;code&amp;gt;EXPECT&amp;lt;/code&amp;gt;-part are fulfilled.&lt;br /&gt;
In contrast to the &amp;lt;code&amp;gt;RULE_FAIL&amp;lt;/code&amp;gt; body (see below), in &amp;lt;code&amp;gt;RULE_FORALL&amp;lt;/code&amp;gt; you can obtain success messages (such as counter examples) for successful applications of the rule.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    RULE_FORALL&lt;br /&gt;
        list of identifiers&lt;br /&gt;
    WHERE &lt;br /&gt;
        conditions on identifiers&lt;br /&gt;
    EXPECT&lt;br /&gt;
        conditions that must be fulfilled for this rule&lt;br /&gt;
    ERROR_TYPE&lt;br /&gt;
        number encoding error type, must be in range of error types&lt;br /&gt;
    ON_SUCCESS &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list) or&lt;br /&gt;
        ```${identifier from list}``` (template string)&lt;br /&gt;
    COUNTEREXAMPLE &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list) or&lt;br /&gt;
        ```${identifier from list}``` (template string)&lt;br /&gt;
    END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, a negated rule can be formulated. Here the execution of the rule results in &amp;lt;code&amp;gt;FAIL&amp;lt;/code&amp;gt; if the conditions in the &amp;lt;code&amp;gt;WHEN&amp;lt;/code&amp;gt;-part are fulfilled.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    RULE_FAIL &lt;br /&gt;
        list of identifiers&lt;br /&gt;
    WHEN &lt;br /&gt;
        conditions on identifiers for a failing rule&lt;br /&gt;
    ERROR_TYPE&lt;br /&gt;
        number encoding error type, must be in range of error types&lt;br /&gt;
    COUNTEREXAMPLE &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list)&lt;br /&gt;
    END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Counterexamples are of the type &amp;lt;code&amp;gt;INTEGER &amp;lt;-&amp;gt; STRING&amp;lt;/code&amp;gt;. The integer contains the error type, while the string contains the message of the counterexample.&lt;br /&gt;
&lt;br /&gt;
Also valid for the rules header are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULEID id&lt;br /&gt;
CLASSIFICATION identifier&lt;br /&gt;
TAGS identifier&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;CLASSIFICATION&amp;lt;/code&amp;gt; keyword can be used to group the rules in the [[#Rule_Validation_in_ProB2-UI|HTML validation report]] according to their classification.&lt;br /&gt;
&lt;br /&gt;
====Computations====&lt;br /&gt;
Computations can be used to define variables. As for rules, their activation can depend on further rules, computations or any other predicate specified as an activation condition. Again, the activation condition is evaluated at initialisation and sets the computation status variable to &amp;lt;code&amp;gt;COMPUTATION_DISABLED&amp;lt;/code&amp;gt; if the predicate is false. Furthermore, a &amp;lt;code&amp;gt;DUMMY_VALUE&amp;lt;/code&amp;gt; can be set, which initialises the variable with the specified value instead of the empty set before execution of the computation. This mechanism implies that each variable defined by a computation must be a set of type &amp;lt;code&amp;gt;POW(S)&amp;lt;/code&amp;gt; for any &amp;lt;code&amp;gt;TYPE&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;S&amp;lt;/code&amp;gt;. A computation can be replaced by a previously defined computation if it sets the same variable (of the same type) by using &amp;lt;code&amp;gt;REPLACES&amp;lt;/code&amp;gt;. The general syntax for computations is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
COMPUTATION computation_name&lt;br /&gt;
DEPENDS_ON_RULE list of rules&lt;br /&gt;
DEPENDS_ON_COMPUTATION list of computations&lt;br /&gt;
ACTIVATION predicate&lt;br /&gt;
REPLACES identifier of exactly one computation&lt;br /&gt;
BODY&lt;br /&gt;
    DEFINE variable_name&lt;br /&gt;
        TYPE type of variable&lt;br /&gt;
        DUMMY_VALUE value of variable before execution (initialisation)&lt;br /&gt;
        VALUE value of variable after execution&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Activation predicates, dependencies, and also the dummy value can be omitted if they are not needed. After the execution of a computation, the value of the corresponding variable &amp;lt;code&amp;gt;computation_name&amp;lt;/code&amp;gt; is changed from &amp;lt;code&amp;gt;NOT_EXECUTED&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;EXECUTED&amp;lt;/code&amp;gt;  and the variable &amp;lt;code&amp;gt;variable_name&amp;lt;/code&amp;gt; has the value \texttt{VALUE}. For related computations, it may be useful to use multiple &amp;lt;code&amp;gt;DEFINE&amp;lt;/code&amp;gt; blocks in one computation.&lt;br /&gt;
Separated by &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt;, the body of a computation can contain any number of variable definitions.&lt;br /&gt;
&lt;br /&gt;
====Functions====&lt;br /&gt;
Functions can be called from any rules machine that references the machine containing the function. Depending on input parameters that must fulfil specified preconditions, the functions returns output value(s) that must fulfil optional postconditions. In the body, any B statement can be used to (sequentially) compute the output value.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FUNCTION output &amp;lt;-- function_name(list of input parameters)&lt;br /&gt;
PRECONDITION&lt;br /&gt;
    predicate&lt;br /&gt;
POSTCONDITION&lt;br /&gt;
    predicate&lt;br /&gt;
BODY&lt;br /&gt;
   some B statements&lt;br /&gt;
   output := ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Additional Syntax====&lt;br /&gt;
There are some useful predicates available in rules machines that can be used to check the success or failure of rules. It is also possible to check whether a certain error type was returned by a rule. These are:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SUCCEEDED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 succeeded&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SUCCEEDED_RULE_ERROR_TYPE(rule1,1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 did not fail with error type 1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;GET_RULE_COUNTEREXAMPLES(rule1)&amp;lt;/code&amp;gt;: set of counterexamples of rule1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 failed&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE_ERROR_TYPE(rule1,2)&amp;lt;/code&amp;gt;: TRUE, if check of rule1 failed with error type 2&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE_ALL_ERROR_TYPES(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 failed with all possible error types for rule1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;NOT_CHECKED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if rule1 has not yet been checked&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;DISABLED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if rule1 is disabled (its preconditions are not fulfilled)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another functionality of rules machines are FOR-loops. Their syntax is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FOR variable(s) IN set&lt;br /&gt;
DO&lt;br /&gt;
    operation(s)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
An example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE example_rule&lt;br /&gt;
BODY&lt;br /&gt;
    FOR x,y IN {1 |-&amp;gt; TRUE, 2 |-&amp;gt; FALSE, 3 |-&amp;gt; FALSE} DO &lt;br /&gt;
        RULE_FAIL &lt;br /&gt;
        WHEN y = FALSE&lt;br /&gt;
        COUNTEREXAMPLE STRING_FORMAT(&amp;quot;example_rule_fail: ~w&amp;quot;, x)&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This rule always fails and returns &amp;lt;code&amp;gt;{1 |-&amp;gt; &amp;quot;example_rule_fail: 2&amp;quot;, 1 |-&amp;gt; &amp;quot;example_rule_fail: 3&amp;quot;}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Rule Validation in ProB2-UI===&lt;br /&gt;
Rule validation has been integrated into the ProB2-UI since version 1.2.2 (not yet released).&lt;br /&gt;
It allows convenient execution of rules and computations together with a graphical representation of the results.&lt;br /&gt;
Rules are grouped by their classification and can be additionally filtered by their name, ID, or tags.&lt;br /&gt;
The results can also be exported as an HTML report.&lt;br /&gt;
In addition, dependencies of rules and computations can be visualised as a graph either for all operations or for just one operation (the HTML report and the dependency graph are generated by the ProB Java API and can also be created without ProB2-UI).&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2 UI Rules View.png|500px|ProB2-UI Rules View]]&lt;br /&gt;
&lt;br /&gt;
===Rule Validation with probcli===&lt;br /&gt;
The probcli recognises the option &amp;lt;code&amp;gt;-rule_report &amp;lt;file&amp;gt;&amp;lt;/code&amp;gt; which generates the same HTML validation report as in ProB2-UI for the current animation state.&lt;br /&gt;
To validate all rules, use this option in combination with &amp;lt;code&amp;gt;-execute_all&amp;lt;/code&amp;gt;.&lt;br /&gt;
The HTML report option is also available in ProB Tcl/Tk via the visualization menu.&lt;br /&gt;
&lt;br /&gt;
===Use Rules for Data Validation===&lt;br /&gt;
The concept of rule validation can be used to validate data from external sources such as CSV or XML files and load the validated data into ProB by successive computations.&lt;br /&gt;
For an XML file, this could look as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULES_MACHINE XML_import&lt;br /&gt;
DEFINITIONS&lt;br /&gt;
    &amp;quot;LibraryXML.def&amp;quot;&lt;br /&gt;
CONSTANTS&lt;br /&gt;
    xml_data&lt;br /&gt;
PROPERTIES&lt;br /&gt;
    xml_data = READ_XML(&amp;quot;xml_file.xml&amp;quot;, &amp;quot;auto&amp;quot;)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now some properties can be validated. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE is_supported_version_of_type_xyz&lt;br /&gt;
ERROR_TYPES 2&lt;br /&gt;
BODY&lt;br /&gt;
    RULE_FAIL e&lt;br /&gt;
    WHEN&lt;br /&gt;
        1 : dom(xml_data) &amp;amp; e = data(1)&#039;element &amp;amp; e /= &amp;quot;xyz&amp;quot;&lt;br /&gt;
    ERROR_TYPE 1 // optional: 1 is standard type&lt;br /&gt;
    COUNTEREXAMPLE&lt;br /&gt;
        STRING_FORMAT(&amp;quot;Error: could not find element &#039;xyz&#039;, was &#039;&amp;quot;^e^&amp;quot;&#039;&amp;quot;)&lt;br /&gt;
    END;&lt;br /&gt;
    RULE_FAIL v&lt;br /&gt;
    WHEN&lt;br /&gt;
        v = xml_data(1)&#039;attributes(&amp;quot;version&amp;quot;) &amp;amp; v /: supported_versions&lt;br /&gt;
    ERROR_TYPE 2&lt;br /&gt;
    COUNTEREXAMPLE&lt;br /&gt;
        &amp;quot;xyz of version &amp;quot;^v^&amp;quot; is currently not supported&amp;quot;&lt;br /&gt;
    END&lt;br /&gt;
END;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Internal Representation===&lt;br /&gt;
Each rules machine is internally translated to an ordinary B machine, which can be accessed as its internal representation.&lt;br /&gt;
Consider the following example rule:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE rule1 BODY RULE_FAIL WHEN bfalse COUNTEREXAMPLE &amp;quot;&amp;quot; END END;&lt;br /&gt;
&lt;br /&gt;
COMPUTATION comp1&lt;br /&gt;
BODY&lt;br /&gt;
    DEFINE x&lt;br /&gt;
    TYPE POW(INTEGER)&lt;br /&gt;
    VALUE 1..10&lt;br /&gt;
    END&lt;br /&gt;
END;&lt;br /&gt;
&lt;br /&gt;
RULE rule2&lt;br /&gt;
DEPENDS_ON_RULE rule1&lt;br /&gt;
// DEPENDS_ON_COMPUTATION comp1&lt;br /&gt;
BODY&lt;br /&gt;
    RULE_FORALL i&lt;br /&gt;
        WHERE i : 1..10&lt;br /&gt;
        EXPECT i &amp;gt; 5&lt;br /&gt;
        COUNTEREXAMPLE STRING_FORMAT(&amp;quot;~w &amp;lt;= 5&amp;quot;, i)&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Its internal representation in classical B is the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
`$RESULT`,`$COUNTEREXAMPLES` &amp;lt;-- rule1 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        rule1 = &amp;quot;NOT_CHECKED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
      rule1,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;SUCCESS&amp;quot;,&amp;quot;SUCCESS&amp;quot;,{}&lt;br /&gt;
    END;&lt;br /&gt;
  &lt;br /&gt;
  comp1 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        comp1 = &amp;quot;NOT_EXECUTED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
      x,comp1 := FORCE(1 .. 10),&amp;quot;EXECUTED&amp;quot;&lt;br /&gt;
    END;&lt;br /&gt;
  &lt;br /&gt;
  `$RESULT`,`$COUNTEREXAMPLES` &amp;lt;-- rule2 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        rule2 = &amp;quot;NOT_CHECKED&amp;quot;&lt;br /&gt;
      &amp;amp; rule1 = &amp;quot;SUCCESS&amp;quot;&lt;br /&gt;
      &amp;amp; comp1 = &amp;quot;EXECUTED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
        rule2,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;SUCCESS&amp;quot;,&amp;quot;SUCCESS&amp;quot;,{} ;&lt;br /&gt;
        VAR `$ResultTuple`,`$ResultStrings`&lt;br /&gt;
        IN&lt;br /&gt;
            `$ResultTuple` := FORCE({i|i : x &amp;amp; not(i &amp;gt; 5)}) ;&lt;br /&gt;
            `$ResultStrings` := FORCE({`$String`|`$String` : STRING &amp;amp; #i.(i : `$ResultTuple` &amp;amp; `$String` = FORMAT_TO_STRING(&amp;quot;~w &amp;lt;= 5&amp;quot;,[TO_STRING(i)]))});&lt;br /&gt;
              rule2_Counterexamples := rule2_Counterexamples \/ {1} * `$ResultStrings` ;&lt;br /&gt;
          IF `$ResultTuple` /= {} THEN&lt;br /&gt;
              rule2,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;FAIL&amp;quot;,&amp;quot;FAIL&amp;quot;,rule2_Counterexamples&lt;br /&gt;
          END&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Observe that the implicit dependency of rule2 on comp1 (rule2 uses its variable x) is detected automatically without explicit declaration.&lt;br /&gt;
&lt;br /&gt;
===Include Rules Machines into other Projects===&lt;br /&gt;
Currently, it is not possible to include rules machines directly into any other machines. Instead, use the rules machine at the top of the hierarchy (of the rules project) and save the internal generated machine as &amp;lt;code&amp;gt;.mch&amp;lt;/code&amp;gt;-file. After changing the machine name accordingly, the rules can be included and used via this machine.&lt;br /&gt;
Note that in this case it is not possible to perform Rules-DSL specific methods of the ProB Java API (like detailed information about rule results).&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Rules-DSL&amp;diff=5938</id>
		<title>Rules-DSL</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Rules-DSL&amp;diff=5938"/>
		<updated>2025-03-31T07:30:17Z</updated>

		<summary type="html">&lt;p&gt;Jan Gruteser: /* Rules */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== B-Rules DSL ==&lt;br /&gt;
&lt;br /&gt;
The B-Rules domain-specific language (B-Rules DSL) mainly provides operations for data validation. &amp;lt;em&amp;gt;Rules&amp;lt;/em&amp;gt; allow checking for expected properties, while &amp;lt;em&amp;gt;computations&amp;lt;/em&amp;gt; can be used to define and compute variables based on the successful execution of certain rules. Furthermore you can use &amp;lt;em&amp;gt;functions&amp;lt;/em&amp;gt; to compute values multiple times depending on different inputs.&lt;br /&gt;
&lt;br /&gt;
===Setting up a Rules Machine===&lt;br /&gt;
Rules machines are stored in &amp;lt;code&amp;gt;.rmch&amp;lt;/code&amp;gt;-files. The general setup for the machine header is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULES_MACHINE machine_name&lt;br /&gt;
REFERENCES list of rules machines&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The latter allows the inclusion of other rules machines and ordinary B machines that contain only constants, but not yet any other B machines. Below, &amp;lt;code&amp;gt;SETS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;DEFINITIONS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;PROPERTIES&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;CONSTANTS&amp;lt;/code&amp;gt; can be used as in a normal B machine. Note that &amp;lt;code&amp;gt;VARIABLES&amp;lt;/code&amp;gt; are not allowed as they are set by rule based computations.&lt;br /&gt;
&lt;br /&gt;
====Rules====&lt;br /&gt;
Rules can be defined in the &amp;lt;code&amp;gt;OPERATIONS&amp;lt;/code&amp;gt;-section of a rules machine. Depending on whether the expectations are met, a rule returns &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;FAIL&amp;lt;/code&amp;gt;. If a rule fails, additionally provided string messages are returned as counterexamples.&lt;br /&gt;
In the B Rules-DSL a rule has the following structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE rule_name // will be the name of the operation and variable storing the result&lt;br /&gt;
DEPENDS_ON_RULE list of rules&lt;br /&gt;
DEPENDS_ON_COMPUTATION list of computations&lt;br /&gt;
ACTIVATION predicate&lt;br /&gt;
ERROR_TYPES positive number of error types&lt;br /&gt;
BODY&lt;br /&gt;
    arbitrarily many rule bodys (see below)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The specified &amp;lt;code&amp;gt;rule_name&amp;lt;/code&amp;gt; will be the name of the operation and variable storing the result.&lt;br /&gt;
If a rule depends on other rules, it can only be executed if the specified rules have been successfully checked, i.e. their corresponding variables &amp;lt;code&amp;gt;rule_name&amp;lt;/code&amp;gt; have the value &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt;. In addition, rules can depend on computations. In this case, a rule is enabled when the specified computations have been executed. If a rule uses variables that are defined by computations, the corresponding computations are added implicitly as dependencies and do not have to be declared explicitly. Any other preconditions can be specified as an &amp;lt;code&amp;gt;ACTIVATION&amp;lt;/code&amp;gt; predicate. An important note is that the activation predicate is evaluated statically at initialisation and disables the rule if the predicate is false. Activation predicates and dependencies can be omitted if they are not needed.&lt;br /&gt;
&lt;br /&gt;
To use different error types (for example, if a rule has multiple bodies and it is necessary to distinguish between them), the number of error types has to be declared in the rule header.&lt;br /&gt;
Error types are also optional.&lt;br /&gt;
&lt;br /&gt;
The actual rule conditions are specified within the body of a rule, which contains the name and the preconditions.&lt;br /&gt;
A rule succeeds if and only if all rule conditions in its body are satisfied.&lt;br /&gt;
There are two constructs for rule bodies that can be used arbitrarily often in the body of a rule.&lt;br /&gt;
The following is formulated in a positive way, i.e. the execution of the rule leads to &amp;lt;code&amp;gt;SUCCESS&amp;lt;/code&amp;gt; if the conditions in the &amp;lt;code&amp;gt;EXPECT&amp;lt;/code&amp;gt;-part are fulfilled.&lt;br /&gt;
In contrast to the &amp;lt;code&amp;gt;RULE_FAIL&amp;lt;/code&amp;gt; body (see below), in &amp;lt;code&amp;gt;RULE_FORALL&amp;lt;/code&amp;gt; you can obtain success messages (such as counter examples) for successful applications of the rule.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    RULE_FORALL&lt;br /&gt;
        list of identifiers&lt;br /&gt;
    WHERE &lt;br /&gt;
        conditions on identifiers&lt;br /&gt;
    EXPECT&lt;br /&gt;
        conditions that must be fulfilled for this rule&lt;br /&gt;
    ERROR_TYPE&lt;br /&gt;
        number encoding error type, must be in range of error types&lt;br /&gt;
    ON_SUCCESS &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list) or&lt;br /&gt;
        ```${identifier from list}``` (template string)&lt;br /&gt;
    COUNTEREXAMPLE &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list) or&lt;br /&gt;
        ```${identifier from list}``` (template string)&lt;br /&gt;
    END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, a negated rule can be formulated. Here the execution of the rule results in &amp;lt;code&amp;gt;FAIL&amp;lt;/code&amp;gt; if the conditions in the &amp;lt;code&amp;gt;WHEN&amp;lt;/code&amp;gt;-part are fulfilled.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    RULE_FAIL &lt;br /&gt;
        list of identifiers&lt;br /&gt;
    WHEN &lt;br /&gt;
        conditions on identifiers for a failing rule&lt;br /&gt;
    ERROR_TYPE&lt;br /&gt;
        number encoding error type, must be in range of error types&lt;br /&gt;
    COUNTEREXAMPLE &lt;br /&gt;
        STRING_FORMAT(&amp;quot;errorMessage ~w&amp;quot;, identifier from list)&lt;br /&gt;
    END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Counterexamples are of the type &amp;lt;code&amp;gt;INTEGER &amp;lt;-&amp;gt; STRING&amp;lt;/code&amp;gt;. The integer contains the error type, while the string contains the message of the counterexample.&lt;br /&gt;
&lt;br /&gt;
Also valid for the rules header are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULEID id&lt;br /&gt;
CLASSIFICATION identifier&lt;br /&gt;
TAGS identifier&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;CLASSIFICATION&amp;lt;/code&amp;gt; keyword can be used to group the rules in the [[#Rule_Validation_in_ProB2-UI|HTML validation report]] according to their classification.&lt;br /&gt;
&lt;br /&gt;
====Computations====&lt;br /&gt;
Computations can be used to define variables. As for rules, their activation can depend on further rules, computations or any other predicate specified as an activation condition. Again, the activation condition is evaluated at initialisation and sets the computation status variable to &amp;lt;code&amp;gt;COMPUTATION_DISABLED&amp;lt;/code&amp;gt; if the predicate is false. Furthermore, a &amp;lt;code&amp;gt;DUMMY_VALUE&amp;lt;/code&amp;gt; can be set, which initialises the variable with the specified value instead of the empty set before execution of the computation. This mechanism implies that each variable defined by a computation must be a set of type &amp;lt;code&amp;gt;POW(S)&amp;lt;/code&amp;gt; for any &amp;lt;code&amp;gt;TYPE&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;S&amp;lt;/code&amp;gt;. A computation can be replaced by a previously defined computation if it sets the same variable (of the same type) by using &amp;lt;code&amp;gt;REPLACES&amp;lt;/code&amp;gt;. The general syntax for computations is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
COMPUTATION computation_name&lt;br /&gt;
DEPENDS_ON_RULE list of rules&lt;br /&gt;
DEPENDS_ON_COMPUTATION list of computations&lt;br /&gt;
ACTIVATION predicate&lt;br /&gt;
REPLACES identifier of exactly one computation&lt;br /&gt;
BODY&lt;br /&gt;
    DEFINE variable_name&lt;br /&gt;
        TYPE type of variable&lt;br /&gt;
        DUMMY_VALUE value of variable before execution (initialisation)&lt;br /&gt;
        VALUE value of variable after execution&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Activation predicates, dependencies, and also the dummy value can be omitted if they are not needed. After the execution of a computation, the value of the corresponding variable &amp;lt;code&amp;gt;computation_name&amp;lt;/code&amp;gt; is changed from &amp;lt;code&amp;gt;NOT_EXECUTED&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;EXECUTED&amp;lt;/code&amp;gt;  and the variable &amp;lt;code&amp;gt;variable_name&amp;lt;/code&amp;gt; has the value \texttt{VALUE}. For related computations, it may be useful to use multiple &amp;lt;code&amp;gt;DEFINE&amp;lt;/code&amp;gt; blocks in one computation.&lt;br /&gt;
Separated by &amp;lt;code&amp;gt;;&amp;lt;/code&amp;gt;, the body of a computation can contain any number of variable definitions.&lt;br /&gt;
&lt;br /&gt;
====Functions====&lt;br /&gt;
Functions can be called from any rules machine that references the machine containing the function. Depending on input parameters that must fulfil specified preconditions, the functions returns output value(s) that must fulfil optional postconditions. In the body, any B statement can be used to (sequentially) compute the output value.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FUNCTION output &amp;lt;-- function_name(list of input parameters)&lt;br /&gt;
PRECONDITION&lt;br /&gt;
    predicate&lt;br /&gt;
POSTCONDITION&lt;br /&gt;
    predicate&lt;br /&gt;
BODY&lt;br /&gt;
   some B statements&lt;br /&gt;
   output := ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Additional Syntax====&lt;br /&gt;
There are some useful predicates available in rules machines that can be used to check the success or failure of rules. It is also possible to check whether a certain error type was returned by a rule. These are:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SUCCEEDED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 succeeded&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SUCCEEDED_RULE_ERROR_TYPE(rule1,1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 did not fail with error type 1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;GET_RULE_COUNTEREXAMPLES(rule1)&amp;lt;/code&amp;gt;: set of counterexamples of rule1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 failed&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE_ERROR_TYPE(rule1,2)&amp;lt;/code&amp;gt;: TRUE, if check of rule1 failed with error type 2&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;FAILED_RULE_ALL_ERROR_TYPES(rule1)&amp;lt;/code&amp;gt;: TRUE, if the check of rule1 failed with all possible error types for rule1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;NOT_CHECKED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if rule1 has not yet been checked&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;DISABLED_RULE(rule1)&amp;lt;/code&amp;gt;: TRUE, if rule1 is disabled (its preconditions are not fulfilled)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another functionality of rules machines are FOR-loops. Their syntax is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FOR variable(s) IN set&lt;br /&gt;
DO&lt;br /&gt;
    operation(s)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
An example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE example_rule&lt;br /&gt;
BODY&lt;br /&gt;
    FOR x,y IN {1 |-&amp;gt; TRUE, 2 |-&amp;gt; FALSE, 3 |-&amp;gt; FALSE} DO &lt;br /&gt;
        RULE_FAIL &lt;br /&gt;
        WHEN y = FALSE&lt;br /&gt;
        COUNTEREXAMPLE STRING_FORMAT(&amp;quot;example_rule_fail: ~w&amp;quot;, x)&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This rule always fails and returns &amp;lt;code&amp;gt;{1 |-&amp;gt; &amp;quot;example_rule_fail: 2&amp;quot;, 1 |-&amp;gt; &amp;quot;example_rule_fail: 3&amp;quot;}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Rule Validation in ProB2-UI===&lt;br /&gt;
Rule validation has been integrated into the ProB2-UI since version 1.2.2 (not yet released).&lt;br /&gt;
It allows convenient execution of rules and computations together with a graphical representation of the results.&lt;br /&gt;
Rules are grouped by their classification and can be additionally filtered by their name, ID, or tags.&lt;br /&gt;
The results can also be exported as an HTML report.&lt;br /&gt;
In addition, dependencies of rules and computations can be visualised as a graph either for all operations or for just one operation (the HTML report and the dependency graph are generated by the ProB Java API and can also be created without ProB2-UI).&lt;br /&gt;
&lt;br /&gt;
[[File:ProB2 UI Rules View.png|500px|ProB2-UI Rules View]]&lt;br /&gt;
&lt;br /&gt;
===Use Rules for Data Validation===&lt;br /&gt;
The concept of rule validation can be used to validate data from external sources such as CSV or XML files and load the validated data into ProB by successive computations.&lt;br /&gt;
For an XML file, this could look as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULES_MACHINE XML_import&lt;br /&gt;
DEFINITIONS&lt;br /&gt;
    &amp;quot;LibraryXML.def&amp;quot;&lt;br /&gt;
CONSTANTS&lt;br /&gt;
    xml_data&lt;br /&gt;
PROPERTIES&lt;br /&gt;
    xml_data = READ_XML(&amp;quot;xml_file.xml&amp;quot;, &amp;quot;auto&amp;quot;)&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now some properties can be validated. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE is_supported_version_of_type_xyz&lt;br /&gt;
ERROR_TYPES 2&lt;br /&gt;
BODY&lt;br /&gt;
    RULE_FAIL e&lt;br /&gt;
    WHEN&lt;br /&gt;
        1 : dom(xml_data) &amp;amp; e = data(1)&#039;element &amp;amp; e /= &amp;quot;xyz&amp;quot;&lt;br /&gt;
    ERROR_TYPE 1 // optional: 1 is standard type&lt;br /&gt;
    COUNTEREXAMPLE&lt;br /&gt;
        STRING_FORMAT(&amp;quot;Error: could not find element &#039;xyz&#039;, was &#039;&amp;quot;^e^&amp;quot;&#039;&amp;quot;)&lt;br /&gt;
    END;&lt;br /&gt;
    RULE_FAIL v&lt;br /&gt;
    WHEN&lt;br /&gt;
        v = xml_data(1)&#039;attributes(&amp;quot;version&amp;quot;) &amp;amp; v /: supported_versions&lt;br /&gt;
    ERROR_TYPE 2&lt;br /&gt;
    COUNTEREXAMPLE&lt;br /&gt;
        &amp;quot;xyz of version &amp;quot;^v^&amp;quot; is currently not supported&amp;quot;&lt;br /&gt;
    END&lt;br /&gt;
END;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Internal Representation===&lt;br /&gt;
Each rules machine is internally translated to an ordinary B machine, which can be accessed as its internal representation.&lt;br /&gt;
Consider the following example rule:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RULE rule1 BODY RULE_FAIL WHEN bfalse COUNTEREXAMPLE &amp;quot;&amp;quot; END END;&lt;br /&gt;
&lt;br /&gt;
COMPUTATION comp1&lt;br /&gt;
BODY&lt;br /&gt;
    DEFINE x&lt;br /&gt;
    TYPE POW(INTEGER)&lt;br /&gt;
    VALUE 1..10&lt;br /&gt;
    END&lt;br /&gt;
END;&lt;br /&gt;
&lt;br /&gt;
RULE rule2&lt;br /&gt;
DEPENDS_ON_RULE rule1&lt;br /&gt;
// DEPENDS_ON_COMPUTATION comp1&lt;br /&gt;
BODY&lt;br /&gt;
    RULE_FORALL i&lt;br /&gt;
        WHERE i : 1..10&lt;br /&gt;
        EXPECT i &amp;gt; 5&lt;br /&gt;
        COUNTEREXAMPLE STRING_FORMAT(&amp;quot;~w &amp;lt;= 5&amp;quot;, i)&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Its internal representation in classical B is the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
`$RESULT`,`$COUNTEREXAMPLES` &amp;lt;-- rule1 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        rule1 = &amp;quot;NOT_CHECKED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
      rule1,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;SUCCESS&amp;quot;,&amp;quot;SUCCESS&amp;quot;,{}&lt;br /&gt;
    END;&lt;br /&gt;
  &lt;br /&gt;
  comp1 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        comp1 = &amp;quot;NOT_EXECUTED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
      x,comp1 := FORCE(1 .. 10),&amp;quot;EXECUTED&amp;quot;&lt;br /&gt;
    END;&lt;br /&gt;
  &lt;br /&gt;
  `$RESULT`,`$COUNTEREXAMPLES` &amp;lt;-- rule2 = &lt;br /&gt;
    SELECT &lt;br /&gt;
        rule2 = &amp;quot;NOT_CHECKED&amp;quot;&lt;br /&gt;
      &amp;amp; rule1 = &amp;quot;SUCCESS&amp;quot;&lt;br /&gt;
      &amp;amp; comp1 = &amp;quot;EXECUTED&amp;quot;&lt;br /&gt;
    THEN &lt;br /&gt;
        rule2,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;SUCCESS&amp;quot;,&amp;quot;SUCCESS&amp;quot;,{} ;&lt;br /&gt;
        VAR `$ResultTuple`,`$ResultStrings`&lt;br /&gt;
        IN&lt;br /&gt;
            `$ResultTuple` := FORCE({i|i : x &amp;amp; not(i &amp;gt; 5)}) ;&lt;br /&gt;
            `$ResultStrings` := FORCE({`$String`|`$String` : STRING &amp;amp; #i.(i : `$ResultTuple` &amp;amp; `$String` = FORMAT_TO_STRING(&amp;quot;~w &amp;lt;= 5&amp;quot;,[TO_STRING(i)]))});&lt;br /&gt;
              rule2_Counterexamples := rule2_Counterexamples \/ {1} * `$ResultStrings` ;&lt;br /&gt;
          IF `$ResultTuple` /= {} THEN&lt;br /&gt;
              rule2,`$RESULT`,`$COUNTEREXAMPLES` := &amp;quot;FAIL&amp;quot;,&amp;quot;FAIL&amp;quot;,rule2_Counterexamples&lt;br /&gt;
          END&lt;br /&gt;
    END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Observe that the implicit dependency of rule2 on comp1 (rule2 uses its variable x) is detected automatically without explicit declaration.&lt;br /&gt;
&lt;br /&gt;
===Include Rules Machines into other Projects===&lt;br /&gt;
Currently, it is not possible to include rules machines directly into any other machines. Instead, use the rules machine at the top of the hierarchy (of the rules project) and save the internal generated machine as &amp;lt;code&amp;gt;.mch&amp;lt;/code&amp;gt;-file. After changing the machine name accordingly, the rules can be included and used via this machine.&lt;br /&gt;
Note that in this case it is not possible to perform Rules-DSL specific methods of the ProB Java API (like detailed information about rule results).&lt;/div&gt;</summary>
		<author><name>Jan Gruteser</name></author>
	</entry>
</feed>