No edit summary |
No edit summary |
||
Line 11: | Line 11: | ||
* Set the symbolic preference of ProB to true (use <tt>-p SYMBOLIC TRUE</tt> for probcli or set the Animation preference "Lazy expansion ... (SYMBOLIC)" to true) if you have large or infinite functions. For example, Event-B does not have a transitive closure operator (classical B has <tt>closure1</tt>). As such, the transitive closure is often axiomatised in Event-B as a function <tt>tclos</tt> from relations to relations. ProB will try to find a value for <tt>tclos</tt>. The search space for this function is <tt>(2^n*n)^(2^n*n)</tt>, where <tt>n</tt> is the size of the base set (see [[Tutorial Understanding the Complexity of B Animation]]). In symbolic mode, ProB will keep lambda expressions and set comprehensions symbolic as much as possible. In classical B, any <tt>ABSTRACT_CONSTANT</tt> will also at first be kept symbolic. However, there are only limited things you can do with a "symbolic" function without forcing an expansion: taking the value of a function is fine, computing the image over a set is also possible as is taking the union with another symbolic function. | * Set the symbolic preference of ProB to true (use <tt>-p SYMBOLIC TRUE</tt> for probcli or set the Animation preference "Lazy expansion ... (SYMBOLIC)" to true) if you have large or infinite functions. For example, Event-B does not have a transitive closure operator (classical B has <tt>closure1</tt>). As such, the transitive closure is often axiomatised in Event-B as a function <tt>tclos</tt> from relations to relations. ProB will try to find a value for <tt>tclos</tt>. The search space for this function is <tt>(2^n*n)^(2^n*n)</tt>, where <tt>n</tt> is the size of the base set (see [[Tutorial Understanding the Complexity of B Animation]]). In symbolic mode, ProB will keep lambda expressions and set comprehensions symbolic as much as possible. In classical B, any <tt>ABSTRACT_CONSTANT</tt> will also at first be kept symbolic. However, there are only limited things you can do with a "symbolic" function without forcing an expansion: taking the value of a function is fine, computing the image over a set is also possible as is taking the union with another symbolic function. | ||
== Effective Constraint Solving with ProB == | |||
=== Existential Quantifiers === | |||
Existential quantifiers can pose subtle problems when solving constraint problems. | |||
For an existential quantifier <tt>#x.P</tt> ProB will often wait until all variables in P apart from x are known to evaluate the quantifier. Indeed, if all variables apart from x are known, ProB can stop when it finds <b>one</b> solution for x. Take for example: | |||
#x.(x:0..1000 & x=p) & p:101..104 | |||
Here, ProB will wait until p is known (e.g., 101) before enumerating possible values for x. | |||
However, it could be that the predicate P is required to instantiate the outside variable, as in this example: | |||
#x.(x:100..101 & x=p) & p:NATURAL | |||
Here, the existential quantifier is required to narrow down the possible values of p. Thus, before enumerating an unbounded variable, ProB will start enumerating the existential variable x. | |||
Note, however, that the priority with which it will be enumerated is much lower than if it was a regular variable! | |||
Hence: | |||
* Tip: Beware of putting important domain variables into existential quantifiers. | |||
One exception to the above treatment are existential quantifiers of the form <tt>#x.(x=E & P)</tt>. They are recognised by ProB as LET-PREDICATES. This is a good use of the existential quantifier. This quantifier will never "block". | |||
* Tip: use existential quantifiers as LET-PREDICATES <tt>#x.(x=E & P)</tt> to avoid repeated computations (common-subexpresion elimination) and to make your predicates more readable |
The most common issue is that ProB needs to find values for the constants which satisfy the properties (aka axioms in Event-B). You should read the tutorial pages on this (in particular Understanding the ProB Setup Phases and Tutorial Troubleshooting the Setup)
Existential quantifiers can pose subtle problems when solving constraint problems.
For an existential quantifier #x.P ProB will often wait until all variables in P apart from x are known to evaluate the quantifier. Indeed, if all variables apart from x are known, ProB can stop when it finds one solution for x. Take for example:
#x.(x:0..1000 & x=p) & p:101..104
Here, ProB will wait until p is known (e.g., 101) before enumerating possible values for x. However, it could be that the predicate P is required to instantiate the outside variable, as in this example:
#x.(x:100..101 & x=p) & p:NATURAL
Here, the existential quantifier is required to narrow down the possible values of p. Thus, before enumerating an unbounded variable, ProB will start enumerating the existential variable x. Note, however, that the priority with which it will be enumerated is much lower than if it was a regular variable! Hence:
One exception to the above treatment are existential quantifiers of the form #x.(x=E & P). They are recognised by ProB as LET-PREDICATES. This is a good use of the existential quantifier. This quantifier will never "block".