--------------------------- MODULE RandomElement ---------------------------
EXTENDS Integers,TLC
VARIABLES x,y
Init == /\ x=0
/\ y=0
Next == /\ \E i \in { RandomElement(1..100) }: PrintT(i) /\ x' = i /\ y' = i
Inv == x=y
=============================================================================
But the behavior of TLC by evaluation the RandomElement operator isn't always obvious. The description of the operator in current-tools.pdf says that "RandomElement(S) = RandomElement(S)" could be evaluated to FLASE. However, if I substitute the calls of the RandomElement operator by an additional definition it will be always evaluated to TRUE:
i == RandomElement(1..100)
ASSUME i = i
This behavior is probably caused by the fact that TLC treats the definition "i" as a constant expression and evaluates the definition only once.
TLC's behavior also leads to tiny detail in my specification above: I added the conjunction operator "/\" at the beginning of the Next definition otherwise TLC would evaluate the expression "{RandomElement(1..100)}" only once. In this case the reason is more subtle. In presence of the conjunction operator TLC treats the Next definition as a single action because TLC can't split a conjunction into separate actions. If there is no conjunction TLC tries to split the body of the existential quantification into separate actions and handles the bounded variables in a different way (evaluating the expression only once).
I'm not sure if it is a desired behavior or a bug.
Dominik
ASSUME LET i == IF PrintT("first") THEN RandomElement(1..100) ELSE FALSE IN i = i
ASSUME LET i(j) == IF PrintT("second") THEN RandomElement(1..100) ELSE FALSE IN i(1) = i(1)
Hi Marc,
TLC was written to evaluate TLA+ specifications.
It uses various optimizations that take advantage
of mathematical properties--for example, that
no matter how many times an expression is
evaluated, it always returns the same result. For
various reasons, certain hacks have been added to
make TLC act as if it were not evaluating
mathematics and were instead executing a
programming language. These interact in strange
ways with TLC's optimizations. While there were
good reasons to add these hacks, they are not good
enough to subvert TLC's main purpose: to evaluate
TLA+ specifications as efficiently as possible.
When using those hacks, you will just have to
learn to live with their strange behavior.
Dominik Hansen has explained one of TLC's
optimizations: trying to compute constant
expressions only once. It therefore (usually)
precomputes definitions of the form
identifier == constant expression
I'm not sure if it does the same thing for LET
definitions, or only computes the value with the
first use of the definition. You can experiment
to find out what it does for LETs. As Dominik
pointed out, you can prevent this once-only
computation by giving the defined operator an
argument.
Another thing that TLC often does is lazy
evaluation, not evaluating an expression until it
needs the expression's value. For recursive
definitions, this can be a pessimization. It
could also lead to problems when trying to use
RandomElement. The operator TLCEval has been
added to the TLC module to cause eager evaluation.
See its description in the document "Current
Versions of the TLA+ Tools".
Leslie
Hi Marc and Dominik,
Section 19.3 of the hyperbook is about how TLC evaluates expressions.
As explained in the secion of Specifying Systems that describes how TLC
computes behaviors, TLC does not simply evaluate the next-state action.
(How could it, when the next-state action contains primed variables and
TLC is trying to compute possible values of the primed variables?)
To see what's going on, try these two next-state actions:
Next == /\ x' = LET i == RandomElement(1..10)
IN <<i, i>>
/\ PrintT(x)
Next == LET i == RandomElement(1..10)
IN /\ x' = <<i, i>>
/\ PrintT(x)
Leslie
--You received this message because you are subscribed to the Google Groups "tlaplus" group.
To unsubscribe from this group and stop receiving emails from it, send an email to tlaplus+u...@googlegroups.com.
To post to this group, send email to tla...@googlegroups.com.
Visit this group at http://groups.google.com/group/tlaplus.
For more options, visit https://groups.google.com/groups/opt_out.