3 ms·
> But reasoning with functions is a specific level of abstraction. Excellent point. The level of abstraction is a fundamental concern, not just in modeling but
by mrefj 10y ago
> But reasoning with functions is a specific level of abstraction.
Excellent point. The level of abstraction is a fundamental concern, not just in modeling but also in reasoning about systems. And state machines (as used in TLA or otherwise) add temporal abstractions to the mix of abstraction mechanism. To add to its power, it does not lead to any loss of generality; since any program in a language with well-defined operational semantics can be modeled using state machine (transition systems with infinite state space to be little more precise).
> In TLA, bisimulation and trace equivalence are the same, and
simulation is just trace-inclusion.
There is a fundamental difference between (bi)simulation and trace inclusion(equivalence); the former is a branching time notion and the later is a linear time notion. In fact if one it is easy to show if A is a simulation of B then A is also a "trace inclusion" of B. And this difference has some practical ramifications as well.
The branching time notions of refinement also has (not so famous) the completeness result.
http://www.ccs.neu.edu/home/pete/pub/charme-refinement-branching-time.pdf http://www.ccs.neu.edu/home/pete/pub/charme-refinement-branc...
https://arxiv.org/pdf/1502.02942v1.pdf https://arxiv.org/pdf/1502.02942v1.pdf
This has some practical ramification as well: the refinement map in Abadi/Lamport is a projection function, while in branching time it can be arbitrary function. The former is intuitively clear but often difficult in practice. The flexibility has been exploited to efficiently analyze correctness of several non-trivial systems like pipelined processors.
> So there is no such thing as two machines, one implementing the other, that cannot be expressed in this way.
To drive home the point what the completeness result means is
that one can always reason at the level of abstraction that was use to specify the system: state and their successors. This is what we are after in type-based reasoning: reasoning at the level of functional abstraction.
- pron 10y ago> the former is a branching time notion and the later is a linear time notion I think it is more precise to say that you cannot formally encode the concept of (bi)sumlation in LTL while you can in CTL. The notion itself, however, is a general structural relation between state machines that is independent of the temporal logic you use to formalize properties of their behavior, if any. I.e. (bi)simulation would exist even if temporal logic didn't. > the refinement map in Abadi/Lamport is a projection function One of the few things I don't like in TLA+ is that you can create a "refinement" mapping which isn't sound (and therefore isn't a refinement). In particular, you can add auxiliary variables that interfere with the specification. I know Lamport is working on a paper where he gives syntactic rules that ensure that the mapping is sound. > This is what we are after in type-based reasoning: reasoning at the level of functional abstraction. The challenge is making that reasoning rich enough (to reason about a wide class of programs), scalable enough, and at the same time affordable and simple for engineers. This goal is far from realized (and currently falls short, at least in the last two requirements). P.S I also think that TLA allows reasoning about structural properties of the state machine without any use of temporal logic at all. If A and B are action formulas and S is a state-predicate, then `S ∧ A` denotes the set of transitions from the set of states denoted by S (conversely `S' ∧ A` is the set of transitions into S). And so `S ∧ A ⇒ S ∧ B` means "for every transition A leaving S, there is a transition B leaving S". I think that you can therefore show (bi)simulation directly, structurally, rather than behaviorally; there is no use of behaviors (traces) or computation trees here at all (you may want to show that all the states S are reachable from the initial states). [1]: Unless behaviors are sequences of states, in which case the relationship coincides with the trace-equivalence relationship. There may be subtle technical differences (that I don't quite understand) even then, but they don't matter.
- mrefj 10y ago> create a "refinement" mapping which isn't sound (and therefore isn't a refinement). Could you please illustrate what do you mean by unsound refinement ? Refinement mapping along with the notion of correctness forms the part of "trust computing base". More precisely, the statement "A implements B under a refinement map r" assumes two things (1) what it means to implements; is it trace inclusion or simulation or stuttering simulation .... (2) what is the refinement map r. What am i missing here ?. Also can you please illustrate (with an example possibly) on the syntactic rules that Lamport is working on ? Addition of auxiliary variables to the specification introduces an extra proof obligation, namely, that it does not change its observable behavior. Often this is not very difficult as one can syntactically differentiate between auxiliary variables and the state variables. >I also think that TLA allows reasoning about structural properties of the state machine without any use of temporal logic at all. Definitely. Like you mention the refinement based on (bi)simulation or trace inclusion is different from the use of temporal logic to formalize properties of systems. Though two are related in the sense of adequacy of temporal logic: simulation preserves ACTL* properties while trace inclusion preserves LTL properties. > I think that you can therefore show (bi)simulation directly, structurally, rather than behaviorally; there is no use of behaviors (traces) or computation trees here at all. I do not quite understand what you mean here. Behaviors are succinctly represented using state machines -- set of states and there successors-- and then we look at a state machine as a generator of (possibly infinite) behaviors -- either as traces or computation trees. The scenarios where trace inclusion requires addition of prophecy and history variables to recover local reasoning (in other words structural reasoning using state and its successors) is more related to the completeness argument you mentioned earlier.
- pron 10y ago> (1) what it means to implements; is it trace inclusion or simulation or stuttering simulation .... (2) what is the refinement map Well, in TLA there's only one kind of implementation relation, as the three relations you mention coincide since a trace is a sequence of states, under a stuttering equivalence. All other implementation relations (like event-trace-inclusion) are the same relation on a reduced (abstracted) machine, with some of the state erased, or a refined machine with an added time variable. So the map (which we take to include auxiliary variables) fully describes the "kind" of implementation. > Could you please illustrate what do you mean by unsound refinement? The TLA+ features are, of course, completely sound, but you may not be mapping what you intended to map. The trickiest problem has to do with prophecy variables. You need to ensure that they don't restrict the behavior of the spec, and it's not always obvious. > Also can you please illustrate (with an example possibly) on the syntactic rules that Lamport is working on ? The simplest rule is that if the spec is Init ∧ ◻[Next]_x and, under an invariant: Inv ∧ Inv' ⇒ (Next ≣ ∃i∈Π : N(i)) Then the spec remains equivalent when introducing the prophecy variable p like so: ∃∃p : (Init ∧ p ∈ Π) ∧ ◻[N(p) ∧ p' ∈ Π]_<x, p> This basically means that the prophecy must cover the entire parameter space of N, and that once used, a prophecy must be "forgotten". The problem is parameterizing N. So the rules treat various forms of Next (disjunction, quantification etc.). But if Next is parameterized well so that its behavior isn't restricted by p, then obtaining a useful value from p for the mapping can be tricky: so you know what value will be picked by an existential quantifier, and you know what disjunct will be chosen etc., but you still need an interpreter for those choices to obtain the result of the machine's action. You could write the spec itself in a clever parameterized way so that it would be its own prophecy interpreter, but then you'd make it completely unreadable. In short, the problem is that you need to make sure that your prophecy variables are sound, but you still want to keep the spec at that refinement level readable and not sacrifice it for the sake of refinement to some other level, and the two requirements pull in opposite directions. What you could do (and that's what I did in a complex spec), is to use a prophecy variable that interacts well with the spec (i.e., doesn't make it unreadable) but doesn't conform with Lamport and Merz's rules, and then prove that it is sound. Unfortunately, that property alone can be 95% of what you intend the refinement to show in the first place, and here the model checker can't help you at all. We really need a model checker that can handle temporal quantification. > I do not quite understand what you mean here. Oh, it was just to emphasize the point that simulation is a structural property, unrelated to temporal logic or any notion of time or behavior.