learning_tla/lamport_video/docs/lecture01.md
2025-02-08 18:44:33 +01:00

2.5 KiB

Lecture 1 : introduction to TLA⁺

  • TLA⁺ is for modeling systems at a high-level

    • High-level means at the design level, above the code level
  • To model critical parts, without the less important ones and implementation details

  • To find and correct design errors

  • LL PoV: his important contributions were not solutions, but discovering new problems that had been obscured by details, hence the quest for abstraction

  • Brannon Batson: The hard part of learning to write TLA+ specs is learning to think abstractly about the system.
  • E. Verhulst (RTOS for Rosetta spacecraft) said using TLA+ modeling allowed them to reduce code size by a factor of 10.

  • Basic abstraction: an execeution of a system is represented as a sequence of discrete steps

    • sequence also applies in concurrent systems, and is actually simple
    • steps are state changes
    • an execution is a sequence of states, called a behavior
    • states are described as an assignment of values to variables
  • State machines

    • can be described by three things: 0. what the variables describing state are 1.all possible initial states 2. what next states can follow any given state: a relation between their values at a step and the next
    • stop when they reach a state for which there is no possible next state

Initial example:

int i;

void main() {
    i = someNumberFrom0to1000();
    i = i + 1;
}

A possible execution:

declaration    func. call  increment
[i: 0]      →   [i: 42]  →  [i: 43]
[i: 0]      →   [i: 43]  →  [i: 44]

First attempt

  1. The variables: i
  2. Initial values: i = 0
  3. The relationships : i:43 is an end state. And yet, if function returns 43, the state will be that state, so the program cannot be represented as a state machine

Second attempt

The problem is that i is not the only part of the state: we are missing the statement executed next.

That part of the state is called the "control" state, which we'll call pc

  • pc: "start" before calling the function
  • pc: "middle" before the increment
  • pc: "done" when the program has finished
  1. The variables: i, pc
  2. Initial values: `[i: 0, pc: 'start']
If the current value of pc is "start", 
  then next value of i is in `{0, 1, ... 1000}`
           next value of `pc` is "middle"
  else if current value of pc is "middle"          
          then next value of i equals current value of i plus one. It is in `{1, 2, ... 1001}`
               next value of `pc` is "done"
       else /* pc is "done" */ no next values