<?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=Vella</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=Vella"/>
	<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Special:Contributions/Vella"/>
	<updated>2026-05-27T06:46:00Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=ProBLicence&amp;diff=5998</id>
		<title>ProBLicence</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=ProBLicence&amp;diff=5998"/>
		<updated>2025-07-18T13:54:17Z</updated>

		<summary type="html">&lt;p&gt;Vella: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== ProB Licence ==&lt;br /&gt;
&lt;br /&gt;
The ProB source code is distributed under the [http://www.eclipse.org/org/documents/epl-v10.html EPL v1.0 license] (see also [[Getting_Involved|Getting Involved]]).&lt;br /&gt;
&lt;br /&gt;
(C) 2000-2025 Michael Leuschel and many others.&lt;br /&gt;
&lt;br /&gt;
ProB comes with ABSOLUTELY NO WARRANTY OF ANY KIND !&lt;br /&gt;
This software is distributed in the hope that it will be useful&lt;br /&gt;
but WITHOUT ANY WARRANTY. The author(s) do not accept responsibility&lt;br /&gt;
to anyone for the consequences of using it or for whether it serves&lt;br /&gt;
any particular purpose or works at all. No warranty is made about&lt;br /&gt;
the software or its performance.&lt;br /&gt;
&lt;br /&gt;
The ProB binary and source distributions of version 1.15.0 and below contain the nauty library before version 2.6. You cannot use nauty symmetry reduction for applications with nontrivial military&lt;br /&gt;
significance, see https://pallini.di.uniroma1.it/. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For availability of commercial support, please contact [http://stups.hhu.de/w/Prof._Dr._Michael_Leuschel Michael Leuschel] or [http://www.formalmind.com/ Formal Mind].&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Bugs&amp;diff=5981</id>
		<title>Bugs</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Bugs&amp;diff=5981"/>
		<updated>2025-06-18T08:59:59Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Version Information */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: we have migrated our issues to the [https://github.com/hhu-stups/prob-issues/issues prob-issues] GitHub project.&lt;br /&gt;
Use this [https://github.com/hhu-stups/prob-issues/issues/new link to add a new issue].&lt;br /&gt;
&lt;br /&gt;
=== Version Information ===&lt;br /&gt;
Typically it is helpful for us to know as much information as possible about your environment:&lt;br /&gt;
* the operating system you are using (Windows, macOS, Linux) and which version thereof&lt;br /&gt;
* which version of ProB you are using, which can be obtained as follows&lt;br /&gt;
** for probcli you can use the command: &amp;lt;tt&amp;gt;probcli -version -v&amp;lt;/tt&amp;gt;&lt;br /&gt;
** in ProB Tcl/Tk you can use the &amp;quot;About ProB&amp;quot; menu command&lt;br /&gt;
** in ProB2-UI you can use the &amp;quot;About ProB2&amp;quot; menu command, which gives you the version of ProB2 UI, the version of the Java ProB API, the version of probcli, the version of the parser and the Java version. The dialog has a &amp;quot;Copy&amp;quot; button for your convenience.&lt;br /&gt;
* when having issues with visualization and you use a local version of dot/graphviz or plantuml we need that version as well&lt;br /&gt;
&lt;br /&gt;
=== Console Output ===&lt;br /&gt;
For ProB2-UI the following information can also be helpful to us:&lt;br /&gt;
* either the output on the console, if you have started ProB2-UI inside a terminal or a console&lt;br /&gt;
** on Windows, there is a separate Start Menu entry for starting ProB2-UI with a visible console window&lt;br /&gt;
* the contents of the ProB2-UI logfile named &amp;quot;ProB2UI.log&amp;quot; which can be found inside your home directory inside the &amp;quot;.prob&amp;quot; folder&lt;br /&gt;
* alternatively, the contents of the ProB2-UI Prolog console, which is available in the Advanced menu using the &amp;quot;ProB Core Console&amp;quot; command. This contains less information than the full log, but can still be very helpful to diagnose issues.&lt;br /&gt;
&lt;br /&gt;
=== Old Bug Tracker ===&lt;br /&gt;
&lt;br /&gt;
If you want, you can also use our old bug tracker to submit a report&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;a id=&amp;quot;myCustomTrigger&amp;quot;&amp;gt;Jira bug tracker&amp;lt;/a&amp;gt; &lt;br /&gt;
&amp;lt;script&lt;br /&gt;
  src=&amp;quot;https://code.jquery.com/jquery-2.2.4.min.js&amp;quot;&lt;br /&gt;
  integrity=&amp;quot;sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=&amp;quot;&lt;br /&gt;
  crossorigin=&amp;quot;anonymous&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://probjira.atlassian.net/s/d41d8cd98f00b204e9800998ecf8427e-T/-w0bwo4/b/14/a44af77267a987a660377e5c46e0fb64/_/download/batch/com.atlassian.jira.collector.plugin.jira-issue-collector-plugin:issuecollector/com.atlassian.jira.collector.plugin.jira-issue-collector-plugin:issuecollector.js?locale=en-US&amp;amp;collectorId=9e060bbf&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;window.ATL_JQ_PAGE_PROPS =  {&lt;br /&gt;
	&amp;quot;triggerFunction&amp;quot;: function(showCollectorDialog) {&lt;br /&gt;
		//Requires that jQuery is available! &lt;br /&gt;
		jQuery(&amp;quot;#myCustomTrigger&amp;quot;).click(function(e) {&lt;br /&gt;
			e.preventDefault();&lt;br /&gt;
			showCollectorDialog();&lt;br /&gt;
		});&lt;br /&gt;
	}};&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
(in case this link does not work in your browser you can go directly to https://probjira.atlassian.net/secure/Dashboard.jspa)&lt;br /&gt;
You may also want to ask questions within our [https://groups.google.com/d/forum/prob-users prob-users group].&lt;br /&gt;
&lt;br /&gt;
We use a free [http://www.atlassian.com/software/views/open-source-license-request/ Open Source license] from Atlassian!&lt;br /&gt;
&lt;br /&gt;
[[Image:jira.png|200px|]]&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=JSON_and_Sockets&amp;diff=5954</id>
		<title>JSON and Sockets</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=JSON_and_Sockets&amp;diff=5954"/>
		<updated>2025-04-04T12:09:48Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Example Machine */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
ProB contains external functions to read and write JSON data and to communicate via sockets using JSON-RPC:&lt;br /&gt;
&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;
&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) protocol implementation either over regular sockets or ZMQ sockets. &lt;br /&gt;
&lt;br /&gt;
We have used this library to control Crazyflie drones via ProB:&lt;br /&gt;
[[File:prob_drone.jpeg||800px]]&lt;br /&gt;
&lt;br /&gt;
== JSON Library ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;LibraryJSON.mch&amp;lt;/tt&amp;gt; defines a FREETYPE to represent [https://json.org/ JSON] data in a type-safe way:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  JsonValue = JsonNull,&lt;br /&gt;
              JsonBoolean(BOOL),&lt;br /&gt;
              JsonNumber(FLOAT),&lt;br /&gt;
              JsonString(STRING),&lt;br /&gt;
              JsonArray(seq(JsonValue)),&lt;br /&gt;
              JsonObject(STRING +-&amp;gt; JsonValue)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Free Types]] are inductive data types.&lt;br /&gt;
They are not standard B, but stem from Z and Rodin&#039;s theory plug-in.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;JsonValue&amp;lt;/tt&amp;gt; maps quite naturally to the specification of JSON itself.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;LibraryJSON.def&amp;lt;/tt&amp;gt; contains the definitions for the the external functions to interact with JSON text data:&lt;br /&gt;
* &amp;lt;tt&amp;gt;READ_JSON(file)&amp;lt;/tt&amp;gt; &lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;STRING --&amp;gt; JsonValue&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Reads a file path on the disk and parses the contained JSON data into the freetype representation.&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this function does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;READ_JSON_FROM_STRING(contents)&amp;lt;/tt&amp;gt; &lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;STRING --&amp;gt; JsonValue&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Parses the given JSON text into the freetype representation.&lt;br /&gt;
* &amp;lt;tt&amp;gt;WRITE_JSON (json, file)&amp;lt;/tt&amp;gt; &lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;JsonValue * STRING&amp;lt;/tt&amp;gt; (predicate, always returns &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt;)&lt;br /&gt;
** Converts the given JSON data from the freetype representation into text and writes it to the given file path.&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this function does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;WRITE_JSON_TO_STRING(json)&amp;lt;/tt&amp;gt; &lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;JsonValue --&amp;gt; STRING&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Converts the given JSON data from the freetype representation into text.&lt;br /&gt;
&lt;br /&gt;
You need to include &amp;lt;b&amp;gt;both&amp;lt;/b&amp;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; to interact with JSON. One contains the freetype definition, the other one the external function definitions.&lt;br /&gt;
&lt;br /&gt;
== JSON-RPC Library ==&lt;br /&gt;
&lt;br /&gt;
Implements the [http://jsonrpc.org/spec JSON RPC]  protocol.&lt;br /&gt;
&lt;br /&gt;
Despite their names the &amp;lt;tt&amp;gt;LibraryZMQ_RPC&amp;lt;/tt&amp;gt; libraries can use both [https://zeromq.org/ ZeroMQ] library and native sockets.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;LibraryZMQ_RPC.mch&amp;lt;/tt&amp;gt; defines a FREETYPE to represent JSON-RPC response object in a type-safe way:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 RpcResult = RpcSuccess(JsonValue), RpcError(STRING)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;LibraryZMQ_RPC.def&amp;lt;/tt&amp;gt; contains the definitions for the the external functions to interact with JSON RPC as a client or server:&lt;br /&gt;
* &amp;lt;tt&amp;gt;ZMQ_RPC_INIT(endpoint)&amp;lt;/tt&amp;gt; &lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;STRING --&amp;gt; SOCKET&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Creates a ZMQ socket for RPC with the ZMQ library and binds it to the given endpoint.&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this function does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;SOCKET_RPC_INIT(port)&amp;lt;/tt&amp;gt; &lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;INTEGER --&amp;gt; SOCKET&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Creates a native socket for RPC and binds it to the given port.&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this function does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;ZMQ_RPC_DESTROY(socket)&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;SOCKET&amp;lt;/tt&amp;gt; (substitution, no return value)&lt;br /&gt;
** Closes the given ZMQ or native socket.&lt;br /&gt;
** &amp;lt;i&amp;gt;Note: despite its name this function works with both ZMQ and native sockets&amp;lt;/i&amp;gt;&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this substitution does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;ZMQ_RPC_SEND(socket, name, args)&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;(SOCKET*STRING*(STRING+-&amp;gt;JsonValue)) --&amp;gt; RpcResult&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Sends a JSON-RPC request object over the given ZMQ or native socket.&lt;br /&gt;
** &amp;lt;i&amp;gt;Note: despite its name this function works with both ZMQ and native sockets&amp;lt;/i&amp;gt;&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this function does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;SOCKET_RPC_ACCEPT(port)&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;INTEGER --&amp;gt; JsonValue&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Open a native server socket, wait for a client to connect, receive a JSON-RPC request object and return it.&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this function does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;SOCKET_RPC_REPLY(port,rpcresult)&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;(INTEGER * RpcResult) --&amp;gt; BOOL&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Respond to a previously received JSON-RPC request object with the given JSON-RPC response object. Will always return &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
** &amp;lt;i&amp;gt;Note: must be called right after &amp;lt;tt&amp;gt;SOCKET_RPC_ACCEPT&amp;lt;/tt&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this function does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;LibraryZMQ_RPC.def&amp;lt;/tt&amp;gt; will transitively include &amp;lt;tt&amp;gt;LibraryJson.def&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
You need to include &amp;lt;b&amp;gt;all&amp;lt;/b&amp;gt; of &amp;lt;tt&amp;gt;LibraryJson.mch&amp;lt;/tt&amp;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; to interact with JSON-RPC, because the freetype definitions have to be separate from the external function definitions.&lt;br /&gt;
&lt;br /&gt;
== Example Machine ==&lt;br /&gt;
This is an excerpt from the B machine used to communicate with the Crazyflie drone.&lt;br /&gt;
Parallel to this a Python script is running, which implements all the JSON-RPC methods and uses [https://pypi.org/project/cflib/ &amp;lt;tt&amp;gt;cflib&amp;lt;/tt&amp;gt;] to communicate with the drone over radio.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE DroneCommunicator USES LibraryJSON, LibraryZMQ_RPC&lt;br /&gt;
DEFINITIONS&lt;br /&gt;
  &amp;quot;LibraryZMQ_RPC.def&amp;quot;;&lt;br /&gt;
  &amp;quot;LibraryReals.def&amp;quot;;&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == 0;&lt;br /&gt;
CONSTANTS DRONE_URL&lt;br /&gt;
PROPERTIES DRONE_URL:STRING &amp;amp; DRONE_URL = &amp;quot;radio://0/80/2M/5700B500F7&amp;quot;&lt;br /&gt;
VARIABLES init, socket, cycle&lt;br /&gt;
INVARIANT&lt;br /&gt;
  init:BOOL &amp;amp;&lt;br /&gt;
  socket:SOCKET &amp;amp;&lt;br /&gt;
  cycle:INTEGER&lt;br /&gt;
INITIALISATION&lt;br /&gt;
  init := FALSE;&lt;br /&gt;
  socket := 0;&lt;br /&gt;
  cycle := 1&lt;br /&gt;
&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Init = &lt;br /&gt;
  SELECT init = FALSE THEN&lt;br /&gt;
    socket := ZMQ_RPC_INIT(&amp;quot;tcp://localhost:22272&amp;quot;);&lt;br /&gt;
    init := TRUE&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  Destroy =&lt;br /&gt;
  SELECT init = TRUE THEN&lt;br /&gt;
    ZMQ_RPC_DESTROY(socket);&lt;br /&gt;
    init := FALSE&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  register_sensors = &lt;br /&gt;
  SELECT init = TRUE THEN&lt;br /&gt;
    VAR res IN&lt;br /&gt;
      res := RpcSuccess~(ZMQ_RPC_SEND(socket, &amp;quot;register_log&amp;quot;, {&lt;br /&gt;
        (&amp;quot;url&amp;quot; |-&amp;gt; JsonString(DRONE_URL)),&lt;br /&gt;
        (&amp;quot;name&amp;quot; |-&amp;gt; JsonString(&amp;quot;Telemetry&amp;quot;)),&lt;br /&gt;
        (&amp;quot;variables&amp;quot; |-&amp;gt; JsonArray([&lt;br /&gt;
          JsonString(&amp;quot;stateEstimate.x&amp;quot;),&lt;br /&gt;
          JsonString(&amp;quot;stateEstimate.y&amp;quot;),&lt;br /&gt;
          JsonString(&amp;quot;stateEstimate.z&amp;quot;),&lt;br /&gt;
          JsonString(&amp;quot;stateEstimate.roll&amp;quot;),&lt;br /&gt;
          JsonString(&amp;quot;stateEstimate.pitch&amp;quot;),&lt;br /&gt;
          JsonString(&amp;quot;stateEstimate.yaw&amp;quot;)&lt;br /&gt;
        ]))}));&lt;br /&gt;
    END&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  Drone_Takeoff = &lt;br /&gt;
  SELECT init = TRUE THEN&lt;br /&gt;
    VAR res IN&lt;br /&gt;
      res := RpcSuccess~(ZMQ_RPC_SEND(socket, &amp;quot;takeoff&amp;quot;, {(&amp;quot;url&amp;quot; |-&amp;gt; JsonString(DRONE_URL))}))&lt;br /&gt;
    END&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  Drone_Land = &lt;br /&gt;
  SELECT init = TRUE THEN&lt;br /&gt;
    VAR res IN&lt;br /&gt;
      res := RpcSuccess~(ZMQ_RPC_SEND(socket, &amp;quot;land&amp;quot;, {(&amp;quot;url&amp;quot; |-&amp;gt; JsonString(DRONE_URL))}))&lt;br /&gt;
    END&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  Drone_Left(dist) = &lt;br /&gt;
  SELECT&lt;br /&gt;
    init = TRUE &amp;amp;&lt;br /&gt;
    dist : 0..2000&lt;br /&gt;
  THEN&lt;br /&gt;
    VAR res IN&lt;br /&gt;
      res := RpcSuccess~(ZMQ_RPC_SEND(socket, &amp;quot;left&amp;quot;, {(&amp;quot;url&amp;quot; |-&amp;gt; JsonString(DRONE_URL)), (&amp;quot;distance&amp;quot; |-&amp;gt; JsonNumber(RDIV(real(dist), real(1000))))}))&lt;br /&gt;
    END&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  Drone_Right(dist) = &lt;br /&gt;
  SELECT&lt;br /&gt;
    init = TRUE &amp;amp;&lt;br /&gt;
    dist : 0..2000&lt;br /&gt;
  THEN&lt;br /&gt;
    VAR res IN&lt;br /&gt;
      res := RpcSuccess~(ZMQ_RPC_SEND(socket, &amp;quot;right&amp;quot;, {(&amp;quot;url&amp;quot; |-&amp;gt; JsonString(DRONE_URL)), (&amp;quot;distance&amp;quot; |-&amp;gt; JsonNumber(RDIV(real(dist), real(1000))))}))&lt;br /&gt;
    END&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  Drone_Up(dist) = &lt;br /&gt;
  SELECT&lt;br /&gt;
    init = TRUE &amp;amp;&lt;br /&gt;
    dist : 0..2000&lt;br /&gt;
  THEN&lt;br /&gt;
    VAR res IN&lt;br /&gt;
      res := RpcSuccess~(ZMQ_RPC_SEND(socket, &amp;quot;up&amp;quot;, {(&amp;quot;url&amp;quot; |-&amp;gt; JsonString(DRONE_URL)), (&amp;quot;distance&amp;quot; |-&amp;gt; JsonNumber(RDIV(real(dist), real(1000))))}))&lt;br /&gt;
    END&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  Drone_Down(dist) = &lt;br /&gt;
  SELECT&lt;br /&gt;
    init = TRUE &amp;amp;&lt;br /&gt;
    dist : 0..2000&lt;br /&gt;
  THEN&lt;br /&gt;
    VAR res IN&lt;br /&gt;
      res := RpcSuccess~(ZMQ_RPC_SEND(socket, &amp;quot;down&amp;quot;, {(&amp;quot;url&amp;quot; |-&amp;gt; JsonString(DRONE_URL)), (&amp;quot;distance&amp;quot; |-&amp;gt; JsonNumber(RDIV(real(dist), real(1000))))}))&lt;br /&gt;
    END&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  Drone_Forward(dist) = &lt;br /&gt;
  SELECT&lt;br /&gt;
    init = TRUE &amp;amp;&lt;br /&gt;
    dist : 0..2000&lt;br /&gt;
  THEN&lt;br /&gt;
    VAR res IN&lt;br /&gt;
      res := RpcSuccess~(ZMQ_RPC_SEND(socket, &amp;quot;forward&amp;quot;, {(&amp;quot;url&amp;quot; |-&amp;gt; JsonString(DRONE_URL)), (&amp;quot;distance&amp;quot; |-&amp;gt; JsonNumber(RDIV(real(dist), real(1000))))}))&lt;br /&gt;
    END&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  Drone_Backward(dist) = &lt;br /&gt;
  SELECT&lt;br /&gt;
    init = TRUE &amp;amp;&lt;br /&gt;
    dist : 0..2000&lt;br /&gt;
  THEN&lt;br /&gt;
    VAR res IN&lt;br /&gt;
      res := RpcSuccess~(ZMQ_RPC_SEND(socket, &amp;quot;backward&amp;quot;, {(&amp;quot;url&amp;quot; |-&amp;gt; JsonString(DRONE_URL)), (&amp;quot;distance&amp;quot; |-&amp;gt; JsonNumber(RDIV(real(dist), real(1000))))}))&lt;br /&gt;
    END&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  out &amp;lt;-- Drone_GetX = &lt;br /&gt;
  SELECT init = TRUE THEN&lt;br /&gt;
    out := floor(1000.0 * JsonNumber~(RpcSuccess~(ZMQ_RPC_SEND(socket, &amp;quot;get_log_var&amp;quot;, {(&amp;quot;url&amp;quot; |-&amp;gt; JsonString(DRONE_URL)), (&amp;quot;name&amp;quot; |-&amp;gt; JsonString(&amp;quot;stateEstimate.x&amp;quot;))}))));&lt;br /&gt;
    cycle := cycle + 1&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=JSON_and_Sockets&amp;diff=5953</id>
		<title>JSON and Sockets</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=JSON_and_Sockets&amp;diff=5953"/>
		<updated>2025-04-04T12:05:49Z</updated>

		<summary type="html">&lt;p&gt;Vella: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
ProB contains external functions to read and write JSON data and to communicate via sockets using JSON-RPC:&lt;br /&gt;
&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;
&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) protocol implementation either over regular sockets or ZMQ sockets. &lt;br /&gt;
&lt;br /&gt;
We have used this library to control Crazyflie drones via ProB:&lt;br /&gt;
[[File:prob_drone.jpeg||800px]]&lt;br /&gt;
&lt;br /&gt;
== JSON Library ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;LibraryJSON.mch&amp;lt;/tt&amp;gt; defines a FREETYPE to represent [https://json.org/ JSON] data in a type-safe way:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  JsonValue = JsonNull,&lt;br /&gt;
              JsonBoolean(BOOL),&lt;br /&gt;
              JsonNumber(FLOAT),&lt;br /&gt;
              JsonString(STRING),&lt;br /&gt;
              JsonArray(seq(JsonValue)),&lt;br /&gt;
              JsonObject(STRING +-&amp;gt; JsonValue)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Free Types]] are inductive data types.&lt;br /&gt;
They are not standard B, but stem from Z and Rodin&#039;s theory plug-in.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;JsonValue&amp;lt;/tt&amp;gt; maps quite naturally to the specification of JSON itself.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;LibraryJSON.def&amp;lt;/tt&amp;gt; contains the definitions for the the external functions to interact with JSON text data:&lt;br /&gt;
* &amp;lt;tt&amp;gt;READ_JSON(file)&amp;lt;/tt&amp;gt; &lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;STRING --&amp;gt; JsonValue&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Reads a file path on the disk and parses the contained JSON data into the freetype representation.&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this function does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;READ_JSON_FROM_STRING(contents)&amp;lt;/tt&amp;gt; &lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;STRING --&amp;gt; JsonValue&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Parses the given JSON text into the freetype representation.&lt;br /&gt;
* &amp;lt;tt&amp;gt;WRITE_JSON (json, file)&amp;lt;/tt&amp;gt; &lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;JsonValue * STRING&amp;lt;/tt&amp;gt; (predicate, always returns &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt;)&lt;br /&gt;
** Converts the given JSON data from the freetype representation into text and writes it to the given file path.&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this function does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;WRITE_JSON_TO_STRING(json)&amp;lt;/tt&amp;gt; &lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;JsonValue --&amp;gt; STRING&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Converts the given JSON data from the freetype representation into text.&lt;br /&gt;
&lt;br /&gt;
You need to include &amp;lt;b&amp;gt;both&amp;lt;/b&amp;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; to interact with JSON. One contains the freetype definition, the other one the external function definitions.&lt;br /&gt;
&lt;br /&gt;
== JSON-RPC Library ==&lt;br /&gt;
&lt;br /&gt;
Implements the [http://jsonrpc.org/spec JSON RPC]  protocol.&lt;br /&gt;
&lt;br /&gt;
Despite their names the &amp;lt;tt&amp;gt;LibraryZMQ_RPC&amp;lt;/tt&amp;gt; libraries can use both [https://zeromq.org/ ZeroMQ] library and native sockets.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;LibraryZMQ_RPC.mch&amp;lt;/tt&amp;gt; defines a FREETYPE to represent JSON-RPC response object in a type-safe way:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 RpcResult = RpcSuccess(JsonValue), RpcError(STRING)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;LibraryZMQ_RPC.def&amp;lt;/tt&amp;gt; contains the definitions for the the external functions to interact with JSON RPC as a client or server:&lt;br /&gt;
* &amp;lt;tt&amp;gt;ZMQ_RPC_INIT(endpoint)&amp;lt;/tt&amp;gt; &lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;STRING --&amp;gt; SOCKET&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Creates a ZMQ socket for RPC with the ZMQ library and binds it to the given endpoint.&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this function does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;SOCKET_RPC_INIT(port)&amp;lt;/tt&amp;gt; &lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;INTEGER --&amp;gt; SOCKET&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Creates a native socket for RPC and binds it to the given port.&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this function does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;ZMQ_RPC_DESTROY(socket)&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;SOCKET&amp;lt;/tt&amp;gt; (substitution, no return value)&lt;br /&gt;
** Closes the given ZMQ or native socket.&lt;br /&gt;
** &amp;lt;i&amp;gt;Note: despite its name this function works with both ZMQ and native sockets&amp;lt;/i&amp;gt;&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this substitution does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;ZMQ_RPC_SEND(socket, name, args)&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;(SOCKET*STRING*(STRING+-&amp;gt;JsonValue)) --&amp;gt; RpcResult&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Sends a JSON-RPC request object over the given ZMQ or native socket.&lt;br /&gt;
** &amp;lt;i&amp;gt;Note: despite its name this function works with both ZMQ and native sockets&amp;lt;/i&amp;gt;&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this function does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;SOCKET_RPC_ACCEPT(port)&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;INTEGER --&amp;gt; JsonValue&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Open a native server socket, wait for a client to connect, receive a JSON-RPC request object and return it.&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this function does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;SOCKET_RPC_REPLY(port,rpcresult)&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;(INTEGER * RpcResult) --&amp;gt; BOOL&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Respond to a previously received JSON-RPC request object with the given JSON-RPC response object. Will always return &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
** &amp;lt;i&amp;gt;Note: must be called right after &amp;lt;tt&amp;gt;SOCKET_RPC_ACCEPT&amp;lt;/tt&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this function does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;LibraryZMQ_RPC.def&amp;lt;/tt&amp;gt; will transitively include &amp;lt;tt&amp;gt;LibraryJson.def&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
You need to include &amp;lt;b&amp;gt;all&amp;lt;/b&amp;gt; of &amp;lt;tt&amp;gt;LibraryJson.mch&amp;lt;/tt&amp;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; to interact with JSON-RPC, because the freetype definitions have to be separate from the external function definitions.&lt;br /&gt;
&lt;br /&gt;
== Example Machine ==&lt;br /&gt;
This is an excerpt from the B machine used to communicate with the Crazyflie drone.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MACHINE DroneCommunicator USES LibraryJSON, LibraryZMQ_RPC&lt;br /&gt;
DEFINITIONS&lt;br /&gt;
  &amp;quot;LibraryZMQ_RPC.def&amp;quot;;&lt;br /&gt;
  &amp;quot;LibraryReals.def&amp;quot;;&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == 0;&lt;br /&gt;
CONSTANTS DRONE_URL&lt;br /&gt;
PROPERTIES DRONE_URL:STRING &amp;amp; DRONE_URL = &amp;quot;radio://0/80/2M/5700B500F7&amp;quot;&lt;br /&gt;
VARIABLES init, socket, cycle&lt;br /&gt;
INVARIANT&lt;br /&gt;
  init:BOOL &amp;amp;&lt;br /&gt;
  socket:SOCKET &amp;amp;&lt;br /&gt;
  cycle:INTEGER&lt;br /&gt;
INITIALISATION&lt;br /&gt;
  init := FALSE;&lt;br /&gt;
  socket := 0;&lt;br /&gt;
  cycle := 1&lt;br /&gt;
&lt;br /&gt;
OPERATIONS&lt;br /&gt;
  Init = &lt;br /&gt;
  SELECT init = FALSE THEN&lt;br /&gt;
    socket := ZMQ_RPC_INIT(&amp;quot;tcp://localhost:22272&amp;quot;);&lt;br /&gt;
    init := TRUE&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  Destroy =&lt;br /&gt;
  SELECT init = TRUE THEN&lt;br /&gt;
    ZMQ_RPC_DESTROY(socket);&lt;br /&gt;
    init := FALSE&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  register_sensors = &lt;br /&gt;
  SELECT init = TRUE THEN&lt;br /&gt;
    VAR res IN&lt;br /&gt;
      res := RpcSuccess~(ZMQ_RPC_SEND(socket, &amp;quot;register_log&amp;quot;, {&lt;br /&gt;
        (&amp;quot;url&amp;quot; |-&amp;gt; JsonString(DRONE_URL)),&lt;br /&gt;
        (&amp;quot;name&amp;quot; |-&amp;gt; JsonString(&amp;quot;Telemetry&amp;quot;)),&lt;br /&gt;
        (&amp;quot;variables&amp;quot; |-&amp;gt; JsonArray([&lt;br /&gt;
          JsonString(&amp;quot;stateEstimate.x&amp;quot;),&lt;br /&gt;
          JsonString(&amp;quot;stateEstimate.y&amp;quot;),&lt;br /&gt;
          JsonString(&amp;quot;stateEstimate.z&amp;quot;),&lt;br /&gt;
          JsonString(&amp;quot;stateEstimate.roll&amp;quot;),&lt;br /&gt;
          JsonString(&amp;quot;stateEstimate.pitch&amp;quot;),&lt;br /&gt;
          JsonString(&amp;quot;stateEstimate.yaw&amp;quot;)&lt;br /&gt;
        ]))}));&lt;br /&gt;
    END&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  Drone_Takeoff = &lt;br /&gt;
  SELECT init = TRUE THEN&lt;br /&gt;
    VAR res IN&lt;br /&gt;
      res := RpcSuccess~(ZMQ_RPC_SEND(socket, &amp;quot;takeoff&amp;quot;, {(&amp;quot;url&amp;quot; |-&amp;gt; JsonString(DRONE_URL))}))&lt;br /&gt;
    END&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  Drone_Land = &lt;br /&gt;
  SELECT init = TRUE THEN&lt;br /&gt;
    VAR res IN&lt;br /&gt;
      res := RpcSuccess~(ZMQ_RPC_SEND(socket, &amp;quot;land&amp;quot;, {(&amp;quot;url&amp;quot; |-&amp;gt; JsonString(DRONE_URL))}))&lt;br /&gt;
    END&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  Drone_Left(dist) = &lt;br /&gt;
  SELECT&lt;br /&gt;
    init = TRUE &amp;amp;&lt;br /&gt;
    dist : 0..2000&lt;br /&gt;
  THEN&lt;br /&gt;
    VAR res IN&lt;br /&gt;
      res := RpcSuccess~(ZMQ_RPC_SEND(socket, &amp;quot;left&amp;quot;, {(&amp;quot;url&amp;quot; |-&amp;gt; JsonString(DRONE_URL)), (&amp;quot;distance&amp;quot; |-&amp;gt; JsonNumber(RDIV(real(dist), real(1000))))}))&lt;br /&gt;
    END&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  Drone_Right(dist) = &lt;br /&gt;
  SELECT&lt;br /&gt;
    init = TRUE &amp;amp;&lt;br /&gt;
    dist : 0..2000&lt;br /&gt;
  THEN&lt;br /&gt;
    VAR res IN&lt;br /&gt;
      res := RpcSuccess~(ZMQ_RPC_SEND(socket, &amp;quot;right&amp;quot;, {(&amp;quot;url&amp;quot; |-&amp;gt; JsonString(DRONE_URL)), (&amp;quot;distance&amp;quot; |-&amp;gt; JsonNumber(RDIV(real(dist), real(1000))))}))&lt;br /&gt;
    END&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  Drone_Up(dist) = &lt;br /&gt;
  SELECT&lt;br /&gt;
    init = TRUE &amp;amp;&lt;br /&gt;
    dist : 0..2000&lt;br /&gt;
  THEN&lt;br /&gt;
    VAR res IN&lt;br /&gt;
      res := RpcSuccess~(ZMQ_RPC_SEND(socket, &amp;quot;up&amp;quot;, {(&amp;quot;url&amp;quot; |-&amp;gt; JsonString(DRONE_URL)), (&amp;quot;distance&amp;quot; |-&amp;gt; JsonNumber(RDIV(real(dist), real(1000))))}))&lt;br /&gt;
    END&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  Drone_Down(dist) = &lt;br /&gt;
  SELECT&lt;br /&gt;
    init = TRUE &amp;amp;&lt;br /&gt;
    dist : 0..2000&lt;br /&gt;
  THEN&lt;br /&gt;
    VAR res IN&lt;br /&gt;
      res := RpcSuccess~(ZMQ_RPC_SEND(socket, &amp;quot;down&amp;quot;, {(&amp;quot;url&amp;quot; |-&amp;gt; JsonString(DRONE_URL)), (&amp;quot;distance&amp;quot; |-&amp;gt; JsonNumber(RDIV(real(dist), real(1000))))}))&lt;br /&gt;
    END&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  Drone_Forward(dist) = &lt;br /&gt;
  SELECT&lt;br /&gt;
    init = TRUE &amp;amp;&lt;br /&gt;
    dist : 0..2000&lt;br /&gt;
  THEN&lt;br /&gt;
    VAR res IN&lt;br /&gt;
      res := RpcSuccess~(ZMQ_RPC_SEND(socket, &amp;quot;forward&amp;quot;, {(&amp;quot;url&amp;quot; |-&amp;gt; JsonString(DRONE_URL)), (&amp;quot;distance&amp;quot; |-&amp;gt; JsonNumber(RDIV(real(dist), real(1000))))}))&lt;br /&gt;
    END&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  Drone_Backward(dist) = &lt;br /&gt;
  SELECT&lt;br /&gt;
    init = TRUE &amp;amp;&lt;br /&gt;
    dist : 0..2000&lt;br /&gt;
  THEN&lt;br /&gt;
    VAR res IN&lt;br /&gt;
      res := RpcSuccess~(ZMQ_RPC_SEND(socket, &amp;quot;backward&amp;quot;, {(&amp;quot;url&amp;quot; |-&amp;gt; JsonString(DRONE_URL)), (&amp;quot;distance&amp;quot; |-&amp;gt; JsonNumber(RDIV(real(dist), real(1000))))}))&lt;br /&gt;
    END&lt;br /&gt;
  END;&lt;br /&gt;
&lt;br /&gt;
  out &amp;lt;-- Drone_GetX = &lt;br /&gt;
  SELECT init = TRUE THEN&lt;br /&gt;
    out := floor(1000.0 * JsonNumber~(RpcSuccess~(ZMQ_RPC_SEND(socket, &amp;quot;get_log_var&amp;quot;, {(&amp;quot;url&amp;quot; |-&amp;gt; JsonString(DRONE_URL)), (&amp;quot;name&amp;quot; |-&amp;gt; JsonString(&amp;quot;stateEstimate.x&amp;quot;))}))));&lt;br /&gt;
    cycle := cycle + 1&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=JSON_and_Sockets&amp;diff=5952</id>
		<title>JSON and Sockets</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=JSON_and_Sockets&amp;diff=5952"/>
		<updated>2025-04-04T11:48:54Z</updated>

		<summary type="html">&lt;p&gt;Vella: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
ProB contains external functions to read and write JSON data and to communicate via sockets using JSON-RPC:&lt;br /&gt;
&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;
&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) protocol implementation either over regular sockets or ZMQ sockets. &lt;br /&gt;
&lt;br /&gt;
We have used this library to control Crazyflie drones via ProB:&lt;br /&gt;
[[File:prob_drone.jpeg||800px]]&lt;br /&gt;
&lt;br /&gt;
== JSON Library ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;LibraryJSON.mch&amp;lt;/tt&amp;gt; defines a FREETYPE to represent [https://json.org/ JSON] data in a type-safe way:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  JsonValue = JsonNull,&lt;br /&gt;
              JsonBoolean(BOOL),&lt;br /&gt;
              JsonNumber(FLOAT),&lt;br /&gt;
              JsonString(STRING),&lt;br /&gt;
              JsonArray(seq(JsonValue)),&lt;br /&gt;
              JsonObject(STRING +-&amp;gt; JsonValue)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Free Types]] are inductive data types.&lt;br /&gt;
They are not standard B, but stem from Z and Rodin&#039;s theory plug-in.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;JsonValue&amp;lt;/tt&amp;gt; maps quite naturally to the specification of JSON itself.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;LibraryJSON.def&amp;lt;/tt&amp;gt; contains the definitions for the the external functions to interact with JSON text data:&lt;br /&gt;
* &amp;lt;tt&amp;gt;READ_JSON(file)&amp;lt;/tt&amp;gt; &lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;STRING --&amp;gt; JsonValue&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Reads a file path on the disk and parses the contained JSON data into the freetype representation.&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this function does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;READ_JSON_FROM_STRING(contents)&amp;lt;/tt&amp;gt; &lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;STRING --&amp;gt; JsonValue&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Parses the given JSON text into the freetype representation.&lt;br /&gt;
* &amp;lt;tt&amp;gt;WRITE_JSON (json, file)&amp;lt;/tt&amp;gt; &lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;JsonValue * STRING&amp;lt;/tt&amp;gt; (predicate, always returns &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt;)&lt;br /&gt;
** Converts the given JSON data from the freetype representation into text and writes it to the given file path.&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this function does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;WRITE_JSON_TO_STRING(json)&amp;lt;/tt&amp;gt; &lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;JsonValue --&amp;gt; STRING&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Converts the given JSON data from the freetype representation into text.&lt;br /&gt;
&lt;br /&gt;
You need to include &amp;lt;b&amp;gt;both&amp;lt;/b&amp;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; to interact with JSON. One contains the freetype definition, the other one the external function definitions.&lt;br /&gt;
&lt;br /&gt;
== JSON-RPC Library ==&lt;br /&gt;
&lt;br /&gt;
Implements the [http://jsonrpc.org/spec JSON RPC]  protocol.&lt;br /&gt;
&lt;br /&gt;
Despite their names the &amp;lt;tt&amp;gt;LibraryZMQ_RPC&amp;lt;/tt&amp;gt; libraries can use both [https://zeromq.org/ ZeroMQ] library and native sockets.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;LibraryZMQ_RPC.mch&amp;lt;/tt&amp;gt; defines a FREETYPE to represent JSON-RPC response object in a type-safe way:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 RpcResult = RpcSuccess(JsonValue), RpcError(STRING)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;LibraryZMQ_RPC.def&amp;lt;/tt&amp;gt; contains the definitions for the the external functions to interact with JSON RPC as a client or server:&lt;br /&gt;
* &amp;lt;tt&amp;gt;ZMQ_RPC_INIT(endpoint)&amp;lt;/tt&amp;gt; &lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;STRING --&amp;gt; SOCKET&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Creates a ZMQ socket for RPC with the ZMQ library and binds it to the given endpoint.&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this function does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;SOCKET_RPC_INIT(port)&amp;lt;/tt&amp;gt; &lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;INTEGER --&amp;gt; SOCKET&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Creates a native socket for RPC and binds it to the given port.&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this function does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;ZMQ_RPC_DESTROY(socket)&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;SOCKET&amp;lt;/tt&amp;gt; (substitution, no return value)&lt;br /&gt;
** Closes the given ZMQ or native socket.&lt;br /&gt;
** &amp;lt;i&amp;gt;Note: despite its name this function works with both ZMQ and native sockets&amp;lt;/i&amp;gt;&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this substitution does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;ZMQ_RPC_SEND(socket, name, args)&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;(SOCKET*STRING*(STRING+-&amp;gt;JsonValue)) --&amp;gt; RpcResult&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Sends a JSON-RPC request object over the given ZMQ or native socket.&lt;br /&gt;
** &amp;lt;i&amp;gt;Note: despite its name this function works with both ZMQ and native sockets&amp;lt;/i&amp;gt;&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this function does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;SOCKET_RPC_ACCEPT(port)&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;INTEGER --&amp;gt; JsonValue&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Open a native server socket, wait for a client to connect, receive a JSON-RPC request object and return it.&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this function does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;SOCKET_RPC_REPLY(port,rpcresult)&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Type Signature: &amp;lt;tt&amp;gt;(INTEGER * RpcResult) --&amp;gt; BOOL&amp;lt;/tt&amp;gt;&lt;br /&gt;
** Respond to a previously received JSON-RPC request object with the given JSON-RPC response object. Will always return &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
** &amp;lt;i&amp;gt;Note: must be called right after &amp;lt;tt&amp;gt;SOCKET_RPC_ACCEPT&amp;lt;/tt&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
** &amp;lt;i&amp;gt;Warning: this function does external IO and should be guarded by a &amp;lt;tt&amp;gt;MAX_OPERATIONS == 0&amp;lt;/tt&amp;gt; definition&amp;lt;/i&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;LibraryZMQ_RPC.def&amp;lt;/tt&amp;gt; will transitively include &amp;lt;tt&amp;gt;LibraryJson.def&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
You need to include &amp;lt;b&amp;gt;all&amp;lt;/b&amp;gt; of &amp;lt;tt&amp;gt;LibraryJson.mch&amp;lt;/tt&amp;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; to interact with JSON-RPC, because the freetype definitions have to be separate from the external function definitions.&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=SimB&amp;diff=5896</id>
		<title>SimB</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=SimB&amp;diff=5896"/>
		<updated>2025-02-19T18:46:19Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Direct Activation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== SimB ==&lt;br /&gt;
&lt;br /&gt;
Additional documentation is available here: [https://github.com/hhu-stups/prob2_ui/blob/develop/src/main/helpsources/help_en/Main%20Menu/Advanced/SimB.md SimB Documentation]&lt;br /&gt;
&lt;br /&gt;
SimB is a simulator built on top of ProB.  It is available in the latest SNAPSHOT version in the new JavaFX based user interface [[ProB2-UI]] (https://github.com/hhu-stups/prob2_ui), The modeler can write SimB annotations for a formal model to simulate it. Examples are available at https://github.com/favu100/SimB-examples.&lt;br /&gt;
Furthermore, it is then possible to validate probabilistic and timing properties with statistical validation techniques such as hypothesis testing and estimation.&lt;br /&gt;
&lt;br /&gt;
SimB also contains a feature called interactive simulation.&lt;br /&gt;
This feature allows user interaction to trigger a simulation.&lt;br /&gt;
For interactive simulation, a modeler has to encode SimB listeners on events, triggering a SimB simulation.&lt;br /&gt;
Interactive Simulation examples are available at https://github.com/favu100/SimB-examples/tree/main/Interactive_Examples.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
More recently, SimB is extended by a new feature which makes it possible to load an Reinforcement learning Agent.&lt;br /&gt;
Technically, each step of the RL agent is converted into a SimB activation.&lt;br /&gt;
In order to simulate a RL agent in SimB, one must (1) create a formal B model for the RL agent, and (2) create a mapping between the state in the RL agent and the formal model, and (3) provide information to the formal B model again.&lt;br /&gt;
Reinforcement Learning examples are available at: https://github.com/hhu-stups/reinforcement-learning-b-models&lt;br /&gt;
&lt;br /&gt;
== Citing SimB ==&lt;br /&gt;
To cite SimB as a tool, its timing or probabilistic simulation features, or SimBs statistical validation techniques, please use:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@InProceedings{simb,&lt;br /&gt;
  Author    = {Vu, Fabian and Leuschel, Michael and Mashkoor, Atif},&lt;br /&gt;
  Title        = {{Validation of Formal Models by Timed Probabilistic Simulation}},&lt;br /&gt;
  Booktitle    = {Proceedings ABZ},&lt;br /&gt;
  Year        = 2021,&lt;br /&gt;
  Series    = {LNCS},&lt;br /&gt;
  Volume     = {12709},&lt;br /&gt;
  Pages = {81--96}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To cite SimBs interactive simulation, please use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@InProceedings{simb,&lt;br /&gt;
  Author    = {Vu, Fabian and Leuschel, Michael},&lt;br /&gt;
  Title        = {{Validation of Formal Models by Interactive Simulation}},&lt;br /&gt;
  Booktitle    = {Proceedings ABZ},&lt;br /&gt;
  Year        = 2023&lt;br /&gt;
  Series = {LNCS},&lt;br /&gt;
  Volume = {14010},&lt;br /&gt;
  Pages = {59--69}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using SimB ==&lt;br /&gt;
&lt;br /&gt;
Start SimB via &amp;quot;SimB&amp;quot; in the &amp;quot;Advanced&amp;quot; Menu after opening a machine. &lt;br /&gt;
&lt;br /&gt;
[[File:Open_SimB.png|800px]]&lt;br /&gt;
&lt;br /&gt;
Now, you can open a SimB file (JSON format)  controlling the underlying formal model.&lt;br /&gt;
&lt;br /&gt;
[[File:SimB_Window.png|800px]]&lt;br /&gt;
&lt;br /&gt;
A SimB file consists of SimB activations and SimB listeners to simulate the model.&lt;br /&gt;
SimB activations encode an activation diagram with probabilistic and timing elements for automatic simulation.&lt;br /&gt;
To enable interactive simulation, it is also necessary to encode interactive elements aka. SimB listeners which trigger other SimB activations.&lt;br /&gt;
Within these elements, the modeler can user B expressions which are evaluated on the current state.&lt;br /&gt;
&lt;br /&gt;
The general structure of a SimB simulation is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;activations&amp;quot;: [...]&lt;br /&gt;
  &amp;quot;listeners&amp;quot;: [...]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;activations&amp;lt;/tt&amp;gt; stores SimB activations, while &amp;lt;tt&amp;gt;listeners&amp;lt;/tt&amp;gt; stores SimB listeners.&lt;br /&gt;
&amp;lt;tt&amp;gt;activations&amp;lt;/tt&amp;gt; must be encoded,  &amp;lt;tt&amp;gt;listeners&amp;lt;/tt&amp;gt; is optional and defaults to the empty list.&lt;br /&gt;
&lt;br /&gt;
== Probabilistic and Timing Elements in SimB ==&lt;br /&gt;
&lt;br /&gt;
The SimB file always contains an &amp;lt;tt&amp;gt;activations&amp;lt;/tt&amp;gt; field storing a list of probabilistic and timing elements to control the simulation. Probabilistic values are always interpreted as weights and thus may sum to any number greater than zero.&lt;br /&gt;
There are two types of activations: direct activation and probabilistic choice.&lt;br /&gt;
All activations are identified by their  &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
===Direct Activation ===&lt;br /&gt;
&lt;br /&gt;
A direct activation activates an event to be executed in the future.&lt;br /&gt;
It requires the fields &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt; to be defined.&lt;br /&gt;
All other fields can be defined optionally.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt; identifies the activated event by its name.&lt;br /&gt;
* &amp;lt;tt&amp;gt;after&amp;lt;/tt&amp;gt; defines the scheduled time (in ms) when activating an event. By default, it is set to 0 ms, e.g., when this field is not defined explicitly.&lt;br /&gt;
* &amp;lt;tt&amp;gt;activating&amp;lt;/tt&amp;gt; stores events that will be activated when executing the event defined by &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;. Missing definition leads to the behavior that no other events are activated. The modeler can either write a String (to activate a single event) or a list of Strings (to activate multiple events)&lt;br /&gt;
* &amp;lt;tt&amp;gt;activationKind&amp;lt;/tt&amp;gt; stores the kind of activation for &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;. Possible options are &amp;lt;tt&amp;gt;multi&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;single&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;single:min&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;single:max&amp;lt;/tt&amp;gt;. The default value is &amp;lt;tt&amp;gt;multi&amp;lt;/tt&amp;gt;&lt;br /&gt;
** &amp;lt;tt&amp;gt;multi&amp;lt;/tt&amp;gt; means that the activation will be queued for execution. &lt;br /&gt;
** &amp;lt;tt&amp;gt;single&amp;lt;/tt&amp;gt; means that the activation will only be queued if there are no queued activations with the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;&lt;br /&gt;
** &amp;lt;tt&amp;gt;single:min&amp;lt;/tt&amp;gt; means that the activation will only be queued if (1) there are no queued activations for the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; or (2) there is a queued activation with the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; whose value for the scheduled time is greater. In the case of (2), the already queued activation will be discarded.&lt;br /&gt;
** &amp;lt;tt&amp;gt;single:max&amp;lt;/tt&amp;gt; means that the activation will only be queued if (1) there are no queued activations for the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; or (2) there is a queued activation with the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; whose value for the scheduled time is lower. In the case of (2), the already queued activation will be discarded.&lt;br /&gt;
* &amp;lt;tt&amp;gt;additionalGuards&amp;lt;/tt&amp;gt; stores optional guards when executing the event stored in &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;fixedVariables&amp;lt;/tt&amp;gt; stores a Map. Here, a variable (parameter, or non-deterministic assigned variable) is assigned to its value.&lt;br /&gt;
* &amp;lt;tt&amp;gt;probabilisticVariables&amp;lt;/tt&amp;gt;stores a Map. Here a variable (parameter, or non-deterministic assigned variable) is assigned to another Map defining the probabilistic choice of its value. The second Map stores Key-Value pairs where values are mapped to the probability/weight. &lt;br /&gt;
* &amp;lt;tt&amp;gt;transitionSelection&amp;lt;/tt&amp;gt; determines how SimB choses from multiple possible transitions (due to not specified variables):&lt;br /&gt;
** &amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; (the default) means that the first transition is chosen for execution.&lt;br /&gt;
** &amp;lt;tt&amp;gt;uniform&amp;lt;/tt&amp;gt; means that a transition is selected from all alternatives uniformly.&lt;br /&gt;
* &amp;lt;tt&amp;gt;priority&amp;lt;/tt&amp;gt; stores the priority for scheduling &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;. Lower number means greater priority.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;id&amp;quot;:  ...&lt;br /&gt;
   &amp;quot;execute&amp;quot;: ...&lt;br /&gt;
   &amp;quot;after&amp;quot;: ...&lt;br /&gt;
   &amp;quot;activating&amp;quot;: ...&lt;br /&gt;
   &amp;quot;activationKind&amp;quot;: ...&lt;br /&gt;
   &amp;quot;additionalGuards&amp;quot;: ...&lt;br /&gt;
   &amp;quot;fixedVariables&amp;quot;: ....&lt;br /&gt;
   &amp;quot;probabilisticVariables&amp;quot;: ....&lt;br /&gt;
   &amp;quot;transitionSelection&amp;quot;: ...,&lt;br /&gt;
   &amp;quot;priority&amp;quot;: ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Probabilistic Choice ===&lt;br /&gt;
&lt;br /&gt;
A probabilistic choice selects an event to be executed in the future.&lt;br /&gt;
It requires the two fields &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;chooseActivation&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;chooseActivation&amp;lt;/tt&amp;gt; is a Map storing Key-Value pairs where activations (identified by their &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;) are mapped to a probability/weight.  It is possible to chain multiple probabilistic choices together, but eventually, a direct activation must be reached.&lt;br /&gt;
The probabilities are always interpreted as weights and may sum to any number greater than zero.&lt;br /&gt;
Thus, a &amp;lt;tt&amp;gt;probabilistic choice&amp;lt;/tt&amp;gt; is of the following form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;id&amp;quot;:  ...&lt;br /&gt;
   &amp;quot;chooseActivation&amp;quot;: ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the following, an example for a SimB file controlling a Traffic Lights for cars and pedestrians (with timing and probabilistic behavior) is shown:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;activations&amp;quot;: [&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;$initialise_machine&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;$initialise_machine&amp;quot;, &amp;quot;activating&amp;quot;:&amp;quot;choose&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;choose&amp;quot;, &amp;quot;chooseActivation&amp;quot;:{&amp;quot;cars_ry&amp;quot;: &amp;quot;0.8&amp;quot;, &amp;quot;peds_g&amp;quot;: &amp;quot;0.2&amp;quot;}},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_ry&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_ry&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;cars_g&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_g&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_g&amp;quot;, &amp;quot;after&amp;quot;:500, &amp;quot;activating&amp;quot;:&amp;quot;cars_y&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_y&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_y&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;cars_r&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_r&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_r&amp;quot;, &amp;quot;after&amp;quot;:500, &amp;quot;activating&amp;quot;:&amp;quot;choose&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;peds_g&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;peds_g&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;peds_r&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;peds_r&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;peds_r&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;choose&amp;quot;}&lt;br /&gt;
 ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interactive Elements in SimB ==&lt;br /&gt;
&lt;br /&gt;
Interactive elements in SimB are so called SimB listeners.&lt;br /&gt;
A SimB listener consists of four fields &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;activating&amp;lt;/tt&amp;gt;.&lt;br /&gt;
This means that the SimB listener associated with &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; listens on a manual/user interaction on &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; with &amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt; after which activations in &amp;lt;tt&amp;gt;activating&amp;lt;/tt&amp;gt; are triggered.&lt;br /&gt;
&amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt; is optional and defaults to &amp;lt;tt&amp;gt;1=1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Manual/User interaction is recognized via VisB and ProB&#039;s Operations View.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;id&amp;quot;:  ...&lt;br /&gt;
   &amp;quot;event&amp;quot;: ...&lt;br /&gt;
   &amp;quot;predicate&amp;quot;: ...&lt;br /&gt;
   &amp;quot;activating&amp;quot;: [...]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the following, we parts of a SimB simulation from an automotive case study.&lt;br /&gt;
The SimB simulation contains a SimB listener which is linked to two activations.&lt;br /&gt;
The case study models the car&#039;s lighting system controlled by pitman controller, the key ignition, and the warning lights button.&lt;br /&gt;
&lt;br /&gt;
The SimB listeners states that SimB listens on user interaction on the event &amp;lt;tt&amp;gt;ENV_Pitman_DirectionBlinking&amp;lt;/tt&amp;gt;, to trigger two SimB activations &amp;lt;tt&amp;gt;blinking_on&amp;lt;/tt&amp;gt; and blinking_off afterward.&lt;br /&gt;
Practically, this means that a driver&#039;s input on the pitman for direction blinking activates the blinking cycle for the corresponding direction indicators.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;activations&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;blinking_on&amp;quot;, &lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;RTIME_BlinkerOn&amp;quot;, &lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;curDeadlines(blink_deadline)&amp;quot;,&lt;br /&gt;
       &amp;quot;activating&amp;quot; : &amp;quot;blinking_off&amp;quot;, &lt;br /&gt;
       ...&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;blinking_off&amp;quot;, &lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;RTIME_BlinkerOff&amp;quot;, &lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;curDeadlines(blink_deadline)&amp;quot;,&lt;br /&gt;
       &amp;quot;activating&amp;quot; : &amp;quot;blinking_on&amp;quot;, &lt;br /&gt;
       ...&lt;br /&gt;
    },&lt;br /&gt;
    ...&lt;br /&gt;
  ]&lt;br /&gt;
  &amp;quot;listeners&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;start_blinking&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;: &amp;quot;ENV_Pitman_DirectionBlinking&amp;quot;, &lt;br /&gt;
      &amp;quot;activating&amp;quot; : [&amp;quot;blinking_on&amp;quot;, &amp;quot;blinking_off&amp;quot;]&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Reinforcement Learning Agent in SimB ==&lt;br /&gt;
&lt;br /&gt;
Instead of loading a SimB simulation as a JSON file, one can also load a Reinforcement Learning &lt;br /&gt;
agent implemented in Python (.py).&lt;br /&gt;
For the simulation to work, one has to apply the following steps:&lt;br /&gt;
&lt;br /&gt;
1. Train a model of a Reinforcement Learning agent.&lt;br /&gt;
&lt;br /&gt;
2. Create a formal B model (including safety shield) for the RL agent. &lt;br /&gt;
&lt;br /&gt;
The operations represent the actions the RL agent can choose from. The formal model&#039;s state mainly represents the state of the environment.&lt;br /&gt;
Safety shields are encoded by the operations&#039; guards which are provided to the RL agent. Enabled operations are considered to be safe. Thus, the RL agent chooses the enabled operation/action with the highest predicted reward.&lt;br /&gt;
The operations&#039; substitutions model the desired behavior of the respective actions.&lt;br /&gt;
&lt;br /&gt;
An example for the FASTER of a HighwayEnvironment is as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FASTER = &lt;br /&gt;
PRE&lt;br /&gt;
  ¬(∃v. (v ∈ PresentVehicles \ {EgoVehicle} ∧ VehiclesX(v) &amp;gt; 0.0 ∧ VehiclesX(v) &amp;lt; 45.0 ∧ &lt;br /&gt;
  VehiclesY(v) &amp;lt; 3.5 ∧ VehiclesY(v) &amp;gt; -3.5))&lt;br /&gt;
THEN&lt;br /&gt;
  Crash :∈ BOOL ||&lt;br /&gt;
  PresentVehicles :∈ P(Vehicles) ;&lt;br /&gt;
  VehiclesX :∈ Vehicles → R ||&lt;br /&gt;
  VehiclesY :∈ Vehicles → R ||&lt;br /&gt;
  VehiclesVx :| (VehiclesVx ∈ PresentVehicles → R ∧ &lt;br /&gt;
             VehiclesVx(EgoVehicle) ≥ VehiclesVx’(EgoVehicle) - 0.05) ||&lt;br /&gt;
  VehiclesVy :∈ Vehicles → R ||&lt;br /&gt;
  VehiclesAx :| (VehiclesAx ∈ PresentVehicles → R ∧ VehiclesAx(EgoVehicle) ≥ -0.05) || &lt;br /&gt;
  VehiclesAy :∈ Vehicles → R ||&lt;br /&gt;
  Reward :∈ R&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lines 2-4 shows the operation&#039;s guard which is used as safety shield. &lt;br /&gt;
&lt;br /&gt;
Lines 6-15 shows the operation&#039;s substitution describing the desired behavior after executing FASTER.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3. Implement the mapping between the RL agent in Python and the formal B model.&lt;br /&gt;
This includes the mapping of actions to operations, and the mapping of information from the RL agent, particularly the environment and observation, to the variables.&lt;br /&gt;
&lt;br /&gt;
An example for the mapping of actions to operations is as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
action_names = {&lt;br /&gt;
    0: &amp;quot;LANE_LEFT&amp;quot;,&lt;br /&gt;
    1: &amp;quot;IDLE&amp;quot;,&lt;br /&gt;
    2: &amp;quot;LANE_RIGHT&amp;quot;,&lt;br /&gt;
    3: &amp;quot;FASTER&amp;quot;,&lt;br /&gt;
    4: &amp;quot;SLOWER&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, one can see that the numbers representing the actions in the RL agents are mapped to the corresponding operation names in the formal B model.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An example for a mapping to a variable in the formal B model is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def get_VehiclesX(obs):&lt;br /&gt;
    return &amp;quot;{{EgoVehicle |-&amp;gt; {0}, Vehicles2 |-&amp;gt; {1}, Vehicles3 |-&amp;gt; {2}, &lt;br /&gt;
             Vehicles4 |-&amp;gt; {3},  Vehicles5 |-&amp;gt; {4}}}&amp;quot;&lt;br /&gt;
         .format(obs[0][1]*200, obs[1][1]*200, obs[2][1]*200, &lt;br /&gt;
                  obs[3][1]*200, obs[4][1]*200) # Implemented manually&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remark: While the getter for the variable is generated by B2Program, the function for the mapping is implemented manually.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4. Implement necessary messages sent between the ProB animator and the RL agent.&lt;br /&gt;
Simulation should be a while-loop which runs while the simulation has not finished. &lt;br /&gt;
&lt;br /&gt;
* 1st message: Sent from ProB Animator: List of enabled operations&lt;br /&gt;
** Meanwhile RL agent predicts enabled operation with highest reward&lt;br /&gt;
* 2nd message: Sent from RL agent: Name of chosen action/operation&lt;br /&gt;
* 3rd message: Sent from RL agent: Time until executing chosen action/operation&lt;br /&gt;
* 4th message: Sent from RL agent: Succeeding B state as a predicate&lt;br /&gt;
* 5th message: Sent from RL agent: Boolean flag describing whether simulation is finished&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example code (line 70 - 113; particularly 86 - 113): https://github.com/hhu-stups/reinforcement-learning-b-models/blob/main/HighwayEnvironment/HighwayEnvironment.py&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To generate a RL agent for SimB, one can use the high-level code generator B2Program: https://github.com/favu100/b2program&lt;br /&gt;
&lt;br /&gt;
Given a formal B model, B2Program generates an RL agent which loads a given trained model and execute the necessary steps. This includes the fourth step described before.&lt;br /&gt;
The third step still has to be implemented; in this step, B2Program only generates the templates for the mappings which are then completed manually.&lt;br /&gt;
&lt;br /&gt;
== Validation ==&lt;br /&gt;
&lt;br /&gt;
=== Real-Time Simulation ===&lt;br /&gt;
&lt;br /&gt;
Using a SimB file, the modeler can play a single simulation on the underlying model in real-time. &lt;br /&gt;
The modeler can then manually check whether the model behaves as desired. Combining [[VisB]] and SimB, a simulation can be seen as an animated picture similar to a GIF picture.  &lt;br /&gt;
This gives the domain expert even a better understanding of the model.&lt;br /&gt;
With SimB listeners, it is also possible to encode simulations that are triggered by manual/user actions.&lt;br /&gt;
&lt;br /&gt;
A Traffic Light example (based on the SimB file shown in [[SimB|Using_SimB]] ) simulating the first 21 seconds is shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:TrafficLight_Simulation.gif|800px]]&lt;br /&gt;
&lt;br /&gt;
=== Timed Trace Replay ===&lt;br /&gt;
&lt;br /&gt;
Based on a single simulation, the modeler can generate a timed trace which is also stored in the SimB format. Afterwards, it can be used to replay a scenario. similar to real-time simulation. &lt;br /&gt;
&lt;br /&gt;
Below, the resulting timed trace for the scenario in [[SimB|Real-Time Simulation]] is shown&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;activations&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;$initialise_machine&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: {&lt;br /&gt;
        &amp;quot;tl_cars&amp;quot;: &amp;quot;red&amp;quot;,&lt;br /&gt;
        &amp;quot;tl_peds&amp;quot;: &amp;quot;red&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_ry_1&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;$initialise_machine&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_ry&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_g_2&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_ry_1&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_g&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;500&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_y_3&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_g_2&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_y&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_r_4&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_y_3&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_r&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;500&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;peds_g_5&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_r_4&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;peds_g&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;peds_r_6&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;peds_g_5&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;peds_r&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: null,&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;peds_r_6&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;fileType&amp;quot;: &amp;quot;Timed_Trace&amp;quot;,&lt;br /&gt;
    &amp;quot;formatVersion&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;savedAt&amp;quot;: &amp;quot;2021-03-03T11:04:08.460477Z&amp;quot;,&lt;br /&gt;
    &amp;quot;creator&amp;quot;: &amp;quot;User&amp;quot;,&lt;br /&gt;
    &amp;quot;proB2KernelVersion&amp;quot;: &amp;quot;4.0.0-SNAPSHOT&amp;quot;,&lt;br /&gt;
    &amp;quot;proBCliVersion&amp;quot;: null,&lt;br /&gt;
    &amp;quot;modelName&amp;quot;: null&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Monte Carlo Simulation ===&lt;br /&gt;
&lt;br /&gt;
It is also possible to apply Monte Carlo simulation to generate a certain number of simulations.&lt;br /&gt;
Here, all simulations are played without real time. However, it is possible for the user, to replay the generated scenarios with real-time afterwards. &lt;br /&gt;
&lt;br /&gt;
The input parameters are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Number of Simulations&amp;lt;/em&amp;gt; defines the number of simulations to be generated.&lt;br /&gt;
* &amp;lt;em&amp;gt; Max Steps Before Start&amp;lt;/em&amp;gt; defines the number of steps before taking into account the starting and ending conditions.&lt;br /&gt;
* &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; defines condition to simulate until before taking &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; into account. It is either defined by a &amp;lt;em&amp;gt;No Condition&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Number of Steps&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Starting Time&amp;lt;/em&amp;gt; or &amp;lt;em&amp;gt;Starting Predicate&amp;lt;/em&amp;gt;.&lt;br /&gt;
* &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; defines condition to simulate until after taking  &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; into account (defines the last transition of the simulation). It is either defined by a &amp;lt;em&amp;gt;Number of Steps&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Ending Time&amp;lt;/em&amp;gt; or &amp;lt;em&amp;gt;Ending Predicate&amp;lt;/em&amp;gt;&lt;br /&gt;
* &amp;lt;em&amp;gt;Check&amp;lt;/em&amp;gt; defines the check to apply for the simulation. &amp;lt;em&amp;gt;Monte Carlo Simulation&amp;lt;/em&amp;gt; means that there are no checks to be applied, while the other options are &amp;lt;em&amp;gt;Hypothesis Testing&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Estimation&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:MonteCarloSimulation.png|400px]]&lt;br /&gt;
&lt;br /&gt;
Furthermore, there are two statistical validation techniques that can be applied based on Monte Carlo simulations: Hypothesis Testing and Estimation.&lt;br /&gt;
&lt;br /&gt;
=== Hypothesis Testing ===&lt;br /&gt;
&lt;br /&gt;
Hypothesis Testing expects the same parameters as Monte Carlo Simulation: &amp;lt;em&amp;gt;Max Steps before Simulation&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Number of Simulations&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The additional input parameters for Hypothesis Testing are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Property&amp;lt;/em&amp;gt; defines the property to be checked between &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; for each simulation. Possible configurations are:&lt;br /&gt;
** &amp;lt;em&amp;gt;All Invariants&amp;lt;/em&amp;gt; can be used to check all invariants.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate as Invariant&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is always true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Final Predicate&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked in the final state of a simulation.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate Eventually&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is eventually true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Timing&amp;lt;/em&amp;gt; can be used to check the time.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Hypothesis Check&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Left-tailed hypothesis test&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Right-tailed hypothesis test&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Two-tailed hypothesis test&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Probability&amp;lt;/em&amp;gt; (in the hypothesis)&lt;br /&gt;
* &amp;lt;em&amp;gt;Significance Level&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:HypothesisTesting.png|400px]]&lt;br /&gt;
&lt;br /&gt;
=== Estimation ===&lt;br /&gt;
&lt;br /&gt;
Estimation expects the same parameters as Monte Carlo Simulation: &amp;lt;em&amp;gt;Number of Simulations&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The additional input parameters for Estimation are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Property&amp;lt;/em&amp;gt; defines the property to be checked between &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; for each simulation. Possible configurations are:&lt;br /&gt;
** &amp;lt;em&amp;gt;All Invariants&amp;lt;/em&amp;gt; can be used to check all invariants.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate as Invariant&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is always true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Final Predicate&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked in the final state of a simulation.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate Eventually&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is eventually true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Timing&amp;lt;/em&amp;gt; can be used to check the time.&lt;br /&gt;
** &amp;lt;em&amp;gt;Average&amp;lt;/em&amp;gt; can be used to check the average value of an expression.&lt;br /&gt;
** &amp;lt;em&amp;gt;Sum&amp;lt;/em&amp;gt; can be used to check the sum of an expression.&lt;br /&gt;
* &amp;lt;em&amp;gt;Estimator&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Minimum Estimator&amp;lt;/em&amp;gt; returns the minimum estimated value from all simulated runs.&lt;br /&gt;
** &amp;lt;em&amp;gt;Mean Estimator&amp;lt;/em&amp;gt; returns the mean estimated value from all simulated runs.&lt;br /&gt;
** &amp;lt;em&amp;gt;Maximum Estimator&amp;lt;/em&amp;gt; returns the maximum estimated value from all simulated runs.&lt;br /&gt;
* &amp;lt;em&amp;gt;Desired Value&amp;lt;/em&amp;gt;&lt;br /&gt;
* &amp;lt;em&amp;gt;Epsilon&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For an estimated value e, a desired value d, and an epsilon eps, it checks for each simulation whether e is within [d - eps, d + eps]&lt;br /&gt;
&lt;br /&gt;
[[File:Estimation.png|400px]]&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=SimB&amp;diff=5895</id>
		<title>SimB</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=SimB&amp;diff=5895"/>
		<updated>2025-02-19T18:45:55Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Probabilistic and Timing Elements in SimB */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== SimB ==&lt;br /&gt;
&lt;br /&gt;
Additional documentation is available here: [https://github.com/hhu-stups/prob2_ui/blob/develop/src/main/helpsources/help_en/Main%20Menu/Advanced/SimB.md SimB Documentation]&lt;br /&gt;
&lt;br /&gt;
SimB is a simulator built on top of ProB.  It is available in the latest SNAPSHOT version in the new JavaFX based user interface [[ProB2-UI]] (https://github.com/hhu-stups/prob2_ui), The modeler can write SimB annotations for a formal model to simulate it. Examples are available at https://github.com/favu100/SimB-examples.&lt;br /&gt;
Furthermore, it is then possible to validate probabilistic and timing properties with statistical validation techniques such as hypothesis testing and estimation.&lt;br /&gt;
&lt;br /&gt;
SimB also contains a feature called interactive simulation.&lt;br /&gt;
This feature allows user interaction to trigger a simulation.&lt;br /&gt;
For interactive simulation, a modeler has to encode SimB listeners on events, triggering a SimB simulation.&lt;br /&gt;
Interactive Simulation examples are available at https://github.com/favu100/SimB-examples/tree/main/Interactive_Examples.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
More recently, SimB is extended by a new feature which makes it possible to load an Reinforcement learning Agent.&lt;br /&gt;
Technically, each step of the RL agent is converted into a SimB activation.&lt;br /&gt;
In order to simulate a RL agent in SimB, one must (1) create a formal B model for the RL agent, and (2) create a mapping between the state in the RL agent and the formal model, and (3) provide information to the formal B model again.&lt;br /&gt;
Reinforcement Learning examples are available at: https://github.com/hhu-stups/reinforcement-learning-b-models&lt;br /&gt;
&lt;br /&gt;
== Citing SimB ==&lt;br /&gt;
To cite SimB as a tool, its timing or probabilistic simulation features, or SimBs statistical validation techniques, please use:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@InProceedings{simb,&lt;br /&gt;
  Author    = {Vu, Fabian and Leuschel, Michael and Mashkoor, Atif},&lt;br /&gt;
  Title        = {{Validation of Formal Models by Timed Probabilistic Simulation}},&lt;br /&gt;
  Booktitle    = {Proceedings ABZ},&lt;br /&gt;
  Year        = 2021,&lt;br /&gt;
  Series    = {LNCS},&lt;br /&gt;
  Volume     = {12709},&lt;br /&gt;
  Pages = {81--96}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To cite SimBs interactive simulation, please use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@InProceedings{simb,&lt;br /&gt;
  Author    = {Vu, Fabian and Leuschel, Michael},&lt;br /&gt;
  Title        = {{Validation of Formal Models by Interactive Simulation}},&lt;br /&gt;
  Booktitle    = {Proceedings ABZ},&lt;br /&gt;
  Year        = 2023&lt;br /&gt;
  Series = {LNCS},&lt;br /&gt;
  Volume = {14010},&lt;br /&gt;
  Pages = {59--69}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using SimB ==&lt;br /&gt;
&lt;br /&gt;
Start SimB via &amp;quot;SimB&amp;quot; in the &amp;quot;Advanced&amp;quot; Menu after opening a machine. &lt;br /&gt;
&lt;br /&gt;
[[File:Open_SimB.png|800px]]&lt;br /&gt;
&lt;br /&gt;
Now, you can open a SimB file (JSON format)  controlling the underlying formal model.&lt;br /&gt;
&lt;br /&gt;
[[File:SimB_Window.png|800px]]&lt;br /&gt;
&lt;br /&gt;
A SimB file consists of SimB activations and SimB listeners to simulate the model.&lt;br /&gt;
SimB activations encode an activation diagram with probabilistic and timing elements for automatic simulation.&lt;br /&gt;
To enable interactive simulation, it is also necessary to encode interactive elements aka. SimB listeners which trigger other SimB activations.&lt;br /&gt;
Within these elements, the modeler can user B expressions which are evaluated on the current state.&lt;br /&gt;
&lt;br /&gt;
The general structure of a SimB simulation is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;activations&amp;quot;: [...]&lt;br /&gt;
  &amp;quot;listeners&amp;quot;: [...]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;activations&amp;lt;/tt&amp;gt; stores SimB activations, while &amp;lt;tt&amp;gt;listeners&amp;lt;/tt&amp;gt; stores SimB listeners.&lt;br /&gt;
&amp;lt;tt&amp;gt;activations&amp;lt;/tt&amp;gt; must be encoded,  &amp;lt;tt&amp;gt;listeners&amp;lt;/tt&amp;gt; is optional and defaults to the empty list.&lt;br /&gt;
&lt;br /&gt;
== Probabilistic and Timing Elements in SimB ==&lt;br /&gt;
&lt;br /&gt;
The SimB file always contains an &amp;lt;tt&amp;gt;activations&amp;lt;/tt&amp;gt; field storing a list of probabilistic and timing elements to control the simulation. Probabilistic values are always interpreted as weights and thus may sum to any number greater than zero.&lt;br /&gt;
There are two types of activations: direct activation and probabilistic choice.&lt;br /&gt;
All activations are identified by their  &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
===Direct Activation ===&lt;br /&gt;
&lt;br /&gt;
A direct activation activates an event to be executed in the future.&lt;br /&gt;
It requires the fields &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt; to be defined.&lt;br /&gt;
All other fields can be defined optionally.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt; identifies the activated event by its name.&lt;br /&gt;
* &amp;lt;tt&amp;gt;after&amp;lt;/tt&amp;gt; defines the scheduled time (in ms) when activating an event. By default, it is set to 0 ms, e.g., when this field is not defined explicitly.&lt;br /&gt;
* &amp;lt;tt&amp;gt;activating&amp;lt;/tt&amp;gt; stores events that will be activated when executing the event defined by &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;. Missing definition leads to the behavior that no other events are activated. The modeler can either write a String (to activate a single event) or a list of Strings (to activate multiple events)&lt;br /&gt;
* &amp;lt;tt&amp;gt;activationKind&amp;lt;/tt&amp;gt; stores the kind of activation for &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;. Possible options are &amp;lt;tt&amp;gt;multi&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;single&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;single:min&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;single:max&amp;lt;/tt&amp;gt;. The default value is &amp;lt;tt&amp;gt;multi&amp;lt;/tt&amp;gt;&lt;br /&gt;
** &amp;lt;tt&amp;gt;multi&amp;lt;/tt&amp;gt; means that the activation will be queued for execution. &lt;br /&gt;
** &amp;lt;tt&amp;gt;single&amp;lt;/tt&amp;gt; means that the activation will only be queued if there are no queued activations with the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;&lt;br /&gt;
** &amp;lt;tt&amp;gt;single:min&amp;lt;/tt&amp;gt; means that the activation will only be queued if (1) there are no queued activations for the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; or (2) there is a queued activation with the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; whose value for the scheduled time is greater. In the case of (2), the already queued activation will be discarded.&lt;br /&gt;
** &amp;lt;tt&amp;gt;single:max&amp;lt;/tt&amp;gt; means that the activation will only be queued if (1) there are no queued activations for the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; or (2) there is a queued activation with the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; whose value for the scheduled time is lower. In the case of (2), the already queued activation will be discarded.&lt;br /&gt;
* &amp;lt;tt&amp;gt;additionalGuards&amp;lt;/tt&amp;gt; stores optional guards when executing the event stored in &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;fixedVariables&amp;lt;/tt&amp;gt; stores a Map. Here, a variable (parameter, or non-deterministic assigned variable) is assigned to its value.&lt;br /&gt;
* &amp;lt;tt&amp;gt;probabilisticVariables&amp;lt;/tt&amp;gt;stores a Map. Here a variable (parameter, or non-deterministic assigned variable) is assigned to another Map defining the probabilistic choice of its value. The second Map stores Key-Value pairs where values are mapped to the probability/weight. &lt;br /&gt;
* &amp;lt;tt&amp;gt;transitionSelection&amp;lt;/tt&amp;gt; determines how SimB choses from multiple possible transitions (due to not specified variables):&lt;br /&gt;
** &amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; (the default) means that the first transition is chosen for execution.&lt;br /&gt;
** &amp;lt;tt&amp;gt;uniform&amp;lt;/tt&amp;gt; means that a transition is selected from all alternatives uniformly.&lt;br /&gt;
* &amp;lt;tt&amp;gt;priority&amp;lt;/tt&amp;gt; stores the priority for scheduling &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;. Lower number means greater priority.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;id&amp;quot;:  ...&lt;br /&gt;
   &amp;quot;execute&amp;quot;: ...&lt;br /&gt;
   &amp;quot;after&amp;quot;: ...&lt;br /&gt;
   &amp;quot;activating&amp;quot;: ...&lt;br /&gt;
   &amp;quot;activationKind&amp;quot;: ...&lt;br /&gt;
   &amp;quot;additionalGuards&amp;quot;: ...&lt;br /&gt;
   &amp;quot;fixedVariables&amp;quot;: ....&lt;br /&gt;
   &amp;quot;probabilisticVariables&amp;quot;: ....&lt;br /&gt;
   &amp;quot;priority&amp;quot;: ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Probabilistic Choice ===&lt;br /&gt;
&lt;br /&gt;
A probabilistic choice selects an event to be executed in the future.&lt;br /&gt;
It requires the two fields &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;chooseActivation&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;chooseActivation&amp;lt;/tt&amp;gt; is a Map storing Key-Value pairs where activations (identified by their &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;) are mapped to a probability/weight.  It is possible to chain multiple probabilistic choices together, but eventually, a direct activation must be reached.&lt;br /&gt;
The probabilities are always interpreted as weights and may sum to any number greater than zero.&lt;br /&gt;
Thus, a &amp;lt;tt&amp;gt;probabilistic choice&amp;lt;/tt&amp;gt; is of the following form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;id&amp;quot;:  ...&lt;br /&gt;
   &amp;quot;chooseActivation&amp;quot;: ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the following, an example for a SimB file controlling a Traffic Lights for cars and pedestrians (with timing and probabilistic behavior) is shown:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;activations&amp;quot;: [&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;$initialise_machine&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;$initialise_machine&amp;quot;, &amp;quot;activating&amp;quot;:&amp;quot;choose&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;choose&amp;quot;, &amp;quot;chooseActivation&amp;quot;:{&amp;quot;cars_ry&amp;quot;: &amp;quot;0.8&amp;quot;, &amp;quot;peds_g&amp;quot;: &amp;quot;0.2&amp;quot;}},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_ry&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_ry&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;cars_g&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_g&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_g&amp;quot;, &amp;quot;after&amp;quot;:500, &amp;quot;activating&amp;quot;:&amp;quot;cars_y&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_y&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_y&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;cars_r&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_r&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_r&amp;quot;, &amp;quot;after&amp;quot;:500, &amp;quot;activating&amp;quot;:&amp;quot;choose&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;peds_g&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;peds_g&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;peds_r&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;peds_r&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;peds_r&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;choose&amp;quot;}&lt;br /&gt;
 ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interactive Elements in SimB ==&lt;br /&gt;
&lt;br /&gt;
Interactive elements in SimB are so called SimB listeners.&lt;br /&gt;
A SimB listener consists of four fields &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;activating&amp;lt;/tt&amp;gt;.&lt;br /&gt;
This means that the SimB listener associated with &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; listens on a manual/user interaction on &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; with &amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt; after which activations in &amp;lt;tt&amp;gt;activating&amp;lt;/tt&amp;gt; are triggered.&lt;br /&gt;
&amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt; is optional and defaults to &amp;lt;tt&amp;gt;1=1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Manual/User interaction is recognized via VisB and ProB&#039;s Operations View.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;id&amp;quot;:  ...&lt;br /&gt;
   &amp;quot;event&amp;quot;: ...&lt;br /&gt;
   &amp;quot;predicate&amp;quot;: ...&lt;br /&gt;
   &amp;quot;activating&amp;quot;: [...]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the following, we parts of a SimB simulation from an automotive case study.&lt;br /&gt;
The SimB simulation contains a SimB listener which is linked to two activations.&lt;br /&gt;
The case study models the car&#039;s lighting system controlled by pitman controller, the key ignition, and the warning lights button.&lt;br /&gt;
&lt;br /&gt;
The SimB listeners states that SimB listens on user interaction on the event &amp;lt;tt&amp;gt;ENV_Pitman_DirectionBlinking&amp;lt;/tt&amp;gt;, to trigger two SimB activations &amp;lt;tt&amp;gt;blinking_on&amp;lt;/tt&amp;gt; and blinking_off afterward.&lt;br /&gt;
Practically, this means that a driver&#039;s input on the pitman for direction blinking activates the blinking cycle for the corresponding direction indicators.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;activations&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;blinking_on&amp;quot;, &lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;RTIME_BlinkerOn&amp;quot;, &lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;curDeadlines(blink_deadline)&amp;quot;,&lt;br /&gt;
       &amp;quot;activating&amp;quot; : &amp;quot;blinking_off&amp;quot;, &lt;br /&gt;
       ...&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;blinking_off&amp;quot;, &lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;RTIME_BlinkerOff&amp;quot;, &lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;curDeadlines(blink_deadline)&amp;quot;,&lt;br /&gt;
       &amp;quot;activating&amp;quot; : &amp;quot;blinking_on&amp;quot;, &lt;br /&gt;
       ...&lt;br /&gt;
    },&lt;br /&gt;
    ...&lt;br /&gt;
  ]&lt;br /&gt;
  &amp;quot;listeners&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;start_blinking&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;: &amp;quot;ENV_Pitman_DirectionBlinking&amp;quot;, &lt;br /&gt;
      &amp;quot;activating&amp;quot; : [&amp;quot;blinking_on&amp;quot;, &amp;quot;blinking_off&amp;quot;]&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Reinforcement Learning Agent in SimB ==&lt;br /&gt;
&lt;br /&gt;
Instead of loading a SimB simulation as a JSON file, one can also load a Reinforcement Learning &lt;br /&gt;
agent implemented in Python (.py).&lt;br /&gt;
For the simulation to work, one has to apply the following steps:&lt;br /&gt;
&lt;br /&gt;
1. Train a model of a Reinforcement Learning agent.&lt;br /&gt;
&lt;br /&gt;
2. Create a formal B model (including safety shield) for the RL agent. &lt;br /&gt;
&lt;br /&gt;
The operations represent the actions the RL agent can choose from. The formal model&#039;s state mainly represents the state of the environment.&lt;br /&gt;
Safety shields are encoded by the operations&#039; guards which are provided to the RL agent. Enabled operations are considered to be safe. Thus, the RL agent chooses the enabled operation/action with the highest predicted reward.&lt;br /&gt;
The operations&#039; substitutions model the desired behavior of the respective actions.&lt;br /&gt;
&lt;br /&gt;
An example for the FASTER of a HighwayEnvironment is as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FASTER = &lt;br /&gt;
PRE&lt;br /&gt;
  ¬(∃v. (v ∈ PresentVehicles \ {EgoVehicle} ∧ VehiclesX(v) &amp;gt; 0.0 ∧ VehiclesX(v) &amp;lt; 45.0 ∧ &lt;br /&gt;
  VehiclesY(v) &amp;lt; 3.5 ∧ VehiclesY(v) &amp;gt; -3.5))&lt;br /&gt;
THEN&lt;br /&gt;
  Crash :∈ BOOL ||&lt;br /&gt;
  PresentVehicles :∈ P(Vehicles) ;&lt;br /&gt;
  VehiclesX :∈ Vehicles → R ||&lt;br /&gt;
  VehiclesY :∈ Vehicles → R ||&lt;br /&gt;
  VehiclesVx :| (VehiclesVx ∈ PresentVehicles → R ∧ &lt;br /&gt;
             VehiclesVx(EgoVehicle) ≥ VehiclesVx’(EgoVehicle) - 0.05) ||&lt;br /&gt;
  VehiclesVy :∈ Vehicles → R ||&lt;br /&gt;
  VehiclesAx :| (VehiclesAx ∈ PresentVehicles → R ∧ VehiclesAx(EgoVehicle) ≥ -0.05) || &lt;br /&gt;
  VehiclesAy :∈ Vehicles → R ||&lt;br /&gt;
  Reward :∈ R&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lines 2-4 shows the operation&#039;s guard which is used as safety shield. &lt;br /&gt;
&lt;br /&gt;
Lines 6-15 shows the operation&#039;s substitution describing the desired behavior after executing FASTER.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3. Implement the mapping between the RL agent in Python and the formal B model.&lt;br /&gt;
This includes the mapping of actions to operations, and the mapping of information from the RL agent, particularly the environment and observation, to the variables.&lt;br /&gt;
&lt;br /&gt;
An example for the mapping of actions to operations is as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
action_names = {&lt;br /&gt;
    0: &amp;quot;LANE_LEFT&amp;quot;,&lt;br /&gt;
    1: &amp;quot;IDLE&amp;quot;,&lt;br /&gt;
    2: &amp;quot;LANE_RIGHT&amp;quot;,&lt;br /&gt;
    3: &amp;quot;FASTER&amp;quot;,&lt;br /&gt;
    4: &amp;quot;SLOWER&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, one can see that the numbers representing the actions in the RL agents are mapped to the corresponding operation names in the formal B model.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An example for a mapping to a variable in the formal B model is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def get_VehiclesX(obs):&lt;br /&gt;
    return &amp;quot;{{EgoVehicle |-&amp;gt; {0}, Vehicles2 |-&amp;gt; {1}, Vehicles3 |-&amp;gt; {2}, &lt;br /&gt;
             Vehicles4 |-&amp;gt; {3},  Vehicles5 |-&amp;gt; {4}}}&amp;quot;&lt;br /&gt;
         .format(obs[0][1]*200, obs[1][1]*200, obs[2][1]*200, &lt;br /&gt;
                  obs[3][1]*200, obs[4][1]*200) # Implemented manually&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remark: While the getter for the variable is generated by B2Program, the function for the mapping is implemented manually.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4. Implement necessary messages sent between the ProB animator and the RL agent.&lt;br /&gt;
Simulation should be a while-loop which runs while the simulation has not finished. &lt;br /&gt;
&lt;br /&gt;
* 1st message: Sent from ProB Animator: List of enabled operations&lt;br /&gt;
** Meanwhile RL agent predicts enabled operation with highest reward&lt;br /&gt;
* 2nd message: Sent from RL agent: Name of chosen action/operation&lt;br /&gt;
* 3rd message: Sent from RL agent: Time until executing chosen action/operation&lt;br /&gt;
* 4th message: Sent from RL agent: Succeeding B state as a predicate&lt;br /&gt;
* 5th message: Sent from RL agent: Boolean flag describing whether simulation is finished&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example code (line 70 - 113; particularly 86 - 113): https://github.com/hhu-stups/reinforcement-learning-b-models/blob/main/HighwayEnvironment/HighwayEnvironment.py&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To generate a RL agent for SimB, one can use the high-level code generator B2Program: https://github.com/favu100/b2program&lt;br /&gt;
&lt;br /&gt;
Given a formal B model, B2Program generates an RL agent which loads a given trained model and execute the necessary steps. This includes the fourth step described before.&lt;br /&gt;
The third step still has to be implemented; in this step, B2Program only generates the templates for the mappings which are then completed manually.&lt;br /&gt;
&lt;br /&gt;
== Validation ==&lt;br /&gt;
&lt;br /&gt;
=== Real-Time Simulation ===&lt;br /&gt;
&lt;br /&gt;
Using a SimB file, the modeler can play a single simulation on the underlying model in real-time. &lt;br /&gt;
The modeler can then manually check whether the model behaves as desired. Combining [[VisB]] and SimB, a simulation can be seen as an animated picture similar to a GIF picture.  &lt;br /&gt;
This gives the domain expert even a better understanding of the model.&lt;br /&gt;
With SimB listeners, it is also possible to encode simulations that are triggered by manual/user actions.&lt;br /&gt;
&lt;br /&gt;
A Traffic Light example (based on the SimB file shown in [[SimB|Using_SimB]] ) simulating the first 21 seconds is shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:TrafficLight_Simulation.gif|800px]]&lt;br /&gt;
&lt;br /&gt;
=== Timed Trace Replay ===&lt;br /&gt;
&lt;br /&gt;
Based on a single simulation, the modeler can generate a timed trace which is also stored in the SimB format. Afterwards, it can be used to replay a scenario. similar to real-time simulation. &lt;br /&gt;
&lt;br /&gt;
Below, the resulting timed trace for the scenario in [[SimB|Real-Time Simulation]] is shown&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;activations&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;$initialise_machine&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: {&lt;br /&gt;
        &amp;quot;tl_cars&amp;quot;: &amp;quot;red&amp;quot;,&lt;br /&gt;
        &amp;quot;tl_peds&amp;quot;: &amp;quot;red&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_ry_1&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;$initialise_machine&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_ry&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_g_2&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_ry_1&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_g&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;500&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_y_3&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_g_2&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_y&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_r_4&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_y_3&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_r&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;500&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;peds_g_5&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_r_4&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;peds_g&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;peds_r_6&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;peds_g_5&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;peds_r&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: null,&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;peds_r_6&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;fileType&amp;quot;: &amp;quot;Timed_Trace&amp;quot;,&lt;br /&gt;
    &amp;quot;formatVersion&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;savedAt&amp;quot;: &amp;quot;2021-03-03T11:04:08.460477Z&amp;quot;,&lt;br /&gt;
    &amp;quot;creator&amp;quot;: &amp;quot;User&amp;quot;,&lt;br /&gt;
    &amp;quot;proB2KernelVersion&amp;quot;: &amp;quot;4.0.0-SNAPSHOT&amp;quot;,&lt;br /&gt;
    &amp;quot;proBCliVersion&amp;quot;: null,&lt;br /&gt;
    &amp;quot;modelName&amp;quot;: null&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Monte Carlo Simulation ===&lt;br /&gt;
&lt;br /&gt;
It is also possible to apply Monte Carlo simulation to generate a certain number of simulations.&lt;br /&gt;
Here, all simulations are played without real time. However, it is possible for the user, to replay the generated scenarios with real-time afterwards. &lt;br /&gt;
&lt;br /&gt;
The input parameters are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Number of Simulations&amp;lt;/em&amp;gt; defines the number of simulations to be generated.&lt;br /&gt;
* &amp;lt;em&amp;gt; Max Steps Before Start&amp;lt;/em&amp;gt; defines the number of steps before taking into account the starting and ending conditions.&lt;br /&gt;
* &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; defines condition to simulate until before taking &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; into account. It is either defined by a &amp;lt;em&amp;gt;No Condition&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Number of Steps&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Starting Time&amp;lt;/em&amp;gt; or &amp;lt;em&amp;gt;Starting Predicate&amp;lt;/em&amp;gt;.&lt;br /&gt;
* &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; defines condition to simulate until after taking  &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; into account (defines the last transition of the simulation). It is either defined by a &amp;lt;em&amp;gt;Number of Steps&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Ending Time&amp;lt;/em&amp;gt; or &amp;lt;em&amp;gt;Ending Predicate&amp;lt;/em&amp;gt;&lt;br /&gt;
* &amp;lt;em&amp;gt;Check&amp;lt;/em&amp;gt; defines the check to apply for the simulation. &amp;lt;em&amp;gt;Monte Carlo Simulation&amp;lt;/em&amp;gt; means that there are no checks to be applied, while the other options are &amp;lt;em&amp;gt;Hypothesis Testing&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Estimation&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:MonteCarloSimulation.png|400px]]&lt;br /&gt;
&lt;br /&gt;
Furthermore, there are two statistical validation techniques that can be applied based on Monte Carlo simulations: Hypothesis Testing and Estimation.&lt;br /&gt;
&lt;br /&gt;
=== Hypothesis Testing ===&lt;br /&gt;
&lt;br /&gt;
Hypothesis Testing expects the same parameters as Monte Carlo Simulation: &amp;lt;em&amp;gt;Max Steps before Simulation&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Number of Simulations&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The additional input parameters for Hypothesis Testing are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Property&amp;lt;/em&amp;gt; defines the property to be checked between &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; for each simulation. Possible configurations are:&lt;br /&gt;
** &amp;lt;em&amp;gt;All Invariants&amp;lt;/em&amp;gt; can be used to check all invariants.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate as Invariant&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is always true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Final Predicate&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked in the final state of a simulation.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate Eventually&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is eventually true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Timing&amp;lt;/em&amp;gt; can be used to check the time.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Hypothesis Check&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Left-tailed hypothesis test&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Right-tailed hypothesis test&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Two-tailed hypothesis test&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Probability&amp;lt;/em&amp;gt; (in the hypothesis)&lt;br /&gt;
* &amp;lt;em&amp;gt;Significance Level&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:HypothesisTesting.png|400px]]&lt;br /&gt;
&lt;br /&gt;
=== Estimation ===&lt;br /&gt;
&lt;br /&gt;
Estimation expects the same parameters as Monte Carlo Simulation: &amp;lt;em&amp;gt;Number of Simulations&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The additional input parameters for Estimation are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Property&amp;lt;/em&amp;gt; defines the property to be checked between &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; for each simulation. Possible configurations are:&lt;br /&gt;
** &amp;lt;em&amp;gt;All Invariants&amp;lt;/em&amp;gt; can be used to check all invariants.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate as Invariant&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is always true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Final Predicate&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked in the final state of a simulation.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate Eventually&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is eventually true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Timing&amp;lt;/em&amp;gt; can be used to check the time.&lt;br /&gt;
** &amp;lt;em&amp;gt;Average&amp;lt;/em&amp;gt; can be used to check the average value of an expression.&lt;br /&gt;
** &amp;lt;em&amp;gt;Sum&amp;lt;/em&amp;gt; can be used to check the sum of an expression.&lt;br /&gt;
* &amp;lt;em&amp;gt;Estimator&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Minimum Estimator&amp;lt;/em&amp;gt; returns the minimum estimated value from all simulated runs.&lt;br /&gt;
** &amp;lt;em&amp;gt;Mean Estimator&amp;lt;/em&amp;gt; returns the mean estimated value from all simulated runs.&lt;br /&gt;
** &amp;lt;em&amp;gt;Maximum Estimator&amp;lt;/em&amp;gt; returns the maximum estimated value from all simulated runs.&lt;br /&gt;
* &amp;lt;em&amp;gt;Desired Value&amp;lt;/em&amp;gt;&lt;br /&gt;
* &amp;lt;em&amp;gt;Epsilon&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For an estimated value e, a desired value d, and an epsilon eps, it checks for each simulation whether e is within [d - eps, d + eps]&lt;br /&gt;
&lt;br /&gt;
[[File:Estimation.png|400px]]&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=SimB&amp;diff=5894</id>
		<title>SimB</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=SimB&amp;diff=5894"/>
		<updated>2025-02-19T18:45:27Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Direct Activation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== SimB ==&lt;br /&gt;
&lt;br /&gt;
Additional documentation is available here: [https://github.com/hhu-stups/prob2_ui/blob/develop/src/main/helpsources/help_en/Main%20Menu/Advanced/SimB.md SimB Documentation]&lt;br /&gt;
&lt;br /&gt;
SimB is a simulator built on top of ProB.  It is available in the latest SNAPSHOT version in the new JavaFX based user interface [[ProB2-UI]] (https://github.com/hhu-stups/prob2_ui), The modeler can write SimB annotations for a formal model to simulate it. Examples are available at https://github.com/favu100/SimB-examples.&lt;br /&gt;
Furthermore, it is then possible to validate probabilistic and timing properties with statistical validation techniques such as hypothesis testing and estimation.&lt;br /&gt;
&lt;br /&gt;
SimB also contains a feature called interactive simulation.&lt;br /&gt;
This feature allows user interaction to trigger a simulation.&lt;br /&gt;
For interactive simulation, a modeler has to encode SimB listeners on events, triggering a SimB simulation.&lt;br /&gt;
Interactive Simulation examples are available at https://github.com/favu100/SimB-examples/tree/main/Interactive_Examples.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
More recently, SimB is extended by a new feature which makes it possible to load an Reinforcement learning Agent.&lt;br /&gt;
Technically, each step of the RL agent is converted into a SimB activation.&lt;br /&gt;
In order to simulate a RL agent in SimB, one must (1) create a formal B model for the RL agent, and (2) create a mapping between the state in the RL agent and the formal model, and (3) provide information to the formal B model again.&lt;br /&gt;
Reinforcement Learning examples are available at: https://github.com/hhu-stups/reinforcement-learning-b-models&lt;br /&gt;
&lt;br /&gt;
== Citing SimB ==&lt;br /&gt;
To cite SimB as a tool, its timing or probabilistic simulation features, or SimBs statistical validation techniques, please use:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@InProceedings{simb,&lt;br /&gt;
  Author    = {Vu, Fabian and Leuschel, Michael and Mashkoor, Atif},&lt;br /&gt;
  Title        = {{Validation of Formal Models by Timed Probabilistic Simulation}},&lt;br /&gt;
  Booktitle    = {Proceedings ABZ},&lt;br /&gt;
  Year        = 2021,&lt;br /&gt;
  Series    = {LNCS},&lt;br /&gt;
  Volume     = {12709},&lt;br /&gt;
  Pages = {81--96}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To cite SimBs interactive simulation, please use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@InProceedings{simb,&lt;br /&gt;
  Author    = {Vu, Fabian and Leuschel, Michael},&lt;br /&gt;
  Title        = {{Validation of Formal Models by Interactive Simulation}},&lt;br /&gt;
  Booktitle    = {Proceedings ABZ},&lt;br /&gt;
  Year        = 2023&lt;br /&gt;
  Series = {LNCS},&lt;br /&gt;
  Volume = {14010},&lt;br /&gt;
  Pages = {59--69}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using SimB ==&lt;br /&gt;
&lt;br /&gt;
Start SimB via &amp;quot;SimB&amp;quot; in the &amp;quot;Advanced&amp;quot; Menu after opening a machine. &lt;br /&gt;
&lt;br /&gt;
[[File:Open_SimB.png|800px]]&lt;br /&gt;
&lt;br /&gt;
Now, you can open a SimB file (JSON format)  controlling the underlying formal model.&lt;br /&gt;
&lt;br /&gt;
[[File:SimB_Window.png|800px]]&lt;br /&gt;
&lt;br /&gt;
A SimB file consists of SimB activations and SimB listeners to simulate the model.&lt;br /&gt;
SimB activations encode an activation diagram with probabilistic and timing elements for automatic simulation.&lt;br /&gt;
To enable interactive simulation, it is also necessary to encode interactive elements aka. SimB listeners which trigger other SimB activations.&lt;br /&gt;
Within these elements, the modeler can user B expressions which are evaluated on the current state.&lt;br /&gt;
&lt;br /&gt;
The general structure of a SimB simulation is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;activations&amp;quot;: [...]&lt;br /&gt;
  &amp;quot;listeners&amp;quot;: [...]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;activations&amp;lt;/tt&amp;gt; stores SimB activations, while &amp;lt;tt&amp;gt;listeners&amp;lt;/tt&amp;gt; stores SimB listeners.&lt;br /&gt;
&amp;lt;tt&amp;gt;activations&amp;lt;/tt&amp;gt; must be encoded,  &amp;lt;tt&amp;gt;listeners&amp;lt;/tt&amp;gt; is optional and defaults to the empty list.&lt;br /&gt;
&lt;br /&gt;
== Probabilistic and Timing Elements in SimB ==&lt;br /&gt;
&lt;br /&gt;
The SimB file always contains an &amp;lt;tt&amp;gt;activations&amp;lt;/tt&amp;gt; field storing a list of probabilistic and timing elements to control the simulation. Probabilistic values ​​are always evaluated to ensure that the sum of all possibilities is always 1. Otherwise an error will be thrown at runtime. &lt;br /&gt;
There are two types of activations: direct activation and probabilistic choice.&lt;br /&gt;
All activations are identified by their  &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
===Direct Activation ===&lt;br /&gt;
&lt;br /&gt;
A direct activation activates an event to be executed in the future.&lt;br /&gt;
It requires the fields &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt; to be defined.&lt;br /&gt;
All other fields can be defined optionally.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt; identifies the activated event by its name.&lt;br /&gt;
* &amp;lt;tt&amp;gt;after&amp;lt;/tt&amp;gt; defines the scheduled time (in ms) when activating an event. By default, it is set to 0 ms, e.g., when this field is not defined explicitly.&lt;br /&gt;
* &amp;lt;tt&amp;gt;activating&amp;lt;/tt&amp;gt; stores events that will be activated when executing the event defined by &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;. Missing definition leads to the behavior that no other events are activated. The modeler can either write a String (to activate a single event) or a list of Strings (to activate multiple events)&lt;br /&gt;
* &amp;lt;tt&amp;gt;activationKind&amp;lt;/tt&amp;gt; stores the kind of activation for &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;. Possible options are &amp;lt;tt&amp;gt;multi&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;single&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;single:min&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;single:max&amp;lt;/tt&amp;gt;. The default value is &amp;lt;tt&amp;gt;multi&amp;lt;/tt&amp;gt;&lt;br /&gt;
** &amp;lt;tt&amp;gt;multi&amp;lt;/tt&amp;gt; means that the activation will be queued for execution. &lt;br /&gt;
** &amp;lt;tt&amp;gt;single&amp;lt;/tt&amp;gt; means that the activation will only be queued if there are no queued activations with the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;&lt;br /&gt;
** &amp;lt;tt&amp;gt;single:min&amp;lt;/tt&amp;gt; means that the activation will only be queued if (1) there are no queued activations for the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; or (2) there is a queued activation with the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; whose value for the scheduled time is greater. In the case of (2), the already queued activation will be discarded.&lt;br /&gt;
** &amp;lt;tt&amp;gt;single:max&amp;lt;/tt&amp;gt; means that the activation will only be queued if (1) there are no queued activations for the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; or (2) there is a queued activation with the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; whose value for the scheduled time is lower. In the case of (2), the already queued activation will be discarded.&lt;br /&gt;
* &amp;lt;tt&amp;gt;additionalGuards&amp;lt;/tt&amp;gt; stores optional guards when executing the event stored in &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;fixedVariables&amp;lt;/tt&amp;gt; stores a Map. Here, a variable (parameter, or non-deterministic assigned variable) is assigned to its value.&lt;br /&gt;
* &amp;lt;tt&amp;gt;probabilisticVariables&amp;lt;/tt&amp;gt;stores a Map. Here a variable (parameter, or non-deterministic assigned variable) is assigned to another Map defining the probabilistic choice of its value. The second Map stores Key-Value pairs where values are mapped to the probability/weight. &lt;br /&gt;
* &amp;lt;tt&amp;gt;transitionSelection&amp;lt;/tt&amp;gt; determines how SimB choses from multiple possible transitions (due to not specified variables):&lt;br /&gt;
** &amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; (the default) means that the first transition is chosen for execution.&lt;br /&gt;
** &amp;lt;tt&amp;gt;uniform&amp;lt;/tt&amp;gt; means that a transition is selected from all alternatives uniformly.&lt;br /&gt;
* &amp;lt;tt&amp;gt;priority&amp;lt;/tt&amp;gt; stores the priority for scheduling &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;. Lower number means greater priority.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;id&amp;quot;:  ...&lt;br /&gt;
   &amp;quot;execute&amp;quot;: ...&lt;br /&gt;
   &amp;quot;after&amp;quot;: ...&lt;br /&gt;
   &amp;quot;activating&amp;quot;: ...&lt;br /&gt;
   &amp;quot;activationKind&amp;quot;: ...&lt;br /&gt;
   &amp;quot;additionalGuards&amp;quot;: ...&lt;br /&gt;
   &amp;quot;fixedVariables&amp;quot;: ....&lt;br /&gt;
   &amp;quot;probabilisticVariables&amp;quot;: ....&lt;br /&gt;
   &amp;quot;priority&amp;quot;: ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Probabilistic Choice ===&lt;br /&gt;
&lt;br /&gt;
A probabilistic choice selects an event to be executed in the future.&lt;br /&gt;
It requires the two fields &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;chooseActivation&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;chooseActivation&amp;lt;/tt&amp;gt; is a Map storing Key-Value pairs where activations (identified by their &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;) are mapped to a probability/weight.  It is possible to chain multiple probabilistic choices together, but eventually, a direct activation must be reached.&lt;br /&gt;
The probabilities are always interpreted as weights and may sum to any number greater than zero.&lt;br /&gt;
Thus, a &amp;lt;tt&amp;gt;probabilistic choice&amp;lt;/tt&amp;gt; is of the following form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;id&amp;quot;:  ...&lt;br /&gt;
   &amp;quot;chooseActivation&amp;quot;: ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the following, an example for a SimB file controlling a Traffic Lights for cars and pedestrians (with timing and probabilistic behavior) is shown:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;activations&amp;quot;: [&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;$initialise_machine&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;$initialise_machine&amp;quot;, &amp;quot;activating&amp;quot;:&amp;quot;choose&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;choose&amp;quot;, &amp;quot;chooseActivation&amp;quot;:{&amp;quot;cars_ry&amp;quot;: &amp;quot;0.8&amp;quot;, &amp;quot;peds_g&amp;quot;: &amp;quot;0.2&amp;quot;}},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_ry&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_ry&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;cars_g&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_g&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_g&amp;quot;, &amp;quot;after&amp;quot;:500, &amp;quot;activating&amp;quot;:&amp;quot;cars_y&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_y&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_y&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;cars_r&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_r&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_r&amp;quot;, &amp;quot;after&amp;quot;:500, &amp;quot;activating&amp;quot;:&amp;quot;choose&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;peds_g&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;peds_g&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;peds_r&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;peds_r&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;peds_r&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;choose&amp;quot;}&lt;br /&gt;
 ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interactive Elements in SimB ==&lt;br /&gt;
&lt;br /&gt;
Interactive elements in SimB are so called SimB listeners.&lt;br /&gt;
A SimB listener consists of four fields &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;activating&amp;lt;/tt&amp;gt;.&lt;br /&gt;
This means that the SimB listener associated with &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; listens on a manual/user interaction on &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; with &amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt; after which activations in &amp;lt;tt&amp;gt;activating&amp;lt;/tt&amp;gt; are triggered.&lt;br /&gt;
&amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt; is optional and defaults to &amp;lt;tt&amp;gt;1=1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Manual/User interaction is recognized via VisB and ProB&#039;s Operations View.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;id&amp;quot;:  ...&lt;br /&gt;
   &amp;quot;event&amp;quot;: ...&lt;br /&gt;
   &amp;quot;predicate&amp;quot;: ...&lt;br /&gt;
   &amp;quot;activating&amp;quot;: [...]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the following, we parts of a SimB simulation from an automotive case study.&lt;br /&gt;
The SimB simulation contains a SimB listener which is linked to two activations.&lt;br /&gt;
The case study models the car&#039;s lighting system controlled by pitman controller, the key ignition, and the warning lights button.&lt;br /&gt;
&lt;br /&gt;
The SimB listeners states that SimB listens on user interaction on the event &amp;lt;tt&amp;gt;ENV_Pitman_DirectionBlinking&amp;lt;/tt&amp;gt;, to trigger two SimB activations &amp;lt;tt&amp;gt;blinking_on&amp;lt;/tt&amp;gt; and blinking_off afterward.&lt;br /&gt;
Practically, this means that a driver&#039;s input on the pitman for direction blinking activates the blinking cycle for the corresponding direction indicators.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;activations&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;blinking_on&amp;quot;, &lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;RTIME_BlinkerOn&amp;quot;, &lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;curDeadlines(blink_deadline)&amp;quot;,&lt;br /&gt;
       &amp;quot;activating&amp;quot; : &amp;quot;blinking_off&amp;quot;, &lt;br /&gt;
       ...&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;blinking_off&amp;quot;, &lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;RTIME_BlinkerOff&amp;quot;, &lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;curDeadlines(blink_deadline)&amp;quot;,&lt;br /&gt;
       &amp;quot;activating&amp;quot; : &amp;quot;blinking_on&amp;quot;, &lt;br /&gt;
       ...&lt;br /&gt;
    },&lt;br /&gt;
    ...&lt;br /&gt;
  ]&lt;br /&gt;
  &amp;quot;listeners&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;start_blinking&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;: &amp;quot;ENV_Pitman_DirectionBlinking&amp;quot;, &lt;br /&gt;
      &amp;quot;activating&amp;quot; : [&amp;quot;blinking_on&amp;quot;, &amp;quot;blinking_off&amp;quot;]&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Reinforcement Learning Agent in SimB ==&lt;br /&gt;
&lt;br /&gt;
Instead of loading a SimB simulation as a JSON file, one can also load a Reinforcement Learning &lt;br /&gt;
agent implemented in Python (.py).&lt;br /&gt;
For the simulation to work, one has to apply the following steps:&lt;br /&gt;
&lt;br /&gt;
1. Train a model of a Reinforcement Learning agent.&lt;br /&gt;
&lt;br /&gt;
2. Create a formal B model (including safety shield) for the RL agent. &lt;br /&gt;
&lt;br /&gt;
The operations represent the actions the RL agent can choose from. The formal model&#039;s state mainly represents the state of the environment.&lt;br /&gt;
Safety shields are encoded by the operations&#039; guards which are provided to the RL agent. Enabled operations are considered to be safe. Thus, the RL agent chooses the enabled operation/action with the highest predicted reward.&lt;br /&gt;
The operations&#039; substitutions model the desired behavior of the respective actions.&lt;br /&gt;
&lt;br /&gt;
An example for the FASTER of a HighwayEnvironment is as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FASTER = &lt;br /&gt;
PRE&lt;br /&gt;
  ¬(∃v. (v ∈ PresentVehicles \ {EgoVehicle} ∧ VehiclesX(v) &amp;gt; 0.0 ∧ VehiclesX(v) &amp;lt; 45.0 ∧ &lt;br /&gt;
  VehiclesY(v) &amp;lt; 3.5 ∧ VehiclesY(v) &amp;gt; -3.5))&lt;br /&gt;
THEN&lt;br /&gt;
  Crash :∈ BOOL ||&lt;br /&gt;
  PresentVehicles :∈ P(Vehicles) ;&lt;br /&gt;
  VehiclesX :∈ Vehicles → R ||&lt;br /&gt;
  VehiclesY :∈ Vehicles → R ||&lt;br /&gt;
  VehiclesVx :| (VehiclesVx ∈ PresentVehicles → R ∧ &lt;br /&gt;
             VehiclesVx(EgoVehicle) ≥ VehiclesVx’(EgoVehicle) - 0.05) ||&lt;br /&gt;
  VehiclesVy :∈ Vehicles → R ||&lt;br /&gt;
  VehiclesAx :| (VehiclesAx ∈ PresentVehicles → R ∧ VehiclesAx(EgoVehicle) ≥ -0.05) || &lt;br /&gt;
  VehiclesAy :∈ Vehicles → R ||&lt;br /&gt;
  Reward :∈ R&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lines 2-4 shows the operation&#039;s guard which is used as safety shield. &lt;br /&gt;
&lt;br /&gt;
Lines 6-15 shows the operation&#039;s substitution describing the desired behavior after executing FASTER.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3. Implement the mapping between the RL agent in Python and the formal B model.&lt;br /&gt;
This includes the mapping of actions to operations, and the mapping of information from the RL agent, particularly the environment and observation, to the variables.&lt;br /&gt;
&lt;br /&gt;
An example for the mapping of actions to operations is as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
action_names = {&lt;br /&gt;
    0: &amp;quot;LANE_LEFT&amp;quot;,&lt;br /&gt;
    1: &amp;quot;IDLE&amp;quot;,&lt;br /&gt;
    2: &amp;quot;LANE_RIGHT&amp;quot;,&lt;br /&gt;
    3: &amp;quot;FASTER&amp;quot;,&lt;br /&gt;
    4: &amp;quot;SLOWER&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, one can see that the numbers representing the actions in the RL agents are mapped to the corresponding operation names in the formal B model.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An example for a mapping to a variable in the formal B model is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def get_VehiclesX(obs):&lt;br /&gt;
    return &amp;quot;{{EgoVehicle |-&amp;gt; {0}, Vehicles2 |-&amp;gt; {1}, Vehicles3 |-&amp;gt; {2}, &lt;br /&gt;
             Vehicles4 |-&amp;gt; {3},  Vehicles5 |-&amp;gt; {4}}}&amp;quot;&lt;br /&gt;
         .format(obs[0][1]*200, obs[1][1]*200, obs[2][1]*200, &lt;br /&gt;
                  obs[3][1]*200, obs[4][1]*200) # Implemented manually&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remark: While the getter for the variable is generated by B2Program, the function for the mapping is implemented manually.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4. Implement necessary messages sent between the ProB animator and the RL agent.&lt;br /&gt;
Simulation should be a while-loop which runs while the simulation has not finished. &lt;br /&gt;
&lt;br /&gt;
* 1st message: Sent from ProB Animator: List of enabled operations&lt;br /&gt;
** Meanwhile RL agent predicts enabled operation with highest reward&lt;br /&gt;
* 2nd message: Sent from RL agent: Name of chosen action/operation&lt;br /&gt;
* 3rd message: Sent from RL agent: Time until executing chosen action/operation&lt;br /&gt;
* 4th message: Sent from RL agent: Succeeding B state as a predicate&lt;br /&gt;
* 5th message: Sent from RL agent: Boolean flag describing whether simulation is finished&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example code (line 70 - 113; particularly 86 - 113): https://github.com/hhu-stups/reinforcement-learning-b-models/blob/main/HighwayEnvironment/HighwayEnvironment.py&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To generate a RL agent for SimB, one can use the high-level code generator B2Program: https://github.com/favu100/b2program&lt;br /&gt;
&lt;br /&gt;
Given a formal B model, B2Program generates an RL agent which loads a given trained model and execute the necessary steps. This includes the fourth step described before.&lt;br /&gt;
The third step still has to be implemented; in this step, B2Program only generates the templates for the mappings which are then completed manually.&lt;br /&gt;
&lt;br /&gt;
== Validation ==&lt;br /&gt;
&lt;br /&gt;
=== Real-Time Simulation ===&lt;br /&gt;
&lt;br /&gt;
Using a SimB file, the modeler can play a single simulation on the underlying model in real-time. &lt;br /&gt;
The modeler can then manually check whether the model behaves as desired. Combining [[VisB]] and SimB, a simulation can be seen as an animated picture similar to a GIF picture.  &lt;br /&gt;
This gives the domain expert even a better understanding of the model.&lt;br /&gt;
With SimB listeners, it is also possible to encode simulations that are triggered by manual/user actions.&lt;br /&gt;
&lt;br /&gt;
A Traffic Light example (based on the SimB file shown in [[SimB|Using_SimB]] ) simulating the first 21 seconds is shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:TrafficLight_Simulation.gif|800px]]&lt;br /&gt;
&lt;br /&gt;
=== Timed Trace Replay ===&lt;br /&gt;
&lt;br /&gt;
Based on a single simulation, the modeler can generate a timed trace which is also stored in the SimB format. Afterwards, it can be used to replay a scenario. similar to real-time simulation. &lt;br /&gt;
&lt;br /&gt;
Below, the resulting timed trace for the scenario in [[SimB|Real-Time Simulation]] is shown&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;activations&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;$initialise_machine&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: {&lt;br /&gt;
        &amp;quot;tl_cars&amp;quot;: &amp;quot;red&amp;quot;,&lt;br /&gt;
        &amp;quot;tl_peds&amp;quot;: &amp;quot;red&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_ry_1&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;$initialise_machine&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_ry&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_g_2&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_ry_1&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_g&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;500&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_y_3&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_g_2&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_y&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_r_4&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_y_3&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_r&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;500&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;peds_g_5&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_r_4&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;peds_g&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;peds_r_6&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;peds_g_5&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;peds_r&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: null,&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;peds_r_6&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;fileType&amp;quot;: &amp;quot;Timed_Trace&amp;quot;,&lt;br /&gt;
    &amp;quot;formatVersion&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;savedAt&amp;quot;: &amp;quot;2021-03-03T11:04:08.460477Z&amp;quot;,&lt;br /&gt;
    &amp;quot;creator&amp;quot;: &amp;quot;User&amp;quot;,&lt;br /&gt;
    &amp;quot;proB2KernelVersion&amp;quot;: &amp;quot;4.0.0-SNAPSHOT&amp;quot;,&lt;br /&gt;
    &amp;quot;proBCliVersion&amp;quot;: null,&lt;br /&gt;
    &amp;quot;modelName&amp;quot;: null&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Monte Carlo Simulation ===&lt;br /&gt;
&lt;br /&gt;
It is also possible to apply Monte Carlo simulation to generate a certain number of simulations.&lt;br /&gt;
Here, all simulations are played without real time. However, it is possible for the user, to replay the generated scenarios with real-time afterwards. &lt;br /&gt;
&lt;br /&gt;
The input parameters are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Number of Simulations&amp;lt;/em&amp;gt; defines the number of simulations to be generated.&lt;br /&gt;
* &amp;lt;em&amp;gt; Max Steps Before Start&amp;lt;/em&amp;gt; defines the number of steps before taking into account the starting and ending conditions.&lt;br /&gt;
* &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; defines condition to simulate until before taking &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; into account. It is either defined by a &amp;lt;em&amp;gt;No Condition&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Number of Steps&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Starting Time&amp;lt;/em&amp;gt; or &amp;lt;em&amp;gt;Starting Predicate&amp;lt;/em&amp;gt;.&lt;br /&gt;
* &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; defines condition to simulate until after taking  &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; into account (defines the last transition of the simulation). It is either defined by a &amp;lt;em&amp;gt;Number of Steps&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Ending Time&amp;lt;/em&amp;gt; or &amp;lt;em&amp;gt;Ending Predicate&amp;lt;/em&amp;gt;&lt;br /&gt;
* &amp;lt;em&amp;gt;Check&amp;lt;/em&amp;gt; defines the check to apply for the simulation. &amp;lt;em&amp;gt;Monte Carlo Simulation&amp;lt;/em&amp;gt; means that there are no checks to be applied, while the other options are &amp;lt;em&amp;gt;Hypothesis Testing&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Estimation&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:MonteCarloSimulation.png|400px]]&lt;br /&gt;
&lt;br /&gt;
Furthermore, there are two statistical validation techniques that can be applied based on Monte Carlo simulations: Hypothesis Testing and Estimation.&lt;br /&gt;
&lt;br /&gt;
=== Hypothesis Testing ===&lt;br /&gt;
&lt;br /&gt;
Hypothesis Testing expects the same parameters as Monte Carlo Simulation: &amp;lt;em&amp;gt;Max Steps before Simulation&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Number of Simulations&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The additional input parameters for Hypothesis Testing are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Property&amp;lt;/em&amp;gt; defines the property to be checked between &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; for each simulation. Possible configurations are:&lt;br /&gt;
** &amp;lt;em&amp;gt;All Invariants&amp;lt;/em&amp;gt; can be used to check all invariants.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate as Invariant&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is always true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Final Predicate&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked in the final state of a simulation.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate Eventually&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is eventually true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Timing&amp;lt;/em&amp;gt; can be used to check the time.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Hypothesis Check&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Left-tailed hypothesis test&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Right-tailed hypothesis test&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Two-tailed hypothesis test&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Probability&amp;lt;/em&amp;gt; (in the hypothesis)&lt;br /&gt;
* &amp;lt;em&amp;gt;Significance Level&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:HypothesisTesting.png|400px]]&lt;br /&gt;
&lt;br /&gt;
=== Estimation ===&lt;br /&gt;
&lt;br /&gt;
Estimation expects the same parameters as Monte Carlo Simulation: &amp;lt;em&amp;gt;Number of Simulations&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The additional input parameters for Estimation are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Property&amp;lt;/em&amp;gt; defines the property to be checked between &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; for each simulation. Possible configurations are:&lt;br /&gt;
** &amp;lt;em&amp;gt;All Invariants&amp;lt;/em&amp;gt; can be used to check all invariants.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate as Invariant&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is always true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Final Predicate&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked in the final state of a simulation.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate Eventually&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is eventually true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Timing&amp;lt;/em&amp;gt; can be used to check the time.&lt;br /&gt;
** &amp;lt;em&amp;gt;Average&amp;lt;/em&amp;gt; can be used to check the average value of an expression.&lt;br /&gt;
** &amp;lt;em&amp;gt;Sum&amp;lt;/em&amp;gt; can be used to check the sum of an expression.&lt;br /&gt;
* &amp;lt;em&amp;gt;Estimator&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Minimum Estimator&amp;lt;/em&amp;gt; returns the minimum estimated value from all simulated runs.&lt;br /&gt;
** &amp;lt;em&amp;gt;Mean Estimator&amp;lt;/em&amp;gt; returns the mean estimated value from all simulated runs.&lt;br /&gt;
** &amp;lt;em&amp;gt;Maximum Estimator&amp;lt;/em&amp;gt; returns the maximum estimated value from all simulated runs.&lt;br /&gt;
* &amp;lt;em&amp;gt;Desired Value&amp;lt;/em&amp;gt;&lt;br /&gt;
* &amp;lt;em&amp;gt;Epsilon&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For an estimated value e, a desired value d, and an epsilon eps, it checks for each simulation whether e is within [d - eps, d + eps]&lt;br /&gt;
&lt;br /&gt;
[[File:Estimation.png|400px]]&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=SimB&amp;diff=5893</id>
		<title>SimB</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=SimB&amp;diff=5893"/>
		<updated>2025-02-19T18:44:58Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Probabilistic Choice */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== SimB ==&lt;br /&gt;
&lt;br /&gt;
Additional documentation is available here: [https://github.com/hhu-stups/prob2_ui/blob/develop/src/main/helpsources/help_en/Main%20Menu/Advanced/SimB.md SimB Documentation]&lt;br /&gt;
&lt;br /&gt;
SimB is a simulator built on top of ProB.  It is available in the latest SNAPSHOT version in the new JavaFX based user interface [[ProB2-UI]] (https://github.com/hhu-stups/prob2_ui), The modeler can write SimB annotations for a formal model to simulate it. Examples are available at https://github.com/favu100/SimB-examples.&lt;br /&gt;
Furthermore, it is then possible to validate probabilistic and timing properties with statistical validation techniques such as hypothesis testing and estimation.&lt;br /&gt;
&lt;br /&gt;
SimB also contains a feature called interactive simulation.&lt;br /&gt;
This feature allows user interaction to trigger a simulation.&lt;br /&gt;
For interactive simulation, a modeler has to encode SimB listeners on events, triggering a SimB simulation.&lt;br /&gt;
Interactive Simulation examples are available at https://github.com/favu100/SimB-examples/tree/main/Interactive_Examples.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
More recently, SimB is extended by a new feature which makes it possible to load an Reinforcement learning Agent.&lt;br /&gt;
Technically, each step of the RL agent is converted into a SimB activation.&lt;br /&gt;
In order to simulate a RL agent in SimB, one must (1) create a formal B model for the RL agent, and (2) create a mapping between the state in the RL agent and the formal model, and (3) provide information to the formal B model again.&lt;br /&gt;
Reinforcement Learning examples are available at: https://github.com/hhu-stups/reinforcement-learning-b-models&lt;br /&gt;
&lt;br /&gt;
== Citing SimB ==&lt;br /&gt;
To cite SimB as a tool, its timing or probabilistic simulation features, or SimBs statistical validation techniques, please use:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@InProceedings{simb,&lt;br /&gt;
  Author    = {Vu, Fabian and Leuschel, Michael and Mashkoor, Atif},&lt;br /&gt;
  Title        = {{Validation of Formal Models by Timed Probabilistic Simulation}},&lt;br /&gt;
  Booktitle    = {Proceedings ABZ},&lt;br /&gt;
  Year        = 2021,&lt;br /&gt;
  Series    = {LNCS},&lt;br /&gt;
  Volume     = {12709},&lt;br /&gt;
  Pages = {81--96}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To cite SimBs interactive simulation, please use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@InProceedings{simb,&lt;br /&gt;
  Author    = {Vu, Fabian and Leuschel, Michael},&lt;br /&gt;
  Title        = {{Validation of Formal Models by Interactive Simulation}},&lt;br /&gt;
  Booktitle    = {Proceedings ABZ},&lt;br /&gt;
  Year        = 2023&lt;br /&gt;
  Series = {LNCS},&lt;br /&gt;
  Volume = {14010},&lt;br /&gt;
  Pages = {59--69}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using SimB ==&lt;br /&gt;
&lt;br /&gt;
Start SimB via &amp;quot;SimB&amp;quot; in the &amp;quot;Advanced&amp;quot; Menu after opening a machine. &lt;br /&gt;
&lt;br /&gt;
[[File:Open_SimB.png|800px]]&lt;br /&gt;
&lt;br /&gt;
Now, you can open a SimB file (JSON format)  controlling the underlying formal model.&lt;br /&gt;
&lt;br /&gt;
[[File:SimB_Window.png|800px]]&lt;br /&gt;
&lt;br /&gt;
A SimB file consists of SimB activations and SimB listeners to simulate the model.&lt;br /&gt;
SimB activations encode an activation diagram with probabilistic and timing elements for automatic simulation.&lt;br /&gt;
To enable interactive simulation, it is also necessary to encode interactive elements aka. SimB listeners which trigger other SimB activations.&lt;br /&gt;
Within these elements, the modeler can user B expressions which are evaluated on the current state.&lt;br /&gt;
&lt;br /&gt;
The general structure of a SimB simulation is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;activations&amp;quot;: [...]&lt;br /&gt;
  &amp;quot;listeners&amp;quot;: [...]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;activations&amp;lt;/tt&amp;gt; stores SimB activations, while &amp;lt;tt&amp;gt;listeners&amp;lt;/tt&amp;gt; stores SimB listeners.&lt;br /&gt;
&amp;lt;tt&amp;gt;activations&amp;lt;/tt&amp;gt; must be encoded,  &amp;lt;tt&amp;gt;listeners&amp;lt;/tt&amp;gt; is optional and defaults to the empty list.&lt;br /&gt;
&lt;br /&gt;
== Probabilistic and Timing Elements in SimB ==&lt;br /&gt;
&lt;br /&gt;
The SimB file always contains an &amp;lt;tt&amp;gt;activations&amp;lt;/tt&amp;gt; field storing a list of probabilistic and timing elements to control the simulation. Probabilistic values ​​are always evaluated to ensure that the sum of all possibilities is always 1. Otherwise an error will be thrown at runtime. &lt;br /&gt;
There are two types of activations: direct activation and probabilistic choice.&lt;br /&gt;
All activations are identified by their  &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
===Direct Activation ===&lt;br /&gt;
&lt;br /&gt;
A direct activation activates an event to be executed in the future.&lt;br /&gt;
It requires the fields &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt; to be defined.&lt;br /&gt;
All other fields can be defined optionally.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt; identifies the activated event by its name.&lt;br /&gt;
* &amp;lt;tt&amp;gt;after&amp;lt;/tt&amp;gt; defines the scheduled time (in ms) when activating an event. By default, it is set to 0 ms, e.g., when this field is not defined explicitly.&lt;br /&gt;
* &amp;lt;tt&amp;gt;activating&amp;lt;/tt&amp;gt; stores events that will be activated when executing the event defined by &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;. Missing definition leads to the behavior that no other events are activated. The modeler can either write a String (to activate a single event) or a list of Strings (to activate multiple events)&lt;br /&gt;
* &amp;lt;tt&amp;gt;activationKind&amp;lt;/tt&amp;gt; stores the kind of activation for &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;. Possible options are &amp;lt;tt&amp;gt;multi&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;single&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;single:min&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;single:max&amp;lt;/tt&amp;gt;. The default value is &amp;lt;tt&amp;gt;multi&amp;lt;/tt&amp;gt;&lt;br /&gt;
** &amp;lt;tt&amp;gt;multi&amp;lt;/tt&amp;gt; means that the activation will be queued for execution. &lt;br /&gt;
** &amp;lt;tt&amp;gt;single&amp;lt;/tt&amp;gt; means that the activation will only be queued if there are no queued activations with the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;&lt;br /&gt;
** &amp;lt;tt&amp;gt;single:min&amp;lt;/tt&amp;gt; means that the activation will only be queued if (1) there are no queued activations for the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; or (2) there is a queued activation with the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; whose value for the scheduled time is greater. In the case of (2), the already queued activation will be discarded.&lt;br /&gt;
** &amp;lt;tt&amp;gt;single:max&amp;lt;/tt&amp;gt; means that the activation will only be queued if (1) there are no queued activations for the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; or (2) there is a queued activation with the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; whose value for the scheduled time is lower. In the case of (2), the already queued activation will be discarded.&lt;br /&gt;
* &amp;lt;tt&amp;gt;additionalGuards&amp;lt;/tt&amp;gt; stores optional guards when executing the event stored in &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;fixedVariables&amp;lt;/tt&amp;gt; stores a Map. Here, a variable (parameter, or non-deterministic assigned variable) is assigned to its value.&lt;br /&gt;
* &amp;lt;tt&amp;gt;probabilisticVariables&amp;lt;/tt&amp;gt;stores a Map. Here a variable (parameter, or non-deterministic assigned variable) is assigned to another Map defining the probabilistic choice of its value. The second Map stores Key-Value pairs where values are mapped to the probability. &lt;br /&gt;
* &amp;lt;tt&amp;gt;transitionSelection&amp;lt;/tt&amp;gt; determines how SimB choses from multiple possible transitions (due to not specified variables):&lt;br /&gt;
** &amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; (the default) means that the first transition is chosen for execution.&lt;br /&gt;
** &amp;lt;tt&amp;gt;uniform&amp;lt;/tt&amp;gt; means that a transition is selected from all alternatives uniformly.&lt;br /&gt;
* &amp;lt;tt&amp;gt;priority&amp;lt;/tt&amp;gt; stores the priority for scheduling &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;. Lower number means greater priority.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;id&amp;quot;:  ...&lt;br /&gt;
   &amp;quot;execute&amp;quot;: ...&lt;br /&gt;
   &amp;quot;after&amp;quot;: ...&lt;br /&gt;
   &amp;quot;activating&amp;quot;: ...&lt;br /&gt;
   &amp;quot;activationKind&amp;quot;: ...&lt;br /&gt;
   &amp;quot;additionalGuards&amp;quot;: ...&lt;br /&gt;
   &amp;quot;fixedVariables&amp;quot;: ....&lt;br /&gt;
   &amp;quot;probabilisticVariables&amp;quot;: ....&lt;br /&gt;
   &amp;quot;priority&amp;quot;: ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Probabilistic Choice ===&lt;br /&gt;
&lt;br /&gt;
A probabilistic choice selects an event to be executed in the future.&lt;br /&gt;
It requires the two fields &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;chooseActivation&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;chooseActivation&amp;lt;/tt&amp;gt; is a Map storing Key-Value pairs where activations (identified by their &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;) are mapped to a probability/weight.  It is possible to chain multiple probabilistic choices together, but eventually, a direct activation must be reached.&lt;br /&gt;
The probabilities are always interpreted as weights and may sum to any number greater than zero.&lt;br /&gt;
Thus, a &amp;lt;tt&amp;gt;probabilistic choice&amp;lt;/tt&amp;gt; is of the following form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;id&amp;quot;:  ...&lt;br /&gt;
   &amp;quot;chooseActivation&amp;quot;: ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the following, an example for a SimB file controlling a Traffic Lights for cars and pedestrians (with timing and probabilistic behavior) is shown:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;activations&amp;quot;: [&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;$initialise_machine&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;$initialise_machine&amp;quot;, &amp;quot;activating&amp;quot;:&amp;quot;choose&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;choose&amp;quot;, &amp;quot;chooseActivation&amp;quot;:{&amp;quot;cars_ry&amp;quot;: &amp;quot;0.8&amp;quot;, &amp;quot;peds_g&amp;quot;: &amp;quot;0.2&amp;quot;}},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_ry&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_ry&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;cars_g&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_g&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_g&amp;quot;, &amp;quot;after&amp;quot;:500, &amp;quot;activating&amp;quot;:&amp;quot;cars_y&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_y&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_y&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;cars_r&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_r&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_r&amp;quot;, &amp;quot;after&amp;quot;:500, &amp;quot;activating&amp;quot;:&amp;quot;choose&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;peds_g&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;peds_g&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;peds_r&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;peds_r&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;peds_r&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;choose&amp;quot;}&lt;br /&gt;
 ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interactive Elements in SimB ==&lt;br /&gt;
&lt;br /&gt;
Interactive elements in SimB are so called SimB listeners.&lt;br /&gt;
A SimB listener consists of four fields &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;activating&amp;lt;/tt&amp;gt;.&lt;br /&gt;
This means that the SimB listener associated with &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; listens on a manual/user interaction on &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; with &amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt; after which activations in &amp;lt;tt&amp;gt;activating&amp;lt;/tt&amp;gt; are triggered.&lt;br /&gt;
&amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt; is optional and defaults to &amp;lt;tt&amp;gt;1=1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Manual/User interaction is recognized via VisB and ProB&#039;s Operations View.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;id&amp;quot;:  ...&lt;br /&gt;
   &amp;quot;event&amp;quot;: ...&lt;br /&gt;
   &amp;quot;predicate&amp;quot;: ...&lt;br /&gt;
   &amp;quot;activating&amp;quot;: [...]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the following, we parts of a SimB simulation from an automotive case study.&lt;br /&gt;
The SimB simulation contains a SimB listener which is linked to two activations.&lt;br /&gt;
The case study models the car&#039;s lighting system controlled by pitman controller, the key ignition, and the warning lights button.&lt;br /&gt;
&lt;br /&gt;
The SimB listeners states that SimB listens on user interaction on the event &amp;lt;tt&amp;gt;ENV_Pitman_DirectionBlinking&amp;lt;/tt&amp;gt;, to trigger two SimB activations &amp;lt;tt&amp;gt;blinking_on&amp;lt;/tt&amp;gt; and blinking_off afterward.&lt;br /&gt;
Practically, this means that a driver&#039;s input on the pitman for direction blinking activates the blinking cycle for the corresponding direction indicators.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;activations&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;blinking_on&amp;quot;, &lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;RTIME_BlinkerOn&amp;quot;, &lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;curDeadlines(blink_deadline)&amp;quot;,&lt;br /&gt;
       &amp;quot;activating&amp;quot; : &amp;quot;blinking_off&amp;quot;, &lt;br /&gt;
       ...&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;blinking_off&amp;quot;, &lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;RTIME_BlinkerOff&amp;quot;, &lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;curDeadlines(blink_deadline)&amp;quot;,&lt;br /&gt;
       &amp;quot;activating&amp;quot; : &amp;quot;blinking_on&amp;quot;, &lt;br /&gt;
       ...&lt;br /&gt;
    },&lt;br /&gt;
    ...&lt;br /&gt;
  ]&lt;br /&gt;
  &amp;quot;listeners&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;start_blinking&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;: &amp;quot;ENV_Pitman_DirectionBlinking&amp;quot;, &lt;br /&gt;
      &amp;quot;activating&amp;quot; : [&amp;quot;blinking_on&amp;quot;, &amp;quot;blinking_off&amp;quot;]&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Reinforcement Learning Agent in SimB ==&lt;br /&gt;
&lt;br /&gt;
Instead of loading a SimB simulation as a JSON file, one can also load a Reinforcement Learning &lt;br /&gt;
agent implemented in Python (.py).&lt;br /&gt;
For the simulation to work, one has to apply the following steps:&lt;br /&gt;
&lt;br /&gt;
1. Train a model of a Reinforcement Learning agent.&lt;br /&gt;
&lt;br /&gt;
2. Create a formal B model (including safety shield) for the RL agent. &lt;br /&gt;
&lt;br /&gt;
The operations represent the actions the RL agent can choose from. The formal model&#039;s state mainly represents the state of the environment.&lt;br /&gt;
Safety shields are encoded by the operations&#039; guards which are provided to the RL agent. Enabled operations are considered to be safe. Thus, the RL agent chooses the enabled operation/action with the highest predicted reward.&lt;br /&gt;
The operations&#039; substitutions model the desired behavior of the respective actions.&lt;br /&gt;
&lt;br /&gt;
An example for the FASTER of a HighwayEnvironment is as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FASTER = &lt;br /&gt;
PRE&lt;br /&gt;
  ¬(∃v. (v ∈ PresentVehicles \ {EgoVehicle} ∧ VehiclesX(v) &amp;gt; 0.0 ∧ VehiclesX(v) &amp;lt; 45.0 ∧ &lt;br /&gt;
  VehiclesY(v) &amp;lt; 3.5 ∧ VehiclesY(v) &amp;gt; -3.5))&lt;br /&gt;
THEN&lt;br /&gt;
  Crash :∈ BOOL ||&lt;br /&gt;
  PresentVehicles :∈ P(Vehicles) ;&lt;br /&gt;
  VehiclesX :∈ Vehicles → R ||&lt;br /&gt;
  VehiclesY :∈ Vehicles → R ||&lt;br /&gt;
  VehiclesVx :| (VehiclesVx ∈ PresentVehicles → R ∧ &lt;br /&gt;
             VehiclesVx(EgoVehicle) ≥ VehiclesVx’(EgoVehicle) - 0.05) ||&lt;br /&gt;
  VehiclesVy :∈ Vehicles → R ||&lt;br /&gt;
  VehiclesAx :| (VehiclesAx ∈ PresentVehicles → R ∧ VehiclesAx(EgoVehicle) ≥ -0.05) || &lt;br /&gt;
  VehiclesAy :∈ Vehicles → R ||&lt;br /&gt;
  Reward :∈ R&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lines 2-4 shows the operation&#039;s guard which is used as safety shield. &lt;br /&gt;
&lt;br /&gt;
Lines 6-15 shows the operation&#039;s substitution describing the desired behavior after executing FASTER.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3. Implement the mapping between the RL agent in Python and the formal B model.&lt;br /&gt;
This includes the mapping of actions to operations, and the mapping of information from the RL agent, particularly the environment and observation, to the variables.&lt;br /&gt;
&lt;br /&gt;
An example for the mapping of actions to operations is as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
action_names = {&lt;br /&gt;
    0: &amp;quot;LANE_LEFT&amp;quot;,&lt;br /&gt;
    1: &amp;quot;IDLE&amp;quot;,&lt;br /&gt;
    2: &amp;quot;LANE_RIGHT&amp;quot;,&lt;br /&gt;
    3: &amp;quot;FASTER&amp;quot;,&lt;br /&gt;
    4: &amp;quot;SLOWER&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, one can see that the numbers representing the actions in the RL agents are mapped to the corresponding operation names in the formal B model.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An example for a mapping to a variable in the formal B model is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def get_VehiclesX(obs):&lt;br /&gt;
    return &amp;quot;{{EgoVehicle |-&amp;gt; {0}, Vehicles2 |-&amp;gt; {1}, Vehicles3 |-&amp;gt; {2}, &lt;br /&gt;
             Vehicles4 |-&amp;gt; {3},  Vehicles5 |-&amp;gt; {4}}}&amp;quot;&lt;br /&gt;
         .format(obs[0][1]*200, obs[1][1]*200, obs[2][1]*200, &lt;br /&gt;
                  obs[3][1]*200, obs[4][1]*200) # Implemented manually&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remark: While the getter for the variable is generated by B2Program, the function for the mapping is implemented manually.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4. Implement necessary messages sent between the ProB animator and the RL agent.&lt;br /&gt;
Simulation should be a while-loop which runs while the simulation has not finished. &lt;br /&gt;
&lt;br /&gt;
* 1st message: Sent from ProB Animator: List of enabled operations&lt;br /&gt;
** Meanwhile RL agent predicts enabled operation with highest reward&lt;br /&gt;
* 2nd message: Sent from RL agent: Name of chosen action/operation&lt;br /&gt;
* 3rd message: Sent from RL agent: Time until executing chosen action/operation&lt;br /&gt;
* 4th message: Sent from RL agent: Succeeding B state as a predicate&lt;br /&gt;
* 5th message: Sent from RL agent: Boolean flag describing whether simulation is finished&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example code (line 70 - 113; particularly 86 - 113): https://github.com/hhu-stups/reinforcement-learning-b-models/blob/main/HighwayEnvironment/HighwayEnvironment.py&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To generate a RL agent for SimB, one can use the high-level code generator B2Program: https://github.com/favu100/b2program&lt;br /&gt;
&lt;br /&gt;
Given a formal B model, B2Program generates an RL agent which loads a given trained model and execute the necessary steps. This includes the fourth step described before.&lt;br /&gt;
The third step still has to be implemented; in this step, B2Program only generates the templates for the mappings which are then completed manually.&lt;br /&gt;
&lt;br /&gt;
== Validation ==&lt;br /&gt;
&lt;br /&gt;
=== Real-Time Simulation ===&lt;br /&gt;
&lt;br /&gt;
Using a SimB file, the modeler can play a single simulation on the underlying model in real-time. &lt;br /&gt;
The modeler can then manually check whether the model behaves as desired. Combining [[VisB]] and SimB, a simulation can be seen as an animated picture similar to a GIF picture.  &lt;br /&gt;
This gives the domain expert even a better understanding of the model.&lt;br /&gt;
With SimB listeners, it is also possible to encode simulations that are triggered by manual/user actions.&lt;br /&gt;
&lt;br /&gt;
A Traffic Light example (based on the SimB file shown in [[SimB|Using_SimB]] ) simulating the first 21 seconds is shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:TrafficLight_Simulation.gif|800px]]&lt;br /&gt;
&lt;br /&gt;
=== Timed Trace Replay ===&lt;br /&gt;
&lt;br /&gt;
Based on a single simulation, the modeler can generate a timed trace which is also stored in the SimB format. Afterwards, it can be used to replay a scenario. similar to real-time simulation. &lt;br /&gt;
&lt;br /&gt;
Below, the resulting timed trace for the scenario in [[SimB|Real-Time Simulation]] is shown&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;activations&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;$initialise_machine&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: {&lt;br /&gt;
        &amp;quot;tl_cars&amp;quot;: &amp;quot;red&amp;quot;,&lt;br /&gt;
        &amp;quot;tl_peds&amp;quot;: &amp;quot;red&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_ry_1&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;$initialise_machine&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_ry&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_g_2&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_ry_1&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_g&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;500&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_y_3&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_g_2&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_y&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_r_4&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_y_3&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_r&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;500&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;peds_g_5&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_r_4&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;peds_g&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;peds_r_6&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;peds_g_5&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;peds_r&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: null,&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;peds_r_6&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;fileType&amp;quot;: &amp;quot;Timed_Trace&amp;quot;,&lt;br /&gt;
    &amp;quot;formatVersion&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;savedAt&amp;quot;: &amp;quot;2021-03-03T11:04:08.460477Z&amp;quot;,&lt;br /&gt;
    &amp;quot;creator&amp;quot;: &amp;quot;User&amp;quot;,&lt;br /&gt;
    &amp;quot;proB2KernelVersion&amp;quot;: &amp;quot;4.0.0-SNAPSHOT&amp;quot;,&lt;br /&gt;
    &amp;quot;proBCliVersion&amp;quot;: null,&lt;br /&gt;
    &amp;quot;modelName&amp;quot;: null&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Monte Carlo Simulation ===&lt;br /&gt;
&lt;br /&gt;
It is also possible to apply Monte Carlo simulation to generate a certain number of simulations.&lt;br /&gt;
Here, all simulations are played without real time. However, it is possible for the user, to replay the generated scenarios with real-time afterwards. &lt;br /&gt;
&lt;br /&gt;
The input parameters are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Number of Simulations&amp;lt;/em&amp;gt; defines the number of simulations to be generated.&lt;br /&gt;
* &amp;lt;em&amp;gt; Max Steps Before Start&amp;lt;/em&amp;gt; defines the number of steps before taking into account the starting and ending conditions.&lt;br /&gt;
* &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; defines condition to simulate until before taking &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; into account. It is either defined by a &amp;lt;em&amp;gt;No Condition&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Number of Steps&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Starting Time&amp;lt;/em&amp;gt; or &amp;lt;em&amp;gt;Starting Predicate&amp;lt;/em&amp;gt;.&lt;br /&gt;
* &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; defines condition to simulate until after taking  &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; into account (defines the last transition of the simulation). It is either defined by a &amp;lt;em&amp;gt;Number of Steps&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Ending Time&amp;lt;/em&amp;gt; or &amp;lt;em&amp;gt;Ending Predicate&amp;lt;/em&amp;gt;&lt;br /&gt;
* &amp;lt;em&amp;gt;Check&amp;lt;/em&amp;gt; defines the check to apply for the simulation. &amp;lt;em&amp;gt;Monte Carlo Simulation&amp;lt;/em&amp;gt; means that there are no checks to be applied, while the other options are &amp;lt;em&amp;gt;Hypothesis Testing&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Estimation&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:MonteCarloSimulation.png|400px]]&lt;br /&gt;
&lt;br /&gt;
Furthermore, there are two statistical validation techniques that can be applied based on Monte Carlo simulations: Hypothesis Testing and Estimation.&lt;br /&gt;
&lt;br /&gt;
=== Hypothesis Testing ===&lt;br /&gt;
&lt;br /&gt;
Hypothesis Testing expects the same parameters as Monte Carlo Simulation: &amp;lt;em&amp;gt;Max Steps before Simulation&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Number of Simulations&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The additional input parameters for Hypothesis Testing are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Property&amp;lt;/em&amp;gt; defines the property to be checked between &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; for each simulation. Possible configurations are:&lt;br /&gt;
** &amp;lt;em&amp;gt;All Invariants&amp;lt;/em&amp;gt; can be used to check all invariants.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate as Invariant&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is always true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Final Predicate&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked in the final state of a simulation.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate Eventually&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is eventually true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Timing&amp;lt;/em&amp;gt; can be used to check the time.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Hypothesis Check&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Left-tailed hypothesis test&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Right-tailed hypothesis test&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Two-tailed hypothesis test&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Probability&amp;lt;/em&amp;gt; (in the hypothesis)&lt;br /&gt;
* &amp;lt;em&amp;gt;Significance Level&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:HypothesisTesting.png|400px]]&lt;br /&gt;
&lt;br /&gt;
=== Estimation ===&lt;br /&gt;
&lt;br /&gt;
Estimation expects the same parameters as Monte Carlo Simulation: &amp;lt;em&amp;gt;Number of Simulations&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The additional input parameters for Estimation are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Property&amp;lt;/em&amp;gt; defines the property to be checked between &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; for each simulation. Possible configurations are:&lt;br /&gt;
** &amp;lt;em&amp;gt;All Invariants&amp;lt;/em&amp;gt; can be used to check all invariants.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate as Invariant&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is always true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Final Predicate&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked in the final state of a simulation.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate Eventually&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is eventually true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Timing&amp;lt;/em&amp;gt; can be used to check the time.&lt;br /&gt;
** &amp;lt;em&amp;gt;Average&amp;lt;/em&amp;gt; can be used to check the average value of an expression.&lt;br /&gt;
** &amp;lt;em&amp;gt;Sum&amp;lt;/em&amp;gt; can be used to check the sum of an expression.&lt;br /&gt;
* &amp;lt;em&amp;gt;Estimator&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Minimum Estimator&amp;lt;/em&amp;gt; returns the minimum estimated value from all simulated runs.&lt;br /&gt;
** &amp;lt;em&amp;gt;Mean Estimator&amp;lt;/em&amp;gt; returns the mean estimated value from all simulated runs.&lt;br /&gt;
** &amp;lt;em&amp;gt;Maximum Estimator&amp;lt;/em&amp;gt; returns the maximum estimated value from all simulated runs.&lt;br /&gt;
* &amp;lt;em&amp;gt;Desired Value&amp;lt;/em&amp;gt;&lt;br /&gt;
* &amp;lt;em&amp;gt;Epsilon&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For an estimated value e, a desired value d, and an epsilon eps, it checks for each simulation whether e is within [d - eps, d + eps]&lt;br /&gt;
&lt;br /&gt;
[[File:Estimation.png|400px]]&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=SimB&amp;diff=5892</id>
		<title>SimB</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=SimB&amp;diff=5892"/>
		<updated>2025-02-19T18:43:33Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Direct Activation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== SimB ==&lt;br /&gt;
&lt;br /&gt;
Additional documentation is available here: [https://github.com/hhu-stups/prob2_ui/blob/develop/src/main/helpsources/help_en/Main%20Menu/Advanced/SimB.md SimB Documentation]&lt;br /&gt;
&lt;br /&gt;
SimB is a simulator built on top of ProB.  It is available in the latest SNAPSHOT version in the new JavaFX based user interface [[ProB2-UI]] (https://github.com/hhu-stups/prob2_ui), The modeler can write SimB annotations for a formal model to simulate it. Examples are available at https://github.com/favu100/SimB-examples.&lt;br /&gt;
Furthermore, it is then possible to validate probabilistic and timing properties with statistical validation techniques such as hypothesis testing and estimation.&lt;br /&gt;
&lt;br /&gt;
SimB also contains a feature called interactive simulation.&lt;br /&gt;
This feature allows user interaction to trigger a simulation.&lt;br /&gt;
For interactive simulation, a modeler has to encode SimB listeners on events, triggering a SimB simulation.&lt;br /&gt;
Interactive Simulation examples are available at https://github.com/favu100/SimB-examples/tree/main/Interactive_Examples.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
More recently, SimB is extended by a new feature which makes it possible to load an Reinforcement learning Agent.&lt;br /&gt;
Technically, each step of the RL agent is converted into a SimB activation.&lt;br /&gt;
In order to simulate a RL agent in SimB, one must (1) create a formal B model for the RL agent, and (2) create a mapping between the state in the RL agent and the formal model, and (3) provide information to the formal B model again.&lt;br /&gt;
Reinforcement Learning examples are available at: https://github.com/hhu-stups/reinforcement-learning-b-models&lt;br /&gt;
&lt;br /&gt;
== Citing SimB ==&lt;br /&gt;
To cite SimB as a tool, its timing or probabilistic simulation features, or SimBs statistical validation techniques, please use:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@InProceedings{simb,&lt;br /&gt;
  Author    = {Vu, Fabian and Leuschel, Michael and Mashkoor, Atif},&lt;br /&gt;
  Title        = {{Validation of Formal Models by Timed Probabilistic Simulation}},&lt;br /&gt;
  Booktitle    = {Proceedings ABZ},&lt;br /&gt;
  Year        = 2021,&lt;br /&gt;
  Series    = {LNCS},&lt;br /&gt;
  Volume     = {12709},&lt;br /&gt;
  Pages = {81--96}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To cite SimBs interactive simulation, please use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@InProceedings{simb,&lt;br /&gt;
  Author    = {Vu, Fabian and Leuschel, Michael},&lt;br /&gt;
  Title        = {{Validation of Formal Models by Interactive Simulation}},&lt;br /&gt;
  Booktitle    = {Proceedings ABZ},&lt;br /&gt;
  Year        = 2023&lt;br /&gt;
  Series = {LNCS},&lt;br /&gt;
  Volume = {14010},&lt;br /&gt;
  Pages = {59--69}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using SimB ==&lt;br /&gt;
&lt;br /&gt;
Start SimB via &amp;quot;SimB&amp;quot; in the &amp;quot;Advanced&amp;quot; Menu after opening a machine. &lt;br /&gt;
&lt;br /&gt;
[[File:Open_SimB.png|800px]]&lt;br /&gt;
&lt;br /&gt;
Now, you can open a SimB file (JSON format)  controlling the underlying formal model.&lt;br /&gt;
&lt;br /&gt;
[[File:SimB_Window.png|800px]]&lt;br /&gt;
&lt;br /&gt;
A SimB file consists of SimB activations and SimB listeners to simulate the model.&lt;br /&gt;
SimB activations encode an activation diagram with probabilistic and timing elements for automatic simulation.&lt;br /&gt;
To enable interactive simulation, it is also necessary to encode interactive elements aka. SimB listeners which trigger other SimB activations.&lt;br /&gt;
Within these elements, the modeler can user B expressions which are evaluated on the current state.&lt;br /&gt;
&lt;br /&gt;
The general structure of a SimB simulation is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;activations&amp;quot;: [...]&lt;br /&gt;
  &amp;quot;listeners&amp;quot;: [...]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;activations&amp;lt;/tt&amp;gt; stores SimB activations, while &amp;lt;tt&amp;gt;listeners&amp;lt;/tt&amp;gt; stores SimB listeners.&lt;br /&gt;
&amp;lt;tt&amp;gt;activations&amp;lt;/tt&amp;gt; must be encoded,  &amp;lt;tt&amp;gt;listeners&amp;lt;/tt&amp;gt; is optional and defaults to the empty list.&lt;br /&gt;
&lt;br /&gt;
== Probabilistic and Timing Elements in SimB ==&lt;br /&gt;
&lt;br /&gt;
The SimB file always contains an &amp;lt;tt&amp;gt;activations&amp;lt;/tt&amp;gt; field storing a list of probabilistic and timing elements to control the simulation. Probabilistic values ​​are always evaluated to ensure that the sum of all possibilities is always 1. Otherwise an error will be thrown at runtime. &lt;br /&gt;
There are two types of activations: direct activation and probabilistic choice.&lt;br /&gt;
All activations are identified by their  &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
===Direct Activation ===&lt;br /&gt;
&lt;br /&gt;
A direct activation activates an event to be executed in the future.&lt;br /&gt;
It requires the fields &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt; to be defined.&lt;br /&gt;
All other fields can be defined optionally.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt; identifies the activated event by its name.&lt;br /&gt;
* &amp;lt;tt&amp;gt;after&amp;lt;/tt&amp;gt; defines the scheduled time (in ms) when activating an event. By default, it is set to 0 ms, e.g., when this field is not defined explicitly.&lt;br /&gt;
* &amp;lt;tt&amp;gt;activating&amp;lt;/tt&amp;gt; stores events that will be activated when executing the event defined by &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;. Missing definition leads to the behavior that no other events are activated. The modeler can either write a String (to activate a single event) or a list of Strings (to activate multiple events)&lt;br /&gt;
* &amp;lt;tt&amp;gt;activationKind&amp;lt;/tt&amp;gt; stores the kind of activation for &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;. Possible options are &amp;lt;tt&amp;gt;multi&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;single&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;single:min&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;single:max&amp;lt;/tt&amp;gt;. The default value is &amp;lt;tt&amp;gt;multi&amp;lt;/tt&amp;gt;&lt;br /&gt;
** &amp;lt;tt&amp;gt;multi&amp;lt;/tt&amp;gt; means that the activation will be queued for execution. &lt;br /&gt;
** &amp;lt;tt&amp;gt;single&amp;lt;/tt&amp;gt; means that the activation will only be queued if there are no queued activations with the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;&lt;br /&gt;
** &amp;lt;tt&amp;gt;single:min&amp;lt;/tt&amp;gt; means that the activation will only be queued if (1) there are no queued activations for the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; or (2) there is a queued activation with the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; whose value for the scheduled time is greater. In the case of (2), the already queued activation will be discarded.&lt;br /&gt;
** &amp;lt;tt&amp;gt;single:max&amp;lt;/tt&amp;gt; means that the activation will only be queued if (1) there are no queued activations for the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; or (2) there is a queued activation with the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; whose value for the scheduled time is lower. In the case of (2), the already queued activation will be discarded.&lt;br /&gt;
* &amp;lt;tt&amp;gt;additionalGuards&amp;lt;/tt&amp;gt; stores optional guards when executing the event stored in &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;fixedVariables&amp;lt;/tt&amp;gt; stores a Map. Here, a variable (parameter, or non-deterministic assigned variable) is assigned to its value.&lt;br /&gt;
* &amp;lt;tt&amp;gt;probabilisticVariables&amp;lt;/tt&amp;gt;stores a Map. Here a variable (parameter, or non-deterministic assigned variable) is assigned to another Map defining the probabilistic choice of its value. The second Map stores Key-Value pairs where values are mapped to the probability. &lt;br /&gt;
* &amp;lt;tt&amp;gt;transitionSelection&amp;lt;/tt&amp;gt; determines how SimB choses from multiple possible transitions (due to not specified variables):&lt;br /&gt;
** &amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; (the default) means that the first transition is chosen for execution.&lt;br /&gt;
** &amp;lt;tt&amp;gt;uniform&amp;lt;/tt&amp;gt; means that a transition is selected from all alternatives uniformly.&lt;br /&gt;
* &amp;lt;tt&amp;gt;priority&amp;lt;/tt&amp;gt; stores the priority for scheduling &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;. Lower number means greater priority.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;id&amp;quot;:  ...&lt;br /&gt;
   &amp;quot;execute&amp;quot;: ...&lt;br /&gt;
   &amp;quot;after&amp;quot;: ...&lt;br /&gt;
   &amp;quot;activating&amp;quot;: ...&lt;br /&gt;
   &amp;quot;activationKind&amp;quot;: ...&lt;br /&gt;
   &amp;quot;additionalGuards&amp;quot;: ...&lt;br /&gt;
   &amp;quot;fixedVariables&amp;quot;: ....&lt;br /&gt;
   &amp;quot;probabilisticVariables&amp;quot;: ....&lt;br /&gt;
   &amp;quot;priority&amp;quot;: ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Probabilistic Choice ===&lt;br /&gt;
&lt;br /&gt;
A probabilistic choice selects an event to be executed in the future.&lt;br /&gt;
It requires the two fields &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;chooseActivation&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;chooseActivation&amp;lt;/tt&amp;gt; is a Map storing Key-Value pairs where activations (identified by their &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;) are mapped to a probability.  It is possible to chain multiple probabilistic choices together, but eventually, a direct activation must be reached.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;id&amp;quot;:  ...&lt;br /&gt;
   &amp;quot;chooseActivation&amp;quot;: ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the following, an example for a SimB file controlling a Traffic Lights for cars and pedestrians (with timing and probabilistic behavior) is shown:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;activations&amp;quot;: [&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;$initialise_machine&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;$initialise_machine&amp;quot;, &amp;quot;activating&amp;quot;:&amp;quot;choose&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;choose&amp;quot;, &amp;quot;chooseActivation&amp;quot;:{&amp;quot;cars_ry&amp;quot;: &amp;quot;0.8&amp;quot;, &amp;quot;peds_g&amp;quot;: &amp;quot;0.2&amp;quot;}},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_ry&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_ry&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;cars_g&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_g&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_g&amp;quot;, &amp;quot;after&amp;quot;:500, &amp;quot;activating&amp;quot;:&amp;quot;cars_y&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_y&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_y&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;cars_r&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_r&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_r&amp;quot;, &amp;quot;after&amp;quot;:500, &amp;quot;activating&amp;quot;:&amp;quot;choose&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;peds_g&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;peds_g&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;peds_r&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;peds_r&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;peds_r&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;choose&amp;quot;}&lt;br /&gt;
 ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interactive Elements in SimB ==&lt;br /&gt;
&lt;br /&gt;
Interactive elements in SimB are so called SimB listeners.&lt;br /&gt;
A SimB listener consists of four fields &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;activating&amp;lt;/tt&amp;gt;.&lt;br /&gt;
This means that the SimB listener associated with &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; listens on a manual/user interaction on &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; with &amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt; after which activations in &amp;lt;tt&amp;gt;activating&amp;lt;/tt&amp;gt; are triggered.&lt;br /&gt;
&amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt; is optional and defaults to &amp;lt;tt&amp;gt;1=1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Manual/User interaction is recognized via VisB and ProB&#039;s Operations View.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;id&amp;quot;:  ...&lt;br /&gt;
   &amp;quot;event&amp;quot;: ...&lt;br /&gt;
   &amp;quot;predicate&amp;quot;: ...&lt;br /&gt;
   &amp;quot;activating&amp;quot;: [...]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the following, we parts of a SimB simulation from an automotive case study.&lt;br /&gt;
The SimB simulation contains a SimB listener which is linked to two activations.&lt;br /&gt;
The case study models the car&#039;s lighting system controlled by pitman controller, the key ignition, and the warning lights button.&lt;br /&gt;
&lt;br /&gt;
The SimB listeners states that SimB listens on user interaction on the event &amp;lt;tt&amp;gt;ENV_Pitman_DirectionBlinking&amp;lt;/tt&amp;gt;, to trigger two SimB activations &amp;lt;tt&amp;gt;blinking_on&amp;lt;/tt&amp;gt; and blinking_off afterward.&lt;br /&gt;
Practically, this means that a driver&#039;s input on the pitman for direction blinking activates the blinking cycle for the corresponding direction indicators.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;activations&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;blinking_on&amp;quot;, &lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;RTIME_BlinkerOn&amp;quot;, &lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;curDeadlines(blink_deadline)&amp;quot;,&lt;br /&gt;
       &amp;quot;activating&amp;quot; : &amp;quot;blinking_off&amp;quot;, &lt;br /&gt;
       ...&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;blinking_off&amp;quot;, &lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;RTIME_BlinkerOff&amp;quot;, &lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;curDeadlines(blink_deadline)&amp;quot;,&lt;br /&gt;
       &amp;quot;activating&amp;quot; : &amp;quot;blinking_on&amp;quot;, &lt;br /&gt;
       ...&lt;br /&gt;
    },&lt;br /&gt;
    ...&lt;br /&gt;
  ]&lt;br /&gt;
  &amp;quot;listeners&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;start_blinking&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;: &amp;quot;ENV_Pitman_DirectionBlinking&amp;quot;, &lt;br /&gt;
      &amp;quot;activating&amp;quot; : [&amp;quot;blinking_on&amp;quot;, &amp;quot;blinking_off&amp;quot;]&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Reinforcement Learning Agent in SimB ==&lt;br /&gt;
&lt;br /&gt;
Instead of loading a SimB simulation as a JSON file, one can also load a Reinforcement Learning &lt;br /&gt;
agent implemented in Python (.py).&lt;br /&gt;
For the simulation to work, one has to apply the following steps:&lt;br /&gt;
&lt;br /&gt;
1. Train a model of a Reinforcement Learning agent.&lt;br /&gt;
&lt;br /&gt;
2. Create a formal B model (including safety shield) for the RL agent. &lt;br /&gt;
&lt;br /&gt;
The operations represent the actions the RL agent can choose from. The formal model&#039;s state mainly represents the state of the environment.&lt;br /&gt;
Safety shields are encoded by the operations&#039; guards which are provided to the RL agent. Enabled operations are considered to be safe. Thus, the RL agent chooses the enabled operation/action with the highest predicted reward.&lt;br /&gt;
The operations&#039; substitutions model the desired behavior of the respective actions.&lt;br /&gt;
&lt;br /&gt;
An example for the FASTER of a HighwayEnvironment is as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FASTER = &lt;br /&gt;
PRE&lt;br /&gt;
  ¬(∃v. (v ∈ PresentVehicles \ {EgoVehicle} ∧ VehiclesX(v) &amp;gt; 0.0 ∧ VehiclesX(v) &amp;lt; 45.0 ∧ &lt;br /&gt;
  VehiclesY(v) &amp;lt; 3.5 ∧ VehiclesY(v) &amp;gt; -3.5))&lt;br /&gt;
THEN&lt;br /&gt;
  Crash :∈ BOOL ||&lt;br /&gt;
  PresentVehicles :∈ P(Vehicles) ;&lt;br /&gt;
  VehiclesX :∈ Vehicles → R ||&lt;br /&gt;
  VehiclesY :∈ Vehicles → R ||&lt;br /&gt;
  VehiclesVx :| (VehiclesVx ∈ PresentVehicles → R ∧ &lt;br /&gt;
             VehiclesVx(EgoVehicle) ≥ VehiclesVx’(EgoVehicle) - 0.05) ||&lt;br /&gt;
  VehiclesVy :∈ Vehicles → R ||&lt;br /&gt;
  VehiclesAx :| (VehiclesAx ∈ PresentVehicles → R ∧ VehiclesAx(EgoVehicle) ≥ -0.05) || &lt;br /&gt;
  VehiclesAy :∈ Vehicles → R ||&lt;br /&gt;
  Reward :∈ R&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lines 2-4 shows the operation&#039;s guard which is used as safety shield. &lt;br /&gt;
&lt;br /&gt;
Lines 6-15 shows the operation&#039;s substitution describing the desired behavior after executing FASTER.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3. Implement the mapping between the RL agent in Python and the formal B model.&lt;br /&gt;
This includes the mapping of actions to operations, and the mapping of information from the RL agent, particularly the environment and observation, to the variables.&lt;br /&gt;
&lt;br /&gt;
An example for the mapping of actions to operations is as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
action_names = {&lt;br /&gt;
    0: &amp;quot;LANE_LEFT&amp;quot;,&lt;br /&gt;
    1: &amp;quot;IDLE&amp;quot;,&lt;br /&gt;
    2: &amp;quot;LANE_RIGHT&amp;quot;,&lt;br /&gt;
    3: &amp;quot;FASTER&amp;quot;,&lt;br /&gt;
    4: &amp;quot;SLOWER&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, one can see that the numbers representing the actions in the RL agents are mapped to the corresponding operation names in the formal B model.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An example for a mapping to a variable in the formal B model is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def get_VehiclesX(obs):&lt;br /&gt;
    return &amp;quot;{{EgoVehicle |-&amp;gt; {0}, Vehicles2 |-&amp;gt; {1}, Vehicles3 |-&amp;gt; {2}, &lt;br /&gt;
             Vehicles4 |-&amp;gt; {3},  Vehicles5 |-&amp;gt; {4}}}&amp;quot;&lt;br /&gt;
         .format(obs[0][1]*200, obs[1][1]*200, obs[2][1]*200, &lt;br /&gt;
                  obs[3][1]*200, obs[4][1]*200) # Implemented manually&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remark: While the getter for the variable is generated by B2Program, the function for the mapping is implemented manually.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4. Implement necessary messages sent between the ProB animator and the RL agent.&lt;br /&gt;
Simulation should be a while-loop which runs while the simulation has not finished. &lt;br /&gt;
&lt;br /&gt;
* 1st message: Sent from ProB Animator: List of enabled operations&lt;br /&gt;
** Meanwhile RL agent predicts enabled operation with highest reward&lt;br /&gt;
* 2nd message: Sent from RL agent: Name of chosen action/operation&lt;br /&gt;
* 3rd message: Sent from RL agent: Time until executing chosen action/operation&lt;br /&gt;
* 4th message: Sent from RL agent: Succeeding B state as a predicate&lt;br /&gt;
* 5th message: Sent from RL agent: Boolean flag describing whether simulation is finished&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example code (line 70 - 113; particularly 86 - 113): https://github.com/hhu-stups/reinforcement-learning-b-models/blob/main/HighwayEnvironment/HighwayEnvironment.py&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To generate a RL agent for SimB, one can use the high-level code generator B2Program: https://github.com/favu100/b2program&lt;br /&gt;
&lt;br /&gt;
Given a formal B model, B2Program generates an RL agent which loads a given trained model and execute the necessary steps. This includes the fourth step described before.&lt;br /&gt;
The third step still has to be implemented; in this step, B2Program only generates the templates for the mappings which are then completed manually.&lt;br /&gt;
&lt;br /&gt;
== Validation ==&lt;br /&gt;
&lt;br /&gt;
=== Real-Time Simulation ===&lt;br /&gt;
&lt;br /&gt;
Using a SimB file, the modeler can play a single simulation on the underlying model in real-time. &lt;br /&gt;
The modeler can then manually check whether the model behaves as desired. Combining [[VisB]] and SimB, a simulation can be seen as an animated picture similar to a GIF picture.  &lt;br /&gt;
This gives the domain expert even a better understanding of the model.&lt;br /&gt;
With SimB listeners, it is also possible to encode simulations that are triggered by manual/user actions.&lt;br /&gt;
&lt;br /&gt;
A Traffic Light example (based on the SimB file shown in [[SimB|Using_SimB]] ) simulating the first 21 seconds is shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:TrafficLight_Simulation.gif|800px]]&lt;br /&gt;
&lt;br /&gt;
=== Timed Trace Replay ===&lt;br /&gt;
&lt;br /&gt;
Based on a single simulation, the modeler can generate a timed trace which is also stored in the SimB format. Afterwards, it can be used to replay a scenario. similar to real-time simulation. &lt;br /&gt;
&lt;br /&gt;
Below, the resulting timed trace for the scenario in [[SimB|Real-Time Simulation]] is shown&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;activations&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;$initialise_machine&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: {&lt;br /&gt;
        &amp;quot;tl_cars&amp;quot;: &amp;quot;red&amp;quot;,&lt;br /&gt;
        &amp;quot;tl_peds&amp;quot;: &amp;quot;red&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_ry_1&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;$initialise_machine&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_ry&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_g_2&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_ry_1&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_g&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;500&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_y_3&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_g_2&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_y&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_r_4&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_y_3&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_r&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;500&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;peds_g_5&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_r_4&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;peds_g&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;peds_r_6&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;peds_g_5&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;peds_r&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: null,&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;peds_r_6&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;fileType&amp;quot;: &amp;quot;Timed_Trace&amp;quot;,&lt;br /&gt;
    &amp;quot;formatVersion&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;savedAt&amp;quot;: &amp;quot;2021-03-03T11:04:08.460477Z&amp;quot;,&lt;br /&gt;
    &amp;quot;creator&amp;quot;: &amp;quot;User&amp;quot;,&lt;br /&gt;
    &amp;quot;proB2KernelVersion&amp;quot;: &amp;quot;4.0.0-SNAPSHOT&amp;quot;,&lt;br /&gt;
    &amp;quot;proBCliVersion&amp;quot;: null,&lt;br /&gt;
    &amp;quot;modelName&amp;quot;: null&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Monte Carlo Simulation ===&lt;br /&gt;
&lt;br /&gt;
It is also possible to apply Monte Carlo simulation to generate a certain number of simulations.&lt;br /&gt;
Here, all simulations are played without real time. However, it is possible for the user, to replay the generated scenarios with real-time afterwards. &lt;br /&gt;
&lt;br /&gt;
The input parameters are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Number of Simulations&amp;lt;/em&amp;gt; defines the number of simulations to be generated.&lt;br /&gt;
* &amp;lt;em&amp;gt; Max Steps Before Start&amp;lt;/em&amp;gt; defines the number of steps before taking into account the starting and ending conditions.&lt;br /&gt;
* &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; defines condition to simulate until before taking &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; into account. It is either defined by a &amp;lt;em&amp;gt;No Condition&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Number of Steps&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Starting Time&amp;lt;/em&amp;gt; or &amp;lt;em&amp;gt;Starting Predicate&amp;lt;/em&amp;gt;.&lt;br /&gt;
* &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; defines condition to simulate until after taking  &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; into account (defines the last transition of the simulation). It is either defined by a &amp;lt;em&amp;gt;Number of Steps&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Ending Time&amp;lt;/em&amp;gt; or &amp;lt;em&amp;gt;Ending Predicate&amp;lt;/em&amp;gt;&lt;br /&gt;
* &amp;lt;em&amp;gt;Check&amp;lt;/em&amp;gt; defines the check to apply for the simulation. &amp;lt;em&amp;gt;Monte Carlo Simulation&amp;lt;/em&amp;gt; means that there are no checks to be applied, while the other options are &amp;lt;em&amp;gt;Hypothesis Testing&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Estimation&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:MonteCarloSimulation.png|400px]]&lt;br /&gt;
&lt;br /&gt;
Furthermore, there are two statistical validation techniques that can be applied based on Monte Carlo simulations: Hypothesis Testing and Estimation.&lt;br /&gt;
&lt;br /&gt;
=== Hypothesis Testing ===&lt;br /&gt;
&lt;br /&gt;
Hypothesis Testing expects the same parameters as Monte Carlo Simulation: &amp;lt;em&amp;gt;Max Steps before Simulation&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Number of Simulations&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The additional input parameters for Hypothesis Testing are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Property&amp;lt;/em&amp;gt; defines the property to be checked between &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; for each simulation. Possible configurations are:&lt;br /&gt;
** &amp;lt;em&amp;gt;All Invariants&amp;lt;/em&amp;gt; can be used to check all invariants.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate as Invariant&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is always true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Final Predicate&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked in the final state of a simulation.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate Eventually&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is eventually true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Timing&amp;lt;/em&amp;gt; can be used to check the time.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Hypothesis Check&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Left-tailed hypothesis test&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Right-tailed hypothesis test&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Two-tailed hypothesis test&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Probability&amp;lt;/em&amp;gt; (in the hypothesis)&lt;br /&gt;
* &amp;lt;em&amp;gt;Significance Level&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:HypothesisTesting.png|400px]]&lt;br /&gt;
&lt;br /&gt;
=== Estimation ===&lt;br /&gt;
&lt;br /&gt;
Estimation expects the same parameters as Monte Carlo Simulation: &amp;lt;em&amp;gt;Number of Simulations&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The additional input parameters for Estimation are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Property&amp;lt;/em&amp;gt; defines the property to be checked between &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; for each simulation. Possible configurations are:&lt;br /&gt;
** &amp;lt;em&amp;gt;All Invariants&amp;lt;/em&amp;gt; can be used to check all invariants.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate as Invariant&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is always true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Final Predicate&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked in the final state of a simulation.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate Eventually&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is eventually true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Timing&amp;lt;/em&amp;gt; can be used to check the time.&lt;br /&gt;
** &amp;lt;em&amp;gt;Average&amp;lt;/em&amp;gt; can be used to check the average value of an expression.&lt;br /&gt;
** &amp;lt;em&amp;gt;Sum&amp;lt;/em&amp;gt; can be used to check the sum of an expression.&lt;br /&gt;
* &amp;lt;em&amp;gt;Estimator&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Minimum Estimator&amp;lt;/em&amp;gt; returns the minimum estimated value from all simulated runs.&lt;br /&gt;
** &amp;lt;em&amp;gt;Mean Estimator&amp;lt;/em&amp;gt; returns the mean estimated value from all simulated runs.&lt;br /&gt;
** &amp;lt;em&amp;gt;Maximum Estimator&amp;lt;/em&amp;gt; returns the maximum estimated value from all simulated runs.&lt;br /&gt;
* &amp;lt;em&amp;gt;Desired Value&amp;lt;/em&amp;gt;&lt;br /&gt;
* &amp;lt;em&amp;gt;Epsilon&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For an estimated value e, a desired value d, and an epsilon eps, it checks for each simulation whether e is within [d - eps, d + eps]&lt;br /&gt;
&lt;br /&gt;
[[File:Estimation.png|400px]]&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=SimB&amp;diff=5891</id>
		<title>SimB</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=SimB&amp;diff=5891"/>
		<updated>2025-02-19T18:43:22Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Direct Activation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== SimB ==&lt;br /&gt;
&lt;br /&gt;
Additional documentation is available here: [https://github.com/hhu-stups/prob2_ui/blob/develop/src/main/helpsources/help_en/Main%20Menu/Advanced/SimB.md SimB Documentation]&lt;br /&gt;
&lt;br /&gt;
SimB is a simulator built on top of ProB.  It is available in the latest SNAPSHOT version in the new JavaFX based user interface [[ProB2-UI]] (https://github.com/hhu-stups/prob2_ui), The modeler can write SimB annotations for a formal model to simulate it. Examples are available at https://github.com/favu100/SimB-examples.&lt;br /&gt;
Furthermore, it is then possible to validate probabilistic and timing properties with statistical validation techniques such as hypothesis testing and estimation.&lt;br /&gt;
&lt;br /&gt;
SimB also contains a feature called interactive simulation.&lt;br /&gt;
This feature allows user interaction to trigger a simulation.&lt;br /&gt;
For interactive simulation, a modeler has to encode SimB listeners on events, triggering a SimB simulation.&lt;br /&gt;
Interactive Simulation examples are available at https://github.com/favu100/SimB-examples/tree/main/Interactive_Examples.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
More recently, SimB is extended by a new feature which makes it possible to load an Reinforcement learning Agent.&lt;br /&gt;
Technically, each step of the RL agent is converted into a SimB activation.&lt;br /&gt;
In order to simulate a RL agent in SimB, one must (1) create a formal B model for the RL agent, and (2) create a mapping between the state in the RL agent and the formal model, and (3) provide information to the formal B model again.&lt;br /&gt;
Reinforcement Learning examples are available at: https://github.com/hhu-stups/reinforcement-learning-b-models&lt;br /&gt;
&lt;br /&gt;
== Citing SimB ==&lt;br /&gt;
To cite SimB as a tool, its timing or probabilistic simulation features, or SimBs statistical validation techniques, please use:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@InProceedings{simb,&lt;br /&gt;
  Author    = {Vu, Fabian and Leuschel, Michael and Mashkoor, Atif},&lt;br /&gt;
  Title        = {{Validation of Formal Models by Timed Probabilistic Simulation}},&lt;br /&gt;
  Booktitle    = {Proceedings ABZ},&lt;br /&gt;
  Year        = 2021,&lt;br /&gt;
  Series    = {LNCS},&lt;br /&gt;
  Volume     = {12709},&lt;br /&gt;
  Pages = {81--96}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To cite SimBs interactive simulation, please use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@InProceedings{simb,&lt;br /&gt;
  Author    = {Vu, Fabian and Leuschel, Michael},&lt;br /&gt;
  Title        = {{Validation of Formal Models by Interactive Simulation}},&lt;br /&gt;
  Booktitle    = {Proceedings ABZ},&lt;br /&gt;
  Year        = 2023&lt;br /&gt;
  Series = {LNCS},&lt;br /&gt;
  Volume = {14010},&lt;br /&gt;
  Pages = {59--69}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using SimB ==&lt;br /&gt;
&lt;br /&gt;
Start SimB via &amp;quot;SimB&amp;quot; in the &amp;quot;Advanced&amp;quot; Menu after opening a machine. &lt;br /&gt;
&lt;br /&gt;
[[File:Open_SimB.png|800px]]&lt;br /&gt;
&lt;br /&gt;
Now, you can open a SimB file (JSON format)  controlling the underlying formal model.&lt;br /&gt;
&lt;br /&gt;
[[File:SimB_Window.png|800px]]&lt;br /&gt;
&lt;br /&gt;
A SimB file consists of SimB activations and SimB listeners to simulate the model.&lt;br /&gt;
SimB activations encode an activation diagram with probabilistic and timing elements for automatic simulation.&lt;br /&gt;
To enable interactive simulation, it is also necessary to encode interactive elements aka. SimB listeners which trigger other SimB activations.&lt;br /&gt;
Within these elements, the modeler can user B expressions which are evaluated on the current state.&lt;br /&gt;
&lt;br /&gt;
The general structure of a SimB simulation is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;activations&amp;quot;: [...]&lt;br /&gt;
  &amp;quot;listeners&amp;quot;: [...]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;activations&amp;lt;/tt&amp;gt; stores SimB activations, while &amp;lt;tt&amp;gt;listeners&amp;lt;/tt&amp;gt; stores SimB listeners.&lt;br /&gt;
&amp;lt;tt&amp;gt;activations&amp;lt;/tt&amp;gt; must be encoded,  &amp;lt;tt&amp;gt;listeners&amp;lt;/tt&amp;gt; is optional and defaults to the empty list.&lt;br /&gt;
&lt;br /&gt;
== Probabilistic and Timing Elements in SimB ==&lt;br /&gt;
&lt;br /&gt;
The SimB file always contains an &amp;lt;tt&amp;gt;activations&amp;lt;/tt&amp;gt; field storing a list of probabilistic and timing elements to control the simulation. Probabilistic values ​​are always evaluated to ensure that the sum of all possibilities is always 1. Otherwise an error will be thrown at runtime. &lt;br /&gt;
There are two types of activations: direct activation and probabilistic choice.&lt;br /&gt;
All activations are identified by their  &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
===Direct Activation ===&lt;br /&gt;
&lt;br /&gt;
A direct activation activates an event to be executed in the future.&lt;br /&gt;
It requires the fields &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt; to be defined.&lt;br /&gt;
All other fields can be defined optionally.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt; identifies the activated event by its name.&lt;br /&gt;
* &amp;lt;tt&amp;gt;after&amp;lt;/tt&amp;gt; defines the scheduled time (in ms) when activating an event. By default, it is set to 0 ms, e.g., when this field is not defined explicitly.&lt;br /&gt;
* &amp;lt;tt&amp;gt;activating&amp;lt;/tt&amp;gt; stores events that will be activated when executing the event defined by &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;. Missing definition leads to the behavior that no other events are activated. The modeler can either write a String (to activate a single event) or a list of Strings (to activate multiple events)&lt;br /&gt;
* &amp;lt;tt&amp;gt;activationKind&amp;lt;/tt&amp;gt; stores the kind of activation for &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;. Possible options are &amp;lt;tt&amp;gt;multi&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;single&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;single:min&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;single:max&amp;lt;/tt&amp;gt;. The default value is &amp;lt;tt&amp;gt;multi&amp;lt;/tt&amp;gt;&lt;br /&gt;
** &amp;lt;tt&amp;gt;multi&amp;lt;/tt&amp;gt; means that the activation will be queued for execution. &lt;br /&gt;
** &amp;lt;tt&amp;gt;single&amp;lt;/tt&amp;gt; means that the activation will only be queued if there are no queued activations with the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;&lt;br /&gt;
** &amp;lt;tt&amp;gt;single:min&amp;lt;/tt&amp;gt; means that the activation will only be queued if (1) there are no queued activations for the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; or (2) there is a queued activation with the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; whose value for the scheduled time is greater. In the case of (2), the already queued activation will be discarded.&lt;br /&gt;
** &amp;lt;tt&amp;gt;single:max&amp;lt;/tt&amp;gt; means that the activation will only be queued if (1) there are no queued activations for the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; or (2) there is a queued activation with the same &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; whose value for the scheduled time is lower. In the case of (2), the already queued activation will be discarded.&lt;br /&gt;
* &amp;lt;tt&amp;gt;additionalGuards&amp;lt;/tt&amp;gt; stores optional guards when executing the event stored in &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;fixedVariables&amp;lt;/tt&amp;gt; stores a Map. Here, a variable (parameter, or non-deterministic assigned variable) is assigned to its value.&lt;br /&gt;
* &amp;lt;tt&amp;gt;probabilisticVariables&amp;lt;/tt&amp;gt;stores a Map. Here a variable (parameter, or non-deterministic assigned variable) is assigned to another Map defining the probabilistic choice of its value. The second Map stores Key-Value pairs where values are mapped to the probability. &lt;br /&gt;
- &amp;lt;tt&amp;gt;transitionSelection&amp;lt;/tt&amp;gt; determines how SimB choses from multiple possible transitions (due to not specified variables):&lt;br /&gt;
** &amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; (the default) means that the first transition is chosen for execution.&lt;br /&gt;
** &amp;lt;tt&amp;gt;uniform&amp;lt;/tt&amp;gt; means that a transition is selected from all alternatives uniformly.&lt;br /&gt;
* &amp;lt;tt&amp;gt;priority&amp;lt;/tt&amp;gt; stores the priority for scheduling &amp;lt;tt&amp;gt;execute&amp;lt;/tt&amp;gt;. Lower number means greater priority.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;id&amp;quot;:  ...&lt;br /&gt;
   &amp;quot;execute&amp;quot;: ...&lt;br /&gt;
   &amp;quot;after&amp;quot;: ...&lt;br /&gt;
   &amp;quot;activating&amp;quot;: ...&lt;br /&gt;
   &amp;quot;activationKind&amp;quot;: ...&lt;br /&gt;
   &amp;quot;additionalGuards&amp;quot;: ...&lt;br /&gt;
   &amp;quot;fixedVariables&amp;quot;: ....&lt;br /&gt;
   &amp;quot;probabilisticVariables&amp;quot;: ....&lt;br /&gt;
   &amp;quot;priority&amp;quot;: ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Probabilistic Choice ===&lt;br /&gt;
&lt;br /&gt;
A probabilistic choice selects an event to be executed in the future.&lt;br /&gt;
It requires the two fields &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;chooseActivation&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;chooseActivation&amp;lt;/tt&amp;gt; is a Map storing Key-Value pairs where activations (identified by their &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;) are mapped to a probability.  It is possible to chain multiple probabilistic choices together, but eventually, a direct activation must be reached.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;id&amp;quot;:  ...&lt;br /&gt;
   &amp;quot;chooseActivation&amp;quot;: ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the following, an example for a SimB file controlling a Traffic Lights for cars and pedestrians (with timing and probabilistic behavior) is shown:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;activations&amp;quot;: [&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;$initialise_machine&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;$initialise_machine&amp;quot;, &amp;quot;activating&amp;quot;:&amp;quot;choose&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;choose&amp;quot;, &amp;quot;chooseActivation&amp;quot;:{&amp;quot;cars_ry&amp;quot;: &amp;quot;0.8&amp;quot;, &amp;quot;peds_g&amp;quot;: &amp;quot;0.2&amp;quot;}},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_ry&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_ry&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;cars_g&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_g&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_g&amp;quot;, &amp;quot;after&amp;quot;:500, &amp;quot;activating&amp;quot;:&amp;quot;cars_y&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_y&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_y&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;cars_r&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;cars_r&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;cars_r&amp;quot;, &amp;quot;after&amp;quot;:500, &amp;quot;activating&amp;quot;:&amp;quot;choose&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;peds_g&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;peds_g&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;peds_r&amp;quot;},&lt;br /&gt;
  {&amp;quot;id&amp;quot;:&amp;quot;peds_r&amp;quot;, &amp;quot;execute&amp;quot;:&amp;quot;peds_r&amp;quot;, &amp;quot;after&amp;quot;:5000, &amp;quot;activating&amp;quot;:&amp;quot;choose&amp;quot;}&lt;br /&gt;
 ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interactive Elements in SimB ==&lt;br /&gt;
&lt;br /&gt;
Interactive elements in SimB are so called SimB listeners.&lt;br /&gt;
A SimB listener consists of four fields &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;activating&amp;lt;/tt&amp;gt;.&lt;br /&gt;
This means that the SimB listener associated with &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; listens on a manual/user interaction on &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; with &amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt; after which activations in &amp;lt;tt&amp;gt;activating&amp;lt;/tt&amp;gt; are triggered.&lt;br /&gt;
&amp;lt;tt&amp;gt;predicate&amp;lt;/tt&amp;gt; is optional and defaults to &amp;lt;tt&amp;gt;1=1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Manual/User interaction is recognized via VisB and ProB&#039;s Operations View.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;id&amp;quot;:  ...&lt;br /&gt;
   &amp;quot;event&amp;quot;: ...&lt;br /&gt;
   &amp;quot;predicate&amp;quot;: ...&lt;br /&gt;
   &amp;quot;activating&amp;quot;: [...]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the following, we parts of a SimB simulation from an automotive case study.&lt;br /&gt;
The SimB simulation contains a SimB listener which is linked to two activations.&lt;br /&gt;
The case study models the car&#039;s lighting system controlled by pitman controller, the key ignition, and the warning lights button.&lt;br /&gt;
&lt;br /&gt;
The SimB listeners states that SimB listens on user interaction on the event &amp;lt;tt&amp;gt;ENV_Pitman_DirectionBlinking&amp;lt;/tt&amp;gt;, to trigger two SimB activations &amp;lt;tt&amp;gt;blinking_on&amp;lt;/tt&amp;gt; and blinking_off afterward.&lt;br /&gt;
Practically, this means that a driver&#039;s input on the pitman for direction blinking activates the blinking cycle for the corresponding direction indicators.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;activations&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;blinking_on&amp;quot;, &lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;RTIME_BlinkerOn&amp;quot;, &lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;curDeadlines(blink_deadline)&amp;quot;,&lt;br /&gt;
       &amp;quot;activating&amp;quot; : &amp;quot;blinking_off&amp;quot;, &lt;br /&gt;
       ...&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;blinking_off&amp;quot;, &lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;RTIME_BlinkerOff&amp;quot;, &lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;curDeadlines(blink_deadline)&amp;quot;,&lt;br /&gt;
       &amp;quot;activating&amp;quot; : &amp;quot;blinking_on&amp;quot;, &lt;br /&gt;
       ...&lt;br /&gt;
    },&lt;br /&gt;
    ...&lt;br /&gt;
  ]&lt;br /&gt;
  &amp;quot;listeners&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;start_blinking&amp;quot;,&lt;br /&gt;
      &amp;quot;event&amp;quot;: &amp;quot;ENV_Pitman_DirectionBlinking&amp;quot;, &lt;br /&gt;
      &amp;quot;activating&amp;quot; : [&amp;quot;blinking_on&amp;quot;, &amp;quot;blinking_off&amp;quot;]&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Reinforcement Learning Agent in SimB ==&lt;br /&gt;
&lt;br /&gt;
Instead of loading a SimB simulation as a JSON file, one can also load a Reinforcement Learning &lt;br /&gt;
agent implemented in Python (.py).&lt;br /&gt;
For the simulation to work, one has to apply the following steps:&lt;br /&gt;
&lt;br /&gt;
1. Train a model of a Reinforcement Learning agent.&lt;br /&gt;
&lt;br /&gt;
2. Create a formal B model (including safety shield) for the RL agent. &lt;br /&gt;
&lt;br /&gt;
The operations represent the actions the RL agent can choose from. The formal model&#039;s state mainly represents the state of the environment.&lt;br /&gt;
Safety shields are encoded by the operations&#039; guards which are provided to the RL agent. Enabled operations are considered to be safe. Thus, the RL agent chooses the enabled operation/action with the highest predicted reward.&lt;br /&gt;
The operations&#039; substitutions model the desired behavior of the respective actions.&lt;br /&gt;
&lt;br /&gt;
An example for the FASTER of a HighwayEnvironment is as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FASTER = &lt;br /&gt;
PRE&lt;br /&gt;
  ¬(∃v. (v ∈ PresentVehicles \ {EgoVehicle} ∧ VehiclesX(v) &amp;gt; 0.0 ∧ VehiclesX(v) &amp;lt; 45.0 ∧ &lt;br /&gt;
  VehiclesY(v) &amp;lt; 3.5 ∧ VehiclesY(v) &amp;gt; -3.5))&lt;br /&gt;
THEN&lt;br /&gt;
  Crash :∈ BOOL ||&lt;br /&gt;
  PresentVehicles :∈ P(Vehicles) ;&lt;br /&gt;
  VehiclesX :∈ Vehicles → R ||&lt;br /&gt;
  VehiclesY :∈ Vehicles → R ||&lt;br /&gt;
  VehiclesVx :| (VehiclesVx ∈ PresentVehicles → R ∧ &lt;br /&gt;
             VehiclesVx(EgoVehicle) ≥ VehiclesVx’(EgoVehicle) - 0.05) ||&lt;br /&gt;
  VehiclesVy :∈ Vehicles → R ||&lt;br /&gt;
  VehiclesAx :| (VehiclesAx ∈ PresentVehicles → R ∧ VehiclesAx(EgoVehicle) ≥ -0.05) || &lt;br /&gt;
  VehiclesAy :∈ Vehicles → R ||&lt;br /&gt;
  Reward :∈ R&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lines 2-4 shows the operation&#039;s guard which is used as safety shield. &lt;br /&gt;
&lt;br /&gt;
Lines 6-15 shows the operation&#039;s substitution describing the desired behavior after executing FASTER.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3. Implement the mapping between the RL agent in Python and the formal B model.&lt;br /&gt;
This includes the mapping of actions to operations, and the mapping of information from the RL agent, particularly the environment and observation, to the variables.&lt;br /&gt;
&lt;br /&gt;
An example for the mapping of actions to operations is as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
action_names = {&lt;br /&gt;
    0: &amp;quot;LANE_LEFT&amp;quot;,&lt;br /&gt;
    1: &amp;quot;IDLE&amp;quot;,&lt;br /&gt;
    2: &amp;quot;LANE_RIGHT&amp;quot;,&lt;br /&gt;
    3: &amp;quot;FASTER&amp;quot;,&lt;br /&gt;
    4: &amp;quot;SLOWER&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, one can see that the numbers representing the actions in the RL agents are mapped to the corresponding operation names in the formal B model.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An example for a mapping to a variable in the formal B model is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def get_VehiclesX(obs):&lt;br /&gt;
    return &amp;quot;{{EgoVehicle |-&amp;gt; {0}, Vehicles2 |-&amp;gt; {1}, Vehicles3 |-&amp;gt; {2}, &lt;br /&gt;
             Vehicles4 |-&amp;gt; {3},  Vehicles5 |-&amp;gt; {4}}}&amp;quot;&lt;br /&gt;
         .format(obs[0][1]*200, obs[1][1]*200, obs[2][1]*200, &lt;br /&gt;
                  obs[3][1]*200, obs[4][1]*200) # Implemented manually&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remark: While the getter for the variable is generated by B2Program, the function for the mapping is implemented manually.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4. Implement necessary messages sent between the ProB animator and the RL agent.&lt;br /&gt;
Simulation should be a while-loop which runs while the simulation has not finished. &lt;br /&gt;
&lt;br /&gt;
* 1st message: Sent from ProB Animator: List of enabled operations&lt;br /&gt;
** Meanwhile RL agent predicts enabled operation with highest reward&lt;br /&gt;
* 2nd message: Sent from RL agent: Name of chosen action/operation&lt;br /&gt;
* 3rd message: Sent from RL agent: Time until executing chosen action/operation&lt;br /&gt;
* 4th message: Sent from RL agent: Succeeding B state as a predicate&lt;br /&gt;
* 5th message: Sent from RL agent: Boolean flag describing whether simulation is finished&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example code (line 70 - 113; particularly 86 - 113): https://github.com/hhu-stups/reinforcement-learning-b-models/blob/main/HighwayEnvironment/HighwayEnvironment.py&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To generate a RL agent for SimB, one can use the high-level code generator B2Program: https://github.com/favu100/b2program&lt;br /&gt;
&lt;br /&gt;
Given a formal B model, B2Program generates an RL agent which loads a given trained model and execute the necessary steps. This includes the fourth step described before.&lt;br /&gt;
The third step still has to be implemented; in this step, B2Program only generates the templates for the mappings which are then completed manually.&lt;br /&gt;
&lt;br /&gt;
== Validation ==&lt;br /&gt;
&lt;br /&gt;
=== Real-Time Simulation ===&lt;br /&gt;
&lt;br /&gt;
Using a SimB file, the modeler can play a single simulation on the underlying model in real-time. &lt;br /&gt;
The modeler can then manually check whether the model behaves as desired. Combining [[VisB]] and SimB, a simulation can be seen as an animated picture similar to a GIF picture.  &lt;br /&gt;
This gives the domain expert even a better understanding of the model.&lt;br /&gt;
With SimB listeners, it is also possible to encode simulations that are triggered by manual/user actions.&lt;br /&gt;
&lt;br /&gt;
A Traffic Light example (based on the SimB file shown in [[SimB|Using_SimB]] ) simulating the first 21 seconds is shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:TrafficLight_Simulation.gif|800px]]&lt;br /&gt;
&lt;br /&gt;
=== Timed Trace Replay ===&lt;br /&gt;
&lt;br /&gt;
Based on a single simulation, the modeler can generate a timed trace which is also stored in the SimB format. Afterwards, it can be used to replay a scenario. similar to real-time simulation. &lt;br /&gt;
&lt;br /&gt;
Below, the resulting timed trace for the scenario in [[SimB|Real-Time Simulation]] is shown&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;activations&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;$initialise_machine&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: {&lt;br /&gt;
        &amp;quot;tl_cars&amp;quot;: &amp;quot;red&amp;quot;,&lt;br /&gt;
        &amp;quot;tl_peds&amp;quot;: &amp;quot;red&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_ry_1&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;$initialise_machine&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_ry&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_g_2&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_ry_1&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_g&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;500&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_y_3&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_g_2&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_y&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;cars_r_4&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_y_3&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;cars_r&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;500&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;peds_g_5&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;cars_r_4&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;peds_g&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: [&lt;br /&gt;
        &amp;quot;peds_r_6&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;peds_g_5&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;execute&amp;quot;: &amp;quot;peds_r&amp;quot;,&lt;br /&gt;
      &amp;quot;after&amp;quot;: &amp;quot;5000&amp;quot;,&lt;br /&gt;
      &amp;quot;priority&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;additionalGuards&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activationKind&amp;quot;: null,&lt;br /&gt;
      &amp;quot;fixedVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;probabilisticVariables&amp;quot;: null,&lt;br /&gt;
      &amp;quot;activating&amp;quot;: null,&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;peds_r_6&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;fileType&amp;quot;: &amp;quot;Timed_Trace&amp;quot;,&lt;br /&gt;
    &amp;quot;formatVersion&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;savedAt&amp;quot;: &amp;quot;2021-03-03T11:04:08.460477Z&amp;quot;,&lt;br /&gt;
    &amp;quot;creator&amp;quot;: &amp;quot;User&amp;quot;,&lt;br /&gt;
    &amp;quot;proB2KernelVersion&amp;quot;: &amp;quot;4.0.0-SNAPSHOT&amp;quot;,&lt;br /&gt;
    &amp;quot;proBCliVersion&amp;quot;: null,&lt;br /&gt;
    &amp;quot;modelName&amp;quot;: null&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Monte Carlo Simulation ===&lt;br /&gt;
&lt;br /&gt;
It is also possible to apply Monte Carlo simulation to generate a certain number of simulations.&lt;br /&gt;
Here, all simulations are played without real time. However, it is possible for the user, to replay the generated scenarios with real-time afterwards. &lt;br /&gt;
&lt;br /&gt;
The input parameters are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Number of Simulations&amp;lt;/em&amp;gt; defines the number of simulations to be generated.&lt;br /&gt;
* &amp;lt;em&amp;gt; Max Steps Before Start&amp;lt;/em&amp;gt; defines the number of steps before taking into account the starting and ending conditions.&lt;br /&gt;
* &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; defines condition to simulate until before taking &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; into account. It is either defined by a &amp;lt;em&amp;gt;No Condition&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Number of Steps&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Starting Time&amp;lt;/em&amp;gt; or &amp;lt;em&amp;gt;Starting Predicate&amp;lt;/em&amp;gt;.&lt;br /&gt;
* &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; defines condition to simulate until after taking  &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; into account (defines the last transition of the simulation). It is either defined by a &amp;lt;em&amp;gt;Number of Steps&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Ending Time&amp;lt;/em&amp;gt; or &amp;lt;em&amp;gt;Ending Predicate&amp;lt;/em&amp;gt;&lt;br /&gt;
* &amp;lt;em&amp;gt;Check&amp;lt;/em&amp;gt; defines the check to apply for the simulation. &amp;lt;em&amp;gt;Monte Carlo Simulation&amp;lt;/em&amp;gt; means that there are no checks to be applied, while the other options are &amp;lt;em&amp;gt;Hypothesis Testing&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Estimation&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:MonteCarloSimulation.png|400px]]&lt;br /&gt;
&lt;br /&gt;
Furthermore, there are two statistical validation techniques that can be applied based on Monte Carlo simulations: Hypothesis Testing and Estimation.&lt;br /&gt;
&lt;br /&gt;
=== Hypothesis Testing ===&lt;br /&gt;
&lt;br /&gt;
Hypothesis Testing expects the same parameters as Monte Carlo Simulation: &amp;lt;em&amp;gt;Max Steps before Simulation&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Number of Simulations&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The additional input parameters for Hypothesis Testing are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Property&amp;lt;/em&amp;gt; defines the property to be checked between &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; for each simulation. Possible configurations are:&lt;br /&gt;
** &amp;lt;em&amp;gt;All Invariants&amp;lt;/em&amp;gt; can be used to check all invariants.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate as Invariant&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is always true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Final Predicate&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked in the final state of a simulation.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate Eventually&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is eventually true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Timing&amp;lt;/em&amp;gt; can be used to check the time.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Hypothesis Check&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Left-tailed hypothesis test&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Right-tailed hypothesis test&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Two-tailed hypothesis test&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Probability&amp;lt;/em&amp;gt; (in the hypothesis)&lt;br /&gt;
* &amp;lt;em&amp;gt;Significance Level&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:HypothesisTesting.png|400px]]&lt;br /&gt;
&lt;br /&gt;
=== Estimation ===&lt;br /&gt;
&lt;br /&gt;
Estimation expects the same parameters as Monte Carlo Simulation: &amp;lt;em&amp;gt;Number of Simulations&amp;lt;/em&amp;gt;, &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The additional input parameters for Estimation are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;em&amp;gt;Property&amp;lt;/em&amp;gt; defines the property to be checked between &amp;lt;em&amp;gt;Starting Condition&amp;lt;/em&amp;gt; and &amp;lt;em&amp;gt;Ending Condition&amp;lt;/em&amp;gt; for each simulation. Possible configurations are:&lt;br /&gt;
** &amp;lt;em&amp;gt;All Invariants&amp;lt;/em&amp;gt; can be used to check all invariants.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate as Invariant&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is always true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Final Predicate&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked in the final state of a simulation.&lt;br /&gt;
** &amp;lt;em&amp;gt;Predicate Eventually&amp;lt;/em&amp;gt; can be used to provide a predicate to be checked whether it is eventually true.&lt;br /&gt;
** &amp;lt;em&amp;gt;Timing&amp;lt;/em&amp;gt; can be used to check the time.&lt;br /&gt;
** &amp;lt;em&amp;gt;Average&amp;lt;/em&amp;gt; can be used to check the average value of an expression.&lt;br /&gt;
** &amp;lt;em&amp;gt;Sum&amp;lt;/em&amp;gt; can be used to check the sum of an expression.&lt;br /&gt;
* &amp;lt;em&amp;gt;Estimator&amp;lt;/em&amp;gt;&lt;br /&gt;
** &amp;lt;em&amp;gt;Minimum Estimator&amp;lt;/em&amp;gt; returns the minimum estimated value from all simulated runs.&lt;br /&gt;
** &amp;lt;em&amp;gt;Mean Estimator&amp;lt;/em&amp;gt; returns the mean estimated value from all simulated runs.&lt;br /&gt;
** &amp;lt;em&amp;gt;Maximum Estimator&amp;lt;/em&amp;gt; returns the maximum estimated value from all simulated runs.&lt;br /&gt;
* &amp;lt;em&amp;gt;Desired Value&amp;lt;/em&amp;gt;&lt;br /&gt;
* &amp;lt;em&amp;gt;Epsilon&amp;lt;/em&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For an estimated value e, a desired value d, and an epsilon eps, it checks for each simulation whether e is within [d - eps, d + eps]&lt;br /&gt;
&lt;br /&gt;
[[File:Estimation.png|400px]]&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5818</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5818"/>
		<updated>2024-06-13T13:07:20Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Differences with AtelierB/B4Free */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
In ProB, however, some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 size(s)   the length of a string s&lt;br /&gt;
 rev(s)    the reverse of a string s&lt;br /&gt;
 s ^ t     the concatenation of two strings&lt;br /&gt;
 conc(ss)  the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the &amp;lt;tt&amp;gt;STRING_AS_SEQUENCE&amp;lt;/tt&amp;gt; preference.&lt;br /&gt;
The [[External_Functions|library]] LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &amp;lt;tt&amp;gt;TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;FORMAT_TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;INT_TO_HEX_STRING&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
&lt;br /&gt;
ProB also allows multi-line strings.&lt;br /&gt;
&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 \n  newline (ASCII character 13)&lt;br /&gt;
 \r  carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;  the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;  the single quote symbol &#039;&lt;br /&gt;
 \\  the backslash symbol&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Within single-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r into an integer&lt;br /&gt;
 ceiling(r)  convert a real r into an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One can also use a lowercase &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; for literals in scientific notation (e.g. &amp;lt;tt&amp;gt;1.0e-10&amp;lt;/tt&amp;gt;).&lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus do not hold.&lt;br /&gt;
The  [[External_Functions|library]] LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &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;RLOG&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RSQRT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RPOW&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
You can turn off support for REALS using the preference &amp;lt;tt&amp;gt;ALLOW_REALS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The &amp;lt;tt&amp;gt;REAL_SOLVER&amp;lt;/tt&amp;gt; preference how constraints are solved.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, &amp;lt;tt&amp;gt;n=[1,2,1]&amp;lt;/tt&amp;gt;&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S.&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 tree(S)       set of trees over domain S&lt;br /&gt;
 btree(S)      set of binary trees over domain S&lt;br /&gt;
 top(t)        top of a tree&lt;br /&gt;
 const(E,s)    construct a tree from info E and sequence of subtrees s&lt;br /&gt;
 rank(t,n)     rank of the node at end of branch n in the tree t&lt;br /&gt;
 father(t,n)   father of the node denoted by branch n in the tree t&lt;br /&gt;
 son(t,n,i)    the ith son of the node denoted by branch n in tree t&lt;br /&gt;
 sons(t)       the sequence of sons of the root of the tree t&lt;br /&gt;
 subtree(t,n)&lt;br /&gt;
 arity(t,n)&lt;br /&gt;
 bin(E)        construct a binary tree with a single node E&lt;br /&gt;
 bin(tl,E,tr)  construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
 left(t)       the left (first) son of the root of the binary tree t&lt;br /&gt;
 right(t)      the right (last) son of the root of the binary tree t&lt;br /&gt;
 sizet(t)      the size of the tree (number of nodes)&lt;br /&gt;
 prefix(t)     the nodes of the tree t in prefix order&lt;br /&gt;
 postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
 mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates, expressions and substitutions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 IF P THEN E1 END                    conditional branching&lt;br /&gt;
 IF P THEN E1 ELSIF E2 END           we also allow multiple ELSIF branches&lt;br /&gt;
 IF P THEN E1 ELSE E2 END            but you always need an ELSE branch for expressions and predicates&lt;br /&gt;
 IF P THEN E1 ELSIF E2 ELSE E3 END&lt;br /&gt;
 LET x1,... BE x1=E1 &amp;amp; ... IN E END  introduce local variables&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expression &amp;lt;tt&amp;gt;Ei&amp;lt;/tt&amp;gt; defining &amp;lt;tt&amp;gt;xi&amp;lt;/tt&amp;gt; is allowed to use &amp;lt;tt&amp;gt;x1,...,x(i-1)&amp;lt;/tt&amp;gt; for predicates/expressions.&lt;br /&gt;
By setting the preference &amp;lt;tt&amp;gt;ALLOW_COMPLEX_LETS&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;, this is also allowed for substitutions.&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 skip                                                      no operation&lt;br /&gt;
 x := E                                                    assignment&lt;br /&gt;
 f(x) := E                                                 functional override&lt;br /&gt;
 x :: S                                                    choice from set&lt;br /&gt;
 x : (P)                                                   choice by predicate P (constraining x; previous value of x is x$0)&lt;br /&gt;
 x &amp;lt;-- OP(x)                                               call operation and assign return value&lt;br /&gt;
 G||H                                                      parallel substitution**&lt;br /&gt;
 G;H                                                       sequential composition**&lt;br /&gt;
 ANY x,... WHERE P THEN G END                              non deterministic choice&lt;br /&gt;
 LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
 VAR x,... IN G END                                        generate local variables&lt;br /&gt;
 PRE P THEN G END&lt;br /&gt;
 ASSERT P THEN G END&lt;br /&gt;
 CHOICE G OR H END&lt;br /&gt;
 IF P THEN G END&lt;br /&gt;
 IF P THEN G ELSE H END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
 WHILE P1 DO G INVARIANT P2 VARIANT E END&lt;br /&gt;
 WHEN P THEN G END                                         is a synonym for SELECT P THEN G END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;amp;ast;&amp;amp;ast;: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
be wrapped inside a &amp;lt;tt&amp;gt;BEGIN END&amp;lt;/tt&amp;gt; or another statement (to avoid&lt;br /&gt;
confusion with the operators &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; on relations).&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
&lt;br /&gt;
You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CONSTRAINTS         P                     (logical predicate)&lt;br /&gt;
 SETS                S;T={e1,e2,...};...&lt;br /&gt;
 FREETYPES           x=x1,x2(arg2),...;...&lt;br /&gt;
 CONSTANTS           x,y,...&lt;br /&gt;
 CONCRETE_CONSTANTS  cx,cy,...&lt;br /&gt;
 PROPERTIES          P                     (logical predicate)&lt;br /&gt;
 DEFINITIONS         m(x,...) == BODY;...&lt;br /&gt;
 VARIABLES           x,y,...&lt;br /&gt;
 CONCRETE_VARIABLES  cv,cw,...&lt;br /&gt;
 INVARIANT           P                     (logical predicate)&lt;br /&gt;
 ASSERTIONS          P;...;P               (list of logical predicates separated by ;)&lt;br /&gt;
 INITIALISATION      S                     (substitution)&lt;br /&gt;
 OPERATIONS          O;...                 (operations)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 USES      list of machines&lt;br /&gt;
 INCLUDES  list of machines&lt;br /&gt;
 SEES      list of machines&lt;br /&gt;
 EXTENDS   list of machines&lt;br /&gt;
 PROMOTES  list of operations&lt;br /&gt;
 REFINES   machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 NAME1 == Expression;     Definition without arguments&lt;br /&gt;
 NAME2(ID,...,ID) == E2;  Definition with arguments&lt;br /&gt;
 &amp;quot;FILE.def&amp;quot;;              Include definitions from file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 GOAL == P                          to define a custom Goal predicate for Model Checking&lt;br /&gt;
                                    (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
 SCOPE == P                         to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
 scope_SETNAME == n..n              to define custom cardinality for set SETNAME&lt;br /&gt;
 scope_SETNAME == n                 equivalent to 1..n&lt;br /&gt;
 SET_PREF_MININT == n&lt;br /&gt;
 SET_PREF_MAXINT == n&lt;br /&gt;
 SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
 SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
 MAX_OPERATIONS_OPNAME == n         max. number of enablings for the operation OPNAME&lt;br /&gt;
 SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
 SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
 ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                    Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                    atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
 HEURISTIC_FUNCTION == n            in directed model-checking mode nodes with smalles value will be processed first&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization (n can be empty or a number):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ANIMATION_FUNCTIONn == e                           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
 ANIMATION_FUNCTION_DEFAULT == e                    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                                                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                                                    as a result you can also use STRING values,&lt;br /&gt;
                                                    or even other values which are pretty printed&lt;br /&gt;
 ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;                   a path to a gif file&lt;br /&gt;
 ANIMATION_STRn == &amp;quot;sometext&amp;quot;                       a string without spaces;&lt;br /&gt;
                                                    the result integer n will be rendered as a string&lt;br /&gt;
 ANIMATION_STR_JUSTIFY_LEFT == TRUE                 computes the longest string in the outputs and pads&lt;br /&gt;
                                                    the other strings accordingly&lt;br /&gt;
 SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n         additional padding between images in pixels&lt;br /&gt;
 SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n  additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]] (n can be empty or a number):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CUSTOM_GRAPH_NODESn == e  define a set of nodes to be shown,&lt;br /&gt;
                           nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                           records or sets of records like&lt;br /&gt;
                           rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node, ...)&lt;br /&gt;
                           Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                           Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                           Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
 CUSTOM_GRAPH_EDGESn == e  define a relation to be shown as a graph&lt;br /&gt;
                           edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                           where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                           the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like&lt;br /&gt;
color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, style:&amp;quot;filled&amp;quot;, nodes:e);&lt;br /&gt;
 CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, dir:&amp;quot;none&amp;quot;, penwidth:2, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can now also use a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
(like rankdir or layout) and optionally with edges and nodes attributes&lt;br /&gt;
(replacing CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also provide &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation;&lt;br /&gt;
                                    if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
 VISB_SVG_OBJECTSn == ...           define a record or set of records for creating new SVG objects&lt;br /&gt;
 VISB_SVG_UPDATESn == ...           define a record or set of records containing updates of SVG objects&lt;br /&gt;
 VISB_SVG_HOVERSn == ...            define a record or set of records for VisB hover functions&lt;br /&gt;
 VISB_SVG_BOX == ...                record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
 VISB_SVG_CONTENTS == ...           defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
 /* ... */  block comments&lt;br /&gt;
 // ...     line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 /*@symbolic */             put before comprehension set, lambda, union or composition to instruct ProB&lt;br /&gt;
                            to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
 /*@label LBL */            associates a label LBL with the following predicate&lt;br /&gt;
                            (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
 /*@desc DESC */            associates a description DESC with the preceding predicate or&lt;br /&gt;
                            introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                            There are three special descriptions:&lt;br /&gt;
                            /*@desc memo*/          to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                                    indicating that these functions should be memoized&lt;br /&gt;
                            /*@desc expand*/        to be put after identifiers (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                                                    indicating that they should be expanded and not kept symbolically&lt;br /&gt;
                            /*@desc prob-ignore */  to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                                    should be ignored by ProB&lt;br /&gt;
                                                    when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
 /*@file PATH */            associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                            put pragma after a seen or included machine&lt;br /&gt;
 /*@package NAME */         at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                            NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                            file should be in N1/N2/.../Nk&lt;br /&gt;
 /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                            NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
 /*@generated */            can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                            is generated from some other source&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 .mch   for abstract machine files&lt;br /&gt;
 .ref   for refinement machines&lt;br /&gt;
 .imp   for implementation machines&lt;br /&gt;
 .def   for DEFINITIONS files&lt;br /&gt;
 .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
 - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
 - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
 - not all tree operators are supported&lt;br /&gt;
 - the VALUES clause is only partially supported&lt;br /&gt;
 - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
   predicate or substitution;&lt;br /&gt;
   the arguments to definitions have to be expressions;&lt;br /&gt;
   definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
 - definitions are local to a machine&lt;br /&gt;
 - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
   sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
 - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
   of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
   if P is true then Q should also be well-defined)&lt;br /&gt;
 - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
 - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
   (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
 - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
   are required&lt;br /&gt;
 - You can apply prj1 and prj2 without providing the type arguments, e.g., prj2(prj1(1|-&amp;gt;2|-&amp;gt;3))&lt;br /&gt;
 - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
 - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
 - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
 - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
   and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
   as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
 - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
 - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
 - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
 - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead)&lt;br /&gt;
   ProB now allows btrue and bfalse to be used as predicates.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you discover more differences, please let us know!&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB now supports the Unicode mathematical symbols, exactly like Atelier-B&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
   !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
   !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), &lt;br /&gt;
   !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
 ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5817</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5817"/>
		<updated>2024-06-13T12:51:06Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Other notes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
In ProB, however, some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 size(s)   the length of a string s&lt;br /&gt;
 rev(s)    the reverse of a string s&lt;br /&gt;
 s ^ t     the concatenation of two strings&lt;br /&gt;
 conc(ss)  the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the &amp;lt;tt&amp;gt;STRING_AS_SEQUENCE&amp;lt;/tt&amp;gt; preference.&lt;br /&gt;
The [[External_Functions|library]] LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &amp;lt;tt&amp;gt;TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;FORMAT_TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;INT_TO_HEX_STRING&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
&lt;br /&gt;
ProB also allows multi-line strings.&lt;br /&gt;
&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 \n  newline (ASCII character 13)&lt;br /&gt;
 \r  carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;  the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;  the single quote symbol &#039;&lt;br /&gt;
 \\  the backslash symbol&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Within single-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r into an integer&lt;br /&gt;
 ceiling(r)  convert a real r into an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One can also use a lowercase &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; for literals in scientific notation (e.g. &amp;lt;tt&amp;gt;1.0e-10&amp;lt;/tt&amp;gt;).&lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus do not hold.&lt;br /&gt;
The  [[External_Functions|library]] LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &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;RLOG&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RSQRT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RPOW&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
You can turn off support for REALS using the preference &amp;lt;tt&amp;gt;ALLOW_REALS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The &amp;lt;tt&amp;gt;REAL_SOLVER&amp;lt;/tt&amp;gt; preference how constraints are solved.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, &amp;lt;tt&amp;gt;n=[1,2,1]&amp;lt;/tt&amp;gt;&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S.&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 tree(S)       set of trees over domain S&lt;br /&gt;
 btree(S)      set of binary trees over domain S&lt;br /&gt;
 top(t)        top of a tree&lt;br /&gt;
 const(E,s)    construct a tree from info E and sequence of subtrees s&lt;br /&gt;
 rank(t,n)     rank of the node at end of branch n in the tree t&lt;br /&gt;
 father(t,n)   father of the node denoted by branch n in the tree t&lt;br /&gt;
 son(t,n,i)    the ith son of the node denoted by branch n in tree t&lt;br /&gt;
 sons(t)       the sequence of sons of the root of the tree t&lt;br /&gt;
 subtree(t,n)&lt;br /&gt;
 arity(t,n)&lt;br /&gt;
 bin(E)        construct a binary tree with a single node E&lt;br /&gt;
 bin(tl,E,tr)  construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
 left(t)       the left (first) son of the root of the binary tree t&lt;br /&gt;
 right(t)      the right (last) son of the root of the binary tree t&lt;br /&gt;
 sizet(t)      the size of the tree (number of nodes)&lt;br /&gt;
 prefix(t)     the nodes of the tree t in prefix order&lt;br /&gt;
 postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
 mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates, expressions and substitutions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 IF P THEN E1 END                    conditional branching&lt;br /&gt;
 IF P THEN E1 ELSIF E2 END           we also allow multiple ELSIF branches&lt;br /&gt;
 IF P THEN E1 ELSE E2 END            but you always need an ELSE branch for expressions and predicates&lt;br /&gt;
 IF P THEN E1 ELSIF E2 ELSE E3 END&lt;br /&gt;
 LET x1,... BE x1=E1 &amp;amp; ... IN E END  introduce local variables&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expression &amp;lt;tt&amp;gt;Ei&amp;lt;/tt&amp;gt; defining &amp;lt;tt&amp;gt;xi&amp;lt;/tt&amp;gt; is allowed to use &amp;lt;tt&amp;gt;x1,...,x(i-1)&amp;lt;/tt&amp;gt; for predicates/expressions.&lt;br /&gt;
By setting the preference &amp;lt;tt&amp;gt;ALLOW_COMPLEX_LETS&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;, this is also allowed for substitutions.&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 skip                                                      no operation&lt;br /&gt;
 x := E                                                    assignment&lt;br /&gt;
 f(x) := E                                                 functional override&lt;br /&gt;
 x :: S                                                    choice from set&lt;br /&gt;
 x : (P)                                                   choice by predicate P (constraining x; previous value of x is x$0)&lt;br /&gt;
 x &amp;lt;-- OP(x)                                               call operation and assign return value&lt;br /&gt;
 G||H                                                      parallel substitution**&lt;br /&gt;
 G;H                                                       sequential composition**&lt;br /&gt;
 ANY x,... WHERE P THEN G END                              non deterministic choice&lt;br /&gt;
 LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
 VAR x,... IN G END                                        generate local variables&lt;br /&gt;
 PRE P THEN G END&lt;br /&gt;
 ASSERT P THEN G END&lt;br /&gt;
 CHOICE G OR H END&lt;br /&gt;
 IF P THEN G END&lt;br /&gt;
 IF P THEN G ELSE H END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
 WHILE P1 DO G INVARIANT P2 VARIANT E END&lt;br /&gt;
 WHEN P THEN G END                                         is a synonym for SELECT P THEN G END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;amp;ast;&amp;amp;ast;: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
be wrapped inside a &amp;lt;tt&amp;gt;BEGIN END&amp;lt;/tt&amp;gt; or another statement (to avoid&lt;br /&gt;
confusion with the operators &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; on relations).&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
&lt;br /&gt;
You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CONSTRAINTS         P                     (logical predicate)&lt;br /&gt;
 SETS                S;T={e1,e2,...};...&lt;br /&gt;
 FREETYPES           x=x1,x2(arg2),...;...&lt;br /&gt;
 CONSTANTS           x,y,...&lt;br /&gt;
 CONCRETE_CONSTANTS  cx,cy,...&lt;br /&gt;
 PROPERTIES          P                     (logical predicate)&lt;br /&gt;
 DEFINITIONS         m(x,...) == BODY;...&lt;br /&gt;
 VARIABLES           x,y,...&lt;br /&gt;
 CONCRETE_VARIABLES  cv,cw,...&lt;br /&gt;
 INVARIANT           P                     (logical predicate)&lt;br /&gt;
 ASSERTIONS          P;...;P               (list of logical predicates separated by ;)&lt;br /&gt;
 INITIALISATION      S                     (substitution)&lt;br /&gt;
 OPERATIONS          O;...                 (operations)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 USES      list of machines&lt;br /&gt;
 INCLUDES  list of machines&lt;br /&gt;
 SEES      list of machines&lt;br /&gt;
 EXTENDS   list of machines&lt;br /&gt;
 PROMOTES  list of operations&lt;br /&gt;
 REFINES   machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 NAME1 == Expression;     Definition without arguments&lt;br /&gt;
 NAME2(ID,...,ID) == E2;  Definition with arguments&lt;br /&gt;
 &amp;quot;FILE.def&amp;quot;;              Include definitions from file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 GOAL == P                          to define a custom Goal predicate for Model Checking&lt;br /&gt;
                                    (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
 SCOPE == P                         to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
 scope_SETNAME == n..n              to define custom cardinality for set SETNAME&lt;br /&gt;
 scope_SETNAME == n                 equivalent to 1..n&lt;br /&gt;
 SET_PREF_MININT == n&lt;br /&gt;
 SET_PREF_MAXINT == n&lt;br /&gt;
 SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
 SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
 MAX_OPERATIONS_OPNAME == n         max. number of enablings for the operation OPNAME&lt;br /&gt;
 SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
 SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
 ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                    Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                    atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
 HEURISTIC_FUNCTION == n            in directed model-checking mode nodes with smalles value will be processed first&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization (n can be empty or a number):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ANIMATION_FUNCTIONn == e                           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
 ANIMATION_FUNCTION_DEFAULT == e                    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                                                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                                                    as a result you can also use STRING values,&lt;br /&gt;
                                                    or even other values which are pretty printed&lt;br /&gt;
 ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;                   a path to a gif file&lt;br /&gt;
 ANIMATION_STRn == &amp;quot;sometext&amp;quot;                       a string without spaces;&lt;br /&gt;
                                                    the result integer n will be rendered as a string&lt;br /&gt;
 ANIMATION_STR_JUSTIFY_LEFT == TRUE                 computes the longest string in the outputs and pads&lt;br /&gt;
                                                    the other strings accordingly&lt;br /&gt;
 SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n         additional padding between images in pixels&lt;br /&gt;
 SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n  additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]] (n can be empty or a number):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CUSTOM_GRAPH_NODESn == e  define a set of nodes to be shown,&lt;br /&gt;
                           nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                           records or sets of records like&lt;br /&gt;
                           rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node, ...)&lt;br /&gt;
                           Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                           Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                           Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
 CUSTOM_GRAPH_EDGESn == e  define a relation to be shown as a graph&lt;br /&gt;
                           edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                           where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                           the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like&lt;br /&gt;
color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, style:&amp;quot;filled&amp;quot;, nodes:e);&lt;br /&gt;
 CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, dir:&amp;quot;none&amp;quot;, penwidth:2, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can now also use a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
(like rankdir or layout) and optionally with edges and nodes attributes&lt;br /&gt;
(replacing CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also provide &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation;&lt;br /&gt;
                                    if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
 VISB_SVG_OBJECTSn == ...           define a record or set of records for creating new SVG objects&lt;br /&gt;
 VISB_SVG_UPDATESn == ...           define a record or set of records containing updates of SVG objects&lt;br /&gt;
 VISB_SVG_HOVERSn == ...            define a record or set of records for VisB hover functions&lt;br /&gt;
 VISB_SVG_BOX == ...                record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
 VISB_SVG_CONTENTS == ...           defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
 /* ... */  block comments&lt;br /&gt;
 // ...     line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 /*@symbolic */             put before comprehension set, lambda, union or composition to instruct ProB&lt;br /&gt;
                            to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
 /*@label LBL */            associates a label LBL with the following predicate&lt;br /&gt;
                            (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
 /*@desc DESC */            associates a description DESC with the preceding predicate or&lt;br /&gt;
                            introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                            There are three special descriptions:&lt;br /&gt;
                            /*@desc memo*/          to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                                    indicating that these functions should be memoized&lt;br /&gt;
                            /*@desc expand*/        to be put after identifiers (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                                                    indicating that they should be expanded and not kept symbolically&lt;br /&gt;
                            /*@desc prob-ignore */  to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                                    should be ignored by ProB&lt;br /&gt;
                                                    when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
 /*@file PATH */            associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                            put pragma after a seen or included machine&lt;br /&gt;
 /*@package NAME */         at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                            NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                            file should be in N1/N2/.../Nk&lt;br /&gt;
 /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                            NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
 /*@generated */            can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                            is generated from some other source&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 .mch   for abstract machine files&lt;br /&gt;
 .ref   for refinement machines&lt;br /&gt;
 .imp   for implementation machines&lt;br /&gt;
 .def   for DEFINITIONS files&lt;br /&gt;
 .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB now supports the Unicode mathematical symbols, exactly like Atelier-B&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
   !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
   !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), &lt;br /&gt;
   !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
 ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5816</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5816"/>
		<updated>2024-06-13T12:48:40Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* File Extensions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
In ProB, however, some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 size(s)   the length of a string s&lt;br /&gt;
 rev(s)    the reverse of a string s&lt;br /&gt;
 s ^ t     the concatenation of two strings&lt;br /&gt;
 conc(ss)  the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the &amp;lt;tt&amp;gt;STRING_AS_SEQUENCE&amp;lt;/tt&amp;gt; preference.&lt;br /&gt;
The [[External_Functions|library]] LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &amp;lt;tt&amp;gt;TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;FORMAT_TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;INT_TO_HEX_STRING&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
&lt;br /&gt;
ProB also allows multi-line strings.&lt;br /&gt;
&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 \n  newline (ASCII character 13)&lt;br /&gt;
 \r  carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;  the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;  the single quote symbol &#039;&lt;br /&gt;
 \\  the backslash symbol&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Within single-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r into an integer&lt;br /&gt;
 ceiling(r)  convert a real r into an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One can also use a lowercase &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; for literals in scientific notation (e.g. &amp;lt;tt&amp;gt;1.0e-10&amp;lt;/tt&amp;gt;).&lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus do not hold.&lt;br /&gt;
The  [[External_Functions|library]] LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &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;RLOG&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RSQRT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RPOW&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
You can turn off support for REALS using the preference &amp;lt;tt&amp;gt;ALLOW_REALS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The &amp;lt;tt&amp;gt;REAL_SOLVER&amp;lt;/tt&amp;gt; preference how constraints are solved.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, &amp;lt;tt&amp;gt;n=[1,2,1]&amp;lt;/tt&amp;gt;&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S.&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 tree(S)       set of trees over domain S&lt;br /&gt;
 btree(S)      set of binary trees over domain S&lt;br /&gt;
 top(t)        top of a tree&lt;br /&gt;
 const(E,s)    construct a tree from info E and sequence of subtrees s&lt;br /&gt;
 rank(t,n)     rank of the node at end of branch n in the tree t&lt;br /&gt;
 father(t,n)   father of the node denoted by branch n in the tree t&lt;br /&gt;
 son(t,n,i)    the ith son of the node denoted by branch n in tree t&lt;br /&gt;
 sons(t)       the sequence of sons of the root of the tree t&lt;br /&gt;
 subtree(t,n)&lt;br /&gt;
 arity(t,n)&lt;br /&gt;
 bin(E)        construct a binary tree with a single node E&lt;br /&gt;
 bin(tl,E,tr)  construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
 left(t)       the left (first) son of the root of the binary tree t&lt;br /&gt;
 right(t)      the right (last) son of the root of the binary tree t&lt;br /&gt;
 sizet(t)      the size of the tree (number of nodes)&lt;br /&gt;
 prefix(t)     the nodes of the tree t in prefix order&lt;br /&gt;
 postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
 mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates, expressions and substitutions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 IF P THEN E1 END                    conditional branching&lt;br /&gt;
 IF P THEN E1 ELSIF E2 END           we also allow multiple ELSIF branches&lt;br /&gt;
 IF P THEN E1 ELSE E2 END            but you always need an ELSE branch for expressions and predicates&lt;br /&gt;
 IF P THEN E1 ELSIF E2 ELSE E3 END&lt;br /&gt;
 LET x1,... BE x1=E1 &amp;amp; ... IN E END  introduce local variables&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expression &amp;lt;tt&amp;gt;Ei&amp;lt;/tt&amp;gt; defining &amp;lt;tt&amp;gt;xi&amp;lt;/tt&amp;gt; is allowed to use &amp;lt;tt&amp;gt;x1,...,x(i-1)&amp;lt;/tt&amp;gt; for predicates/expressions.&lt;br /&gt;
By setting the preference &amp;lt;tt&amp;gt;ALLOW_COMPLEX_LETS&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;, this is also allowed for substitutions.&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 skip                                                      no operation&lt;br /&gt;
 x := E                                                    assignment&lt;br /&gt;
 f(x) := E                                                 functional override&lt;br /&gt;
 x :: S                                                    choice from set&lt;br /&gt;
 x : (P)                                                   choice by predicate P (constraining x; previous value of x is x$0)&lt;br /&gt;
 x &amp;lt;-- OP(x)                                               call operation and assign return value&lt;br /&gt;
 G||H                                                      parallel substitution**&lt;br /&gt;
 G;H                                                       sequential composition**&lt;br /&gt;
 ANY x,... WHERE P THEN G END                              non deterministic choice&lt;br /&gt;
 LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
 VAR x,... IN G END                                        generate local variables&lt;br /&gt;
 PRE P THEN G END&lt;br /&gt;
 ASSERT P THEN G END&lt;br /&gt;
 CHOICE G OR H END&lt;br /&gt;
 IF P THEN G END&lt;br /&gt;
 IF P THEN G ELSE H END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
 WHILE P1 DO G INVARIANT P2 VARIANT E END&lt;br /&gt;
 WHEN P THEN G END                                         is a synonym for SELECT P THEN G END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;amp;ast;&amp;amp;ast;: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
be wrapped inside a &amp;lt;tt&amp;gt;BEGIN END&amp;lt;/tt&amp;gt; or another statement (to avoid&lt;br /&gt;
confusion with the operators &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; on relations).&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
&lt;br /&gt;
You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CONSTRAINTS         P                     (logical predicate)&lt;br /&gt;
 SETS                S;T={e1,e2,...};...&lt;br /&gt;
 FREETYPES           x=x1,x2(arg2),...;...&lt;br /&gt;
 CONSTANTS           x,y,...&lt;br /&gt;
 CONCRETE_CONSTANTS  cx,cy,...&lt;br /&gt;
 PROPERTIES          P                     (logical predicate)&lt;br /&gt;
 DEFINITIONS         m(x,...) == BODY;...&lt;br /&gt;
 VARIABLES           x,y,...&lt;br /&gt;
 CONCRETE_VARIABLES  cv,cw,...&lt;br /&gt;
 INVARIANT           P                     (logical predicate)&lt;br /&gt;
 ASSERTIONS          P;...;P               (list of logical predicates separated by ;)&lt;br /&gt;
 INITIALISATION      S                     (substitution)&lt;br /&gt;
 OPERATIONS          O;...                 (operations)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 USES      list of machines&lt;br /&gt;
 INCLUDES  list of machines&lt;br /&gt;
 SEES      list of machines&lt;br /&gt;
 EXTENDS   list of machines&lt;br /&gt;
 PROMOTES  list of operations&lt;br /&gt;
 REFINES   machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 NAME1 == Expression;     Definition without arguments&lt;br /&gt;
 NAME2(ID,...,ID) == E2;  Definition with arguments&lt;br /&gt;
 &amp;quot;FILE.def&amp;quot;;              Include definitions from file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 GOAL == P                          to define a custom Goal predicate for Model Checking&lt;br /&gt;
                                    (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
 SCOPE == P                         to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
 scope_SETNAME == n..n              to define custom cardinality for set SETNAME&lt;br /&gt;
 scope_SETNAME == n                 equivalent to 1..n&lt;br /&gt;
 SET_PREF_MININT == n&lt;br /&gt;
 SET_PREF_MAXINT == n&lt;br /&gt;
 SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
 SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
 MAX_OPERATIONS_OPNAME == n         max. number of enablings for the operation OPNAME&lt;br /&gt;
 SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
 SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
 ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                    Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                    atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
 HEURISTIC_FUNCTION == n            in directed model-checking mode nodes with smalles value will be processed first&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization (n can be empty or a number):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ANIMATION_FUNCTIONn == e                           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
 ANIMATION_FUNCTION_DEFAULT == e                    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                                                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                                                    as a result you can also use STRING values,&lt;br /&gt;
                                                    or even other values which are pretty printed&lt;br /&gt;
 ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;                   a path to a gif file&lt;br /&gt;
 ANIMATION_STRn == &amp;quot;sometext&amp;quot;                       a string without spaces;&lt;br /&gt;
                                                    the result integer n will be rendered as a string&lt;br /&gt;
 ANIMATION_STR_JUSTIFY_LEFT == TRUE                 computes the longest string in the outputs and pads&lt;br /&gt;
                                                    the other strings accordingly&lt;br /&gt;
 SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n         additional padding between images in pixels&lt;br /&gt;
 SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n  additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]] (n can be empty or a number):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CUSTOM_GRAPH_NODESn == e  define a set of nodes to be shown,&lt;br /&gt;
                           nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                           records or sets of records like&lt;br /&gt;
                           rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node, ...)&lt;br /&gt;
                           Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                           Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                           Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
 CUSTOM_GRAPH_EDGESn == e  define a relation to be shown as a graph&lt;br /&gt;
                           edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                           where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                           the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like&lt;br /&gt;
color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, style:&amp;quot;filled&amp;quot;, nodes:e);&lt;br /&gt;
 CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, dir:&amp;quot;none&amp;quot;, penwidth:2, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can now also use a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
(like rankdir or layout) and optionally with edges and nodes attributes&lt;br /&gt;
(replacing CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also provide &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation;&lt;br /&gt;
                                    if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
 VISB_SVG_OBJECTSn == ...           define a record or set of records for creating new SVG objects&lt;br /&gt;
 VISB_SVG_UPDATESn == ...           define a record or set of records containing updates of SVG objects&lt;br /&gt;
 VISB_SVG_HOVERSn == ...            define a record or set of records for VisB hover functions&lt;br /&gt;
 VISB_SVG_BOX == ...                record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
 VISB_SVG_CONTENTS == ...           defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
 /* ... */  block comments&lt;br /&gt;
 // ...     line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 /*@symbolic */             put before comprehension set, lambda, union or composition to instruct ProB&lt;br /&gt;
                            to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
 /*@label LBL */            associates a label LBL with the following predicate&lt;br /&gt;
                            (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
 /*@desc DESC */            associates a description DESC with the preceding predicate or&lt;br /&gt;
                            introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                            There are three special descriptions:&lt;br /&gt;
                            /*@desc memo*/          to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                                    indicating that these functions should be memoized&lt;br /&gt;
                            /*@desc expand*/        to be put after identifiers (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                                                    indicating that they should be expanded and not kept symbolically&lt;br /&gt;
                            /*@desc prob-ignore */  to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                                    should be ignored by ProB&lt;br /&gt;
                                                    when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
 /*@file PATH */            associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                            put pragma after a seen or included machine&lt;br /&gt;
 /*@package NAME */         at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                            NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                            file should be in N1/N2/.../Nk&lt;br /&gt;
 /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                            NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
 /*@generated */            can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                            is generated from some other source&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 .mch   for abstract machine files&lt;br /&gt;
 .ref   for refinement machines&lt;br /&gt;
 .imp   for implementation machines&lt;br /&gt;
 .def   for DEFINITIONS files&lt;br /&gt;
 .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5815</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5815"/>
		<updated>2024-06-13T12:48:10Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Comments and Pragmas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
In ProB, however, some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 size(s)   the length of a string s&lt;br /&gt;
 rev(s)    the reverse of a string s&lt;br /&gt;
 s ^ t     the concatenation of two strings&lt;br /&gt;
 conc(ss)  the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the &amp;lt;tt&amp;gt;STRING_AS_SEQUENCE&amp;lt;/tt&amp;gt; preference.&lt;br /&gt;
The [[External_Functions|library]] LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &amp;lt;tt&amp;gt;TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;FORMAT_TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;INT_TO_HEX_STRING&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
&lt;br /&gt;
ProB also allows multi-line strings.&lt;br /&gt;
&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 \n  newline (ASCII character 13)&lt;br /&gt;
 \r  carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;  the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;  the single quote symbol &#039;&lt;br /&gt;
 \\  the backslash symbol&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Within single-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r into an integer&lt;br /&gt;
 ceiling(r)  convert a real r into an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One can also use a lowercase &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; for literals in scientific notation (e.g. &amp;lt;tt&amp;gt;1.0e-10&amp;lt;/tt&amp;gt;).&lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus do not hold.&lt;br /&gt;
The  [[External_Functions|library]] LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &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;RLOG&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RSQRT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RPOW&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
You can turn off support for REALS using the preference &amp;lt;tt&amp;gt;ALLOW_REALS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The &amp;lt;tt&amp;gt;REAL_SOLVER&amp;lt;/tt&amp;gt; preference how constraints are solved.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, &amp;lt;tt&amp;gt;n=[1,2,1]&amp;lt;/tt&amp;gt;&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S.&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 tree(S)       set of trees over domain S&lt;br /&gt;
 btree(S)      set of binary trees over domain S&lt;br /&gt;
 top(t)        top of a tree&lt;br /&gt;
 const(E,s)    construct a tree from info E and sequence of subtrees s&lt;br /&gt;
 rank(t,n)     rank of the node at end of branch n in the tree t&lt;br /&gt;
 father(t,n)   father of the node denoted by branch n in the tree t&lt;br /&gt;
 son(t,n,i)    the ith son of the node denoted by branch n in tree t&lt;br /&gt;
 sons(t)       the sequence of sons of the root of the tree t&lt;br /&gt;
 subtree(t,n)&lt;br /&gt;
 arity(t,n)&lt;br /&gt;
 bin(E)        construct a binary tree with a single node E&lt;br /&gt;
 bin(tl,E,tr)  construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
 left(t)       the left (first) son of the root of the binary tree t&lt;br /&gt;
 right(t)      the right (last) son of the root of the binary tree t&lt;br /&gt;
 sizet(t)      the size of the tree (number of nodes)&lt;br /&gt;
 prefix(t)     the nodes of the tree t in prefix order&lt;br /&gt;
 postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
 mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates, expressions and substitutions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 IF P THEN E1 END                    conditional branching&lt;br /&gt;
 IF P THEN E1 ELSIF E2 END           we also allow multiple ELSIF branches&lt;br /&gt;
 IF P THEN E1 ELSE E2 END            but you always need an ELSE branch for expressions and predicates&lt;br /&gt;
 IF P THEN E1 ELSIF E2 ELSE E3 END&lt;br /&gt;
 LET x1,... BE x1=E1 &amp;amp; ... IN E END  introduce local variables&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expression &amp;lt;tt&amp;gt;Ei&amp;lt;/tt&amp;gt; defining &amp;lt;tt&amp;gt;xi&amp;lt;/tt&amp;gt; is allowed to use &amp;lt;tt&amp;gt;x1,...,x(i-1)&amp;lt;/tt&amp;gt; for predicates/expressions.&lt;br /&gt;
By setting the preference &amp;lt;tt&amp;gt;ALLOW_COMPLEX_LETS&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;, this is also allowed for substitutions.&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 skip                                                      no operation&lt;br /&gt;
 x := E                                                    assignment&lt;br /&gt;
 f(x) := E                                                 functional override&lt;br /&gt;
 x :: S                                                    choice from set&lt;br /&gt;
 x : (P)                                                   choice by predicate P (constraining x; previous value of x is x$0)&lt;br /&gt;
 x &amp;lt;-- OP(x)                                               call operation and assign return value&lt;br /&gt;
 G||H                                                      parallel substitution**&lt;br /&gt;
 G;H                                                       sequential composition**&lt;br /&gt;
 ANY x,... WHERE P THEN G END                              non deterministic choice&lt;br /&gt;
 LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
 VAR x,... IN G END                                        generate local variables&lt;br /&gt;
 PRE P THEN G END&lt;br /&gt;
 ASSERT P THEN G END&lt;br /&gt;
 CHOICE G OR H END&lt;br /&gt;
 IF P THEN G END&lt;br /&gt;
 IF P THEN G ELSE H END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
 WHILE P1 DO G INVARIANT P2 VARIANT E END&lt;br /&gt;
 WHEN P THEN G END                                         is a synonym for SELECT P THEN G END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;amp;ast;&amp;amp;ast;: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
be wrapped inside a &amp;lt;tt&amp;gt;BEGIN END&amp;lt;/tt&amp;gt; or another statement (to avoid&lt;br /&gt;
confusion with the operators &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; on relations).&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
&lt;br /&gt;
You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CONSTRAINTS         P                     (logical predicate)&lt;br /&gt;
 SETS                S;T={e1,e2,...};...&lt;br /&gt;
 FREETYPES           x=x1,x2(arg2),...;...&lt;br /&gt;
 CONSTANTS           x,y,...&lt;br /&gt;
 CONCRETE_CONSTANTS  cx,cy,...&lt;br /&gt;
 PROPERTIES          P                     (logical predicate)&lt;br /&gt;
 DEFINITIONS         m(x,...) == BODY;...&lt;br /&gt;
 VARIABLES           x,y,...&lt;br /&gt;
 CONCRETE_VARIABLES  cv,cw,...&lt;br /&gt;
 INVARIANT           P                     (logical predicate)&lt;br /&gt;
 ASSERTIONS          P;...;P               (list of logical predicates separated by ;)&lt;br /&gt;
 INITIALISATION      S                     (substitution)&lt;br /&gt;
 OPERATIONS          O;...                 (operations)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 USES      list of machines&lt;br /&gt;
 INCLUDES  list of machines&lt;br /&gt;
 SEES      list of machines&lt;br /&gt;
 EXTENDS   list of machines&lt;br /&gt;
 PROMOTES  list of operations&lt;br /&gt;
 REFINES   machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 NAME1 == Expression;     Definition without arguments&lt;br /&gt;
 NAME2(ID,...,ID) == E2;  Definition with arguments&lt;br /&gt;
 &amp;quot;FILE.def&amp;quot;;              Include definitions from file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 GOAL == P                          to define a custom Goal predicate for Model Checking&lt;br /&gt;
                                    (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
 SCOPE == P                         to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
 scope_SETNAME == n..n              to define custom cardinality for set SETNAME&lt;br /&gt;
 scope_SETNAME == n                 equivalent to 1..n&lt;br /&gt;
 SET_PREF_MININT == n&lt;br /&gt;
 SET_PREF_MAXINT == n&lt;br /&gt;
 SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
 SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
 MAX_OPERATIONS_OPNAME == n         max. number of enablings for the operation OPNAME&lt;br /&gt;
 SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
 SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
 ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                    Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                    atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
 HEURISTIC_FUNCTION == n            in directed model-checking mode nodes with smalles value will be processed first&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization (n can be empty or a number):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ANIMATION_FUNCTIONn == e                           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
 ANIMATION_FUNCTION_DEFAULT == e                    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                                                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                                                    as a result you can also use STRING values,&lt;br /&gt;
                                                    or even other values which are pretty printed&lt;br /&gt;
 ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;                   a path to a gif file&lt;br /&gt;
 ANIMATION_STRn == &amp;quot;sometext&amp;quot;                       a string without spaces;&lt;br /&gt;
                                                    the result integer n will be rendered as a string&lt;br /&gt;
 ANIMATION_STR_JUSTIFY_LEFT == TRUE                 computes the longest string in the outputs and pads&lt;br /&gt;
                                                    the other strings accordingly&lt;br /&gt;
 SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n         additional padding between images in pixels&lt;br /&gt;
 SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n  additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]] (n can be empty or a number):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CUSTOM_GRAPH_NODESn == e  define a set of nodes to be shown,&lt;br /&gt;
                           nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                           records or sets of records like&lt;br /&gt;
                           rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node, ...)&lt;br /&gt;
                           Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                           Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                           Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
 CUSTOM_GRAPH_EDGESn == e  define a relation to be shown as a graph&lt;br /&gt;
                           edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                           where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                           the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like&lt;br /&gt;
color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, style:&amp;quot;filled&amp;quot;, nodes:e);&lt;br /&gt;
 CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, dir:&amp;quot;none&amp;quot;, penwidth:2, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can now also use a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
(like rankdir or layout) and optionally with edges and nodes attributes&lt;br /&gt;
(replacing CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also provide &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation;&lt;br /&gt;
                                    if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
 VISB_SVG_OBJECTSn == ...           define a record or set of records for creating new SVG objects&lt;br /&gt;
 VISB_SVG_UPDATESn == ...           define a record or set of records containing updates of SVG objects&lt;br /&gt;
 VISB_SVG_HOVERSn == ...            define a record or set of records for VisB hover functions&lt;br /&gt;
 VISB_SVG_BOX == ...                record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
 VISB_SVG_CONTENTS == ...           defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
 /* ... */  block comments&lt;br /&gt;
 // ...     line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 /*@symbolic */             put before comprehension set, lambda, union or composition to instruct ProB&lt;br /&gt;
                            to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
 /*@label LBL */            associates a label LBL with the following predicate&lt;br /&gt;
                            (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
 /*@desc DESC */            associates a description DESC with the preceding predicate or&lt;br /&gt;
                            introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                            There are three special descriptions:&lt;br /&gt;
                            /*@desc memo*/          to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                                    indicating that these functions should be memoized&lt;br /&gt;
                            /*@desc expand*/        to be put after identifiers (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                                                    indicating that they should be expanded and not kept symbolically&lt;br /&gt;
                            /*@desc prob-ignore */  to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                                    should be ignored by ProB&lt;br /&gt;
                                                    when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
 /*@file PATH */            associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                            put pragma after a seen or included machine&lt;br /&gt;
 /*@package NAME */         at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                            NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                            file should be in N1/N2/.../Nk&lt;br /&gt;
 /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                            NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
 /*@generated */            can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                            is generated from some other source&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5814</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5814"/>
		<updated>2024-06-13T12:43:14Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Definitions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
In ProB, however, some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 size(s)   the length of a string s&lt;br /&gt;
 rev(s)    the reverse of a string s&lt;br /&gt;
 s ^ t     the concatenation of two strings&lt;br /&gt;
 conc(ss)  the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the &amp;lt;tt&amp;gt;STRING_AS_SEQUENCE&amp;lt;/tt&amp;gt; preference.&lt;br /&gt;
The [[External_Functions|library]] LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &amp;lt;tt&amp;gt;TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;FORMAT_TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;INT_TO_HEX_STRING&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
&lt;br /&gt;
ProB also allows multi-line strings.&lt;br /&gt;
&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 \n  newline (ASCII character 13)&lt;br /&gt;
 \r  carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;  the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;  the single quote symbol &#039;&lt;br /&gt;
 \\  the backslash symbol&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Within single-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r into an integer&lt;br /&gt;
 ceiling(r)  convert a real r into an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One can also use a lowercase &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; for literals in scientific notation (e.g. &amp;lt;tt&amp;gt;1.0e-10&amp;lt;/tt&amp;gt;).&lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus do not hold.&lt;br /&gt;
The  [[External_Functions|library]] LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &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;RLOG&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RSQRT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RPOW&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
You can turn off support for REALS using the preference &amp;lt;tt&amp;gt;ALLOW_REALS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The &amp;lt;tt&amp;gt;REAL_SOLVER&amp;lt;/tt&amp;gt; preference how constraints are solved.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, &amp;lt;tt&amp;gt;n=[1,2,1]&amp;lt;/tt&amp;gt;&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S.&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 tree(S)       set of trees over domain S&lt;br /&gt;
 btree(S)      set of binary trees over domain S&lt;br /&gt;
 top(t)        top of a tree&lt;br /&gt;
 const(E,s)    construct a tree from info E and sequence of subtrees s&lt;br /&gt;
 rank(t,n)     rank of the node at end of branch n in the tree t&lt;br /&gt;
 father(t,n)   father of the node denoted by branch n in the tree t&lt;br /&gt;
 son(t,n,i)    the ith son of the node denoted by branch n in tree t&lt;br /&gt;
 sons(t)       the sequence of sons of the root of the tree t&lt;br /&gt;
 subtree(t,n)&lt;br /&gt;
 arity(t,n)&lt;br /&gt;
 bin(E)        construct a binary tree with a single node E&lt;br /&gt;
 bin(tl,E,tr)  construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
 left(t)       the left (first) son of the root of the binary tree t&lt;br /&gt;
 right(t)      the right (last) son of the root of the binary tree t&lt;br /&gt;
 sizet(t)      the size of the tree (number of nodes)&lt;br /&gt;
 prefix(t)     the nodes of the tree t in prefix order&lt;br /&gt;
 postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
 mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates, expressions and substitutions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 IF P THEN E1 END                    conditional branching&lt;br /&gt;
 IF P THEN E1 ELSIF E2 END           we also allow multiple ELSIF branches&lt;br /&gt;
 IF P THEN E1 ELSE E2 END            but you always need an ELSE branch for expressions and predicates&lt;br /&gt;
 IF P THEN E1 ELSIF E2 ELSE E3 END&lt;br /&gt;
 LET x1,... BE x1=E1 &amp;amp; ... IN E END  introduce local variables&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expression &amp;lt;tt&amp;gt;Ei&amp;lt;/tt&amp;gt; defining &amp;lt;tt&amp;gt;xi&amp;lt;/tt&amp;gt; is allowed to use &amp;lt;tt&amp;gt;x1,...,x(i-1)&amp;lt;/tt&amp;gt; for predicates/expressions.&lt;br /&gt;
By setting the preference &amp;lt;tt&amp;gt;ALLOW_COMPLEX_LETS&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;, this is also allowed for substitutions.&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 skip                                                      no operation&lt;br /&gt;
 x := E                                                    assignment&lt;br /&gt;
 f(x) := E                                                 functional override&lt;br /&gt;
 x :: S                                                    choice from set&lt;br /&gt;
 x : (P)                                                   choice by predicate P (constraining x; previous value of x is x$0)&lt;br /&gt;
 x &amp;lt;-- OP(x)                                               call operation and assign return value&lt;br /&gt;
 G||H                                                      parallel substitution**&lt;br /&gt;
 G;H                                                       sequential composition**&lt;br /&gt;
 ANY x,... WHERE P THEN G END                              non deterministic choice&lt;br /&gt;
 LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
 VAR x,... IN G END                                        generate local variables&lt;br /&gt;
 PRE P THEN G END&lt;br /&gt;
 ASSERT P THEN G END&lt;br /&gt;
 CHOICE G OR H END&lt;br /&gt;
 IF P THEN G END&lt;br /&gt;
 IF P THEN G ELSE H END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
 WHILE P1 DO G INVARIANT P2 VARIANT E END&lt;br /&gt;
 WHEN P THEN G END                                         is a synonym for SELECT P THEN G END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;amp;ast;&amp;amp;ast;: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
be wrapped inside a &amp;lt;tt&amp;gt;BEGIN END&amp;lt;/tt&amp;gt; or another statement (to avoid&lt;br /&gt;
confusion with the operators &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; on relations).&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
&lt;br /&gt;
You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CONSTRAINTS         P                     (logical predicate)&lt;br /&gt;
 SETS                S;T={e1,e2,...};...&lt;br /&gt;
 FREETYPES           x=x1,x2(arg2),...;...&lt;br /&gt;
 CONSTANTS           x,y,...&lt;br /&gt;
 CONCRETE_CONSTANTS  cx,cy,...&lt;br /&gt;
 PROPERTIES          P                     (logical predicate)&lt;br /&gt;
 DEFINITIONS         m(x,...) == BODY;...&lt;br /&gt;
 VARIABLES           x,y,...&lt;br /&gt;
 CONCRETE_VARIABLES  cv,cw,...&lt;br /&gt;
 INVARIANT           P                     (logical predicate)&lt;br /&gt;
 ASSERTIONS          P;...;P               (list of logical predicates separated by ;)&lt;br /&gt;
 INITIALISATION      S                     (substitution)&lt;br /&gt;
 OPERATIONS          O;...                 (operations)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 USES      list of machines&lt;br /&gt;
 INCLUDES  list of machines&lt;br /&gt;
 SEES      list of machines&lt;br /&gt;
 EXTENDS   list of machines&lt;br /&gt;
 PROMOTES  list of operations&lt;br /&gt;
 REFINES   machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 NAME1 == Expression;     Definition without arguments&lt;br /&gt;
 NAME2(ID,...,ID) == E2;  Definition with arguments&lt;br /&gt;
 &amp;quot;FILE.def&amp;quot;;              Include definitions from file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 GOAL == P                          to define a custom Goal predicate for Model Checking&lt;br /&gt;
                                    (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
 SCOPE == P                         to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
 scope_SETNAME == n..n              to define custom cardinality for set SETNAME&lt;br /&gt;
 scope_SETNAME == n                 equivalent to 1..n&lt;br /&gt;
 SET_PREF_MININT == n&lt;br /&gt;
 SET_PREF_MAXINT == n&lt;br /&gt;
 SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
 SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
 MAX_OPERATIONS_OPNAME == n         max. number of enablings for the operation OPNAME&lt;br /&gt;
 SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
 SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
 ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                    Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                    atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
 HEURISTIC_FUNCTION == n            in directed model-checking mode nodes with smalles value will be processed first&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization (n can be empty or a number):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ANIMATION_FUNCTIONn == e                           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
 ANIMATION_FUNCTION_DEFAULT == e                    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                                                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                                                    as a result you can also use STRING values,&lt;br /&gt;
                                                    or even other values which are pretty printed&lt;br /&gt;
 ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;                   a path to a gif file&lt;br /&gt;
 ANIMATION_STRn == &amp;quot;sometext&amp;quot;                       a string without spaces;&lt;br /&gt;
                                                    the result integer n will be rendered as a string&lt;br /&gt;
 ANIMATION_STR_JUSTIFY_LEFT == TRUE                 computes the longest string in the outputs and pads&lt;br /&gt;
                                                    the other strings accordingly&lt;br /&gt;
 SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n         additional padding between images in pixels&lt;br /&gt;
 SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n  additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]] (n can be empty or a number):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CUSTOM_GRAPH_NODESn == e  define a set of nodes to be shown,&lt;br /&gt;
                           nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                           records or sets of records like&lt;br /&gt;
                           rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node, ...)&lt;br /&gt;
                           Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                           Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                           Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
 CUSTOM_GRAPH_EDGESn == e  define a relation to be shown as a graph&lt;br /&gt;
                           edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                           where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                           the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like&lt;br /&gt;
color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, style:&amp;quot;filled&amp;quot;, nodes:e);&lt;br /&gt;
 CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, dir:&amp;quot;none&amp;quot;, penwidth:2, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can now also use a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
(like rankdir or layout) and optionally with edges and nodes attributes&lt;br /&gt;
(replacing CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also provide &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation;&lt;br /&gt;
                                    if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
 VISB_SVG_OBJECTSn == ...           define a record or set of records for creating new SVG objects&lt;br /&gt;
 VISB_SVG_UPDATESn == ...           define a record or set of records containing updates of SVG objects&lt;br /&gt;
 VISB_SVG_HOVERSn == ...            define a record or set of records for VisB hover functions&lt;br /&gt;
 VISB_SVG_BOX == ...                record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
 VISB_SVG_CONTENTS == ...           defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5813</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5813"/>
		<updated>2024-06-13T12:35:37Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Machine inclusion */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
In ProB, however, some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 size(s)   the length of a string s&lt;br /&gt;
 rev(s)    the reverse of a string s&lt;br /&gt;
 s ^ t     the concatenation of two strings&lt;br /&gt;
 conc(ss)  the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the &amp;lt;tt&amp;gt;STRING_AS_SEQUENCE&amp;lt;/tt&amp;gt; preference.&lt;br /&gt;
The [[External_Functions|library]] LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &amp;lt;tt&amp;gt;TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;FORMAT_TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;INT_TO_HEX_STRING&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
&lt;br /&gt;
ProB also allows multi-line strings.&lt;br /&gt;
&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 \n  newline (ASCII character 13)&lt;br /&gt;
 \r  carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;  the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;  the single quote symbol &#039;&lt;br /&gt;
 \\  the backslash symbol&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Within single-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r into an integer&lt;br /&gt;
 ceiling(r)  convert a real r into an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One can also use a lowercase &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; for literals in scientific notation (e.g. &amp;lt;tt&amp;gt;1.0e-10&amp;lt;/tt&amp;gt;).&lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus do not hold.&lt;br /&gt;
The  [[External_Functions|library]] LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &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;RLOG&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RSQRT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RPOW&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
You can turn off support for REALS using the preference &amp;lt;tt&amp;gt;ALLOW_REALS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The &amp;lt;tt&amp;gt;REAL_SOLVER&amp;lt;/tt&amp;gt; preference how constraints are solved.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, &amp;lt;tt&amp;gt;n=[1,2,1]&amp;lt;/tt&amp;gt;&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S.&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 tree(S)       set of trees over domain S&lt;br /&gt;
 btree(S)      set of binary trees over domain S&lt;br /&gt;
 top(t)        top of a tree&lt;br /&gt;
 const(E,s)    construct a tree from info E and sequence of subtrees s&lt;br /&gt;
 rank(t,n)     rank of the node at end of branch n in the tree t&lt;br /&gt;
 father(t,n)   father of the node denoted by branch n in the tree t&lt;br /&gt;
 son(t,n,i)    the ith son of the node denoted by branch n in tree t&lt;br /&gt;
 sons(t)       the sequence of sons of the root of the tree t&lt;br /&gt;
 subtree(t,n)&lt;br /&gt;
 arity(t,n)&lt;br /&gt;
 bin(E)        construct a binary tree with a single node E&lt;br /&gt;
 bin(tl,E,tr)  construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
 left(t)       the left (first) son of the root of the binary tree t&lt;br /&gt;
 right(t)      the right (last) son of the root of the binary tree t&lt;br /&gt;
 sizet(t)      the size of the tree (number of nodes)&lt;br /&gt;
 prefix(t)     the nodes of the tree t in prefix order&lt;br /&gt;
 postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
 mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates, expressions and substitutions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 IF P THEN E1 END                    conditional branching&lt;br /&gt;
 IF P THEN E1 ELSIF E2 END           we also allow multiple ELSIF branches&lt;br /&gt;
 IF P THEN E1 ELSE E2 END            but you always need an ELSE branch for expressions and predicates&lt;br /&gt;
 IF P THEN E1 ELSIF E2 ELSE E3 END&lt;br /&gt;
 LET x1,... BE x1=E1 &amp;amp; ... IN E END  introduce local variables&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expression &amp;lt;tt&amp;gt;Ei&amp;lt;/tt&amp;gt; defining &amp;lt;tt&amp;gt;xi&amp;lt;/tt&amp;gt; is allowed to use &amp;lt;tt&amp;gt;x1,...,x(i-1)&amp;lt;/tt&amp;gt; for predicates/expressions.&lt;br /&gt;
By setting the preference &amp;lt;tt&amp;gt;ALLOW_COMPLEX_LETS&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;, this is also allowed for substitutions.&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 skip                                                      no operation&lt;br /&gt;
 x := E                                                    assignment&lt;br /&gt;
 f(x) := E                                                 functional override&lt;br /&gt;
 x :: S                                                    choice from set&lt;br /&gt;
 x : (P)                                                   choice by predicate P (constraining x; previous value of x is x$0)&lt;br /&gt;
 x &amp;lt;-- OP(x)                                               call operation and assign return value&lt;br /&gt;
 G||H                                                      parallel substitution**&lt;br /&gt;
 G;H                                                       sequential composition**&lt;br /&gt;
 ANY x,... WHERE P THEN G END                              non deterministic choice&lt;br /&gt;
 LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
 VAR x,... IN G END                                        generate local variables&lt;br /&gt;
 PRE P THEN G END&lt;br /&gt;
 ASSERT P THEN G END&lt;br /&gt;
 CHOICE G OR H END&lt;br /&gt;
 IF P THEN G END&lt;br /&gt;
 IF P THEN G ELSE H END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
 WHILE P1 DO G INVARIANT P2 VARIANT E END&lt;br /&gt;
 WHEN P THEN G END                                         is a synonym for SELECT P THEN G END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;amp;ast;&amp;amp;ast;: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
be wrapped inside a &amp;lt;tt&amp;gt;BEGIN END&amp;lt;/tt&amp;gt; or another statement (to avoid&lt;br /&gt;
confusion with the operators &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; on relations).&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
&lt;br /&gt;
You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CONSTRAINTS         P                     (logical predicate)&lt;br /&gt;
 SETS                S;T={e1,e2,...};...&lt;br /&gt;
 FREETYPES           x=x1,x2(arg2),...;...&lt;br /&gt;
 CONSTANTS           x,y,...&lt;br /&gt;
 CONCRETE_CONSTANTS  cx,cy,...&lt;br /&gt;
 PROPERTIES          P                     (logical predicate)&lt;br /&gt;
 DEFINITIONS         m(x,...) == BODY;...&lt;br /&gt;
 VARIABLES           x,y,...&lt;br /&gt;
 CONCRETE_VARIABLES  cv,cw,...&lt;br /&gt;
 INVARIANT           P                     (logical predicate)&lt;br /&gt;
 ASSERTIONS          P;...;P               (list of logical predicates separated by ;)&lt;br /&gt;
 INITIALISATION      S                     (substitution)&lt;br /&gt;
 OPERATIONS          O;...                 (operations)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 USES      list of machines&lt;br /&gt;
 INCLUDES  list of machines&lt;br /&gt;
 SEES      list of machines&lt;br /&gt;
 EXTENDS   list of machines&lt;br /&gt;
 PROMOTES  list of operations&lt;br /&gt;
 REFINES   machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5812</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5812"/>
		<updated>2024-06-13T12:35:12Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Machine inclusion */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
In ProB, however, some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 size(s)   the length of a string s&lt;br /&gt;
 rev(s)    the reverse of a string s&lt;br /&gt;
 s ^ t     the concatenation of two strings&lt;br /&gt;
 conc(ss)  the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the &amp;lt;tt&amp;gt;STRING_AS_SEQUENCE&amp;lt;/tt&amp;gt; preference.&lt;br /&gt;
The [[External_Functions|library]] LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &amp;lt;tt&amp;gt;TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;FORMAT_TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;INT_TO_HEX_STRING&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
&lt;br /&gt;
ProB also allows multi-line strings.&lt;br /&gt;
&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 \n  newline (ASCII character 13)&lt;br /&gt;
 \r  carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;  the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;  the single quote symbol &#039;&lt;br /&gt;
 \\  the backslash symbol&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Within single-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r into an integer&lt;br /&gt;
 ceiling(r)  convert a real r into an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One can also use a lowercase &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; for literals in scientific notation (e.g. &amp;lt;tt&amp;gt;1.0e-10&amp;lt;/tt&amp;gt;).&lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus do not hold.&lt;br /&gt;
The  [[External_Functions|library]] LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &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;RLOG&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RSQRT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RPOW&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
You can turn off support for REALS using the preference &amp;lt;tt&amp;gt;ALLOW_REALS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The &amp;lt;tt&amp;gt;REAL_SOLVER&amp;lt;/tt&amp;gt; preference how constraints are solved.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, &amp;lt;tt&amp;gt;n=[1,2,1]&amp;lt;/tt&amp;gt;&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S.&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 tree(S)       set of trees over domain S&lt;br /&gt;
 btree(S)      set of binary trees over domain S&lt;br /&gt;
 top(t)        top of a tree&lt;br /&gt;
 const(E,s)    construct a tree from info E and sequence of subtrees s&lt;br /&gt;
 rank(t,n)     rank of the node at end of branch n in the tree t&lt;br /&gt;
 father(t,n)   father of the node denoted by branch n in the tree t&lt;br /&gt;
 son(t,n,i)    the ith son of the node denoted by branch n in tree t&lt;br /&gt;
 sons(t)       the sequence of sons of the root of the tree t&lt;br /&gt;
 subtree(t,n)&lt;br /&gt;
 arity(t,n)&lt;br /&gt;
 bin(E)        construct a binary tree with a single node E&lt;br /&gt;
 bin(tl,E,tr)  construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
 left(t)       the left (first) son of the root of the binary tree t&lt;br /&gt;
 right(t)      the right (last) son of the root of the binary tree t&lt;br /&gt;
 sizet(t)      the size of the tree (number of nodes)&lt;br /&gt;
 prefix(t)     the nodes of the tree t in prefix order&lt;br /&gt;
 postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
 mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates, expressions and substitutions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 IF P THEN E1 END                    conditional branching&lt;br /&gt;
 IF P THEN E1 ELSIF E2 END           we also allow multiple ELSIF branches&lt;br /&gt;
 IF P THEN E1 ELSE E2 END            but you always need an ELSE branch for expressions and predicates&lt;br /&gt;
 IF P THEN E1 ELSIF E2 ELSE E3 END&lt;br /&gt;
 LET x1,... BE x1=E1 &amp;amp; ... IN E END  introduce local variables&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expression &amp;lt;tt&amp;gt;Ei&amp;lt;/tt&amp;gt; defining &amp;lt;tt&amp;gt;xi&amp;lt;/tt&amp;gt; is allowed to use &amp;lt;tt&amp;gt;x1,...,x(i-1)&amp;lt;/tt&amp;gt; for predicates/expressions.&lt;br /&gt;
By setting the preference &amp;lt;tt&amp;gt;ALLOW_COMPLEX_LETS&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;, this is also allowed for substitutions.&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 skip                                                      no operation&lt;br /&gt;
 x := E                                                    assignment&lt;br /&gt;
 f(x) := E                                                 functional override&lt;br /&gt;
 x :: S                                                    choice from set&lt;br /&gt;
 x : (P)                                                   choice by predicate P (constraining x; previous value of x is x$0)&lt;br /&gt;
 x &amp;lt;-- OP(x)                                               call operation and assign return value&lt;br /&gt;
 G||H                                                      parallel substitution**&lt;br /&gt;
 G;H                                                       sequential composition**&lt;br /&gt;
 ANY x,... WHERE P THEN G END                              non deterministic choice&lt;br /&gt;
 LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
 VAR x,... IN G END                                        generate local variables&lt;br /&gt;
 PRE P THEN G END&lt;br /&gt;
 ASSERT P THEN G END&lt;br /&gt;
 CHOICE G OR H END&lt;br /&gt;
 IF P THEN G END&lt;br /&gt;
 IF P THEN G ELSE H END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
 WHILE P1 DO G INVARIANT P2 VARIANT E END&lt;br /&gt;
 WHEN P THEN G END                                         is a synonym for SELECT P THEN G END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;amp;ast;&amp;amp;ast;: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
be wrapped inside a &amp;lt;tt&amp;gt;BEGIN END&amp;lt;/tt&amp;gt; or another statement (to avoid&lt;br /&gt;
confusion with the operators &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; on relations).&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
&lt;br /&gt;
You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CONSTRAINTS         P                     (logical predicate)&lt;br /&gt;
 SETS                S;T={e1,e2,...};...&lt;br /&gt;
 FREETYPES           x=x1,x2(arg2),...;...&lt;br /&gt;
 CONSTANTS           x,y,...&lt;br /&gt;
 CONCRETE_CONSTANTS  cx,cy,...&lt;br /&gt;
 PROPERTIES          P                     (logical predicate)&lt;br /&gt;
 DEFINITIONS         m(x,...) == BODY;...&lt;br /&gt;
 VARIABLES           x,y,...&lt;br /&gt;
 CONCRETE_VARIABLES  cv,cw,...&lt;br /&gt;
 INVARIANT           P                     (logical predicate)&lt;br /&gt;
 ASSERTIONS          P;...;P               (list of logical predicates separated by ;)&lt;br /&gt;
 INITIALISATION      S                     (substitution)&lt;br /&gt;
 OPERATIONS          O;...                 (operations)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 USES list of machines&lt;br /&gt;
 INCLUDES list of machines&lt;br /&gt;
 SEES list of machines&lt;br /&gt;
 EXTENDS list of machines&lt;br /&gt;
 PROMOTES list of operations&lt;br /&gt;
 REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5811</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5811"/>
		<updated>2024-06-13T12:34:26Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Machine sections */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
In ProB, however, some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 size(s)   the length of a string s&lt;br /&gt;
 rev(s)    the reverse of a string s&lt;br /&gt;
 s ^ t     the concatenation of two strings&lt;br /&gt;
 conc(ss)  the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the &amp;lt;tt&amp;gt;STRING_AS_SEQUENCE&amp;lt;/tt&amp;gt; preference.&lt;br /&gt;
The [[External_Functions|library]] LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &amp;lt;tt&amp;gt;TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;FORMAT_TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;INT_TO_HEX_STRING&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
&lt;br /&gt;
ProB also allows multi-line strings.&lt;br /&gt;
&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 \n  newline (ASCII character 13)&lt;br /&gt;
 \r  carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;  the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;  the single quote symbol &#039;&lt;br /&gt;
 \\  the backslash symbol&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Within single-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r into an integer&lt;br /&gt;
 ceiling(r)  convert a real r into an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One can also use a lowercase &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; for literals in scientific notation (e.g. &amp;lt;tt&amp;gt;1.0e-10&amp;lt;/tt&amp;gt;).&lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus do not hold.&lt;br /&gt;
The  [[External_Functions|library]] LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &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;RLOG&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RSQRT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RPOW&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
You can turn off support for REALS using the preference &amp;lt;tt&amp;gt;ALLOW_REALS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The &amp;lt;tt&amp;gt;REAL_SOLVER&amp;lt;/tt&amp;gt; preference how constraints are solved.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, &amp;lt;tt&amp;gt;n=[1,2,1]&amp;lt;/tt&amp;gt;&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S.&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 tree(S)       set of trees over domain S&lt;br /&gt;
 btree(S)      set of binary trees over domain S&lt;br /&gt;
 top(t)        top of a tree&lt;br /&gt;
 const(E,s)    construct a tree from info E and sequence of subtrees s&lt;br /&gt;
 rank(t,n)     rank of the node at end of branch n in the tree t&lt;br /&gt;
 father(t,n)   father of the node denoted by branch n in the tree t&lt;br /&gt;
 son(t,n,i)    the ith son of the node denoted by branch n in tree t&lt;br /&gt;
 sons(t)       the sequence of sons of the root of the tree t&lt;br /&gt;
 subtree(t,n)&lt;br /&gt;
 arity(t,n)&lt;br /&gt;
 bin(E)        construct a binary tree with a single node E&lt;br /&gt;
 bin(tl,E,tr)  construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
 left(t)       the left (first) son of the root of the binary tree t&lt;br /&gt;
 right(t)      the right (last) son of the root of the binary tree t&lt;br /&gt;
 sizet(t)      the size of the tree (number of nodes)&lt;br /&gt;
 prefix(t)     the nodes of the tree t in prefix order&lt;br /&gt;
 postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
 mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates, expressions and substitutions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 IF P THEN E1 END                    conditional branching&lt;br /&gt;
 IF P THEN E1 ELSIF E2 END           we also allow multiple ELSIF branches&lt;br /&gt;
 IF P THEN E1 ELSE E2 END            but you always need an ELSE branch for expressions and predicates&lt;br /&gt;
 IF P THEN E1 ELSIF E2 ELSE E3 END&lt;br /&gt;
 LET x1,... BE x1=E1 &amp;amp; ... IN E END  introduce local variables&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expression &amp;lt;tt&amp;gt;Ei&amp;lt;/tt&amp;gt; defining &amp;lt;tt&amp;gt;xi&amp;lt;/tt&amp;gt; is allowed to use &amp;lt;tt&amp;gt;x1,...,x(i-1)&amp;lt;/tt&amp;gt; for predicates/expressions.&lt;br /&gt;
By setting the preference &amp;lt;tt&amp;gt;ALLOW_COMPLEX_LETS&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;, this is also allowed for substitutions.&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 skip                                                      no operation&lt;br /&gt;
 x := E                                                    assignment&lt;br /&gt;
 f(x) := E                                                 functional override&lt;br /&gt;
 x :: S                                                    choice from set&lt;br /&gt;
 x : (P)                                                   choice by predicate P (constraining x; previous value of x is x$0)&lt;br /&gt;
 x &amp;lt;-- OP(x)                                               call operation and assign return value&lt;br /&gt;
 G||H                                                      parallel substitution**&lt;br /&gt;
 G;H                                                       sequential composition**&lt;br /&gt;
 ANY x,... WHERE P THEN G END                              non deterministic choice&lt;br /&gt;
 LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
 VAR x,... IN G END                                        generate local variables&lt;br /&gt;
 PRE P THEN G END&lt;br /&gt;
 ASSERT P THEN G END&lt;br /&gt;
 CHOICE G OR H END&lt;br /&gt;
 IF P THEN G END&lt;br /&gt;
 IF P THEN G ELSE H END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
 WHILE P1 DO G INVARIANT P2 VARIANT E END&lt;br /&gt;
 WHEN P THEN G END                                         is a synonym for SELECT P THEN G END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;amp;ast;&amp;amp;ast;: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
be wrapped inside a &amp;lt;tt&amp;gt;BEGIN END&amp;lt;/tt&amp;gt; or another statement (to avoid&lt;br /&gt;
confusion with the operators &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; on relations).&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
&lt;br /&gt;
You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 CONSTRAINTS         P                     (logical predicate)&lt;br /&gt;
 SETS                S;T={e1,e2,...};...&lt;br /&gt;
 FREETYPES           x=x1,x2(arg2),...;...&lt;br /&gt;
 CONSTANTS           x,y,...&lt;br /&gt;
 CONCRETE_CONSTANTS  cx,cy,...&lt;br /&gt;
 PROPERTIES          P                     (logical predicate)&lt;br /&gt;
 DEFINITIONS         m(x,...) == BODY;...&lt;br /&gt;
 VARIABLES           x,y,...&lt;br /&gt;
 CONCRETE_VARIABLES  cv,cw,...&lt;br /&gt;
 INVARIANT           P                     (logical predicate)&lt;br /&gt;
 ASSERTIONS          P;...;P               (list of logical predicates separated by ;)&lt;br /&gt;
 INITIALISATION      S                     (substitution)&lt;br /&gt;
 OPERATIONS          O;...                 (operations)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5810</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5810"/>
		<updated>2024-06-13T12:32:14Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Machine header */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
In ProB, however, some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 size(s)   the length of a string s&lt;br /&gt;
 rev(s)    the reverse of a string s&lt;br /&gt;
 s ^ t     the concatenation of two strings&lt;br /&gt;
 conc(ss)  the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the &amp;lt;tt&amp;gt;STRING_AS_SEQUENCE&amp;lt;/tt&amp;gt; preference.&lt;br /&gt;
The [[External_Functions|library]] LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &amp;lt;tt&amp;gt;TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;FORMAT_TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;INT_TO_HEX_STRING&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
&lt;br /&gt;
ProB also allows multi-line strings.&lt;br /&gt;
&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 \n  newline (ASCII character 13)&lt;br /&gt;
 \r  carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;  the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;  the single quote symbol &#039;&lt;br /&gt;
 \\  the backslash symbol&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Within single-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r into an integer&lt;br /&gt;
 ceiling(r)  convert a real r into an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One can also use a lowercase &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; for literals in scientific notation (e.g. &amp;lt;tt&amp;gt;1.0e-10&amp;lt;/tt&amp;gt;).&lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus do not hold.&lt;br /&gt;
The  [[External_Functions|library]] LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &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;RLOG&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RSQRT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RPOW&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
You can turn off support for REALS using the preference &amp;lt;tt&amp;gt;ALLOW_REALS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The &amp;lt;tt&amp;gt;REAL_SOLVER&amp;lt;/tt&amp;gt; preference how constraints are solved.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, &amp;lt;tt&amp;gt;n=[1,2,1]&amp;lt;/tt&amp;gt;&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S.&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 tree(S)       set of trees over domain S&lt;br /&gt;
 btree(S)      set of binary trees over domain S&lt;br /&gt;
 top(t)        top of a tree&lt;br /&gt;
 const(E,s)    construct a tree from info E and sequence of subtrees s&lt;br /&gt;
 rank(t,n)     rank of the node at end of branch n in the tree t&lt;br /&gt;
 father(t,n)   father of the node denoted by branch n in the tree t&lt;br /&gt;
 son(t,n,i)    the ith son of the node denoted by branch n in tree t&lt;br /&gt;
 sons(t)       the sequence of sons of the root of the tree t&lt;br /&gt;
 subtree(t,n)&lt;br /&gt;
 arity(t,n)&lt;br /&gt;
 bin(E)        construct a binary tree with a single node E&lt;br /&gt;
 bin(tl,E,tr)  construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
 left(t)       the left (first) son of the root of the binary tree t&lt;br /&gt;
 right(t)      the right (last) son of the root of the binary tree t&lt;br /&gt;
 sizet(t)      the size of the tree (number of nodes)&lt;br /&gt;
 prefix(t)     the nodes of the tree t in prefix order&lt;br /&gt;
 postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
 mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates, expressions and substitutions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 IF P THEN E1 END                    conditional branching&lt;br /&gt;
 IF P THEN E1 ELSIF E2 END           we also allow multiple ELSIF branches&lt;br /&gt;
 IF P THEN E1 ELSE E2 END            but you always need an ELSE branch for expressions and predicates&lt;br /&gt;
 IF P THEN E1 ELSIF E2 ELSE E3 END&lt;br /&gt;
 LET x1,... BE x1=E1 &amp;amp; ... IN E END  introduce local variables&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expression &amp;lt;tt&amp;gt;Ei&amp;lt;/tt&amp;gt; defining &amp;lt;tt&amp;gt;xi&amp;lt;/tt&amp;gt; is allowed to use &amp;lt;tt&amp;gt;x1,...,x(i-1)&amp;lt;/tt&amp;gt; for predicates/expressions.&lt;br /&gt;
By setting the preference &amp;lt;tt&amp;gt;ALLOW_COMPLEX_LETS&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;, this is also allowed for substitutions.&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 skip                                                      no operation&lt;br /&gt;
 x := E                                                    assignment&lt;br /&gt;
 f(x) := E                                                 functional override&lt;br /&gt;
 x :: S                                                    choice from set&lt;br /&gt;
 x : (P)                                                   choice by predicate P (constraining x; previous value of x is x$0)&lt;br /&gt;
 x &amp;lt;-- OP(x)                                               call operation and assign return value&lt;br /&gt;
 G||H                                                      parallel substitution**&lt;br /&gt;
 G;H                                                       sequential composition**&lt;br /&gt;
 ANY x,... WHERE P THEN G END                              non deterministic choice&lt;br /&gt;
 LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
 VAR x,... IN G END                                        generate local variables&lt;br /&gt;
 PRE P THEN G END&lt;br /&gt;
 ASSERT P THEN G END&lt;br /&gt;
 CHOICE G OR H END&lt;br /&gt;
 IF P THEN G END&lt;br /&gt;
 IF P THEN G ELSE H END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
 WHILE P1 DO G INVARIANT P2 VARIANT E END&lt;br /&gt;
 WHEN P THEN G END                                         is a synonym for SELECT P THEN G END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;amp;ast;&amp;amp;ast;: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
be wrapped inside a &amp;lt;tt&amp;gt;BEGIN END&amp;lt;/tt&amp;gt; or another statement (to avoid&lt;br /&gt;
confusion with the operators &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; on relations).&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
&lt;br /&gt;
You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5809</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5809"/>
		<updated>2024-06-13T12:31:24Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Statements (aka Substitutions) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
In ProB, however, some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 size(s)   the length of a string s&lt;br /&gt;
 rev(s)    the reverse of a string s&lt;br /&gt;
 s ^ t     the concatenation of two strings&lt;br /&gt;
 conc(ss)  the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the &amp;lt;tt&amp;gt;STRING_AS_SEQUENCE&amp;lt;/tt&amp;gt; preference.&lt;br /&gt;
The [[External_Functions|library]] LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &amp;lt;tt&amp;gt;TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;FORMAT_TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;INT_TO_HEX_STRING&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
&lt;br /&gt;
ProB also allows multi-line strings.&lt;br /&gt;
&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 \n  newline (ASCII character 13)&lt;br /&gt;
 \r  carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;  the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;  the single quote symbol &#039;&lt;br /&gt;
 \\  the backslash symbol&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Within single-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r into an integer&lt;br /&gt;
 ceiling(r)  convert a real r into an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One can also use a lowercase &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; for literals in scientific notation (e.g. &amp;lt;tt&amp;gt;1.0e-10&amp;lt;/tt&amp;gt;).&lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus do not hold.&lt;br /&gt;
The  [[External_Functions|library]] LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &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;RLOG&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RSQRT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RPOW&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
You can turn off support for REALS using the preference &amp;lt;tt&amp;gt;ALLOW_REALS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The &amp;lt;tt&amp;gt;REAL_SOLVER&amp;lt;/tt&amp;gt; preference how constraints are solved.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, &amp;lt;tt&amp;gt;n=[1,2,1]&amp;lt;/tt&amp;gt;&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S.&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 tree(S)       set of trees over domain S&lt;br /&gt;
 btree(S)      set of binary trees over domain S&lt;br /&gt;
 top(t)        top of a tree&lt;br /&gt;
 const(E,s)    construct a tree from info E and sequence of subtrees s&lt;br /&gt;
 rank(t,n)     rank of the node at end of branch n in the tree t&lt;br /&gt;
 father(t,n)   father of the node denoted by branch n in the tree t&lt;br /&gt;
 son(t,n,i)    the ith son of the node denoted by branch n in tree t&lt;br /&gt;
 sons(t)       the sequence of sons of the root of the tree t&lt;br /&gt;
 subtree(t,n)&lt;br /&gt;
 arity(t,n)&lt;br /&gt;
 bin(E)        construct a binary tree with a single node E&lt;br /&gt;
 bin(tl,E,tr)  construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
 left(t)       the left (first) son of the root of the binary tree t&lt;br /&gt;
 right(t)      the right (last) son of the root of the binary tree t&lt;br /&gt;
 sizet(t)      the size of the tree (number of nodes)&lt;br /&gt;
 prefix(t)     the nodes of the tree t in prefix order&lt;br /&gt;
 postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
 mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates, expressions and substitutions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 IF P THEN E1 END                    conditional branching&lt;br /&gt;
 IF P THEN E1 ELSIF E2 END           we also allow multiple ELSIF branches&lt;br /&gt;
 IF P THEN E1 ELSE E2 END            but you always need an ELSE branch for expressions and predicates&lt;br /&gt;
 IF P THEN E1 ELSIF E2 ELSE E3 END&lt;br /&gt;
 LET x1,... BE x1=E1 &amp;amp; ... IN E END  introduce local variables&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expression &amp;lt;tt&amp;gt;Ei&amp;lt;/tt&amp;gt; defining &amp;lt;tt&amp;gt;xi&amp;lt;/tt&amp;gt; is allowed to use &amp;lt;tt&amp;gt;x1,...,x(i-1)&amp;lt;/tt&amp;gt; for predicates/expressions.&lt;br /&gt;
By setting the preference &amp;lt;tt&amp;gt;ALLOW_COMPLEX_LETS&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;, this is also allowed for substitutions.&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 skip                                                      no operation&lt;br /&gt;
 x := E                                                    assignment&lt;br /&gt;
 f(x) := E                                                 functional override&lt;br /&gt;
 x :: S                                                    choice from set&lt;br /&gt;
 x : (P)                                                   choice by predicate P (constraining x; previous value of x is x$0)&lt;br /&gt;
 x &amp;lt;-- OP(x)                                               call operation and assign return value&lt;br /&gt;
 G||H                                                      parallel substitution**&lt;br /&gt;
 G;H                                                       sequential composition**&lt;br /&gt;
 ANY x,... WHERE P THEN G END                              non deterministic choice&lt;br /&gt;
 LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
 VAR x,... IN G END                                        generate local variables&lt;br /&gt;
 PRE P THEN G END&lt;br /&gt;
 ASSERT P THEN G END&lt;br /&gt;
 CHOICE G OR H END&lt;br /&gt;
 IF P THEN G END&lt;br /&gt;
 IF P THEN G ELSE H END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
 WHILE P1 DO G INVARIANT P2 VARIANT E END&lt;br /&gt;
 WHEN P THEN G END                                         is a synonym for SELECT P THEN G END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;amp;ast;&amp;amp;ast;: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
be wrapped inside a &amp;lt;tt&amp;gt;BEGIN END&amp;lt;/tt&amp;gt; or another statement (to avoid&lt;br /&gt;
confusion with the operators &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; on relations).&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5808</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5808"/>
		<updated>2024-06-13T12:30:23Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Statements (aka Substitutions) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
In ProB, however, some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 size(s)   the length of a string s&lt;br /&gt;
 rev(s)    the reverse of a string s&lt;br /&gt;
 s ^ t     the concatenation of two strings&lt;br /&gt;
 conc(ss)  the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the &amp;lt;tt&amp;gt;STRING_AS_SEQUENCE&amp;lt;/tt&amp;gt; preference.&lt;br /&gt;
The [[External_Functions|library]] LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &amp;lt;tt&amp;gt;TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;FORMAT_TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;INT_TO_HEX_STRING&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
&lt;br /&gt;
ProB also allows multi-line strings.&lt;br /&gt;
&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 \n  newline (ASCII character 13)&lt;br /&gt;
 \r  carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;  the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;  the single quote symbol &#039;&lt;br /&gt;
 \\  the backslash symbol&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Within single-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r into an integer&lt;br /&gt;
 ceiling(r)  convert a real r into an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One can also use a lowercase &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; for literals in scientific notation (e.g. &amp;lt;tt&amp;gt;1.0e-10&amp;lt;/tt&amp;gt;).&lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus do not hold.&lt;br /&gt;
The  [[External_Functions|library]] LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &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;RLOG&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RSQRT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RPOW&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
You can turn off support for REALS using the preference &amp;lt;tt&amp;gt;ALLOW_REALS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The &amp;lt;tt&amp;gt;REAL_SOLVER&amp;lt;/tt&amp;gt; preference how constraints are solved.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, &amp;lt;tt&amp;gt;n=[1,2,1]&amp;lt;/tt&amp;gt;&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S.&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 tree(S)       set of trees over domain S&lt;br /&gt;
 btree(S)      set of binary trees over domain S&lt;br /&gt;
 top(t)        top of a tree&lt;br /&gt;
 const(E,s)    construct a tree from info E and sequence of subtrees s&lt;br /&gt;
 rank(t,n)     rank of the node at end of branch n in the tree t&lt;br /&gt;
 father(t,n)   father of the node denoted by branch n in the tree t&lt;br /&gt;
 son(t,n,i)    the ith son of the node denoted by branch n in tree t&lt;br /&gt;
 sons(t)       the sequence of sons of the root of the tree t&lt;br /&gt;
 subtree(t,n)&lt;br /&gt;
 arity(t,n)&lt;br /&gt;
 bin(E)        construct a binary tree with a single node E&lt;br /&gt;
 bin(tl,E,tr)  construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
 left(t)       the left (first) son of the root of the binary tree t&lt;br /&gt;
 right(t)      the right (last) son of the root of the binary tree t&lt;br /&gt;
 sizet(t)      the size of the tree (number of nodes)&lt;br /&gt;
 prefix(t)     the nodes of the tree t in prefix order&lt;br /&gt;
 postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
 mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates, expressions and substitutions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 IF P THEN E1 END                    conditional branching&lt;br /&gt;
 IF P THEN E1 ELSIF E2 END           we also allow multiple ELSIF branches&lt;br /&gt;
 IF P THEN E1 ELSE E2 END            but you always need an ELSE branch for expressions and predicates&lt;br /&gt;
 IF P THEN E1 ELSIF E2 ELSE E3 END&lt;br /&gt;
 LET x1,... BE x1=E1 &amp;amp; ... IN E END  introduce local variables&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expression &amp;lt;tt&amp;gt;Ei&amp;lt;/tt&amp;gt; defining &amp;lt;tt&amp;gt;xi&amp;lt;/tt&amp;gt; is allowed to use &amp;lt;tt&amp;gt;x1,...,x(i-1)&amp;lt;/tt&amp;gt; for predicates/expressions.&lt;br /&gt;
By setting the preference &amp;lt;tt&amp;gt;ALLOW_COMPLEX_LETS&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;, this is also allowed for substitutions.&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 skip                                                      no operation&lt;br /&gt;
 x := E                                                    assignment&lt;br /&gt;
 f(x) := E                                                 functional override&lt;br /&gt;
 x :: S                                                    choice from set&lt;br /&gt;
 x : (P)                                                   choice by predicate P (constraining x; previous value of x is x$0)&lt;br /&gt;
 x &amp;lt;-- OP(x)                                               call operation and assign return value&lt;br /&gt;
 G||H                                                      parallel substitution**&lt;br /&gt;
 G;H                                                       sequential composition**&lt;br /&gt;
 ANY x,... WHERE P THEN G END                              non deterministic choice&lt;br /&gt;
 LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
 VAR x,... IN G END                                        generate local variables&lt;br /&gt;
 PRE P THEN G END&lt;br /&gt;
 ASSERT P THEN G END&lt;br /&gt;
 CHOICE G OR H END&lt;br /&gt;
 IF P THEN G END&lt;br /&gt;
 IF P THEN G ELSE H END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
 WHILE P1 DO G INVARIANT P2 VARIANT E END&lt;br /&gt;
 WHEN P THEN G END                                         is a synonym for SELECT P THEN G END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
\**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
be wrapped inside a &amp;lt;tt&amp;gt;BEGIN END&amp;lt;/tt&amp;gt; or another statement (to avoid&lt;br /&gt;
confusion with the operators &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; on relations).&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5807</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5807"/>
		<updated>2024-06-13T12:30:12Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Statements (aka Substitutions) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
In ProB, however, some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 size(s)   the length of a string s&lt;br /&gt;
 rev(s)    the reverse of a string s&lt;br /&gt;
 s ^ t     the concatenation of two strings&lt;br /&gt;
 conc(ss)  the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the &amp;lt;tt&amp;gt;STRING_AS_SEQUENCE&amp;lt;/tt&amp;gt; preference.&lt;br /&gt;
The [[External_Functions|library]] LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &amp;lt;tt&amp;gt;TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;FORMAT_TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;INT_TO_HEX_STRING&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
&lt;br /&gt;
ProB also allows multi-line strings.&lt;br /&gt;
&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 \n  newline (ASCII character 13)&lt;br /&gt;
 \r  carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;  the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;  the single quote symbol &#039;&lt;br /&gt;
 \\  the backslash symbol&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Within single-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r into an integer&lt;br /&gt;
 ceiling(r)  convert a real r into an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One can also use a lowercase &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; for literals in scientific notation (e.g. &amp;lt;tt&amp;gt;1.0e-10&amp;lt;/tt&amp;gt;).&lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus do not hold.&lt;br /&gt;
The  [[External_Functions|library]] LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &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;RLOG&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RSQRT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RPOW&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
You can turn off support for REALS using the preference &amp;lt;tt&amp;gt;ALLOW_REALS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The &amp;lt;tt&amp;gt;REAL_SOLVER&amp;lt;/tt&amp;gt; preference how constraints are solved.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, &amp;lt;tt&amp;gt;n=[1,2,1]&amp;lt;/tt&amp;gt;&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S.&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 tree(S)       set of trees over domain S&lt;br /&gt;
 btree(S)      set of binary trees over domain S&lt;br /&gt;
 top(t)        top of a tree&lt;br /&gt;
 const(E,s)    construct a tree from info E and sequence of subtrees s&lt;br /&gt;
 rank(t,n)     rank of the node at end of branch n in the tree t&lt;br /&gt;
 father(t,n)   father of the node denoted by branch n in the tree t&lt;br /&gt;
 son(t,n,i)    the ith son of the node denoted by branch n in tree t&lt;br /&gt;
 sons(t)       the sequence of sons of the root of the tree t&lt;br /&gt;
 subtree(t,n)&lt;br /&gt;
 arity(t,n)&lt;br /&gt;
 bin(E)        construct a binary tree with a single node E&lt;br /&gt;
 bin(tl,E,tr)  construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
 left(t)       the left (first) son of the root of the binary tree t&lt;br /&gt;
 right(t)      the right (last) son of the root of the binary tree t&lt;br /&gt;
 sizet(t)      the size of the tree (number of nodes)&lt;br /&gt;
 prefix(t)     the nodes of the tree t in prefix order&lt;br /&gt;
 postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
 mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates, expressions and substitutions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 IF P THEN E1 END                    conditional branching&lt;br /&gt;
 IF P THEN E1 ELSIF E2 END           we also allow multiple ELSIF branches&lt;br /&gt;
 IF P THEN E1 ELSE E2 END            but you always need an ELSE branch for expressions and predicates&lt;br /&gt;
 IF P THEN E1 ELSIF E2 ELSE E3 END&lt;br /&gt;
 LET x1,... BE x1=E1 &amp;amp; ... IN E END  introduce local variables&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expression &amp;lt;tt&amp;gt;Ei&amp;lt;/tt&amp;gt; defining &amp;lt;tt&amp;gt;xi&amp;lt;/tt&amp;gt; is allowed to use &amp;lt;tt&amp;gt;x1,...,x(i-1)&amp;lt;/tt&amp;gt; for predicates/expressions.&lt;br /&gt;
By setting the preference &amp;lt;tt&amp;gt;ALLOW_COMPLEX_LETS&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;, this is also allowed for substitutions.&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 skip                                                      no operation&lt;br /&gt;
 x := E                                                    assignment&lt;br /&gt;
 f(x) := E                                                 functional override&lt;br /&gt;
 x :: S                                                    choice from set&lt;br /&gt;
 x : (P)                                                   choice by predicate P (constraining x; previous value of x is x$0)&lt;br /&gt;
 x &amp;lt;-- OP(x)                                               call operation and assign return value&lt;br /&gt;
 G||H                                                      parallel substitution**&lt;br /&gt;
 G;H                                                       sequential composition**&lt;br /&gt;
 ANY x,... WHERE P THEN G END                              non deterministic choice&lt;br /&gt;
 LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
 VAR x,... IN G END                                        generate local variables&lt;br /&gt;
 PRE P THEN G END&lt;br /&gt;
 ASSERT P THEN G END&lt;br /&gt;
 CHOICE G OR H END&lt;br /&gt;
 IF P THEN G END&lt;br /&gt;
 IF P THEN G ELSE H END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
 IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
 SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
 CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
 WHILE P1 DO G INVARIANT P2 VARIANT E END&lt;br /&gt;
 WHEN P THEN G END                                         is a synonym for SELECT P THEN G END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
be wrapped inside a &amp;lt;tt&amp;gt;BEGIN END&amp;lt;/tt&amp;gt; or another statement (to avoid&lt;br /&gt;
confusion with the operators &amp;lt;tt&amp;gt;;&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; on relations).&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5806</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5806"/>
		<updated>2024-06-13T12:27:40Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* LET and IF-THEN-ELSE */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
In ProB, however, some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 size(s)   the length of a string s&lt;br /&gt;
 rev(s)    the reverse of a string s&lt;br /&gt;
 s ^ t     the concatenation of two strings&lt;br /&gt;
 conc(ss)  the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the &amp;lt;tt&amp;gt;STRING_AS_SEQUENCE&amp;lt;/tt&amp;gt; preference.&lt;br /&gt;
The [[External_Functions|library]] LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &amp;lt;tt&amp;gt;TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;FORMAT_TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;INT_TO_HEX_STRING&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
&lt;br /&gt;
ProB also allows multi-line strings.&lt;br /&gt;
&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 \n  newline (ASCII character 13)&lt;br /&gt;
 \r  carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;  the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;  the single quote symbol &#039;&lt;br /&gt;
 \\  the backslash symbol&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Within single-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r into an integer&lt;br /&gt;
 ceiling(r)  convert a real r into an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One can also use a lowercase &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; for literals in scientific notation (e.g. &amp;lt;tt&amp;gt;1.0e-10&amp;lt;/tt&amp;gt;).&lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus do not hold.&lt;br /&gt;
The  [[External_Functions|library]] LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &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;RLOG&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RSQRT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RPOW&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
You can turn off support for REALS using the preference &amp;lt;tt&amp;gt;ALLOW_REALS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The &amp;lt;tt&amp;gt;REAL_SOLVER&amp;lt;/tt&amp;gt; preference how constraints are solved.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, &amp;lt;tt&amp;gt;n=[1,2,1]&amp;lt;/tt&amp;gt;&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S.&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 tree(S)       set of trees over domain S&lt;br /&gt;
 btree(S)      set of binary trees over domain S&lt;br /&gt;
 top(t)        top of a tree&lt;br /&gt;
 const(E,s)    construct a tree from info E and sequence of subtrees s&lt;br /&gt;
 rank(t,n)     rank of the node at end of branch n in the tree t&lt;br /&gt;
 father(t,n)   father of the node denoted by branch n in the tree t&lt;br /&gt;
 son(t,n,i)    the ith son of the node denoted by branch n in tree t&lt;br /&gt;
 sons(t)       the sequence of sons of the root of the tree t&lt;br /&gt;
 subtree(t,n)&lt;br /&gt;
 arity(t,n)&lt;br /&gt;
 bin(E)        construct a binary tree with a single node E&lt;br /&gt;
 bin(tl,E,tr)  construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
 left(t)       the left (first) son of the root of the binary tree t&lt;br /&gt;
 right(t)      the right (last) son of the root of the binary tree t&lt;br /&gt;
 sizet(t)      the size of the tree (number of nodes)&lt;br /&gt;
 prefix(t)     the nodes of the tree t in prefix order&lt;br /&gt;
 postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
 mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates, expressions and substitutions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 IF P THEN E1 END                    conditional branching&lt;br /&gt;
 IF P THEN E1 ELSIF E2 END           we also allow multiple ELSIF branches&lt;br /&gt;
 IF P THEN E1 ELSE E2 END            but you always need an ELSE branch for expressions and predicates&lt;br /&gt;
 IF P THEN E1 ELSIF E2 ELSE E3 END&lt;br /&gt;
 LET x1,... BE x1=E1 &amp;amp; ... IN E END  introduce local variables&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expression &amp;lt;tt&amp;gt;Ei&amp;lt;/tt&amp;gt; defining &amp;lt;tt&amp;gt;xi&amp;lt;/tt&amp;gt; is allowed to use &amp;lt;tt&amp;gt;x1,...,x(i-1)&amp;lt;/tt&amp;gt; for predicates/expressions.&lt;br /&gt;
By setting the preference &amp;lt;tt&amp;gt;ALLOW_COMPLEX_LETS&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;, this is also allowed for substitutions.&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5805</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5805"/>
		<updated>2024-06-13T12:27:06Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* LET and IF-THEN-ELSE */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
In ProB, however, some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 size(s)   the length of a string s&lt;br /&gt;
 rev(s)    the reverse of a string s&lt;br /&gt;
 s ^ t     the concatenation of two strings&lt;br /&gt;
 conc(ss)  the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the &amp;lt;tt&amp;gt;STRING_AS_SEQUENCE&amp;lt;/tt&amp;gt; preference.&lt;br /&gt;
The [[External_Functions|library]] LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &amp;lt;tt&amp;gt;TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;FORMAT_TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;INT_TO_HEX_STRING&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
&lt;br /&gt;
ProB also allows multi-line strings.&lt;br /&gt;
&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 \n  newline (ASCII character 13)&lt;br /&gt;
 \r  carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;  the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;  the single quote symbol &#039;&lt;br /&gt;
 \\  the backslash symbol&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Within single-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r into an integer&lt;br /&gt;
 ceiling(r)  convert a real r into an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One can also use a lowercase &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; for literals in scientific notation (e.g. &amp;lt;tt&amp;gt;1.0e-10&amp;lt;/tt&amp;gt;).&lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus do not hold.&lt;br /&gt;
The  [[External_Functions|library]] LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &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;RLOG&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RSQRT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RPOW&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
You can turn off support for REALS using the preference &amp;lt;tt&amp;gt;ALLOW_REALS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The &amp;lt;tt&amp;gt;REAL_SOLVER&amp;lt;/tt&amp;gt; preference how constraints are solved.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, &amp;lt;tt&amp;gt;n=[1,2,1]&amp;lt;/tt&amp;gt;&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S.&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 tree(S)       set of trees over domain S&lt;br /&gt;
 btree(S)      set of binary trees over domain S&lt;br /&gt;
 top(t)        top of a tree&lt;br /&gt;
 const(E,s)    construct a tree from info E and sequence of subtrees s&lt;br /&gt;
 rank(t,n)     rank of the node at end of branch n in the tree t&lt;br /&gt;
 father(t,n)   father of the node denoted by branch n in the tree t&lt;br /&gt;
 son(t,n,i)    the ith son of the node denoted by branch n in tree t&lt;br /&gt;
 sons(t)       the sequence of sons of the root of the tree t&lt;br /&gt;
 subtree(t,n)&lt;br /&gt;
 arity(t,n)&lt;br /&gt;
 bin(E)        construct a binary tree with a single node E&lt;br /&gt;
 bin(tl,E,tr)  construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
 left(t)       the left (first) son of the root of the binary tree t&lt;br /&gt;
 right(t)      the right (last) son of the root of the binary tree t&lt;br /&gt;
 sizet(t)      the size of the tree (number of nodes)&lt;br /&gt;
 prefix(t)     the nodes of the tree t in prefix order&lt;br /&gt;
 postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
 mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates, expressions and substitutions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 IF P THEN E1 END                    conditional branching&lt;br /&gt;
 IF P THEN E1 ELSIF E2 END           we also allow multiple ELSIF branches&lt;br /&gt;
 IF P THEN E1 ELSE E2 END            but you always need an ELSE branch for expressions and predicates&lt;br /&gt;
 IF P THEN E1 ELSIF E2 ELSE E3 END&lt;br /&gt;
 LET x1,... BE x1=E1 &amp;amp; ... IN E END  introduce local variables&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expression &amp;lt;tt&amp;gt;Ei&amp;lt;/tt&amp;gt; defining &amp;lt;tt&amp;gt;xi&amp;lt;/tt&amp;gt; is allowed to use &amp;lt;tt&amp;gt;x1,...,x(i-1)&amp;lt;/tt&amp;gt; for predicates/expressions.&lt;br /&gt;
      By setting the preference &amp;lt;tt&amp;gt;ALLOW_COMPLEX_LETS&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;, this is also allowed for substitutions.&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5804</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5804"/>
		<updated>2024-06-13T12:18:14Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Trees */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
In ProB, however, some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 size(s)   the length of a string s&lt;br /&gt;
 rev(s)    the reverse of a string s&lt;br /&gt;
 s ^ t     the concatenation of two strings&lt;br /&gt;
 conc(ss)  the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the &amp;lt;tt&amp;gt;STRING_AS_SEQUENCE&amp;lt;/tt&amp;gt; preference.&lt;br /&gt;
The [[External_Functions|library]] LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &amp;lt;tt&amp;gt;TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;FORMAT_TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;INT_TO_HEX_STRING&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
&lt;br /&gt;
ProB also allows multi-line strings.&lt;br /&gt;
&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 \n  newline (ASCII character 13)&lt;br /&gt;
 \r  carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;  the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;  the single quote symbol &#039;&lt;br /&gt;
 \\  the backslash symbol&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Within single-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r into an integer&lt;br /&gt;
 ceiling(r)  convert a real r into an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One can also use a lowercase &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; for literals in scientific notation (e.g. &amp;lt;tt&amp;gt;1.0e-10&amp;lt;/tt&amp;gt;).&lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus do not hold.&lt;br /&gt;
The  [[External_Functions|library]] LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &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;RLOG&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RSQRT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RPOW&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
You can turn off support for REALS using the preference &amp;lt;tt&amp;gt;ALLOW_REALS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The &amp;lt;tt&amp;gt;REAL_SOLVER&amp;lt;/tt&amp;gt; preference how constraints are solved.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, &amp;lt;tt&amp;gt;n=[1,2,1]&amp;lt;/tt&amp;gt;&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S.&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 tree(S)       set of trees over domain S&lt;br /&gt;
 btree(S)      set of binary trees over domain S&lt;br /&gt;
 top(t)        top of a tree&lt;br /&gt;
 const(E,s)    construct a tree from info E and sequence of subtrees s&lt;br /&gt;
 rank(t,n)     rank of the node at end of branch n in the tree t&lt;br /&gt;
 father(t,n)   father of the node denoted by branch n in the tree t&lt;br /&gt;
 son(t,n,i)    the ith son of the node denoted by branch n in tree t&lt;br /&gt;
 sons(t)       the sequence of sons of the root of the tree t&lt;br /&gt;
 subtree(t,n)&lt;br /&gt;
 arity(t,n)&lt;br /&gt;
 bin(E)        construct a binary tree with a single node E&lt;br /&gt;
 bin(tl,E,tr)  construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
 left(t)       the left (first) son of the root of the binary tree t&lt;br /&gt;
 right(t)      the right (last) son of the root of the binary tree t&lt;br /&gt;
 sizet(t)      the size of the tree (number of nodes)&lt;br /&gt;
 prefix(t)     the nodes of the tree t in prefix order&lt;br /&gt;
 postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
 mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5803</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5803"/>
		<updated>2024-06-13T12:16:59Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Reals */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
In ProB, however, some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 size(s)   the length of a string s&lt;br /&gt;
 rev(s)    the reverse of a string s&lt;br /&gt;
 s ^ t     the concatenation of two strings&lt;br /&gt;
 conc(ss)  the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the &amp;lt;tt&amp;gt;STRING_AS_SEQUENCE&amp;lt;/tt&amp;gt; preference.&lt;br /&gt;
The [[External_Functions|library]] LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &amp;lt;tt&amp;gt;TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;FORMAT_TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;INT_TO_HEX_STRING&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
&lt;br /&gt;
ProB also allows multi-line strings.&lt;br /&gt;
&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 \n  newline (ASCII character 13)&lt;br /&gt;
 \r  carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;  the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;  the single quote symbol &#039;&lt;br /&gt;
 \\  the backslash symbol&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Within single-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r into an integer&lt;br /&gt;
 ceiling(r)  convert a real r into an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One can also use a lowercase &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; for literals in scientific notation (e.g. &amp;lt;tt&amp;gt;1.0e-10&amp;lt;/tt&amp;gt;).&lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus do not hold.&lt;br /&gt;
The  [[External_Functions|library]] LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &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;RLOG&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RSQRT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RPOW&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
You can turn off support for REALS using the preference &amp;lt;tt&amp;gt;ALLOW_REALS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
The &amp;lt;tt&amp;gt;REAL_SOLVER&amp;lt;/tt&amp;gt; preference how constraints are solved.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5802</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5802"/>
		<updated>2024-06-13T12:16:39Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Reals */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
In ProB, however, some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 size(s)   the length of a string s&lt;br /&gt;
 rev(s)    the reverse of a string s&lt;br /&gt;
 s ^ t     the concatenation of two strings&lt;br /&gt;
 conc(ss)  the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the &amp;lt;tt&amp;gt;STRING_AS_SEQUENCE&amp;lt;/tt&amp;gt; preference.&lt;br /&gt;
The [[External_Functions|library]] LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &amp;lt;tt&amp;gt;TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;FORMAT_TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;INT_TO_HEX_STRING&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
&lt;br /&gt;
ProB also allows multi-line strings.&lt;br /&gt;
&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 \n  newline (ASCII character 13)&lt;br /&gt;
 \r  carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;  the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;  the single quote symbol &#039;&lt;br /&gt;
 \\  the backslash symbol&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Within single-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r into an integer&lt;br /&gt;
 ceiling(r)  convert a real r into an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One can also use a lowercase &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; for literals in scientific notation (e.g. &amp;lt;tt&amp;gt;1.0e-10&amp;lt;/tt&amp;gt;).&lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus do not hold.&lt;br /&gt;
The  [[External_Functions|library]] LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &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;RLOG&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RSQRT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RPOW&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
You can turn off support for REALS using the preference &amp;lt;tt&amp;gt;ALLOW_REALS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5801</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5801"/>
		<updated>2024-06-13T12:16:15Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Reals */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
In ProB, however, some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 size(s)   the length of a string s&lt;br /&gt;
 rev(s)    the reverse of a string s&lt;br /&gt;
 s ^ t     the concatenation of two strings&lt;br /&gt;
 conc(ss)  the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the &amp;lt;tt&amp;gt;STRING_AS_SEQUENCE&amp;lt;/tt&amp;gt; preference.&lt;br /&gt;
The [[External_Functions|library]] LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &amp;lt;tt&amp;gt;TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;FORMAT_TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;INT_TO_HEX_STRING&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
&lt;br /&gt;
ProB also allows multi-line strings.&lt;br /&gt;
&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 \n  newline (ASCII character 13)&lt;br /&gt;
 \r  carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;  the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;  the single quote symbol &#039;&lt;br /&gt;
 \\  the backslash symbol&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Within single-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r into an integer&lt;br /&gt;
 ceiling(r)  convert a real r into an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One can also use a lowercase e for literals in scientific notation (e.g. 1.0e-10).&lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus do not hold.&lt;br /&gt;
The  [[External_Functions|library]] LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &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;RLOG&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RSQRT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;RPOW&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
You can turn off support for REALS using the preference &amp;lt;tt&amp;gt;ALLOW_REALS&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5800</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5800"/>
		<updated>2024-06-13T12:13:57Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Strings */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
In ProB, however, some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 size(s)   the length of a string s&lt;br /&gt;
 rev(s)    the reverse of a string s&lt;br /&gt;
 s ^ t     the concatenation of two strings&lt;br /&gt;
 conc(ss)  the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the &amp;lt;tt&amp;gt;STRING_AS_SEQUENCE&amp;lt;/tt&amp;gt; preference.&lt;br /&gt;
The [[External_Functions|library]] LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &amp;lt;tt&amp;gt;TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;FORMAT_TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;INT_TO_HEX_STRING&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
&lt;br /&gt;
ProB also allows multi-line strings.&lt;br /&gt;
&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 \n  newline (ASCII character 13)&lt;br /&gt;
 \r  carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;  the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;  the single quote symbol &#039;&lt;br /&gt;
 \\  the backslash symbol&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Within single-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r to an integer&lt;br /&gt;
 ceiling(r)  convert a real r to an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus does not hold.&lt;br /&gt;
The library LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like RSIN, RCOS, RLOG, RSQRT, RPOW, ...).&lt;br /&gt;
You can turn off support for REALS using the preference ALLOW_REALS.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5799</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5799"/>
		<updated>2024-06-13T12:13:21Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Strings */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
In ProB, however, some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 size(s)   the length of a string s&lt;br /&gt;
 rev(s)    the reverse of a string s&lt;br /&gt;
 s ^ t     the concatenation of two strings&lt;br /&gt;
 conc(ss)  the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the &amp;lt;tt&amp;gt;STRING_AS_SEQUENCE&amp;lt;/tt&amp;gt; preference.&lt;br /&gt;
The [[External_Functions|library]] LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &amp;lt;tt&amp;gt;TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;FORMAT_TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;INT_TO_HEX_STRING&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
ProB also allows multi-line strings.&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 \n  newline (ASCII character 13)&lt;br /&gt;
 \r  carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;  the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;  the single quote symbol &#039;&lt;br /&gt;
 \\  the backslash symbol&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Within single-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r to an integer&lt;br /&gt;
 ceiling(r)  convert a real r to an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus does not hold.&lt;br /&gt;
The library LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like RSIN, RCOS, RLOG, RSQRT, RPOW, ...).&lt;br /&gt;
You can turn off support for REALS using the preference ALLOW_REALS.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5798</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5798"/>
		<updated>2024-06-13T12:13:00Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Strings */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
In ProB, however, some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 size(s)   the length of a string s&lt;br /&gt;
 rev(s)    the reverse of a string s&lt;br /&gt;
 s ^ t     the concatenation of two strings&lt;br /&gt;
 conc(ss)  the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the STRING_AS_SEQUENCE preference.&lt;br /&gt;
The [[External_Functions|library]] LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like &amp;lt;tt&amp;gt;TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;STRING_SPLIT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;FORMAT_TO_STRING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;INT_TO_HEX_STRING&amp;lt;/tt&amp;gt;, ...).&lt;br /&gt;
ProB also allows multi-line strings.&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 \n  newline (ASCII character 13)&lt;br /&gt;
 \r  carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;  the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;  the single quote symbol &#039;&lt;br /&gt;
 \\  the backslash symbol&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Within single-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r to an integer&lt;br /&gt;
 ceiling(r)  convert a real r to an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus does not hold.&lt;br /&gt;
The library LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like RSIN, RCOS, RLOG, RSQRT, RPOW, ...).&lt;br /&gt;
You can turn off support for REALS using the preference ALLOW_REALS.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5797</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5797"/>
		<updated>2024-06-13T12:08:21Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Strings */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;quot;astring&amp;quot;      a specific (single-line) string value&lt;br /&gt;
 &#039;&#039;&#039;astring&#039;&#039;&#039;  an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
 ```tstring```  template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding),&lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
 STRING         the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
However, the ProB [[External_Functions|external function library]] contains several operators on strings. ProB also allows multi-line strings.&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
 \n   newline (ASCII character 13)&lt;br /&gt;
 \r   carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;   the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;   the single quote symbol &#039;&lt;br /&gt;
 \\   the backslash symbol&lt;br /&gt;
&lt;br /&gt;
Within single-line string literals, you do not need to escape &#039;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;quot; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
The library LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like TO_STRING, STRING_SPLIT, FORMAT_TO_STRING, INT_TO_HEX_STRING, ...).&lt;br /&gt;
Some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  size(s)     the length of a string s&lt;br /&gt;
  rev(s)      the reverse a string s&lt;br /&gt;
  s ^ t       the concatenation of two strings&lt;br /&gt;
  conc(ss)    the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the STRING_AS_SEQUENCE preference.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r to an integer&lt;br /&gt;
 ceiling(r)  convert a real r to an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus does not hold.&lt;br /&gt;
The library LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like RSIN, RCOS, RLOG, RSQRT, RPOW, ...).&lt;br /&gt;
You can turn off support for REALS using the preference ALLOW_REALS.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5796</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5796"/>
		<updated>2024-06-13T12:06:54Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Summary of B Syntax */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;astring&amp;quot;     a specific (single-line) string value&lt;br /&gt;
  &#039;&#039;&#039;astring&#039;&#039;&#039; an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
  ```tstring``` template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding), &lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
  STRING        the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
However, the ProB [[External_Functions|external function library]] contains several operators on strings. ProB also allows multi-line strings.&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
 \n   newline (ASCII character 13)&lt;br /&gt;
 \r   carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;   the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;   the single quote symbol &#039;&lt;br /&gt;
 \\   the backslash symbol&lt;br /&gt;
&lt;br /&gt;
Within single-line string literals, you do not need to escape &#039;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;quot; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
The library LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like TO_STRING, STRING_SPLIT, FORMAT_TO_STRING, INT_TO_HEX_STRING, ...).&lt;br /&gt;
Some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  size(s)     the length of a string s&lt;br /&gt;
  rev(s)      the reverse a string s&lt;br /&gt;
  s ^ t       the concatenation of two strings&lt;br /&gt;
  conc(ss)    the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the STRING_AS_SEQUENCE preference.&lt;br /&gt;
&lt;br /&gt;
=== Reals === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r to an integer&lt;br /&gt;
 ceiling(r)  convert a real r to an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus does not hold.&lt;br /&gt;
The library LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like RSIN, RCOS, RLOG, RSQRT, RPOW, ...).&lt;br /&gt;
You can turn off support for REALS using the preference ALLOW_REALS.&lt;br /&gt;
&lt;br /&gt;
=== Trees ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5795</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5795"/>
		<updated>2024-06-13T12:05:04Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Summary of B Syntax */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;astring&amp;quot;     a specific (single-line) string value&lt;br /&gt;
  &#039;&#039;&#039;astring&#039;&#039;&#039; an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
  ```tstring``` template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding), &lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
  STRING        the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
However, the ProB [[External_Functions|external function library]] contains several operators on strings. ProB also allows multi-line strings.&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
 \n   newline (ASCII character 13)&lt;br /&gt;
 \r   carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;   the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;   the single quote symbol &#039;&lt;br /&gt;
 \\   the backslash symbol&lt;br /&gt;
&lt;br /&gt;
Within single-line string literals, you do not need to escape &#039;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;quot; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
The library LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like TO_STRING, STRING_SPLIT, FORMAT_TO_STRING, INT_TO_HEX_STRING, ...).&lt;br /&gt;
Some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  size(s)     the length of a string s&lt;br /&gt;
  rev(s)      the reverse a string s&lt;br /&gt;
  s ^ t       the concatenation of two strings&lt;br /&gt;
  conc(ss)    the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the STRING_AS_SEQUENCE preference.&lt;br /&gt;
&lt;br /&gt;
=== Reals: === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r to an integer&lt;br /&gt;
 ceiling(r)  convert a real r to an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus does not hold.&lt;br /&gt;
The library LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like RSIN, RCOS, RLOG, RSQRT, RPOW, ...).&lt;br /&gt;
You can turn off support for REALS using the preference ALLOW_REALS.&lt;br /&gt;
&lt;br /&gt;
=== Trees: ===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE: === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions): ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types: === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free: ===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax: ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5794</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5794"/>
		<updated>2024-06-13T12:03:29Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Summary of B Syntax */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identifiers:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ID    must start with letter (ASCII or Unicode), can then contain&lt;br /&gt;
       letters (ASCII or Unicode), digits and underscore (_) and&lt;br /&gt;
       can end with Unicode subscripts followed by Unicode primes&lt;br /&gt;
 M.ID  composed identifier for identifier coming from included machine M&lt;br /&gt;
 `ID`  an identifier in backquotes can contain almost any character (except newline)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;astring&amp;quot;     a specific (single-line) string value&lt;br /&gt;
  &#039;&#039;&#039;astring&#039;&#039;&#039; an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
  ```tstring``` template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding), &lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
  STRING        the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
However, the ProB [[External_Functions|external function library]] contains several operators on strings. ProB also allows multi-line strings.&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
 \n   newline (ASCII character 13)&lt;br /&gt;
 \r   carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;   the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;   the single quote symbol &#039;&lt;br /&gt;
 \\   the backslash symbol&lt;br /&gt;
&lt;br /&gt;
Within single-line string literals, you do not need to escape &#039;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;quot; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
The library LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like TO_STRING, STRING_SPLIT, FORMAT_TO_STRING, INT_TO_HEX_STRING, ...).&lt;br /&gt;
Some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  size(s)     the length of a string s&lt;br /&gt;
  rev(s)      the reverse a string s&lt;br /&gt;
  s ^ t       the concatenation of two strings&lt;br /&gt;
  conc(ss)    the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the STRING_AS_SEQUENCE preference.&lt;br /&gt;
&lt;br /&gt;
=== Reals: === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r to an integer&lt;br /&gt;
 ceiling(r)  convert a real r to an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus does not hold.&lt;br /&gt;
The library LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like RSIN, RCOS, RLOG, RSQRT, RPOW, ...).&lt;br /&gt;
You can turn off support for REALS using the preference ALLOW_REALS.&lt;br /&gt;
&lt;br /&gt;
=== Trees:===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions):===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5793</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5793"/>
		<updated>2024-06-13T12:01:50Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Records: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 struct(ID:S,...,ID:S)  set of records with given fields and field types&lt;br /&gt;
 rec(ID:E,...,ID:E)     construct a record with given field names and values&lt;br /&gt;
 E&#039;ID                   get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;astring&amp;quot;     a specific (single-line) string value&lt;br /&gt;
  &#039;&#039;&#039;astring&#039;&#039;&#039; an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
  ```tstring``` template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding), &lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
  STRING        the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
However, the ProB [[External_Functions|external function library]] contains several operators on strings. ProB also allows multi-line strings.&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
 \n   newline (ASCII character 13)&lt;br /&gt;
 \r   carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;   the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;   the single quote symbol &#039;&lt;br /&gt;
 \\   the backslash symbol&lt;br /&gt;
&lt;br /&gt;
Within single-line string literals, you do not need to escape &#039;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;quot; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
The library LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like TO_STRING, STRING_SPLIT, FORMAT_TO_STRING, INT_TO_HEX_STRING, ...).&lt;br /&gt;
Some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  size(s)     the length of a string s&lt;br /&gt;
  rev(s)      the reverse a string s&lt;br /&gt;
  s ^ t       the concatenation of two strings&lt;br /&gt;
  conc(ss)    the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the STRING_AS_SEQUENCE preference.&lt;br /&gt;
&lt;br /&gt;
=== Reals: === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r to an integer&lt;br /&gt;
 ceiling(r)  convert a real r to an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus does not hold.&lt;br /&gt;
The library LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like RSIN, RCOS, RLOG, RSQRT, RPOW, ...).&lt;br /&gt;
You can turn off support for REALS using the preference ALLOW_REALS.&lt;br /&gt;
&lt;br /&gt;
=== Trees:===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions):===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5792</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5792"/>
		<updated>2024-06-13T12:01:34Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Sequences: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [] or &amp;lt;&amp;gt;  empty sequence&lt;br /&gt;
 [E]       singleton sequence&lt;br /&gt;
 [E,F]     constructed sequence&lt;br /&gt;
 seq(S)    set of sequences over S&lt;br /&gt;
 seq1(S)   set of non-empty sequences over S&lt;br /&gt;
 iseq(S)   set of injective sequences over S&lt;br /&gt;
 iseq1(S)  set of non-empty injective sequences over S&lt;br /&gt;
 perm(S)   set of bijective sequences (permutations) over S&lt;br /&gt;
 size(s)   size of sequence&lt;br /&gt;
 s^t       concatenation&lt;br /&gt;
 E-&amp;gt;s      prepend element&lt;br /&gt;
 s&amp;lt;-E      append element&lt;br /&gt;
 rev(s)    reverse of sequence&lt;br /&gt;
 first(s)  first element&lt;br /&gt;
 last(s)   last element&lt;br /&gt;
 front(s)  front of sequence (all but last element)&lt;br /&gt;
 tail(s)   tail of sequence (all but first element)&lt;br /&gt;
 conc(S)   concatenation of sequence of sequences&lt;br /&gt;
 s/|\n     take first n elements of sequence&lt;br /&gt;
 s\|/n     drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  struct(ID:S,...,ID:S)   set of records with given fields and field types&lt;br /&gt;
  rec(ID:E,...,ID:E)      construct a record with given field names and values&lt;br /&gt;
  E&#039;ID                    get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;astring&amp;quot;     a specific (single-line) string value&lt;br /&gt;
  &#039;&#039;&#039;astring&#039;&#039;&#039; an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
  ```tstring``` template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding), &lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
  STRING        the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
However, the ProB [[External_Functions|external function library]] contains several operators on strings. ProB also allows multi-line strings.&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
 \n   newline (ASCII character 13)&lt;br /&gt;
 \r   carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;   the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;   the single quote symbol &#039;&lt;br /&gt;
 \\   the backslash symbol&lt;br /&gt;
&lt;br /&gt;
Within single-line string literals, you do not need to escape &#039;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;quot; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
The library LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like TO_STRING, STRING_SPLIT, FORMAT_TO_STRING, INT_TO_HEX_STRING, ...).&lt;br /&gt;
Some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  size(s)     the length of a string s&lt;br /&gt;
  rev(s)      the reverse a string s&lt;br /&gt;
  s ^ t       the concatenation of two strings&lt;br /&gt;
  conc(ss)    the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the STRING_AS_SEQUENCE preference.&lt;br /&gt;
&lt;br /&gt;
=== Reals: === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r to an integer&lt;br /&gt;
 ceiling(r)  convert a real r to an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus does not hold.&lt;br /&gt;
The library LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like RSIN, RCOS, RLOG, RSQRT, RPOW, ...).&lt;br /&gt;
You can turn off support for REALS using the preference ALLOW_REALS.&lt;br /&gt;
&lt;br /&gt;
=== Trees:===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions):===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5791</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5791"/>
		<updated>2024-06-13T12:00:54Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Functions: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S+-&amp;gt;T         partial function&lt;br /&gt;
 S--&amp;gt;T         total function&lt;br /&gt;
 S+-&amp;gt;&amp;gt;T        partial surjection&lt;br /&gt;
 S--&amp;gt;&amp;gt;T        total surjection&lt;br /&gt;
 S&amp;gt;+&amp;gt;T         partial injection&lt;br /&gt;
 S&amp;gt;-&amp;gt;T         total injection&lt;br /&gt;
 S&amp;gt;+&amp;gt;&amp;gt;T        partial bijection&lt;br /&gt;
 S&amp;gt;-&amp;gt;&amp;gt;T        total bijection&lt;br /&gt;
 %x.(P|E)      lambda abstraction&lt;br /&gt;
 f(E)          function application&lt;br /&gt;
 f(E1,...,En)  is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;&amp;gt; or []   empty sequence&lt;br /&gt;
  [E]        singleton sequence&lt;br /&gt;
  [E,F]      constructed sequence&lt;br /&gt;
  seq(S)     set of sequences over S&lt;br /&gt;
  seq1(S)    set of non-empty sequences over S&lt;br /&gt;
  iseq(S)    set of injective sequences over S&lt;br /&gt;
  iseq1(S)   set of non-empty injective sequences over S&lt;br /&gt;
  perm(S)    set of bijective sequences (permutations) over S&lt;br /&gt;
  size(s)    size of sequence&lt;br /&gt;
  s^t        concatenation&lt;br /&gt;
  E-&amp;gt;s       prepend element&lt;br /&gt;
  s&amp;lt;-E       append element&lt;br /&gt;
  rev(s)     reverse of sequence&lt;br /&gt;
  first(s)   first element&lt;br /&gt;
  last(s)    last element&lt;br /&gt;
  front(s)   front of sequence (all but last element)&lt;br /&gt;
  tail(s)    tail of sequence (all but first element)&lt;br /&gt;
  conc(S)    concatenation of sequence of sequences&lt;br /&gt;
  s/|\n      take first n elements of sequence&lt;br /&gt;
  s\|/n      drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  struct(ID:S,...,ID:S)   set of records with given fields and field types&lt;br /&gt;
  rec(ID:E,...,ID:E)      construct a record with given field names and values&lt;br /&gt;
  E&#039;ID                    get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;astring&amp;quot;     a specific (single-line) string value&lt;br /&gt;
  &#039;&#039;&#039;astring&#039;&#039;&#039; an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
  ```tstring``` template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding), &lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
  STRING        the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
However, the ProB [[External_Functions|external function library]] contains several operators on strings. ProB also allows multi-line strings.&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
 \n   newline (ASCII character 13)&lt;br /&gt;
 \r   carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;   the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;   the single quote symbol &#039;&lt;br /&gt;
 \\   the backslash symbol&lt;br /&gt;
&lt;br /&gt;
Within single-line string literals, you do not need to escape &#039;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;quot; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
The library LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like TO_STRING, STRING_SPLIT, FORMAT_TO_STRING, INT_TO_HEX_STRING, ...).&lt;br /&gt;
Some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  size(s)     the length of a string s&lt;br /&gt;
  rev(s)      the reverse a string s&lt;br /&gt;
  s ^ t       the concatenation of two strings&lt;br /&gt;
  conc(ss)    the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the STRING_AS_SEQUENCE preference.&lt;br /&gt;
&lt;br /&gt;
=== Reals: === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r to an integer&lt;br /&gt;
 ceiling(r)  convert a real r to an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus does not hold.&lt;br /&gt;
The library LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like RSIN, RCOS, RLOG, RSQRT, RPOW, ...).&lt;br /&gt;
You can turn off support for REALS using the preference ALLOW_REALS.&lt;br /&gt;
&lt;br /&gt;
=== Trees:===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions):===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5790</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5790"/>
		<updated>2024-06-13T11:59:53Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Relations: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T         relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T        total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T        surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T       total surjective relation&lt;br /&gt;
 E|-&amp;gt;F         maplet&lt;br /&gt;
 dom(r)        domain of relation&lt;br /&gt;
 ran(r)        range of relation&lt;br /&gt;
 id(S)         identity relation&lt;br /&gt;
 S&amp;lt;|r          domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r         domain subtraction&lt;br /&gt;
 r|&amp;gt;S          range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S         range subtraction&lt;br /&gt;
 r~            inverse of relation&lt;br /&gt;
 r[S]          relational image&lt;br /&gt;
 r1&amp;lt;+r2        relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2        direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)       relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)      parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T)     projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T)     projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
               prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)        translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)        translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0&lt;br /&gt;
               (Note: iterate(r,0)=id(s) where s=TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  S+-&amp;gt;T        partial function&lt;br /&gt;
  S--&amp;gt;T        total function&lt;br /&gt;
  S+-&amp;gt;&amp;gt;T       partial surjection&lt;br /&gt;
  S--&amp;gt;&amp;gt;T       total surjection&lt;br /&gt;
  S&amp;gt;+&amp;gt;T        partial injection&lt;br /&gt;
  S&amp;gt;-&amp;gt;T        total injection&lt;br /&gt;
  S&amp;gt;+&amp;gt;&amp;gt;T       partial bijection&lt;br /&gt;
  S&amp;gt;-&amp;gt;&amp;gt;T       total bijection&lt;br /&gt;
  %x.(P|E)     lambda abstraction&lt;br /&gt;
  f(E)         function application&lt;br /&gt;
  f(E1,...,En) is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;&amp;gt; or []   empty sequence&lt;br /&gt;
  [E]        singleton sequence&lt;br /&gt;
  [E,F]      constructed sequence&lt;br /&gt;
  seq(S)     set of sequences over S&lt;br /&gt;
  seq1(S)    set of non-empty sequences over S&lt;br /&gt;
  iseq(S)    set of injective sequences over S&lt;br /&gt;
  iseq1(S)   set of non-empty injective sequences over S&lt;br /&gt;
  perm(S)    set of bijective sequences (permutations) over S&lt;br /&gt;
  size(s)    size of sequence&lt;br /&gt;
  s^t        concatenation&lt;br /&gt;
  E-&amp;gt;s       prepend element&lt;br /&gt;
  s&amp;lt;-E       append element&lt;br /&gt;
  rev(s)     reverse of sequence&lt;br /&gt;
  first(s)   first element&lt;br /&gt;
  last(s)    last element&lt;br /&gt;
  front(s)   front of sequence (all but last element)&lt;br /&gt;
  tail(s)    tail of sequence (all but first element)&lt;br /&gt;
  conc(S)    concatenation of sequence of sequences&lt;br /&gt;
  s/|\n      take first n elements of sequence&lt;br /&gt;
  s\|/n      drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  struct(ID:S,...,ID:S)   set of records with given fields and field types&lt;br /&gt;
  rec(ID:E,...,ID:E)      construct a record with given field names and values&lt;br /&gt;
  E&#039;ID                    get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;astring&amp;quot;     a specific (single-line) string value&lt;br /&gt;
  &#039;&#039;&#039;astring&#039;&#039;&#039; an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
  ```tstring``` template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding), &lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
  STRING        the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
However, the ProB [[External_Functions|external function library]] contains several operators on strings. ProB also allows multi-line strings.&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
 \n   newline (ASCII character 13)&lt;br /&gt;
 \r   carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;   the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;   the single quote symbol &#039;&lt;br /&gt;
 \\   the backslash symbol&lt;br /&gt;
&lt;br /&gt;
Within single-line string literals, you do not need to escape &#039;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;quot; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
The library LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like TO_STRING, STRING_SPLIT, FORMAT_TO_STRING, INT_TO_HEX_STRING, ...).&lt;br /&gt;
Some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  size(s)     the length of a string s&lt;br /&gt;
  rev(s)      the reverse a string s&lt;br /&gt;
  s ^ t       the concatenation of two strings&lt;br /&gt;
  conc(ss)    the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the STRING_AS_SEQUENCE preference.&lt;br /&gt;
&lt;br /&gt;
=== Reals: === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r to an integer&lt;br /&gt;
 ceiling(r)  convert a real r to an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus does not hold.&lt;br /&gt;
The library LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like RSIN, RCOS, RLOG, RSQRT, RPOW, ...).&lt;br /&gt;
You can turn off support for REALS using the preference ALLOW_REALS.&lt;br /&gt;
&lt;br /&gt;
=== Trees:===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions):===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5789</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5789"/>
		<updated>2024-06-13T11:59:21Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Sets: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T or S \ T    set difference&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T     relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T    total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T    surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T   total surjective relation&lt;br /&gt;
 E|-&amp;gt;F     maplet&lt;br /&gt;
 dom(r)    domain of relation&lt;br /&gt;
 ran(r)    range of relation&lt;br /&gt;
 id(S)     identity relation&lt;br /&gt;
 S&amp;lt;|r      domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r     domain subtraction&lt;br /&gt;
 r|&amp;gt;S      range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S     range subtraction&lt;br /&gt;
 r~        inverse of relation&lt;br /&gt;
 r[S]      relational image&lt;br /&gt;
 r1&amp;lt;+r2    relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2    direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)   relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)  parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T) projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T) projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
           prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)    translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)    translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0 &lt;br /&gt;
               (Note: iterate(r,0) = id(s) where s =TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  S+-&amp;gt;T        partial function&lt;br /&gt;
  S--&amp;gt;T        total function&lt;br /&gt;
  S+-&amp;gt;&amp;gt;T       partial surjection&lt;br /&gt;
  S--&amp;gt;&amp;gt;T       total surjection&lt;br /&gt;
  S&amp;gt;+&amp;gt;T        partial injection&lt;br /&gt;
  S&amp;gt;-&amp;gt;T        total injection&lt;br /&gt;
  S&amp;gt;+&amp;gt;&amp;gt;T       partial bijection&lt;br /&gt;
  S&amp;gt;-&amp;gt;&amp;gt;T       total bijection&lt;br /&gt;
  %x.(P|E)     lambda abstraction&lt;br /&gt;
  f(E)         function application&lt;br /&gt;
  f(E1,...,En) is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;&amp;gt; or []   empty sequence&lt;br /&gt;
  [E]        singleton sequence&lt;br /&gt;
  [E,F]      constructed sequence&lt;br /&gt;
  seq(S)     set of sequences over S&lt;br /&gt;
  seq1(S)    set of non-empty sequences over S&lt;br /&gt;
  iseq(S)    set of injective sequences over S&lt;br /&gt;
  iseq1(S)   set of non-empty injective sequences over S&lt;br /&gt;
  perm(S)    set of bijective sequences (permutations) over S&lt;br /&gt;
  size(s)    size of sequence&lt;br /&gt;
  s^t        concatenation&lt;br /&gt;
  E-&amp;gt;s       prepend element&lt;br /&gt;
  s&amp;lt;-E       append element&lt;br /&gt;
  rev(s)     reverse of sequence&lt;br /&gt;
  first(s)   first element&lt;br /&gt;
  last(s)    last element&lt;br /&gt;
  front(s)   front of sequence (all but last element)&lt;br /&gt;
  tail(s)    tail of sequence (all but first element)&lt;br /&gt;
  conc(S)    concatenation of sequence of sequences&lt;br /&gt;
  s/|\n      take first n elements of sequence&lt;br /&gt;
  s\|/n      drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  struct(ID:S,...,ID:S)   set of records with given fields and field types&lt;br /&gt;
  rec(ID:E,...,ID:E)      construct a record with given field names and values&lt;br /&gt;
  E&#039;ID                    get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;astring&amp;quot;     a specific (single-line) string value&lt;br /&gt;
  &#039;&#039;&#039;astring&#039;&#039;&#039; an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
  ```tstring``` template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding), &lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
  STRING        the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
However, the ProB [[External_Functions|external function library]] contains several operators on strings. ProB also allows multi-line strings.&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
 \n   newline (ASCII character 13)&lt;br /&gt;
 \r   carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;   the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;   the single quote symbol &#039;&lt;br /&gt;
 \\   the backslash symbol&lt;br /&gt;
&lt;br /&gt;
Within single-line string literals, you do not need to escape &#039;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;quot; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
The library LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like TO_STRING, STRING_SPLIT, FORMAT_TO_STRING, INT_TO_HEX_STRING, ...).&lt;br /&gt;
Some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  size(s)     the length of a string s&lt;br /&gt;
  rev(s)      the reverse a string s&lt;br /&gt;
  s ^ t       the concatenation of two strings&lt;br /&gt;
  conc(ss)    the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the STRING_AS_SEQUENCE preference.&lt;br /&gt;
&lt;br /&gt;
=== Reals: === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r to an integer&lt;br /&gt;
 ceiling(r)  convert a real r to an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus does not hold.&lt;br /&gt;
The library LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like RSIN, RCOS, RLOG, RSQRT, RPOW, ...).&lt;br /&gt;
You can turn off support for REALS using the preference ALLOW_REALS.&lt;br /&gt;
&lt;br /&gt;
=== Trees:===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions):===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5788</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5788"/>
		<updated>2024-06-13T11:58:52Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Sets: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}              empty set&lt;br /&gt;
 {E}             singleton set&lt;br /&gt;
 {E,F}           set enumeration&lt;br /&gt;
 {x|P}           comprehension set&lt;br /&gt;
 {(x).P|E}       Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)          power set&lt;br /&gt;
 POW1(S)         set of non-empty subsets&lt;br /&gt;
 FIN(S)          set of all finite subsets&lt;br /&gt;
 FIN1(S)         set of all non-empty finite subsets&lt;br /&gt;
 card(S)         cardinality&lt;br /&gt;
 S*T             cartesian product&lt;br /&gt;
 S\/T            set union&lt;br /&gt;
 S/\T            set intersection&lt;br /&gt;
 S-T             set difference (S \ T is also allowed)&lt;br /&gt;
 E:S             element of&lt;br /&gt;
 E/:S            not element of&lt;br /&gt;
 S&amp;lt;:T            subset of&lt;br /&gt;
 S/&amp;lt;:T           not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T           strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T          not strict subset of&lt;br /&gt;
 union(S)        generalised union over sets of sets&lt;br /&gt;
 inter(S)        generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T     relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T    total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T    surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T   total surjective relation&lt;br /&gt;
 E|-&amp;gt;F     maplet&lt;br /&gt;
 dom(r)    domain of relation&lt;br /&gt;
 ran(r)    range of relation&lt;br /&gt;
 id(S)     identity relation&lt;br /&gt;
 S&amp;lt;|r      domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r     domain subtraction&lt;br /&gt;
 r|&amp;gt;S      range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S     range subtraction&lt;br /&gt;
 r~        inverse of relation&lt;br /&gt;
 r[S]      relational image&lt;br /&gt;
 r1&amp;lt;+r2    relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2    direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)   relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)  parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T) projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T) projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
           prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)    translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)    translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0 &lt;br /&gt;
               (Note: iterate(r,0) = id(s) where s =TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  S+-&amp;gt;T        partial function&lt;br /&gt;
  S--&amp;gt;T        total function&lt;br /&gt;
  S+-&amp;gt;&amp;gt;T       partial surjection&lt;br /&gt;
  S--&amp;gt;&amp;gt;T       total surjection&lt;br /&gt;
  S&amp;gt;+&amp;gt;T        partial injection&lt;br /&gt;
  S&amp;gt;-&amp;gt;T        total injection&lt;br /&gt;
  S&amp;gt;+&amp;gt;&amp;gt;T       partial bijection&lt;br /&gt;
  S&amp;gt;-&amp;gt;&amp;gt;T       total bijection&lt;br /&gt;
  %x.(P|E)     lambda abstraction&lt;br /&gt;
  f(E)         function application&lt;br /&gt;
  f(E1,...,En) is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;&amp;gt; or []   empty sequence&lt;br /&gt;
  [E]        singleton sequence&lt;br /&gt;
  [E,F]      constructed sequence&lt;br /&gt;
  seq(S)     set of sequences over S&lt;br /&gt;
  seq1(S)    set of non-empty sequences over S&lt;br /&gt;
  iseq(S)    set of injective sequences over S&lt;br /&gt;
  iseq1(S)   set of non-empty injective sequences over S&lt;br /&gt;
  perm(S)    set of bijective sequences (permutations) over S&lt;br /&gt;
  size(s)    size of sequence&lt;br /&gt;
  s^t        concatenation&lt;br /&gt;
  E-&amp;gt;s       prepend element&lt;br /&gt;
  s&amp;lt;-E       append element&lt;br /&gt;
  rev(s)     reverse of sequence&lt;br /&gt;
  first(s)   first element&lt;br /&gt;
  last(s)    last element&lt;br /&gt;
  front(s)   front of sequence (all but last element)&lt;br /&gt;
  tail(s)    tail of sequence (all but first element)&lt;br /&gt;
  conc(S)    concatenation of sequence of sequences&lt;br /&gt;
  s/|\n      take first n elements of sequence&lt;br /&gt;
  s\|/n      drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  struct(ID:S,...,ID:S)   set of records with given fields and field types&lt;br /&gt;
  rec(ID:E,...,ID:E)      construct a record with given field names and values&lt;br /&gt;
  E&#039;ID                    get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;astring&amp;quot;     a specific (single-line) string value&lt;br /&gt;
  &#039;&#039;&#039;astring&#039;&#039;&#039; an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
  ```tstring``` template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding), &lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
  STRING        the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
However, the ProB [[External_Functions|external function library]] contains several operators on strings. ProB also allows multi-line strings.&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
 \n   newline (ASCII character 13)&lt;br /&gt;
 \r   carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;   the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;   the single quote symbol &#039;&lt;br /&gt;
 \\   the backslash symbol&lt;br /&gt;
&lt;br /&gt;
Within single-line string literals, you do not need to escape &#039;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;quot; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
The library LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like TO_STRING, STRING_SPLIT, FORMAT_TO_STRING, INT_TO_HEX_STRING, ...).&lt;br /&gt;
Some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  size(s)     the length of a string s&lt;br /&gt;
  rev(s)      the reverse a string s&lt;br /&gt;
  s ^ t       the concatenation of two strings&lt;br /&gt;
  conc(ss)    the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the STRING_AS_SEQUENCE preference.&lt;br /&gt;
&lt;br /&gt;
=== Reals: === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r to an integer&lt;br /&gt;
 ceiling(r)  convert a real r to an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus does not hold.&lt;br /&gt;
The library LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like RSIN, RCOS, RLOG, RSQRT, RPOW, ...).&lt;br /&gt;
You can turn off support for REALS using the preference ALLOW_REALS.&lt;br /&gt;
&lt;br /&gt;
=== Trees:===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions):===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5787</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5787"/>
		<updated>2024-06-13T11:58:33Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Integers: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}             empty set&lt;br /&gt;
 {E}            singleton set&lt;br /&gt;
 {E,F}          set enumeration&lt;br /&gt;
 {x|P}          comprehension set&lt;br /&gt;
 {(x).P|E}      Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)         power set&lt;br /&gt;
 POW1(S)        set of non-empty subsets&lt;br /&gt;
 FIN(S)         set of all finite subsets&lt;br /&gt;
 FIN1(S)        set of all non-empty finite subsets&lt;br /&gt;
 card(S)        cardinality&lt;br /&gt;
 S*T            cartesian product&lt;br /&gt;
 S\/T           set union&lt;br /&gt;
 S/\T           set intersection&lt;br /&gt;
 S-T            set difference (S \ T is also allowed)&lt;br /&gt;
 E:S            element of&lt;br /&gt;
 E/:S           not element of&lt;br /&gt;
 S&amp;lt;:T           subset of&lt;br /&gt;
 S/&amp;lt;:T          not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T          strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T         not strict subset of&lt;br /&gt;
 union(S)       generalised union over sets of sets&lt;br /&gt;
 inter(S)       generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E) generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E) generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER         set of integers&lt;br /&gt;
 NATURAL         set of natural numbers&lt;br /&gt;
 NATURAL1        set of non-zero natural numbers&lt;br /&gt;
 INT             set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT             set of implementable natural numbers&lt;br /&gt;
 NAT1            set of non-zero implementable natural numbers&lt;br /&gt;
 n..m            set of numbers from n to m&lt;br /&gt;
 MININT          the minimum implementable integer&lt;br /&gt;
 MAXINT          the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n             greater than&lt;br /&gt;
 m&amp;lt;n             less than&lt;br /&gt;
 m&amp;gt;=n            greater than or equal&lt;br /&gt;
 m&amp;lt;=n            less than or equal&lt;br /&gt;
 max(S)          maximum of a set of numbers&lt;br /&gt;
 min(S)          minimum of a set of numbers&lt;br /&gt;
 m+n             addition&lt;br /&gt;
 m-n             difference&lt;br /&gt;
 m*n             multiplication&lt;br /&gt;
 m/n             division&lt;br /&gt;
 m**n            power&lt;br /&gt;
 m mod n         remainder of division&lt;br /&gt;
 PI(z).(P|E)     set product&lt;br /&gt;
 SIGMA(z).(P|E)  set summation&lt;br /&gt;
 succ(n)         successor (n+1)&lt;br /&gt;
 pred(n)         predecessor (n-1)&lt;br /&gt;
 0xH             hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T     relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T    total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T    surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T   total surjective relation&lt;br /&gt;
 E|-&amp;gt;F     maplet&lt;br /&gt;
 dom(r)    domain of relation&lt;br /&gt;
 ran(r)    range of relation&lt;br /&gt;
 id(S)     identity relation&lt;br /&gt;
 S&amp;lt;|r      domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r     domain subtraction&lt;br /&gt;
 r|&amp;gt;S      range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S     range subtraction&lt;br /&gt;
 r~        inverse of relation&lt;br /&gt;
 r[S]      relational image&lt;br /&gt;
 r1&amp;lt;+r2    relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2    direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)   relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)  parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T) projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T) projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
           prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)    translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)    translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0 &lt;br /&gt;
               (Note: iterate(r,0) = id(s) where s =TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  S+-&amp;gt;T        partial function&lt;br /&gt;
  S--&amp;gt;T        total function&lt;br /&gt;
  S+-&amp;gt;&amp;gt;T       partial surjection&lt;br /&gt;
  S--&amp;gt;&amp;gt;T       total surjection&lt;br /&gt;
  S&amp;gt;+&amp;gt;T        partial injection&lt;br /&gt;
  S&amp;gt;-&amp;gt;T        total injection&lt;br /&gt;
  S&amp;gt;+&amp;gt;&amp;gt;T       partial bijection&lt;br /&gt;
  S&amp;gt;-&amp;gt;&amp;gt;T       total bijection&lt;br /&gt;
  %x.(P|E)     lambda abstraction&lt;br /&gt;
  f(E)         function application&lt;br /&gt;
  f(E1,...,En) is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;&amp;gt; or []   empty sequence&lt;br /&gt;
  [E]        singleton sequence&lt;br /&gt;
  [E,F]      constructed sequence&lt;br /&gt;
  seq(S)     set of sequences over S&lt;br /&gt;
  seq1(S)    set of non-empty sequences over S&lt;br /&gt;
  iseq(S)    set of injective sequences over S&lt;br /&gt;
  iseq1(S)   set of non-empty injective sequences over S&lt;br /&gt;
  perm(S)    set of bijective sequences (permutations) over S&lt;br /&gt;
  size(s)    size of sequence&lt;br /&gt;
  s^t        concatenation&lt;br /&gt;
  E-&amp;gt;s       prepend element&lt;br /&gt;
  s&amp;lt;-E       append element&lt;br /&gt;
  rev(s)     reverse of sequence&lt;br /&gt;
  first(s)   first element&lt;br /&gt;
  last(s)    last element&lt;br /&gt;
  front(s)   front of sequence (all but last element)&lt;br /&gt;
  tail(s)    tail of sequence (all but first element)&lt;br /&gt;
  conc(S)    concatenation of sequence of sequences&lt;br /&gt;
  s/|\n      take first n elements of sequence&lt;br /&gt;
  s\|/n      drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  struct(ID:S,...,ID:S)   set of records with given fields and field types&lt;br /&gt;
  rec(ID:E,...,ID:E)      construct a record with given field names and values&lt;br /&gt;
  E&#039;ID                    get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;astring&amp;quot;     a specific (single-line) string value&lt;br /&gt;
  &#039;&#039;&#039;astring&#039;&#039;&#039; an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
  ```tstring``` template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding), &lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
  STRING        the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
However, the ProB [[External_Functions|external function library]] contains several operators on strings. ProB also allows multi-line strings.&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
 \n   newline (ASCII character 13)&lt;br /&gt;
 \r   carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;   the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;   the single quote symbol &#039;&lt;br /&gt;
 \\   the backslash symbol&lt;br /&gt;
&lt;br /&gt;
Within single-line string literals, you do not need to escape &#039;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;quot; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
The library LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like TO_STRING, STRING_SPLIT, FORMAT_TO_STRING, INT_TO_HEX_STRING, ...).&lt;br /&gt;
Some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  size(s)     the length of a string s&lt;br /&gt;
  rev(s)      the reverse a string s&lt;br /&gt;
  s ^ t       the concatenation of two strings&lt;br /&gt;
  conc(ss)    the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the STRING_AS_SEQUENCE preference.&lt;br /&gt;
&lt;br /&gt;
=== Reals: === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r to an integer&lt;br /&gt;
 ceiling(r)  convert a real r to an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus does not hold.&lt;br /&gt;
The library LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like RSIN, RCOS, RLOG, RSQRT, RPOW, ...).&lt;br /&gt;
You can turn off support for REALS using the preference ALLOW_REALS.&lt;br /&gt;
&lt;br /&gt;
=== Trees:===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions):===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5786</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5786"/>
		<updated>2024-06-13T11:57:14Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Booleans: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are expression values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}             empty set&lt;br /&gt;
 {E}            singleton set&lt;br /&gt;
 {E,F}          set enumeration&lt;br /&gt;
 {x|P}          comprehension set&lt;br /&gt;
 {(x).P|E}      Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)         power set&lt;br /&gt;
 POW1(S)        set of non-empty subsets&lt;br /&gt;
 FIN(S)         set of all finite subsets&lt;br /&gt;
 FIN1(S)        set of all non-empty finite subsets&lt;br /&gt;
 card(S)        cardinality&lt;br /&gt;
 S*T            cartesian product&lt;br /&gt;
 S\/T           set union&lt;br /&gt;
 S/\T           set intersection&lt;br /&gt;
 S-T            set difference (S \ T is also allowed)&lt;br /&gt;
 E:S            element of&lt;br /&gt;
 E/:S           not element of&lt;br /&gt;
 S&amp;lt;:T           subset of&lt;br /&gt;
 S/&amp;lt;:T          not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T          strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T         not strict subset of&lt;br /&gt;
 union(S)       generalised union over sets of sets&lt;br /&gt;
 inter(S)       generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E) generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E) generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER     set of integers&lt;br /&gt;
 NATURAL     set of natural numbers&lt;br /&gt;
 NATURAL1    set of non-zero natural numbers&lt;br /&gt;
 INT         set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT         set of implementable natural numbers&lt;br /&gt;
 NAT1        set of non-zero implementable natural numbers&lt;br /&gt;
 n..m        set of numbers from n to m&lt;br /&gt;
 MININT      the minimum implementable integer&lt;br /&gt;
 MAXINT      the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n         greater than&lt;br /&gt;
 m&amp;lt;n         less than&lt;br /&gt;
 m&amp;gt;=n        greater than or equal&lt;br /&gt;
 m&amp;lt;=n        less than or equal&lt;br /&gt;
 max(S)      maximum of a set of numbers&lt;br /&gt;
 min(S)      minimum of a set of numbers&lt;br /&gt;
 m+n         addition&lt;br /&gt;
 m-n         difference&lt;br /&gt;
 m*n         multiplication&lt;br /&gt;
 m/n         division&lt;br /&gt;
 m**n        power&lt;br /&gt;
 m mod n     remainder of division&lt;br /&gt;
 PI(z).(P|E)    Set product&lt;br /&gt;
 SIGMA(z).(P|E) Set summation&lt;br /&gt;
 succ(n)     successor (n+1)&lt;br /&gt;
 pred(n)     predecessor (n-1)&lt;br /&gt;
 0xH         hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T     relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T    total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T    surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T   total surjective relation&lt;br /&gt;
 E|-&amp;gt;F     maplet&lt;br /&gt;
 dom(r)    domain of relation&lt;br /&gt;
 ran(r)    range of relation&lt;br /&gt;
 id(S)     identity relation&lt;br /&gt;
 S&amp;lt;|r      domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r     domain subtraction&lt;br /&gt;
 r|&amp;gt;S      range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S     range subtraction&lt;br /&gt;
 r~        inverse of relation&lt;br /&gt;
 r[S]      relational image&lt;br /&gt;
 r1&amp;lt;+r2    relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2    direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)   relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)  parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T) projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T) projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
           prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)    translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)    translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0 &lt;br /&gt;
               (Note: iterate(r,0) = id(s) where s =TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  S+-&amp;gt;T        partial function&lt;br /&gt;
  S--&amp;gt;T        total function&lt;br /&gt;
  S+-&amp;gt;&amp;gt;T       partial surjection&lt;br /&gt;
  S--&amp;gt;&amp;gt;T       total surjection&lt;br /&gt;
  S&amp;gt;+&amp;gt;T        partial injection&lt;br /&gt;
  S&amp;gt;-&amp;gt;T        total injection&lt;br /&gt;
  S&amp;gt;+&amp;gt;&amp;gt;T       partial bijection&lt;br /&gt;
  S&amp;gt;-&amp;gt;&amp;gt;T       total bijection&lt;br /&gt;
  %x.(P|E)     lambda abstraction&lt;br /&gt;
  f(E)         function application&lt;br /&gt;
  f(E1,...,En) is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;&amp;gt; or []   empty sequence&lt;br /&gt;
  [E]        singleton sequence&lt;br /&gt;
  [E,F]      constructed sequence&lt;br /&gt;
  seq(S)     set of sequences over S&lt;br /&gt;
  seq1(S)    set of non-empty sequences over S&lt;br /&gt;
  iseq(S)    set of injective sequences over S&lt;br /&gt;
  iseq1(S)   set of non-empty injective sequences over S&lt;br /&gt;
  perm(S)    set of bijective sequences (permutations) over S&lt;br /&gt;
  size(s)    size of sequence&lt;br /&gt;
  s^t        concatenation&lt;br /&gt;
  E-&amp;gt;s       prepend element&lt;br /&gt;
  s&amp;lt;-E       append element&lt;br /&gt;
  rev(s)     reverse of sequence&lt;br /&gt;
  first(s)   first element&lt;br /&gt;
  last(s)    last element&lt;br /&gt;
  front(s)   front of sequence (all but last element)&lt;br /&gt;
  tail(s)    tail of sequence (all but first element)&lt;br /&gt;
  conc(S)    concatenation of sequence of sequences&lt;br /&gt;
  s/|\n      take first n elements of sequence&lt;br /&gt;
  s\|/n      drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  struct(ID:S,...,ID:S)   set of records with given fields and field types&lt;br /&gt;
  rec(ID:E,...,ID:E)      construct a record with given field names and values&lt;br /&gt;
  E&#039;ID                    get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;astring&amp;quot;     a specific (single-line) string value&lt;br /&gt;
  &#039;&#039;&#039;astring&#039;&#039;&#039; an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
  ```tstring``` template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding), &lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
  STRING        the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
However, the ProB [[External_Functions|external function library]] contains several operators on strings. ProB also allows multi-line strings.&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
 \n   newline (ASCII character 13)&lt;br /&gt;
 \r   carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;   the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;   the single quote symbol &#039;&lt;br /&gt;
 \\   the backslash symbol&lt;br /&gt;
&lt;br /&gt;
Within single-line string literals, you do not need to escape &#039;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;quot; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
The library LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like TO_STRING, STRING_SPLIT, FORMAT_TO_STRING, INT_TO_HEX_STRING, ...).&lt;br /&gt;
Some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  size(s)     the length of a string s&lt;br /&gt;
  rev(s)      the reverse a string s&lt;br /&gt;
  s ^ t       the concatenation of two strings&lt;br /&gt;
  conc(ss)    the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the STRING_AS_SEQUENCE preference.&lt;br /&gt;
&lt;br /&gt;
=== Reals: === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r to an integer&lt;br /&gt;
 ceiling(r)  convert a real r to an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus does not hold.&lt;br /&gt;
The library LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like RSIN, RCOS, RLOG, RSQRT, RPOW, ...).&lt;br /&gt;
You can turn off support for REALS using the preference ALLOW_REALS.&lt;br /&gt;
&lt;br /&gt;
=== Trees:===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions):===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5785</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5785"/>
		<updated>2024-06-13T11:56:49Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Booleans: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE     truth value (this is an expression)&lt;br /&gt;
 FALSE    falsity value (this is an expression)&lt;br /&gt;
 BOOL     set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)  convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}             empty set&lt;br /&gt;
 {E}            singleton set&lt;br /&gt;
 {E,F}          set enumeration&lt;br /&gt;
 {x|P}          comprehension set&lt;br /&gt;
 {(x).P|E}      Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)         power set&lt;br /&gt;
 POW1(S)        set of non-empty subsets&lt;br /&gt;
 FIN(S)         set of all finite subsets&lt;br /&gt;
 FIN1(S)        set of all non-empty finite subsets&lt;br /&gt;
 card(S)        cardinality&lt;br /&gt;
 S*T            cartesian product&lt;br /&gt;
 S\/T           set union&lt;br /&gt;
 S/\T           set intersection&lt;br /&gt;
 S-T            set difference (S \ T is also allowed)&lt;br /&gt;
 E:S            element of&lt;br /&gt;
 E/:S           not element of&lt;br /&gt;
 S&amp;lt;:T           subset of&lt;br /&gt;
 S/&amp;lt;:T          not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T          strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T         not strict subset of&lt;br /&gt;
 union(S)       generalised union over sets of sets&lt;br /&gt;
 inter(S)       generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E) generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E) generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER     set of integers&lt;br /&gt;
 NATURAL     set of natural numbers&lt;br /&gt;
 NATURAL1    set of non-zero natural numbers&lt;br /&gt;
 INT         set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT         set of implementable natural numbers&lt;br /&gt;
 NAT1        set of non-zero implementable natural numbers&lt;br /&gt;
 n..m        set of numbers from n to m&lt;br /&gt;
 MININT      the minimum implementable integer&lt;br /&gt;
 MAXINT      the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n         greater than&lt;br /&gt;
 m&amp;lt;n         less than&lt;br /&gt;
 m&amp;gt;=n        greater than or equal&lt;br /&gt;
 m&amp;lt;=n        less than or equal&lt;br /&gt;
 max(S)      maximum of a set of numbers&lt;br /&gt;
 min(S)      minimum of a set of numbers&lt;br /&gt;
 m+n         addition&lt;br /&gt;
 m-n         difference&lt;br /&gt;
 m*n         multiplication&lt;br /&gt;
 m/n         division&lt;br /&gt;
 m**n        power&lt;br /&gt;
 m mod n     remainder of division&lt;br /&gt;
 PI(z).(P|E)    Set product&lt;br /&gt;
 SIGMA(z).(P|E) Set summation&lt;br /&gt;
 succ(n)     successor (n+1)&lt;br /&gt;
 pred(n)     predecessor (n-1)&lt;br /&gt;
 0xH         hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T     relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T    total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T    surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T   total surjective relation&lt;br /&gt;
 E|-&amp;gt;F     maplet&lt;br /&gt;
 dom(r)    domain of relation&lt;br /&gt;
 ran(r)    range of relation&lt;br /&gt;
 id(S)     identity relation&lt;br /&gt;
 S&amp;lt;|r      domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r     domain subtraction&lt;br /&gt;
 r|&amp;gt;S      range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S     range subtraction&lt;br /&gt;
 r~        inverse of relation&lt;br /&gt;
 r[S]      relational image&lt;br /&gt;
 r1&amp;lt;+r2    relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2    direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)   relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)  parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T) projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T) projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
           prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)    translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)    translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0 &lt;br /&gt;
               (Note: iterate(r,0) = id(s) where s =TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  S+-&amp;gt;T        partial function&lt;br /&gt;
  S--&amp;gt;T        total function&lt;br /&gt;
  S+-&amp;gt;&amp;gt;T       partial surjection&lt;br /&gt;
  S--&amp;gt;&amp;gt;T       total surjection&lt;br /&gt;
  S&amp;gt;+&amp;gt;T        partial injection&lt;br /&gt;
  S&amp;gt;-&amp;gt;T        total injection&lt;br /&gt;
  S&amp;gt;+&amp;gt;&amp;gt;T       partial bijection&lt;br /&gt;
  S&amp;gt;-&amp;gt;&amp;gt;T       total bijection&lt;br /&gt;
  %x.(P|E)     lambda abstraction&lt;br /&gt;
  f(E)         function application&lt;br /&gt;
  f(E1,...,En) is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;&amp;gt; or []   empty sequence&lt;br /&gt;
  [E]        singleton sequence&lt;br /&gt;
  [E,F]      constructed sequence&lt;br /&gt;
  seq(S)     set of sequences over S&lt;br /&gt;
  seq1(S)    set of non-empty sequences over S&lt;br /&gt;
  iseq(S)    set of injective sequences over S&lt;br /&gt;
  iseq1(S)   set of non-empty injective sequences over S&lt;br /&gt;
  perm(S)    set of bijective sequences (permutations) over S&lt;br /&gt;
  size(s)    size of sequence&lt;br /&gt;
  s^t        concatenation&lt;br /&gt;
  E-&amp;gt;s       prepend element&lt;br /&gt;
  s&amp;lt;-E       append element&lt;br /&gt;
  rev(s)     reverse of sequence&lt;br /&gt;
  first(s)   first element&lt;br /&gt;
  last(s)    last element&lt;br /&gt;
  front(s)   front of sequence (all but last element)&lt;br /&gt;
  tail(s)    tail of sequence (all but first element)&lt;br /&gt;
  conc(S)    concatenation of sequence of sequences&lt;br /&gt;
  s/|\n      take first n elements of sequence&lt;br /&gt;
  s\|/n      drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  struct(ID:S,...,ID:S)   set of records with given fields and field types&lt;br /&gt;
  rec(ID:E,...,ID:E)      construct a record with given field names and values&lt;br /&gt;
  E&#039;ID                    get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;astring&amp;quot;     a specific (single-line) string value&lt;br /&gt;
  &#039;&#039;&#039;astring&#039;&#039;&#039; an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
  ```tstring``` template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding), &lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
  STRING        the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
However, the ProB [[External_Functions|external function library]] contains several operators on strings. ProB also allows multi-line strings.&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
 \n   newline (ASCII character 13)&lt;br /&gt;
 \r   carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;   the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;   the single quote symbol &#039;&lt;br /&gt;
 \\   the backslash symbol&lt;br /&gt;
&lt;br /&gt;
Within single-line string literals, you do not need to escape &#039;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;quot; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
The library LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like TO_STRING, STRING_SPLIT, FORMAT_TO_STRING, INT_TO_HEX_STRING, ...).&lt;br /&gt;
Some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  size(s)     the length of a string s&lt;br /&gt;
  rev(s)      the reverse a string s&lt;br /&gt;
  s ^ t       the concatenation of two strings&lt;br /&gt;
  conc(ss)    the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the STRING_AS_SEQUENCE preference.&lt;br /&gt;
&lt;br /&gt;
=== Reals: === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r to an integer&lt;br /&gt;
 ceiling(r)  convert a real r to an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus does not hold.&lt;br /&gt;
The library LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like RSIN, RCOS, RLOG, RSQRT, RPOW, ...).&lt;br /&gt;
You can turn off support for REALS using the preference ALLOW_REALS.&lt;br /&gt;
&lt;br /&gt;
=== Trees:===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions):===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5784</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5784"/>
		<updated>2024-06-13T11:56:15Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Equality: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F   equality&lt;br /&gt;
 E /= F  disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE&lt;br /&gt;
 FALSE&lt;br /&gt;
 BOOL        set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)     convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}             empty set&lt;br /&gt;
 {E}            singleton set&lt;br /&gt;
 {E,F}          set enumeration&lt;br /&gt;
 {x|P}          comprehension set&lt;br /&gt;
 {(x).P|E}      Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)         power set&lt;br /&gt;
 POW1(S)        set of non-empty subsets&lt;br /&gt;
 FIN(S)         set of all finite subsets&lt;br /&gt;
 FIN1(S)        set of all non-empty finite subsets&lt;br /&gt;
 card(S)        cardinality&lt;br /&gt;
 S*T            cartesian product&lt;br /&gt;
 S\/T           set union&lt;br /&gt;
 S/\T           set intersection&lt;br /&gt;
 S-T            set difference (S \ T is also allowed)&lt;br /&gt;
 E:S            element of&lt;br /&gt;
 E/:S           not element of&lt;br /&gt;
 S&amp;lt;:T           subset of&lt;br /&gt;
 S/&amp;lt;:T          not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T          strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T         not strict subset of&lt;br /&gt;
 union(S)       generalised union over sets of sets&lt;br /&gt;
 inter(S)       generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E) generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E) generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER     set of integers&lt;br /&gt;
 NATURAL     set of natural numbers&lt;br /&gt;
 NATURAL1    set of non-zero natural numbers&lt;br /&gt;
 INT         set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT         set of implementable natural numbers&lt;br /&gt;
 NAT1        set of non-zero implementable natural numbers&lt;br /&gt;
 n..m        set of numbers from n to m&lt;br /&gt;
 MININT      the minimum implementable integer&lt;br /&gt;
 MAXINT      the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n         greater than&lt;br /&gt;
 m&amp;lt;n         less than&lt;br /&gt;
 m&amp;gt;=n        greater than or equal&lt;br /&gt;
 m&amp;lt;=n        less than or equal&lt;br /&gt;
 max(S)      maximum of a set of numbers&lt;br /&gt;
 min(S)      minimum of a set of numbers&lt;br /&gt;
 m+n         addition&lt;br /&gt;
 m-n         difference&lt;br /&gt;
 m*n         multiplication&lt;br /&gt;
 m/n         division&lt;br /&gt;
 m**n        power&lt;br /&gt;
 m mod n     remainder of division&lt;br /&gt;
 PI(z).(P|E)    Set product&lt;br /&gt;
 SIGMA(z).(P|E) Set summation&lt;br /&gt;
 succ(n)     successor (n+1)&lt;br /&gt;
 pred(n)     predecessor (n-1)&lt;br /&gt;
 0xH         hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T     relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T    total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T    surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T   total surjective relation&lt;br /&gt;
 E|-&amp;gt;F     maplet&lt;br /&gt;
 dom(r)    domain of relation&lt;br /&gt;
 ran(r)    range of relation&lt;br /&gt;
 id(S)     identity relation&lt;br /&gt;
 S&amp;lt;|r      domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r     domain subtraction&lt;br /&gt;
 r|&amp;gt;S      range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S     range subtraction&lt;br /&gt;
 r~        inverse of relation&lt;br /&gt;
 r[S]      relational image&lt;br /&gt;
 r1&amp;lt;+r2    relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2    direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)   relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)  parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T) projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T) projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
           prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)    translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)    translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0 &lt;br /&gt;
               (Note: iterate(r,0) = id(s) where s =TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  S+-&amp;gt;T        partial function&lt;br /&gt;
  S--&amp;gt;T        total function&lt;br /&gt;
  S+-&amp;gt;&amp;gt;T       partial surjection&lt;br /&gt;
  S--&amp;gt;&amp;gt;T       total surjection&lt;br /&gt;
  S&amp;gt;+&amp;gt;T        partial injection&lt;br /&gt;
  S&amp;gt;-&amp;gt;T        total injection&lt;br /&gt;
  S&amp;gt;+&amp;gt;&amp;gt;T       partial bijection&lt;br /&gt;
  S&amp;gt;-&amp;gt;&amp;gt;T       total bijection&lt;br /&gt;
  %x.(P|E)     lambda abstraction&lt;br /&gt;
  f(E)         function application&lt;br /&gt;
  f(E1,...,En) is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;&amp;gt; or []   empty sequence&lt;br /&gt;
  [E]        singleton sequence&lt;br /&gt;
  [E,F]      constructed sequence&lt;br /&gt;
  seq(S)     set of sequences over S&lt;br /&gt;
  seq1(S)    set of non-empty sequences over S&lt;br /&gt;
  iseq(S)    set of injective sequences over S&lt;br /&gt;
  iseq1(S)   set of non-empty injective sequences over S&lt;br /&gt;
  perm(S)    set of bijective sequences (permutations) over S&lt;br /&gt;
  size(s)    size of sequence&lt;br /&gt;
  s^t        concatenation&lt;br /&gt;
  E-&amp;gt;s       prepend element&lt;br /&gt;
  s&amp;lt;-E       append element&lt;br /&gt;
  rev(s)     reverse of sequence&lt;br /&gt;
  first(s)   first element&lt;br /&gt;
  last(s)    last element&lt;br /&gt;
  front(s)   front of sequence (all but last element)&lt;br /&gt;
  tail(s)    tail of sequence (all but first element)&lt;br /&gt;
  conc(S)    concatenation of sequence of sequences&lt;br /&gt;
  s/|\n      take first n elements of sequence&lt;br /&gt;
  s\|/n      drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  struct(ID:S,...,ID:S)   set of records with given fields and field types&lt;br /&gt;
  rec(ID:E,...,ID:E)      construct a record with given field names and values&lt;br /&gt;
  E&#039;ID                    get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;astring&amp;quot;     a specific (single-line) string value&lt;br /&gt;
  &#039;&#039;&#039;astring&#039;&#039;&#039; an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
  ```tstring``` template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding), &lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
  STRING        the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
However, the ProB [[External_Functions|external function library]] contains several operators on strings. ProB also allows multi-line strings.&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
 \n   newline (ASCII character 13)&lt;br /&gt;
 \r   carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;   the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;   the single quote symbol &#039;&lt;br /&gt;
 \\   the backslash symbol&lt;br /&gt;
&lt;br /&gt;
Within single-line string literals, you do not need to escape &#039;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;quot; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
The library LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like TO_STRING, STRING_SPLIT, FORMAT_TO_STRING, INT_TO_HEX_STRING, ...).&lt;br /&gt;
Some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  size(s)     the length of a string s&lt;br /&gt;
  rev(s)      the reverse a string s&lt;br /&gt;
  s ^ t       the concatenation of two strings&lt;br /&gt;
  conc(ss)    the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the STRING_AS_SEQUENCE preference.&lt;br /&gt;
&lt;br /&gt;
=== Reals: === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r to an integer&lt;br /&gt;
 ceiling(r)  convert a real r to an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus does not hold.&lt;br /&gt;
The library LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like RSIN, RCOS, RLOG, RSQRT, RPOW, ...).&lt;br /&gt;
You can turn off support for REALS using the preference ALLOW_REALS.&lt;br /&gt;
&lt;br /&gt;
=== Trees:===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions):===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5783</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5783"/>
		<updated>2024-06-13T11:55:52Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Logical predicates: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q        conjunction&lt;br /&gt;
 P or Q       disjunction&lt;br /&gt;
 P =&amp;gt; Q       implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q      equivalence&lt;br /&gt;
 not(P)       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q)  universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)   existential quantification&lt;br /&gt;
 btrue        truth (this is a predicate)&lt;br /&gt;
 bfalse       falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F      equality&lt;br /&gt;
 E /= F     disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE&lt;br /&gt;
 FALSE&lt;br /&gt;
 BOOL        set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)     convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}             empty set&lt;br /&gt;
 {E}            singleton set&lt;br /&gt;
 {E,F}          set enumeration&lt;br /&gt;
 {x|P}          comprehension set&lt;br /&gt;
 {(x).P|E}      Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)         power set&lt;br /&gt;
 POW1(S)        set of non-empty subsets&lt;br /&gt;
 FIN(S)         set of all finite subsets&lt;br /&gt;
 FIN1(S)        set of all non-empty finite subsets&lt;br /&gt;
 card(S)        cardinality&lt;br /&gt;
 S*T            cartesian product&lt;br /&gt;
 S\/T           set union&lt;br /&gt;
 S/\T           set intersection&lt;br /&gt;
 S-T            set difference (S \ T is also allowed)&lt;br /&gt;
 E:S            element of&lt;br /&gt;
 E/:S           not element of&lt;br /&gt;
 S&amp;lt;:T           subset of&lt;br /&gt;
 S/&amp;lt;:T          not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T          strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T         not strict subset of&lt;br /&gt;
 union(S)       generalised union over sets of sets&lt;br /&gt;
 inter(S)       generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E) generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E) generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER     set of integers&lt;br /&gt;
 NATURAL     set of natural numbers&lt;br /&gt;
 NATURAL1    set of non-zero natural numbers&lt;br /&gt;
 INT         set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT         set of implementable natural numbers&lt;br /&gt;
 NAT1        set of non-zero implementable natural numbers&lt;br /&gt;
 n..m        set of numbers from n to m&lt;br /&gt;
 MININT      the minimum implementable integer&lt;br /&gt;
 MAXINT      the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n         greater than&lt;br /&gt;
 m&amp;lt;n         less than&lt;br /&gt;
 m&amp;gt;=n        greater than or equal&lt;br /&gt;
 m&amp;lt;=n        less than or equal&lt;br /&gt;
 max(S)      maximum of a set of numbers&lt;br /&gt;
 min(S)      minimum of a set of numbers&lt;br /&gt;
 m+n         addition&lt;br /&gt;
 m-n         difference&lt;br /&gt;
 m*n         multiplication&lt;br /&gt;
 m/n         division&lt;br /&gt;
 m**n        power&lt;br /&gt;
 m mod n     remainder of division&lt;br /&gt;
 PI(z).(P|E)    Set product&lt;br /&gt;
 SIGMA(z).(P|E) Set summation&lt;br /&gt;
 succ(n)     successor (n+1)&lt;br /&gt;
 pred(n)     predecessor (n-1)&lt;br /&gt;
 0xH         hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T     relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T    total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T    surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T   total surjective relation&lt;br /&gt;
 E|-&amp;gt;F     maplet&lt;br /&gt;
 dom(r)    domain of relation&lt;br /&gt;
 ran(r)    range of relation&lt;br /&gt;
 id(S)     identity relation&lt;br /&gt;
 S&amp;lt;|r      domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r     domain subtraction&lt;br /&gt;
 r|&amp;gt;S      range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S     range subtraction&lt;br /&gt;
 r~        inverse of relation&lt;br /&gt;
 r[S]      relational image&lt;br /&gt;
 r1&amp;lt;+r2    relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2    direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)   relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)  parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T) projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T) projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
           prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)    translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)    translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0 &lt;br /&gt;
               (Note: iterate(r,0) = id(s) where s =TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  S+-&amp;gt;T        partial function&lt;br /&gt;
  S--&amp;gt;T        total function&lt;br /&gt;
  S+-&amp;gt;&amp;gt;T       partial surjection&lt;br /&gt;
  S--&amp;gt;&amp;gt;T       total surjection&lt;br /&gt;
  S&amp;gt;+&amp;gt;T        partial injection&lt;br /&gt;
  S&amp;gt;-&amp;gt;T        total injection&lt;br /&gt;
  S&amp;gt;+&amp;gt;&amp;gt;T       partial bijection&lt;br /&gt;
  S&amp;gt;-&amp;gt;&amp;gt;T       total bijection&lt;br /&gt;
  %x.(P|E)     lambda abstraction&lt;br /&gt;
  f(E)         function application&lt;br /&gt;
  f(E1,...,En) is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;&amp;gt; or []   empty sequence&lt;br /&gt;
  [E]        singleton sequence&lt;br /&gt;
  [E,F]      constructed sequence&lt;br /&gt;
  seq(S)     set of sequences over S&lt;br /&gt;
  seq1(S)    set of non-empty sequences over S&lt;br /&gt;
  iseq(S)    set of injective sequences over S&lt;br /&gt;
  iseq1(S)   set of non-empty injective sequences over S&lt;br /&gt;
  perm(S)    set of bijective sequences (permutations) over S&lt;br /&gt;
  size(s)    size of sequence&lt;br /&gt;
  s^t        concatenation&lt;br /&gt;
  E-&amp;gt;s       prepend element&lt;br /&gt;
  s&amp;lt;-E       append element&lt;br /&gt;
  rev(s)     reverse of sequence&lt;br /&gt;
  first(s)   first element&lt;br /&gt;
  last(s)    last element&lt;br /&gt;
  front(s)   front of sequence (all but last element)&lt;br /&gt;
  tail(s)    tail of sequence (all but first element)&lt;br /&gt;
  conc(S)    concatenation of sequence of sequences&lt;br /&gt;
  s/|\n      take first n elements of sequence&lt;br /&gt;
  s\|/n      drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  struct(ID:S,...,ID:S)   set of records with given fields and field types&lt;br /&gt;
  rec(ID:E,...,ID:E)      construct a record with given field names and values&lt;br /&gt;
  E&#039;ID                    get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;astring&amp;quot;     a specific (single-line) string value&lt;br /&gt;
  &#039;&#039;&#039;astring&#039;&#039;&#039; an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
  ```tstring``` template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding), &lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
  STRING        the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
However, the ProB [[External_Functions|external function library]] contains several operators on strings. ProB also allows multi-line strings.&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
 \n   newline (ASCII character 13)&lt;br /&gt;
 \r   carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;   the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;   the single quote symbol &#039;&lt;br /&gt;
 \\   the backslash symbol&lt;br /&gt;
&lt;br /&gt;
Within single-line string literals, you do not need to escape &#039;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;quot; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
The library LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like TO_STRING, STRING_SPLIT, FORMAT_TO_STRING, INT_TO_HEX_STRING, ...).&lt;br /&gt;
Some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  size(s)     the length of a string s&lt;br /&gt;
  rev(s)      the reverse a string s&lt;br /&gt;
  s ^ t       the concatenation of two strings&lt;br /&gt;
  conc(ss)    the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the STRING_AS_SEQUENCE preference.&lt;br /&gt;
&lt;br /&gt;
=== Reals: === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r to an integer&lt;br /&gt;
 ceiling(r)  convert a real r to an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus does not hold.&lt;br /&gt;
The library LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like RSIN, RCOS, RLOG, RSQRT, RPOW, ...).&lt;br /&gt;
You can turn off support for REALS using the preference ALLOW_REALS.&lt;br /&gt;
&lt;br /&gt;
=== Trees:===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions):===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5782</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5782"/>
		<updated>2024-06-13T11:55:36Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Logical predicates: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q       conjunction&lt;br /&gt;
 P or Q      disjunction&lt;br /&gt;
 P =&amp;gt; Q      implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q     equivalence&lt;br /&gt;
 not(P)      negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q) universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)  existential quantification&lt;br /&gt;
 btrue       truth (this is a predicate)&lt;br /&gt;
 bfalse      falsity (this is a predicate)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F      equality&lt;br /&gt;
 E /= F     disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE&lt;br /&gt;
 FALSE&lt;br /&gt;
 BOOL        set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)     convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}             empty set&lt;br /&gt;
 {E}            singleton set&lt;br /&gt;
 {E,F}          set enumeration&lt;br /&gt;
 {x|P}          comprehension set&lt;br /&gt;
 {(x).P|E}      Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)         power set&lt;br /&gt;
 POW1(S)        set of non-empty subsets&lt;br /&gt;
 FIN(S)         set of all finite subsets&lt;br /&gt;
 FIN1(S)        set of all non-empty finite subsets&lt;br /&gt;
 card(S)        cardinality&lt;br /&gt;
 S*T            cartesian product&lt;br /&gt;
 S\/T           set union&lt;br /&gt;
 S/\T           set intersection&lt;br /&gt;
 S-T            set difference (S \ T is also allowed)&lt;br /&gt;
 E:S            element of&lt;br /&gt;
 E/:S           not element of&lt;br /&gt;
 S&amp;lt;:T           subset of&lt;br /&gt;
 S/&amp;lt;:T          not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T          strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T         not strict subset of&lt;br /&gt;
 union(S)       generalised union over sets of sets&lt;br /&gt;
 inter(S)       generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E) generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E) generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER     set of integers&lt;br /&gt;
 NATURAL     set of natural numbers&lt;br /&gt;
 NATURAL1    set of non-zero natural numbers&lt;br /&gt;
 INT         set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT         set of implementable natural numbers&lt;br /&gt;
 NAT1        set of non-zero implementable natural numbers&lt;br /&gt;
 n..m        set of numbers from n to m&lt;br /&gt;
 MININT      the minimum implementable integer&lt;br /&gt;
 MAXINT      the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n         greater than&lt;br /&gt;
 m&amp;lt;n         less than&lt;br /&gt;
 m&amp;gt;=n        greater than or equal&lt;br /&gt;
 m&amp;lt;=n        less than or equal&lt;br /&gt;
 max(S)      maximum of a set of numbers&lt;br /&gt;
 min(S)      minimum of a set of numbers&lt;br /&gt;
 m+n         addition&lt;br /&gt;
 m-n         difference&lt;br /&gt;
 m*n         multiplication&lt;br /&gt;
 m/n         division&lt;br /&gt;
 m**n        power&lt;br /&gt;
 m mod n     remainder of division&lt;br /&gt;
 PI(z).(P|E)    Set product&lt;br /&gt;
 SIGMA(z).(P|E) Set summation&lt;br /&gt;
 succ(n)     successor (n+1)&lt;br /&gt;
 pred(n)     predecessor (n-1)&lt;br /&gt;
 0xH         hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T     relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T    total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T    surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T   total surjective relation&lt;br /&gt;
 E|-&amp;gt;F     maplet&lt;br /&gt;
 dom(r)    domain of relation&lt;br /&gt;
 ran(r)    range of relation&lt;br /&gt;
 id(S)     identity relation&lt;br /&gt;
 S&amp;lt;|r      domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r     domain subtraction&lt;br /&gt;
 r|&amp;gt;S      range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S     range subtraction&lt;br /&gt;
 r~        inverse of relation&lt;br /&gt;
 r[S]      relational image&lt;br /&gt;
 r1&amp;lt;+r2    relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2    direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)   relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)  parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T) projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T) projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
           prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)    translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)    translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0 &lt;br /&gt;
               (Note: iterate(r,0) = id(s) where s =TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  S+-&amp;gt;T        partial function&lt;br /&gt;
  S--&amp;gt;T        total function&lt;br /&gt;
  S+-&amp;gt;&amp;gt;T       partial surjection&lt;br /&gt;
  S--&amp;gt;&amp;gt;T       total surjection&lt;br /&gt;
  S&amp;gt;+&amp;gt;T        partial injection&lt;br /&gt;
  S&amp;gt;-&amp;gt;T        total injection&lt;br /&gt;
  S&amp;gt;+&amp;gt;&amp;gt;T       partial bijection&lt;br /&gt;
  S&amp;gt;-&amp;gt;&amp;gt;T       total bijection&lt;br /&gt;
  %x.(P|E)     lambda abstraction&lt;br /&gt;
  f(E)         function application&lt;br /&gt;
  f(E1,...,En) is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;&amp;gt; or []   empty sequence&lt;br /&gt;
  [E]        singleton sequence&lt;br /&gt;
  [E,F]      constructed sequence&lt;br /&gt;
  seq(S)     set of sequences over S&lt;br /&gt;
  seq1(S)    set of non-empty sequences over S&lt;br /&gt;
  iseq(S)    set of injective sequences over S&lt;br /&gt;
  iseq1(S)   set of non-empty injective sequences over S&lt;br /&gt;
  perm(S)    set of bijective sequences (permutations) over S&lt;br /&gt;
  size(s)    size of sequence&lt;br /&gt;
  s^t        concatenation&lt;br /&gt;
  E-&amp;gt;s       prepend element&lt;br /&gt;
  s&amp;lt;-E       append element&lt;br /&gt;
  rev(s)     reverse of sequence&lt;br /&gt;
  first(s)   first element&lt;br /&gt;
  last(s)    last element&lt;br /&gt;
  front(s)   front of sequence (all but last element)&lt;br /&gt;
  tail(s)    tail of sequence (all but first element)&lt;br /&gt;
  conc(S)    concatenation of sequence of sequences&lt;br /&gt;
  s/|\n      take first n elements of sequence&lt;br /&gt;
  s\|/n      drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  struct(ID:S,...,ID:S)   set of records with given fields and field types&lt;br /&gt;
  rec(ID:E,...,ID:E)      construct a record with given field names and values&lt;br /&gt;
  E&#039;ID                    get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;astring&amp;quot;     a specific (single-line) string value&lt;br /&gt;
  &#039;&#039;&#039;astring&#039;&#039;&#039; an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
  ```tstring``` template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding), &lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
  STRING        the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
However, the ProB [[External_Functions|external function library]] contains several operators on strings. ProB also allows multi-line strings.&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
 \n   newline (ASCII character 13)&lt;br /&gt;
 \r   carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;   the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;   the single quote symbol &#039;&lt;br /&gt;
 \\   the backslash symbol&lt;br /&gt;
&lt;br /&gt;
Within single-line string literals, you do not need to escape &#039;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;quot; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
The library LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like TO_STRING, STRING_SPLIT, FORMAT_TO_STRING, INT_TO_HEX_STRING, ...).&lt;br /&gt;
Some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  size(s)     the length of a string s&lt;br /&gt;
  rev(s)      the reverse a string s&lt;br /&gt;
  s ^ t       the concatenation of two strings&lt;br /&gt;
  conc(ss)    the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the STRING_AS_SEQUENCE preference.&lt;br /&gt;
&lt;br /&gt;
=== Reals: === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r to an integer&lt;br /&gt;
 ceiling(r)  convert a real r to an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus does not hold.&lt;br /&gt;
The library LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like RSIN, RCOS, RLOG, RSQRT, RPOW, ...).&lt;br /&gt;
You can turn off support for REALS using the preference ALLOW_REALS.&lt;br /&gt;
&lt;br /&gt;
=== Trees:===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions):===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5781</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5781"/>
		<updated>2024-06-13T11:40:51Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Sets: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q       conjunction&lt;br /&gt;
 P or Q      disjunction&lt;br /&gt;
 P =&amp;gt; Q      implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q     equivalence&lt;br /&gt;
 not P       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q) universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)  existential quantification&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F      equality&lt;br /&gt;
 E /= F     disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE&lt;br /&gt;
 FALSE&lt;br /&gt;
 BOOL        set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)     convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}             empty set&lt;br /&gt;
 {E}            singleton set&lt;br /&gt;
 {E,F}          set enumeration&lt;br /&gt;
 {x|P}          comprehension set&lt;br /&gt;
 {(x).P|E}      Event-B style comprehension set (brackets needed)&lt;br /&gt;
 POW(S)         power set&lt;br /&gt;
 POW1(S)        set of non-empty subsets&lt;br /&gt;
 FIN(S)         set of all finite subsets&lt;br /&gt;
 FIN1(S)        set of all non-empty finite subsets&lt;br /&gt;
 card(S)        cardinality&lt;br /&gt;
 S*T            cartesian product&lt;br /&gt;
 S\/T           set union&lt;br /&gt;
 S/\T           set intersection&lt;br /&gt;
 S-T            set difference (S \ T is also allowed)&lt;br /&gt;
 E:S            element of&lt;br /&gt;
 E/:S           not element of&lt;br /&gt;
 S&amp;lt;:T           subset of&lt;br /&gt;
 S/&amp;lt;:T          not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T          strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T         not strict subset of&lt;br /&gt;
 union(S)       generalised union over sets of sets&lt;br /&gt;
 inter(S)       generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E) generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E) generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER     set of integers&lt;br /&gt;
 NATURAL     set of natural numbers&lt;br /&gt;
 NATURAL1    set of non-zero natural numbers&lt;br /&gt;
 INT         set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT         set of implementable natural numbers&lt;br /&gt;
 NAT1        set of non-zero implementable natural numbers&lt;br /&gt;
 n..m        set of numbers from n to m&lt;br /&gt;
 MININT      the minimum implementable integer&lt;br /&gt;
 MAXINT      the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n         greater than&lt;br /&gt;
 m&amp;lt;n         less than&lt;br /&gt;
 m&amp;gt;=n        greater than or equal&lt;br /&gt;
 m&amp;lt;=n        less than or equal&lt;br /&gt;
 max(S)      maximum of a set of numbers&lt;br /&gt;
 min(S)      minimum of a set of numbers&lt;br /&gt;
 m+n         addition&lt;br /&gt;
 m-n         difference&lt;br /&gt;
 m*n         multiplication&lt;br /&gt;
 m/n         division&lt;br /&gt;
 m**n        power&lt;br /&gt;
 m mod n     remainder of division&lt;br /&gt;
 PI(z).(P|E)    Set product&lt;br /&gt;
 SIGMA(z).(P|E) Set summation&lt;br /&gt;
 succ(n)     successor (n+1)&lt;br /&gt;
 pred(n)     predecessor (n-1)&lt;br /&gt;
 0xH         hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T     relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T    total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T    surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T   total surjective relation&lt;br /&gt;
 E|-&amp;gt;F     maplet&lt;br /&gt;
 dom(r)    domain of relation&lt;br /&gt;
 ran(r)    range of relation&lt;br /&gt;
 id(S)     identity relation&lt;br /&gt;
 S&amp;lt;|r      domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r     domain subtraction&lt;br /&gt;
 r|&amp;gt;S      range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S     range subtraction&lt;br /&gt;
 r~        inverse of relation&lt;br /&gt;
 r[S]      relational image&lt;br /&gt;
 r1&amp;lt;+r2    relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2    direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)   relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)  parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T) projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T) projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
           prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)    translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)    translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0 &lt;br /&gt;
               (Note: iterate(r,0) = id(s) where s =TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  S+-&amp;gt;T        partial function&lt;br /&gt;
  S--&amp;gt;T        total function&lt;br /&gt;
  S+-&amp;gt;&amp;gt;T       partial surjection&lt;br /&gt;
  S--&amp;gt;&amp;gt;T       total surjection&lt;br /&gt;
  S&amp;gt;+&amp;gt;T        partial injection&lt;br /&gt;
  S&amp;gt;-&amp;gt;T        total injection&lt;br /&gt;
  S&amp;gt;+&amp;gt;&amp;gt;T       partial bijection&lt;br /&gt;
  S&amp;gt;-&amp;gt;&amp;gt;T       total bijection&lt;br /&gt;
  %x.(P|E)     lambda abstraction&lt;br /&gt;
  f(E)         function application&lt;br /&gt;
  f(E1,...,En) is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;&amp;gt; or []   empty sequence&lt;br /&gt;
  [E]        singleton sequence&lt;br /&gt;
  [E,F]      constructed sequence&lt;br /&gt;
  seq(S)     set of sequences over S&lt;br /&gt;
  seq1(S)    set of non-empty sequences over S&lt;br /&gt;
  iseq(S)    set of injective sequences over S&lt;br /&gt;
  iseq1(S)   set of non-empty injective sequences over S&lt;br /&gt;
  perm(S)    set of bijective sequences (permutations) over S&lt;br /&gt;
  size(s)    size of sequence&lt;br /&gt;
  s^t        concatenation&lt;br /&gt;
  E-&amp;gt;s       prepend element&lt;br /&gt;
  s&amp;lt;-E       append element&lt;br /&gt;
  rev(s)     reverse of sequence&lt;br /&gt;
  first(s)   first element&lt;br /&gt;
  last(s)    last element&lt;br /&gt;
  front(s)   front of sequence (all but last element)&lt;br /&gt;
  tail(s)    tail of sequence (all but first element)&lt;br /&gt;
  conc(S)    concatenation of sequence of sequences&lt;br /&gt;
  s/|\n      take first n elements of sequence&lt;br /&gt;
  s\|/n      drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  struct(ID:S,...,ID:S)   set of records with given fields and field types&lt;br /&gt;
  rec(ID:E,...,ID:E)      construct a record with given field names and values&lt;br /&gt;
  E&#039;ID                    get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;astring&amp;quot;     a specific (single-line) string value&lt;br /&gt;
  &#039;&#039;&#039;astring&#039;&#039;&#039; an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
  ```tstring``` template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding), &lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
  STRING        the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
However, the ProB [[External_Functions|external function library]] contains several operators on strings. ProB also allows multi-line strings.&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
 \n   newline (ASCII character 13)&lt;br /&gt;
 \r   carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;   the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;   the single quote symbol &#039;&lt;br /&gt;
 \\   the backslash symbol&lt;br /&gt;
&lt;br /&gt;
Within single-line string literals, you do not need to escape &#039;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;quot; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
The library LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like TO_STRING, STRING_SPLIT, FORMAT_TO_STRING, INT_TO_HEX_STRING, ...).&lt;br /&gt;
Some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  size(s)     the length of a string s&lt;br /&gt;
  rev(s)      the reverse a string s&lt;br /&gt;
  s ^ t       the concatenation of two strings&lt;br /&gt;
  conc(ss)    the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the STRING_AS_SEQUENCE preference.&lt;br /&gt;
&lt;br /&gt;
=== Reals: === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r to an integer&lt;br /&gt;
 ceiling(r)  convert a real r to an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus does not hold.&lt;br /&gt;
The library LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like RSIN, RCOS, RLOG, RSQRT, RPOW, ...).&lt;br /&gt;
You can turn off support for REALS using the preference ALLOW_REALS.&lt;br /&gt;
&lt;br /&gt;
=== Trees:===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions):===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
	<entry>
		<id>https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5780</id>
		<title>Summary of B Syntax</title>
		<link rel="alternate" type="text/html" href="https://prob.hhu.de/w/index.php?title=Summary_of_B_Syntax&amp;diff=5780"/>
		<updated>2024-06-13T11:39:23Z</updated>

		<summary type="html">&lt;p&gt;Vella: /* Sets: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorial]]&lt;br /&gt;
[[Category:User Manual]]&lt;br /&gt;
&lt;br /&gt;
== Summary of B Syntax ==&lt;br /&gt;
&lt;br /&gt;
Below we describe the &amp;quot;classical&amp;quot; B syntax as supported by ProB.&lt;br /&gt;
You may also wish to consult&lt;br /&gt;
* The B summary by Ken Robinson ([[File:B-summary.pdf|PDF File]])&lt;br /&gt;
* The [https://www.atelierb.eu Atelier-B] reference manual ([https://www.atelierb.eu/wp-content/uploads/2023/10/b-language-reference-manual.pdf b-language-reference-manual.pdf])&lt;br /&gt;
&lt;br /&gt;
=== Logical predicates: ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 P &amp;amp; Q       conjunction&lt;br /&gt;
 P or Q      disjunction&lt;br /&gt;
 P =&amp;gt; Q      implication&lt;br /&gt;
 P &amp;lt;=&amp;gt; Q     equivalence&lt;br /&gt;
 not P       negation&lt;br /&gt;
 !(x).(P=&amp;gt;Q) universal quantification&lt;br /&gt;
 #(x).(P&amp;amp;Q)  existential quantification&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Above, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Q&amp;lt;/tt&amp;gt; stand for predicates. Inside the universal quantification, &amp;lt;tt&amp;gt;P&amp;lt;/tt&amp;gt; must give a value type to the quantified variable.&lt;br /&gt;
Note: you can also introduce multiple variables inside a universal or existential quantification, e.g., &amp;lt;tt&amp;gt;!(x,y).(P =&amp;gt; Q)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Equality:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 E = F      equality&lt;br /&gt;
 E /= F     disequality&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Booleans:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 TRUE&lt;br /&gt;
 FALSE&lt;br /&gt;
 BOOL        set of boolean values ({TRUE,FALSE})&lt;br /&gt;
 bool(P)     convert predicate into BOOL value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; are values and &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; predicates in B and cannot be combined using logical connectives.&lt;br /&gt;
To combine two boolean values &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; using conjunction you have to write &amp;lt;tt&amp;gt;x=TRUE &amp;amp; y=TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
To convert a predicate such as &amp;lt;tt&amp;gt;z&amp;gt;0&amp;lt;/tt&amp;gt; into a boolean value you have to use &amp;lt;tt&amp;gt;bool(z&amp;gt;0)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Sets:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {}          empty set&lt;br /&gt;
 {E}         singleton set&lt;br /&gt;
 {E,F}       set enumeration&lt;br /&gt;
 {x|P}       comprehension set&lt;br /&gt;
 {(x).P|E}  Event-B style comprehension set&lt;br /&gt;
 {x•P|E}   Event-B style comprehension set&lt;br /&gt;
 POW(S)      power set&lt;br /&gt;
 POW1(S)     set of non-empty subsets&lt;br /&gt;
 FIN(S)      set of all finite subsets&lt;br /&gt;
 FIN1(S)     set of all non-empty finite subsets&lt;br /&gt;
 card(S)     cardinality&lt;br /&gt;
 S*T         cartesian product&lt;br /&gt;
 S\/T        set union&lt;br /&gt;
 S/\T        set intersection&lt;br /&gt;
 S-T         set difference (S \ T is also allowed)&lt;br /&gt;
 E:S         element of&lt;br /&gt;
 E/:S        not element of&lt;br /&gt;
 S&amp;lt;:T        subset of&lt;br /&gt;
 S/&amp;lt;:T       not subset of&lt;br /&gt;
 S&amp;lt;&amp;lt;:T       strict subset of&lt;br /&gt;
 S/&amp;lt;&amp;lt;:T      not strict subset of&lt;br /&gt;
 union(S)    generalised union over sets of sets&lt;br /&gt;
 inter(S)    generalised intersection over sets of sets&lt;br /&gt;
 UNION(z).(P|E)  generalised union with predicate&lt;br /&gt;
 INTER(z).(P|E)  generalised intersection with predicate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integers:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 INTEGER     set of integers&lt;br /&gt;
 NATURAL     set of natural numbers&lt;br /&gt;
 NATURAL1    set of non-zero natural numbers&lt;br /&gt;
 INT         set of implementable integers (MININT..MAXINT)&lt;br /&gt;
 NAT         set of implementable natural numbers&lt;br /&gt;
 NAT1        set of non-zero implementable natural numbers&lt;br /&gt;
 n..m        set of numbers from n to m&lt;br /&gt;
 MININT      the minimum implementable integer&lt;br /&gt;
 MAXINT      the maximum implementable integer&lt;br /&gt;
 m&amp;gt;n         greater than&lt;br /&gt;
 m&amp;lt;n         less than&lt;br /&gt;
 m&amp;gt;=n        greater than or equal&lt;br /&gt;
 m&amp;lt;=n        less than or equal&lt;br /&gt;
 max(S)      maximum of a set of numbers&lt;br /&gt;
 min(S)      minimum of a set of numbers&lt;br /&gt;
 m+n         addition&lt;br /&gt;
 m-n         difference&lt;br /&gt;
 m*n         multiplication&lt;br /&gt;
 m/n         division&lt;br /&gt;
 m**n        power&lt;br /&gt;
 m mod n     remainder of division&lt;br /&gt;
 PI(z).(P|E)    Set product&lt;br /&gt;
 SIGMA(z).(P|E) Set summation&lt;br /&gt;
 succ(n)     successor (n+1)&lt;br /&gt;
 pred(n)     predecessor (n-1)&lt;br /&gt;
 0xH         hexadecimal literal, where H is a sequence of letters in [0-9A-Fa-f]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relations:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 S&amp;lt;-&amp;gt;T     relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;T    total relation&lt;br /&gt;
 S&amp;lt;-&amp;gt;&amp;gt;T    surjective relation&lt;br /&gt;
 S&amp;lt;&amp;lt;-&amp;gt;&amp;gt;T   total surjective relation&lt;br /&gt;
 E|-&amp;gt;F     maplet&lt;br /&gt;
 dom(r)    domain of relation&lt;br /&gt;
 ran(r)    range of relation&lt;br /&gt;
 id(S)     identity relation&lt;br /&gt;
 S&amp;lt;|r      domain restriction&lt;br /&gt;
 S&amp;lt;&amp;lt;|r     domain subtraction&lt;br /&gt;
 r|&amp;gt;S      range restriction&lt;br /&gt;
 r|&amp;gt;&amp;gt;S     range subtraction&lt;br /&gt;
 r~        inverse of relation&lt;br /&gt;
 r[S]      relational image&lt;br /&gt;
 r1&amp;lt;+r2    relational overriding (r2 overrides r1)&lt;br /&gt;
 r1&amp;gt;&amp;lt;r2    direct product (all pairs (x,(y,z)) with x,y:r1 and x,z:r2)&lt;br /&gt;
 (r1;r2)   relational composition {x,y| x|-&amp;gt;z:r1 &amp;amp; z|-&amp;gt;y:r2}&lt;br /&gt;
 (r1||r2)  parallel product (all pairs ((x,v),(y,w)) with x,y:r1 and v,w:r2)&lt;br /&gt;
 prj1(S,T) projection function (usage prj1(Dom,Ran)(Pair))&lt;br /&gt;
 prj2(S,T) projection function (usage prj2(Dom,Ran)(Pair))&lt;br /&gt;
           prj1(Pair) and prj2(Pair) are also allowed&lt;br /&gt;
 fnc(r)    translate relation A&amp;lt;-&amp;gt;B into function A+-&amp;gt;POW(B)&lt;br /&gt;
 rel(r)    translate relation A&amp;lt;-&amp;gt;POW(B) into relation A&amp;lt;-&amp;gt;B&lt;br /&gt;
 closure1(r)   transitive closure&lt;br /&gt;
 closure(r)    reflexive &amp;amp; transitive closure&lt;br /&gt;
               (equal to id(TYPEOF_r) \/ closure1(r))&lt;br /&gt;
 iterate(r,n)  iteration of r with n&amp;gt;=0 &lt;br /&gt;
               (Note: iterate(r,0) = id(s) where s =TYPEOF_r)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Functions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  S+-&amp;gt;T        partial function&lt;br /&gt;
  S--&amp;gt;T        total function&lt;br /&gt;
  S+-&amp;gt;&amp;gt;T       partial surjection&lt;br /&gt;
  S--&amp;gt;&amp;gt;T       total surjection&lt;br /&gt;
  S&amp;gt;+&amp;gt;T        partial injection&lt;br /&gt;
  S&amp;gt;-&amp;gt;T        total injection&lt;br /&gt;
  S&amp;gt;+&amp;gt;&amp;gt;T       partial bijection&lt;br /&gt;
  S&amp;gt;-&amp;gt;&amp;gt;T       total bijection&lt;br /&gt;
  %x.(P|E)     lambda abstraction&lt;br /&gt;
  f(E)         function application&lt;br /&gt;
  f(E1,...,En) is also supported (as well as f(E1|-&amp;gt;E2...|-&amp;gt;En))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequences:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;&amp;gt; or []   empty sequence&lt;br /&gt;
  [E]        singleton sequence&lt;br /&gt;
  [E,F]      constructed sequence&lt;br /&gt;
  seq(S)     set of sequences over S&lt;br /&gt;
  seq1(S)    set of non-empty sequences over S&lt;br /&gt;
  iseq(S)    set of injective sequences over S&lt;br /&gt;
  iseq1(S)   set of non-empty injective sequences over S&lt;br /&gt;
  perm(S)    set of bijective sequences (permutations) over S&lt;br /&gt;
  size(s)    size of sequence&lt;br /&gt;
  s^t        concatenation&lt;br /&gt;
  E-&amp;gt;s       prepend element&lt;br /&gt;
  s&amp;lt;-E       append element&lt;br /&gt;
  rev(s)     reverse of sequence&lt;br /&gt;
  first(s)   first element&lt;br /&gt;
  last(s)    last element&lt;br /&gt;
  front(s)   front of sequence (all but last element)&lt;br /&gt;
  tail(s)    tail of sequence (all but first element)&lt;br /&gt;
  conc(S)    concatenation of sequence of sequences&lt;br /&gt;
  s/|\n      take first n elements of sequence&lt;br /&gt;
  s\|/n      drop first n elements from sequence&lt;br /&gt;
 &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Records:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  struct(ID:S,...,ID:S)   set of records with given fields and field types&lt;br /&gt;
  rec(ID:E,...,ID:E)      construct a record with given field names and values&lt;br /&gt;
  E&#039;ID                    get value of field with name ID&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;astring&amp;quot;     a specific (single-line) string value&lt;br /&gt;
  &#039;&#039;&#039;astring&#039;&#039;&#039; an alternate way of writing (multi-line) strings, no need to escape &amp;quot;&lt;br /&gt;
  ```tstring``` template strings, where ${Expr} parts are evaluated and converted to string,&lt;br /&gt;
                you can provide options separated by commas in square brackets like $[2f]{Expr}.&lt;br /&gt;
                Valid options are: Nf (for floats/reals), Nd (for integer), Np (padding), &lt;br /&gt;
                ascii (can be abbreviated to a), unicode (can be abbreviated to u).&lt;br /&gt;
  STRING        the set of all strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atelier-B does not support any operations on strings, apart from equality and disequality.&lt;br /&gt;
However, the ProB [[External_Functions|external function library]] contains several operators on strings. ProB also allows multi-line strings.&lt;br /&gt;
As of version 1.7.0, ProB will support the following escape sequences within strings:&lt;br /&gt;
 \n   newline (ASCII character 13)&lt;br /&gt;
 \r   carriage return (ASCII 10)&lt;br /&gt;
 \t  tab (ASCII 9)&lt;br /&gt;
 \&amp;quot;   the double quote symbol &amp;quot;&lt;br /&gt;
 \&#039;   the single quote symbol &#039;&lt;br /&gt;
 \\   the backslash symbol&lt;br /&gt;
&lt;br /&gt;
Within single-line string literals, you do not need to escape &#039;.&lt;br /&gt;
Within multi-line string literals, you do not need to escape &amp;quot; and you can use&lt;br /&gt;
tabs and newlines.&lt;br /&gt;
ProB assumes that all B machines and strings use the UTF-8 encoding.&lt;br /&gt;
&lt;br /&gt;
The library LibraryStrings.def in stdlib contains additional useful external functions&lt;br /&gt;
(like TO_STRING, STRING_SPLIT, FORMAT_TO_STRING, INT_TO_HEX_STRING, ...).&lt;br /&gt;
Some of the sequence operators work also on strings:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  size(s)     the length of a string s&lt;br /&gt;
  rev(s)      the reverse a string s&lt;br /&gt;
  s ^ t       the concatenation of two strings&lt;br /&gt;
  conc(ss)    the concatenation of a sequence of strings&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can turn this support off using the STRING_AS_SEQUENCE preference.&lt;br /&gt;
&lt;br /&gt;
=== Reals: === &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 REAL        set of reals&lt;br /&gt;
 FLOAT       set of floating point numbers&lt;br /&gt;
 i.f         real literal in decimal notation, where i and f are natural numbers&lt;br /&gt;
 i.fEg       real literal in scientific notation, where i,f are natural numbers and g is an integer&lt;br /&gt;
 real(n)     convert an integer n into a real number&lt;br /&gt;
 floor(r)    convert a real r to an integer&lt;br /&gt;
 ceiling(r)  convert a real r to an integer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Standard arithmetic operators can be applied to reals: +, - , *, /, SIGMA, PI.&lt;br /&gt;
Exponentiation of a real with an integer is also allowed.&lt;br /&gt;
The comparison predicates =, /=, &amp;lt;, &amp;gt;, &amp;lt;=, &amp;gt;= also all work.&lt;br /&gt;
Support for reals and floats is experimental. The definition in Atelier-B&lt;br /&gt;
is also not stable yet. Currently ProB supports floating point numbers only.&lt;br /&gt;
Warning: properties such as associativity and commutativity of arithmetic operators&lt;br /&gt;
thus does not hold.&lt;br /&gt;
The library LibraryReals.def in stdlib contains additional useful external functions&lt;br /&gt;
(like RSIN, RCOS, RLOG, RSQRT, RPOW, ...).&lt;br /&gt;
You can turn off support for REALS using the preference ALLOW_REALS.&lt;br /&gt;
&lt;br /&gt;
=== Trees:===&lt;br /&gt;
Nodes in the tree are denoted by index sequences (branches), e.g, n=[1,2,1]&lt;br /&gt;
Each node in the tree is labelled with an element from a domain S&lt;br /&gt;
A tree is a function mapping of branches to elements of the domain S.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tree(S)      set of trees over domain S&lt;br /&gt;
  btree(S)     set of binary trees over domain S&lt;br /&gt;
  top(t)       top of a tree&lt;br /&gt;
  const(E,s)   construct a tree from info E and sequence of subtrees s&lt;br /&gt;
  rank(t,n)    rank of the node at end of branch n in the tree t&lt;br /&gt;
  father(t,n)  father of the node denoted by branch n in the tree t&lt;br /&gt;
  son(t,n,i)   the ith son of the node denoted by branch n in tree t&lt;br /&gt;
  sons(t)      the sequence of sons of the root of the tree t&lt;br /&gt;
  subtree(t,n)&lt;br /&gt;
  arity(t,n)&lt;br /&gt;
  bin(E)       construct a binary tree with a single node E&lt;br /&gt;
  bin(tl,E,tr) construct a binary tree with root info E and subtrees tl,tr&lt;br /&gt;
  left(t)      the left (first) son of the root of the binary tree t&lt;br /&gt;
  right(t)     the right (last) son of the root of the binary tree t&lt;br /&gt;
  sizet(t)     the size of the tree (number of nodes)&lt;br /&gt;
  prefix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  postfix(t)    the nodes of the tree t in prefix order&lt;br /&gt;
  mirror, infix are recognised by the parser but not yet supported by ProB itself&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LET and IF-THEN-ELSE === &lt;br /&gt;
ProB allows the following for predicates and expressions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   IF P1 THEN E1 ELSE E2 END&lt;br /&gt;
   IF P1 THEN E1 ELSIF P2 THEN E2 ... ELSE En END    conditional for expressions or predicates E1,E2,...,En&lt;br /&gt;
   LET x1,... BE x1=E1 &amp;amp; ... IN E END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: the expressions E1,... defining x1,... are not allowed to use x1,...&lt;br /&gt;
&lt;br /&gt;
=== Statements (aka Substitutions):===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  skip         no operation&lt;br /&gt;
  x := E       assignment&lt;br /&gt;
  f(x) := E    functional override&lt;br /&gt;
  x :: S       choice from set&lt;br /&gt;
  x : (P)      choice by predicate P (constraining x)&lt;br /&gt;
  x &amp;lt;-- OP(x)  call operation and assign return value&lt;br /&gt;
  G||H         parallel substitution**&lt;br /&gt;
  G;H          sequential composition**&lt;br /&gt;
  ANY x,... WHERE P THEN G END   non deterministic choice&lt;br /&gt;
  LET x,... BE x=E &amp;amp; ... IN G END&lt;br /&gt;
  VAR x,... IN G END             generate local variables&lt;br /&gt;
  PRE P THEN G END&lt;br /&gt;
  ASSERT P THEN G END&lt;br /&gt;
  CHOICE G OR H END&lt;br /&gt;
  IF P THEN G END&lt;br /&gt;
  IF P THEN G ELSE H END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... END&lt;br /&gt;
  IF P1 THEN G1 ELSIF P2 THEN G2 ... ELSE Gn END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H END&lt;br /&gt;
  SELECT P THEN G WHEN ... WHEN Q THEN H ELSE I END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... END END&lt;br /&gt;
  CASE E OF EITHER m THEN G OR n THEN H ... ELSE I END END&lt;br /&gt;
  &lt;br /&gt;
  WHEN P THEN G END  is a synonym for SELECT P THEN G END&lt;br /&gt;
&lt;br /&gt;
**: cannot be used at the top-level of an operation, but needs to&lt;br /&gt;
  be wrapped inside a BEGIN END or another statement (to avoid&lt;br /&gt;
  problems with the operators ; and ||).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine header:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  MACHINE or REFINEMENT or IMPLEMENTATION&lt;br /&gt;
  &lt;br /&gt;
  Note: machine parameters can either be SETS (if identifier is all upper-case)&lt;br /&gt;
        or scalars (i.e., integer, boolean or SET element; if identifier is not&lt;br /&gt;
        all upper-case; typing must be provided be CONSTRAINTS)&lt;br /&gt;
  You can also use MODEL or SYSTEM as a synonym for MACHINE, as well&lt;br /&gt;
  as EVENTS as a synonym for OPERATIONS.&lt;br /&gt;
  ProB also supports the ref keyword of Atelier-B for event refinement.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine sections:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CONSTRAINTS         P      (logical predicate)&lt;br /&gt;
  SETS                S;T={e1,e2,...};...&lt;br /&gt;
  CONSTANTS           x,y,...&lt;br /&gt;
  CONCRETE_CONSTANTS cx,cy,...&lt;br /&gt;
  PROPERTIES         P       (logical predicate)&lt;br /&gt;
  DEFINITIONS        m(x,...) == BODY;....&lt;br /&gt;
  VARIABLES          x,y,...  &lt;br /&gt;
  CONCRETE_VARIABLES cv,cw,...&lt;br /&gt;
  INVARIANT          P       (logical predicate)&lt;br /&gt;
  ASSERTIONS         P;...;P (list of logical predicates separated by ;)&lt;br /&gt;
  INITIALISATION&lt;br /&gt;
  OPERATIONS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Machine inclusion:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  USES list of machines&lt;br /&gt;
  INCLUDES list of machines&lt;br /&gt;
  SEES list of machines&lt;br /&gt;
  EXTENDS list of machines&lt;br /&gt;
  PROMOTES list of operations&lt;br /&gt;
  REFINES machine&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Note: Refinement machines should express the operation preconditions in terms of their own variables.&lt;br /&gt;
&lt;br /&gt;
=== Definitions:===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  NAME1 == Expression;          Definition without arguments&lt;br /&gt;
  NAME2(ID,...,ID) == E2;       Definition with arguments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &amp;quot;FILE.def&amp;quot;;                   Include definitions from file &lt;br /&gt;
&lt;br /&gt;
There are a few Definitions which can be used to influence the animator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
There are a few specific definitions which can be used to influence ProB:&lt;br /&gt;
  GOAL == P                to define a custom Goal predicate for Model Checking&lt;br /&gt;
                        (the Goal is also set by using &amp;quot;Advanced Find...&amp;quot;)&lt;br /&gt;
  SCOPE == P               to limit the search space to &amp;quot;interesting&amp;quot; nodes&lt;br /&gt;
  scope_SETNAME == n..n    to define custom cardinality for set SETNAME&lt;br /&gt;
  scope_SETNAME == n       equivalent to 1..n&lt;br /&gt;
  SET_PREF_MININT == n&lt;br /&gt;
  SET_PREF_MAXINT == n&lt;br /&gt;
  SET_PREF_MAX_INITIALISATIONS == n  max. number of intialisations computed&lt;br /&gt;
  SET_PREF_MAX_OPERATIONS == n       max. number of enablings per operation computed&lt;br /&gt;
  SET_PREF_SYMBOLIC == TRUE/FALSE&lt;br /&gt;
  SET_PREF_TIME_OUT == n             time out for operation computation in ms&lt;br /&gt;
  ASSERT_LTL... == &amp;quot;LTL Formula&amp;quot;  	using X,F,G,U,R LTL operators +&lt;br /&gt;
                                   Y,O,H,S Past-LTL operators +&lt;br /&gt;
                                   atomic propositions: e(OpName), [OpName], {BPredicate}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a custom state visualization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ANIMATION_FUNCTIONn == e           a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
  ANIMATION_FUNCTION_DEFAULT == e    a function (INT*INT) +-&amp;gt; INT or an INT&lt;br /&gt;
                    instead of any INT above you can also use BOOL or any SET&lt;br /&gt;
                    as a result you can also use STRING values,&lt;br /&gt;
                    or even other values which are pretty printed&lt;br /&gt;
  ANIMATION_IMGn == &amp;quot;PATH to .gif&amp;quot;   a path to a gif file&lt;br /&gt;
  ANIMATION_STRn == &amp;quot;sometext&amp;quot;       a string without spaces;&lt;br /&gt;
                                     the result integer n will be rendered as a string&lt;br /&gt;
  ANIMATION_STR_JUSTIFY_LEFT == TRUE computes the longest string in the outputs and pads&lt;br /&gt;
                                     the other strings accordingly&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_PADDING == n          additional padding between images in pixels&lt;br /&gt;
  SET_PREF_TK_CUSTOM_STATE_VIEW_STRING_PADDING == n   additional padding between text in pixels&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following definitions allow providing a [[Custom Graph|custom state graph]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODESn == e    define a set of nodes to be shown,&lt;br /&gt;
                              nodes can also be pairs (Node,Colour), triples (Node,Shape,Colour) or&lt;br /&gt;
                              records rec(color:Colour, shape:Shape, style:Style, label:Label, value:Node)&lt;br /&gt;
                              Colours are strings of valid Dot/Tk colors (e.g., &amp;quot;maroon&amp;quot; or &amp;quot;red&amp;quot;)&lt;br /&gt;
                              Shapes are strings of valid Dot shapes (e.g., &amp;quot;rect&amp;quot; or &amp;quot;hexagon&amp;quot;), and&lt;br /&gt;
                              Styles are valid Dot shape styles (e.g., &amp;quot;rounded&amp;quot; or &amp;quot;solid&amp;quot; or &amp;quot;dashed&amp;quot;)&lt;br /&gt;
  CUSTOM_GRAPH_EDGESn == e    define a relation to be shown as a graph&lt;br /&gt;
                              edges can either be pairs (node1,node2) or triples (node1,Label,node2)&lt;br /&gt;
                              where Label is either a Dot/Tk color or a string or value representing&lt;br /&gt;
                              the label to be used for the edges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases e can also be a record which defines default dot attributes like color, shape, style and description, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CUSTOM_GRAPH_NODES == rec(color:&amp;quot;blue&amp;quot;, shape:&amp;quot;rect&amp;quot;, nodes:e);&lt;br /&gt;
  CUSTOM_GRAPH_EDGES == rec(color:&amp;quot;red&amp;quot;, style:&amp;quot;dotted&amp;quot;, edges:e)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, the complete graph can be put into one definition using [[Custom_Graph|&amp;lt;code&amp;gt;CUSTOM_GRAPH&amp;lt;/code&amp;gt;]].&lt;br /&gt;
You have to define a single CUSTOM_GRAPH definition of a record with global graph attributes&lt;br /&gt;
   (like rankdir or layout) and optionally with edges and nodes attributes (replacing&lt;br /&gt;
    CUSTOM_GRAPH_EDGES and CUSTOM_GRAPH_NODES respectively), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CUSTOM_GRAPH == rec(layout:&amp;quot;circo&amp;quot;, nodes:mynodes, edges:myedges)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also &amp;lt;tt&amp;gt;SEQUENCE_CHART_opname&amp;lt;/tt&amp;gt; definitions for [[Generating UML Sequence Charts|generating UML sequence charts]].&lt;br /&gt;
&lt;br /&gt;
These DEFINITIONS affect [[VisB|VisB]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  VISB_JSON_FILE == &amp;quot;PATH to .json&amp;quot;  a path to a default VisB JSON file for visualisation; &lt;br /&gt;
                                     if it is &amp;quot;&amp;quot; an empty SVG will be created&lt;br /&gt;
  VISB_SVG_OBJECTSn == define a record or set of records for creating new SVG objects&lt;br /&gt;
  VISB_SVG_UPDATESn == define a record or set of records containing updates of SVG objects&lt;br /&gt;
  VISB_SVG_HOVERSn == define a record or set of records for VisB hover functions&lt;br /&gt;
  VISB_SVG_BOX == record with dimensions (height, width) of a default empty SVG&lt;br /&gt;
  VISB_SVG_CONTENTS == defines a string to be included into a created empty SVG file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments and Pragmas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
B supports two styles of comments:&lt;br /&gt;
   /* ... */       block comments&lt;br /&gt;
   // ...          line comments&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProB recognises several pragma comments of the form /*@ PRAGMA VALUE */&lt;br /&gt;
The whitespace between @ and PRAGMA is optional.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /*@symbolic */      put before comprehension set or lambda to instruct ProB&lt;br /&gt;
                      to keep it symbolic and not try to compute it explicitly&lt;br /&gt;
  /*@label LBL */     associates a label LBL with the following predicate&lt;br /&gt;
                      (LBL must be identifier or a string &amp;quot;....&amp;quot;)&lt;br /&gt;
  /*@desc DESC */     associates a description DESC with the preceding predicate or&lt;br /&gt;
                      introduced identifier (in VARIABLES, CONSTANTS,... section)&lt;br /&gt;
                      There are two special descriptions&lt;br /&gt;
                      /*@desc memo*/ to be put after identifiers in the ABSTRACT_CONSTANTS section&lt;br /&gt;
                                     indicating that these functions should be memoized&lt;br /&gt;
                      /*@desc prob-ignore */ to be put after predicates (e.g., in PROPERTIES) which&lt;br /&gt;
                                             should be ignored by ProB&lt;br /&gt;
                                             when the preference USE_IGNORE_PRAGMAS is TRUE&lt;br /&gt;
  /*@file PATH */     associates a file for machines in SEES, INCLUDES, ...&lt;br /&gt;
                      put pragma after a seen or included machine&lt;br /&gt;
  /*@package NAME */  at start of machine, machine file should be in folder NAME/...&lt;br /&gt;
                      NAME can be qualified N1.N2...Nk, in which case the machine&lt;br /&gt;
                      file should be in N1/N2/.../Nk&lt;br /&gt;
  /*@import-package NAME */  adds ../NAME to search paths for SEES,...&lt;br /&gt;
                      NAME can also be qualified N1.N2...Nk, use after package pragma&lt;br /&gt;
  /*@generated */     can be put at the top of a machine file; indicates the machine&lt;br /&gt;
                      is generated from some other source and should not be edited&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Extensions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   .mch   for abstract machine files&lt;br /&gt;
   .ref   for refinement machines&lt;br /&gt;
   .imp   for implementation machines&lt;br /&gt;
   .def   for DEFINITIONS files&lt;br /&gt;
   .rmch  for Rules machines for data validation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Free Types === &lt;br /&gt;
More information can be found [[Free Types|here]].&lt;br /&gt;
&lt;br /&gt;
Free types exist in Z and in the Rodin theory plugin and are supported by ProB.&lt;br /&gt;
You can also define new free types in classical B by adding a &#039;&#039;FREETYPES&#039;&#039; clause with free type definitions separated by semicolon.&lt;br /&gt;
&lt;br /&gt;
Here is a definition of an inductive type &#039;&#039;IntList&#039;&#039; for lists of integers constructed using &#039;&#039;inil&#039;&#039; and &#039;&#039;icons&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FREETYPES&lt;br /&gt;
  IntList = inil, icons(INTEGER*IntList)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Differences with AtelierB/B4Free===&lt;br /&gt;
Basically, ProB tries to be compatible with Atelier B and conforms to the semantics&lt;br /&gt;
of Abrial&#039;s B-Book and of [http://www.atelierb.eu/php/documents-en.php#manuel-reference Atelier B&#039;s reference manual].&lt;br /&gt;
Here are the main differences with Atelier B:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  - tuples without parentheses are not supported; write (a,b,c) instead of a,b,c&lt;br /&gt;
  - relational composition has to be wrapped into parentheses; write (f;g)&lt;br /&gt;
  - parallel product also has to be wrapped into parentheses; write (f||g)&lt;br /&gt;
  - not all tree operators are supported&lt;br /&gt;
  - the VALUES clause is only partially supported&lt;br /&gt;
  - definitions have to be syntactically correct and be either an expression,&lt;br /&gt;
    predicate or substitution;&lt;br /&gt;
    the arguments to definitions have to be expressions;&lt;br /&gt;
    definitions which are predicates or substitutions must be declared before first use&lt;br /&gt;
  - definitions are local to a machine&lt;br /&gt;
  - for ProB the order of fields in a record is not relevant (internally the fields are&lt;br /&gt;
    sorted), Atelier-B reports a type error if the order of the name of the fields changes&lt;br /&gt;
  - well-definedness: for disjunctions and implications ProB uses the L-system&lt;br /&gt;
    of well-definedness (i.e., for P =&amp;gt; Q, P should be well-defined and&lt;br /&gt;
    if P is true then Q should also be well-defined)&lt;br /&gt;
  - ProB allows WHILE loops and sequential composition in abstract machines&lt;br /&gt;
  - ProB now allows the IF-THEN-ELSE and LET for expressions and predicates&lt;br /&gt;
    (e.g., IF x&amp;lt;0 THEN -x ELSE x END or LET x BE x=f(y) IN x+x END)&lt;br /&gt;
  - ProB&#039;s type inference is stronger than Atelier-B&#039;s, much less typing predicates&lt;br /&gt;
    are required&lt;br /&gt;
  - ProB accepts operations with parameters but without pre-conditions&lt;br /&gt;
  - ProB allows identifiers consisting of a single character and identifiers in single backquotes (`id`)&lt;br /&gt;
  - ProB allows to use &amp;lt;&amp;gt; for the empty sequence (but this use is deprecated)&lt;br /&gt;
  - ProB allows escape codes (\n, \&#039;, \&amp;quot;, see above) and supports UTF-8 characters in strings,&lt;br /&gt;
    and ProB allows multi-line string literals written using three apostrophes (&#039;&#039;&#039;string&#039;&#039;&#039;)&lt;br /&gt;
    as well as template strings using three backquotes (e.g., ```1+2=${1+2}```)&lt;br /&gt;
  - ProB allows a she-bang line in machine files starting with #!&lt;br /&gt;
 (If you discover more differences, please let us know!)&lt;br /&gt;
  - ProB allows btrue and bfalse as predicates in B machines&lt;br /&gt;
  - ProB allows to use the Event-B relation operators &amp;lt;&amp;lt;-&amp;gt;, &amp;lt;-&amp;gt;&amp;gt;, &amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;br /&gt;
  - ProB allows set comprehensions with an extra expression like {x•x:1..10|x*x}.&lt;br /&gt;
  - The FREETYPES section and the external libraries (LibraryStrings.def, ...) do not exist in Atelier-B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also our Wiki for documentation:&lt;br /&gt;
* [[Current Limitations]]&lt;br /&gt;
* [[Using ProB with Atelier B]]&lt;br /&gt;
&lt;br /&gt;
Also note that there are various differences between BToolkit and AtelierB/ProB:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 - AtelierB/ProB do not allow true as predicate;&lt;br /&gt;
   e.g., PRE true THEN ... END is not allowed (use BEGIN ... END instead), ProB allows btrue as predicate.&lt;br /&gt;
 - AtelierB/ProB do not allow a machine parameter to be used in the PROPERTIES&lt;br /&gt;
 - AtelierB/ProB require a scalar machine parameter to be typed in the&lt;br /&gt;
   CONSTRAINTS clause&lt;br /&gt;
 - In AtelierB/ProB the BOOL type is pre-defined and cannot be redefined&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other notes===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ProB is best at treating universally quantified formulas of the form&lt;br /&gt;
 !x.(x:SET =&amp;gt; RHS), or&lt;br /&gt;
 !(x,y).(x|-&amp;gt;y:SET =&amp;gt;RHS), !(x,y,z).(x|-&amp;gt;y|-&amp;gt;z:SET =&amp;gt;RHS), ...;&lt;br /&gt;
 otherwise the treatment of !(x1,...,xn).(LHS =&amp;gt; RHS) may delay until all values&lt;br /&gt;
 treated by LHS are known.&lt;br /&gt;
 Similarly, expressions of the form SIGMA(x).(x:SET|Expr) and PI(x).(x:SET|Expr)&lt;br /&gt;
 lead to better constraint propagation.&lt;br /&gt;
 The construction S:FIN(S) is recognised by ProB as equivalent to the Event-B&lt;br /&gt;
 finite(S) operator.&lt;br /&gt;
ProB assumes that machines and STRING values are encoded using UTF-8.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Event-B Syntax ===&lt;br /&gt;
&lt;br /&gt;
Note that the Event-B syntax in Rodin is slightly different (e.g, no sequences or strings built-in). There is also an Event-B summary by Ken Robinson ([[File:EventB-summary.pdf|PDF File]]). The Event-B syntax is only available for Event-B models in Rodin, ProB2-UI and ProB Jupyter notebooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Feedback}}&lt;/div&gt;</summary>
		<author><name>Vella</name></author>
	</entry>
</feed>