How do I model-check a module that depends on an unbound variable? - tla+

I'm going through Specifying Systems right now and I'm a little puzzled about how I'd model-check the following module:
---------------------------- MODULE BoundedFIFO ----------------------------
EXTENDS Naturals, Sequences
VARIABLES in, out
CONSTANT Message, N
ASSUME (N \in Nat) /\ (N > 0)
Inner(q) == INSTANCE InnerFIFO
BNext(q) == /\ Inner(q)!Next
/\ Inner(q)!BufRcv => (Len(q) < N)
Spec == \EE q : Inner(q)!Init /\ [][BNext(q)]_<<in, out, q>>
=============================================================================
I see that both the Init and BNext formulas are operators, parameterized by q. How would I supply this to the model checker?

You can't: \E x : P(x) is an unbounded expression, which TLC cannot handle. Many of the specs in Specifying Systems can't be modeled. More recent guides, such as the TLA+ Hyperbook or Learn TLA+, are more careful to keep all of their specs modelable.

Related

process local invariant in PlusCal

process(Server \in Servers)
variable x;
{
...
}
I want to have an invariant of x > 0 for all processes. Is there any way other than making x global?
I tried
define {
Inv == \A s \in Servers: x[s] > 0
}
But in translated TLA+ code, Inv is defined before variable x
Place the invariant after the \* END TRANSLATION line and it won't get clobbered by the PlusCal translator.

How to prove or model check a theorem in TLA+?

The below module declares a set of numbers that are in the range 10 to 99 that are divisible by 2 only once and call it NumbersThatDivideBy2Once. At the end it declares a theorem that the constant input is a subset of NumbersThatDivideBy2Once.
--------------------------- MODULE TestModule ---------------------------
EXTENDS Naturals
CONSTANT input
Numbers == { n \in Nat : n > 9 /\ n < 100 }
DividesBy2(n) == (n % 2) = 0
DividesBy2Once(n) == DividesBy2(n) /\ ~DividesBy2(n \div 2)
NumbersThatDivideBy2Once == { n \in Numbers: DividesBy2Once(n) }
THEOREM input \subseteq NumbersThatDivideBy2Once
=======================
How can I check if this theorem holds for a given input? If I run a model check with a provided set of numbers as input, even if some of those numbers are not part of NumbersThatDivideBy2Once I still get no errors.
Give your theorem a name,
THEOREM T == input \subseteq NumbersThatDivideBy2Once
Go to the "Model Checking Results" tab, and in "Evaluate Constant Expression" introduce T, in order for it to be evaluated.
Your model checker needs to be told what to do with the specification file, which is essentially a just collection of mathematical definitions.
In "normal use" you want to provide TLC a temporal formula representing your specification (usually given the nameSpec in the specification file). You introduce it in the "model overview" tab, under "what is the behaviour spec?". And that is what TLC uses to perform model checking.
In this case you don't have that. So just keep the option "no behaviour spec" and, as indicated above, specify in the "Model Checking Results" tab the constant expression you want to evaluate.

\in works, while \subseteq gives a "identifier undefined" error

I have the following spec:
------------------------------ MODULE Group ------------------------------
CONSTANTS People
VARIABLES members
Init == members \subseteq People
Next == members' = members
Group == Init /\ [][Next]_members
=============================================================================
(I simplified this spec to the point where it's not doing anything useful.)
When I try to run it through TLC, I get the following error:
In evaluation, the identifier members is either undefined or not an operator.
The error points to the Init line.
When I change the Init line to:
Init == members \in People
it validates fine.
I want the former functionality because I mean for members to be a collection of People, not a single person.
According to section 16.1.6 of Leslie Lamport's Specifying Systems, "TLA+ provides the following operators on sets:" and lists both \in and \subseteq.
Why is TLA+ not letting me use \subseteq?
While that is a valid TLA+ expression, TLC can only assign next-state values to a variable x by the statements x' = e or x' \in S. See section 14.2.6 for details. This holds for the initial assignment, too. In your case, you probably want members \in SUBSET People.

Automata with rules and invariances

I was inspired by the slide http://alloy.mit.edu/alloy/tutorials/day-course/s4_dynamic.pdf of Greg Dennis and Rob Seater, to model an automaton whose transitions are defined by rules and invariances but I can not understand why satisfy the constraints even in the presence of invariances and contradictory rules.
sig State {value : one Int}
sig System { trans : State -> State }
pred i1[s : State] { s.value < 4 }
pred i2[s : State] { s.value > 0 }
pred r1[s, s' : State, m, m' : System] {
s.value = -1 and s'.value = 0 and change[s, s', m, m']
}
pred r2[s, s' : State, m, m' : System] {
s.value = 1 and s'.value = 2 and change[s, s', m, m']
}
pred change[s, s' : State, m, m' : System] {
m'.trans = m.trans + s -> s'
}
assert ruleSafe {
all s, s' : State, m,m' : System |
i1[s] and i2[s] and r1[s,s',m,m'] and r2[s,s',m,m'] =>
i1[s'] and i2[s']
}
check ruleSafe
First, a side note: It's not clear what the value relation is intended to be doing, but do remember that integers in Alloy tend to be very narrow and overflow behavior can make rules like s.value < 4 produce unexpected results. Whenever integers are used only to ensure a nice supply of distinct values, or ordered values it is almost always better to use an uninterpreted type in Alloy with some relations to ensure the necessary constraints.
However, that's not the main source of your confusion. I think you believe that since r1 requires its first argument to have a value of -1 and r2 requires the same argument to have a value of 1, any condition involving both r1 and r2 with the same first argument cannot possibly be satisfied, and there can be no instances of a model which is required to satisfy such a predicate. Almost true!
I think you're correct that r1 and r2 cannot both be true for the same set of arguments (or any sets of arguments with the same first argument s). But the constraint you specify uses r1[s,s',m,m'] and r2[s,s',m,m'] in the antecedent of a conditional. Before you go any further, stop and think: What is the truth value of a conditional if the antecedent is false?
If you are having trouble seeing what is going on, try examining the instances of your model in which the antecedent of your conditional is true for all pairs of States and Systems. Concretely, add the following to your model and look at the instances it produces.
pred antecedent {
all s, s' : State, m, m' : System
| i1[s] and i2[s] and r1[s,s',m,m'] and r2[s,s',m,m']
}
run antecedent
It took me a minute or two before I understood what I was seeing; if it takes you longer than a few minutes, you might try the following variant definition of antecedent and see if it enlightens you.
pred antecedent {
all s, s' : State, m, m' : System
| i1[s] and i2[s] and r1[s,s',m,m'] and r2[s,s',m,m']
some State
some System
}
You are not the first user of first-order logic to have been taken by surprise when a conditional statement in your model turned out to be vacuously true when you expected it to be false. You won't be the last.

G-machine, (non-)strict contexts - why case expressions need special treatment

I'm currently reading Implementing functional languages: a tutorial by SPJ and the (sub)chapter I'll be referring to in this question is 3.8.7 (page 136).
The first remark there is that a reader following the tutorial has not yet implemented C scheme compilation (that is, of expressions appearing in non-strict contexts) of ECase expressions.
The solution proposed is to transform a Core program so that ECase expressions simply never appear in non-strict contexts. Specifically, each such occurrence creates a new supercombinator with exactly one variable which body corresponds to the original ECase expression, and the occurrence itself is replaced with a call to that supercombinator.
Below I present a (slightly modified) example of such transformation from 1
t a b = Pack{2,1} ;
f x = Pack{2,2} (case t x 7 6 of
<1> -> 1;
<2> -> 2) Pack{1,0} ;
main = f 3
== transformed into ==>
t a b = Pack{2,1} ;
f x = Pack{2,2} ($Case1 (t x 7 6)) Pack{1,0} ;
$Case1 x = case x of
<1> -> 1;
<2> -> 2 ;
main = f 3
I implemented this solution and it works like charm, that is, the output is Pack{2,2} 2 Pack{1,0}.
However, what I don't understand is - why all that trouble? I hope it's not just me, but the first thought I had of solving the problem was to just implement compilation of ECase expressions in C scheme. And I did it by mimicking the rule for compilation in E scheme (page 134 in 1 but I present that rule here for completeness): so I used
E[[case e of alts]] p = E[[e]] p ++ [Casejump D[[alts]] p]
and wrote
C[[case e of alts]] p = C[[e]] p ++ [Eval] ++ [Casejump D[[alts]] p]
I added [Eval] because Casejump needs an argument on top of the stack in weak head normal form (WHNF) and C scheme doesn't guarantee that, as opposed to E scheme.
But then the output changes to enigmatic: Pack{2,2} 2 6.
The same applies when I use the same rule as for E scheme, i.e.
C[[case e of alts]] p = E[[e]] p ++ [Casejump D[[alts]] p]
So I guess that my "obvious" solution is inherently wrong - and I can see that from outputs. But I'm having trouble stating formal arguments as to why that approach was bound to fail.
Can someone provide me with such argument/proof or some intuition as to why the naive approach doesn't work?
The purpose of the C scheme is to not perform any computation, but just delay everything until an EVAL happens (which it might or might not). What are you doing in your proposed code generation for case? You're calling EVAL! And the whole purpose of C is to not call EVAL on anything, so you've now evaluated something prematurely.
The only way you could generate code directly for case in the C scheme would be to add some new instruction to perform the case analysis once it's evaluated.
But we (Thomas Johnsson and I) decided it was simpler to just lift out such expressions. The exact historical details are lost in time though. :)

Resources