[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
operator `\sim_x' as defined in erratum differs from TOPLAS
Dear Dr. Lamport, TLA+ Users Group,
The operator `\sim_x' appears to be defined differently in the book's errata (version of 28 Oct 2016)
than in the 1994 TOPLAS paper "The temporal logic of actions".
--------------------------------------- EXAMPLE ---------------------------------------
For example, in ZF, let
sigma == [
n \in Nat |->
IF n = 0
THEN [ x |-> 1, y |-> "a" ]
ELSE IF n = 1
THEN [ x |-> 2, y |-> "a" ]
ELSE [ x |-> 2, y |-> "b" ] ]
tau == [
n \in Nat |->
IF n = 0
THEN [ x |-> 999, y |-> "a" ]
ELSE [ x |-> 999, y |-> "b" ] ]
-----------------------------------------------------------------------------------------------
Using TOPLAS (with Natural defined as in the book, and using the notation
\sim_x to encapsulate the first two conjuncts from Eq.(49)):
sigma \sim_x tau ==
\E rho:
/\ IsABehavior(rho)
/\ Natural(rho) = Natural(sigma)
/\ rho =_x tau
Natural(sigma) = [
0 |-> [ x |-> 1, y |-> "a" ],
1 |-> [ x |-> 2, y |-> "a" ],
2 |-> [ x |-> 2, y |-> "b" ] ]
PROPOSITION Rho1 ==
\A rho:
/\ IsABehavior(rho)
/\ rho =_x tau
=> rho[1]["y"] = "b"
PROOF SKETCH:
BY axiom about function equality,
DOMAIN tau = Nat,
DEF IsABehavior,
\A n \in Nat: DOMAIN rho[n] = VarNames,
"y" \in VarNames,
DEF tau,
DEF =_x.
PROPOSITION NaturalRho1 ==
\A rho:
/\ IsABehavior(rho)
/\ rho =_x tau
=> Natural(rho)[1]["y"] = "b"
PROOF SKETCH:
BY Rho1,
DEF Natural,
DEF =_x,
DEF tau,
"a" # "b".
PROPOSITION Unequal ==
\A rho:
/\ IsABehavior(rho)
/\ rho =_x tau
=> Natural(rho) # Natural(sigma)
PROOF SKETCH:
BY NaturalRho1,
DEF Natural,
axiom about function equality.
THEOREM ~ (sigma \sim_x \tau)
PROOF SKETCH:
BY Unequal, DEF \sim_x.
-----------------------------------------------------------------------------------------------
Using the erratum from 28 Oct 2016:
Overwrite(p, var, value) == [
n \in Nat |->
[ p[n] EXCEPT ![var] = value ] ]
sigma \sim_x tau ==
\E value:
Natural(Overwrite(sigma, "x", value)) =
Natural(Overwrite(tau, "x", value))
PROPOSITION Misc ==
/\ Overwrite(sigma, "x", 999) = [
n \in Nat |->
IF n = 0
THEN [ x |-> 999, y |-> "a" ]
ELSE IF n = 1
THEN [ x |-> 999, y |-> "a" ]
ELSE [ x |-> 999, y |-> "b" ] ]
/\ Overwrite(tau, "x", 999) = tau
/\ Natural(Overwrite(sigma, "x", 999)) = [
0 |-> [ x |-> 999, y |-> "a" ],
1 |-> [ x |-> 999, y |-> "b" ] ]
/\ Natural(Overwrite(tau, "x", 999)) = [
0 |-> [ x |-> 999, y |-> "a" ],
1 |-> [ x |-> 999, y |-> "b" ] ]
THEOREM sigma \sim_x tau
PROOF SKETCH:
BY Misc, DEF \sim_x
================================================
The above example also demonstrates that the TOPLAS paper defines the
operator `\sim_x' to be noncommutative, whereas the erratum defines
a commutative operator.
If the above reasoning is correct, then should the erratum be
considered a revision, or should we continue to use the TOPLAS definition?
The TOPLAS definition seems closer to physical intuition.
It does not allow "squeezing" `sigma' too much to obtain `tau'.
If there are steps in `sigma' that change the unhidden variable `x',
then those steps are preserved as nonstuttering ones in `Natural(sigma)',
and so should appear as nonstuttering steps in both `rho' and `tau'.
This ensures that the "refined" behavior `tau' has at least as many nonstuttering
steps as the "coarser" behavior `sigma'. Otherwise (using the erratum),
`tau' could omit steps that in `sigma' change the unhidden `x',
even though those steps could represent visible behavior of other components.
Of course, a shorter `tau' can always be elongated by stuttering,
so this may leave the definition of temporal quantification unaffected.
Two weeks ago, I observed the difference between the earlier erratum (from Oct 2005)
and TOPLAS, and was working on proving it. In case they may be useful to someone,
I have attached the relevant TLA+ file, and a Python script that
applies this earlier definition to the TOPLAS example.
Best regards,
Ioannis Filippidis
Attachment:
about_temporal_quantifiers.tla
Description: Binary data
#!/usr/bin/env python
"""Compute the unstuttering map as in: Lamport, "Specifying systems"."""
def unstutter(s):
"""Remove repetitions of states from behavior `s`."""
m = len(s)
dom = {f(n, s): n for n in range(m)}
k = len(dom)
assert set(dom) == set(range(k)), dom
r = [s[dom[n]] for n in range(k)]
return r
def f(n, s):
"""Map index `n` to index of stutter-free behavior."""
if n == 0:
return 0
assert n > 0, n
r = f(n - 1, s)
if s[n] != s[n - 1]:
r += 1
return r
def sim_up_to_var(sigma, tau, var):
"""Return `True` if behaviors `sigma, tau` similar modulo `var`."""
t = unstutter(tau)
s = unstutter(sigma)
r = list()
for n, state in enumerate(t):
d = dict(state)
d[var] = s[n][var]
r.append(d)
print('[n \in DOMAIN t |-> t[n] EXCEPT ![var] = s[n][var]] =')
pprint_behavior(r)
return s == r
def main():
"""Example from 1994 Lamport TOPLAS."""
tau = [
dict(x=1, y='a'),
dict(x=2, y='a'),
dict(x=2, y='b')]
sigma = [
dict(x=999, y='a'),
dict(x=999, y='a'),
dict(x=999, y='b')]
# makes domains equal, but still not (sigma ~_x tau)
# sigma.append(dict(x=3, y='b'))
t = unstutter(tau)
s = unstutter(sigma)
print('Natural(tau) =')
pprint_behavior(t)
print('Natural(sigma) =')
pprint_behavior(s)
var = 'x'
sim = sim_up_to_var(sigma, tau, var)
if sim:
print('sigma ~_x tau')
else:
print('not (sigma ~_x tau)')
def pprint_behavior(t):
"""Pretty print behavior `t`."""
for state in t:
print(state)
print('\n')
if __name__ == '__main__':
main()