Computer Science / Software Engineering Notes Network

Advanced Software Modelling & Design

Matthew Barnes

Verification in Event-B        3

Proof-based verification        3

Deductive proof        5

Propositions        5

Quantification and Sets        8

Set Theory        10

Tree structures and transitive closure        14

Reachability in transition systems        21

Debugging models with proof and judgement        22

Refinement in Event-B        26

Extension refinement        26

Data refinement in Event-B        27

Event Convergence and Deadlock-freeness in Event-B        28

Reasoning about Programs        29

Contracts and Programs        29

Reasoning about Loops        32

Verification in Dafny        33

Event-B to Dafny        35

Requirements Analysis and Dependable Systems        35

What is Requirements Engineering?        35

Dependable Systems        37

Redundancy and Diversity        39

Formal Methods and Dependability        39

Safety critical systems        39

Safety critical systems and requirements        39

Safety engineering processes        42

Safety cases        44

Security Engineering        45

Security and dependability        48

Security and organisations        48

Security requirements        48

Secure systems design        48

Secure systems programming        48

Security testing and assurance        48

STPA        48

STAMP        49


Verification in Event-B

Proof-based verification

(x ∈ S ⇒ x > y) [x := x + 1] is x + 1 ∈ S ⇒ x + 1 > y

(∀x · x  S ⇒ x > y) [x := x + 1] is (∀x · x ∈ S ⇒ x > y)

(l < n ∧ n ≤ m) [l,m,n := 0,10,7] is 0 < 7 ∧ 7 ≤ 10

(x ∈ S ∧ y ∈ T) [x,y := y,x] is y ∈ S ∧ x ∈ T

Deductive proof

Propositions

Inference rule name

Inference rule

Explanation

Deduction

If we see an ‘implies’ in the goal, we can use deduction to get rid of it and add the left part to the hypothesis.

Modus ponens

If there’s an ‘implies’ in the hypothesis, we can split it up into two branches.

Hyp

This is usually used at the end, when the goal also exists in the hypothesis.

Introduce conjunction

If there is an ‘and’ in the goal, we can split the goal into two branches, one where the left is true and one where the right is true.

Proof by cases

If there is an ‘or’ in the hypothesis, we can split that or into two branches: one where the left is true, and one where the right is true.

Proof by contradiction

If there is a ‘not’ in the hypothesis, we can swap that with the goal and ‘not’ the goal.

Quantification and Sets

Inference rule name

Inference rule

Explanation

For-all instantiation in goal

∀-GOAL

This is used to get rid of a ‘for all’ in the goal. Basically, this moves the scope of the ‘for all’ from just the goal to the entire sequent.

If x is free in H, then any fresh variable name is used for x.

For-all instantiation in hypotheses

∀-HYP

This is used to instantiate a ‘for all’ in the hypothesis.

Think of the ‘for all’ statement as an ‘expression factory’ and you’re generating new hypothesis statements from it by substituting expressions into it as ‘x’.

The question is, what should you substitute as ‘x’?

Existential instantiation in goal

∃-GOAL

Just like for-all instantiation in goal, we move the scope to the whole sequent.

However, this time, we can substitute x for something, like with the hypotheses rules.

Existential instantiation in hypotheses

∃-HYP

Just like for-all instantiation in hypothesis, we pick an expression or variable to substitute as ‘x’ and we get a new statement.

Only this time, the ‘there-exists’ statement is replaced / destroyed.

If ‘x’ is free in H or Q, then we will use a fresh variable name. Otherwise, we’ll just use ‘x’.

Rewrite rule name (if applicable)

Rewrite rule

Explanation

Rewrite in goal

If E is equal to F, then replace all instances of E with F

Rewrite in hypotheses

The same as the above, but we’re replacing in the hypotheses

Converts two equal sets into subset predicates

Converts subset predicate into a quantified expression

Converts union into a predicate

Converts intersection into a predicate

Converts difference into a predicate

Converts a relation call into predicates

Converts the inverse relation to the normal relation

Set Theory

Tree structures and transitive closure

sets OBJECT

variables file, directory, object

invariants

  file ⊆ OBJECT

  directory ⊆ OBJECT

  object = file ⋃ directory

  file ⋂ directory = Ø

sets OBJECT

variables file, directory, object

invariants

  object ⊆ OBJECT

  partition(object, file, directory)

sets OBJECT, NAME, CONTENT

variables file, directory, object, name, content

invariants

  object ⊆ OBJECT

  partition(object, file, directory)

  name ∈ object → NAME

  content ∈ file → CONTENT

sets OBJECT, NAME, CONTENT

constants root

axioms root ∈ OBJECT


variables file, directory, object, name, content, parent

invariants

  object ⊆ OBJECT

  partition(object, file, directory)

  name ∈ object → NAME

  content ∈ file → CONTENT

  parent ∈ (object \ {root}) → directory

sets OBJECT, NAME, CONTENT

constants root

axioms root ∈ OBJECT


variables file, directory, object, name, content, parent

invariants

  object ⊆ OBJECT

  partition(object, file, directory)

  name ∈ object → NAME

  content ∈ file → CONTENT

  parent ∈ (object \ {root}) → directory

  ∀o.o ∈ object \ {root} ⇒ o ↦ root ∈ parent+

  ∀o.o ∈ object ⇒ o ↦ o ∉ parent+

sets OBJECT, NAME, CONTENT

constants root

axioms root ∈ OBJECT


variables file, directory, object, name, content, parent

invariants

  object ⊆ OBJECT

  partition(object, file, directory)

  name ∈ object → NAME

  content ∈ file → CONTENT

  parent ∈ (object \ {root}) → directory

  ∀o.o ∈ object \ {root} ⇒ o ↦ root ∈ parent+

  ∀o.o ∈ object ⇒ o ↦ o ∉ parent+

events

  MoveObject ≙

    any o, d where

      o ∈ object \ {root}

      d ∈ directory

      d ≠ parent(o)

      n does not clash with other objects in d

      move does not introduce a loop

    then

      parent(o) := d

    end

children = parent~[ {d} ]

name(o) ∉ name[children]

d ↦ o ∉ parent+

o ≠ d

sets OBJECT, NAME, CONTENT

constants root

axioms root ∈ OBJECT


variables file, directory, object, name, content, parent

invariants

  object ⊆ OBJECT

  partition(object, file, directory)

  name ∈ object → NAME

  content ∈ file → CONTENT

  parent ∈ (object \ {root}) → directory

  ∀o.o ∈ object \ {root} ⇒ o ↦ root ∈ parent+

  ∀o.o ∈ object ⇒ o ↦ o ∉ parent+

events

  MoveObject ≙

    any o, d, children where

      o ∈ object \ {root}

      d ∈ directory

      d ≠ parent(o)

      children = parent~[ {d} ]

      name(o) ∉ name[children]

      d ↦ o ∉ parent+

      o ≠ d

    then

      parent(o) := d

    end

sets OBJECT, NAME, CONTENT

constants root

axioms root ∈ OBJECT


variables file, directory, object, name, content, parent

invariants

  object ⊆ OBJECT

  partition(object, file, directory)

  name ∈ object → NAME

  content ∈ file → CONTENT

  parent ∈ (object \ {root}) → directory

  ∀o.o ∈ object \ {root} ⇒ o ↦ root ∈ parent+

  ∀o.o ∈ object ⇒ o ↦ o ∉ parent+

  ∀p,q.p ∈ object \ {root} ∧

       q ∈ object \ {root} ∧

       p ≠ q ∧

       parent(p) = parent(q)

   

       name(p) ≠ name(q)

events

  MoveObject ≙

    any o, d where

      o ∈ object \ {root}

      d ∈ directory

      d ≠ parent(o)

      children = parent~[ {d} ]

      name(o) ∉ name[children]

      d ↦ o ∉ parent+

      o ≠ d

    then

      parent(o) := d

    end

sets OBJECT, NAME, CONTENT

constants root

axioms root ∈ OBJECT


variables file, directory, object, name, content, parent

invariants

  object ⊆ OBJECT

  partition(object, file, directory)

  name ∈ object → NAME

  content ∈ file → CONTENT

  parent ∈ (object \ {root}) → directory

  ∀o.o ∈ object \ {root} ⇒ o ↦ root ∈ parent+

  ∀o.o ∈ object ⇒ o ↦ o ∉ parent+

  ∀p,q.p ∈ object \ {root} ∧

       q ∈ object \ {root} ∧

       p ≠ q ∧

       parent(p) = parent(q)

   

       name(p) ≠ name(q)

events

  MoveObject ≙

    any o, d where

      o ∈ object \ {root}

      d ∈ directory

      d ≠ parent(o)

      children = parent~[ {d} ]

      name(o) ∉ name[children]

      d ↦ o ∉ parent+

      o ≠ d

    then

      parent(o) := d

    end

  // I’ve added it over here

  CreateDirectory ≙

    any p, n, children, result where

      p ∈ directory

      n ∈ NAME

      children = parent~[{p}]

      n ∉ name[children]

      result ∈ OBJECT \ object

    then

      object := object ⋃ {result}

      directory := directory ⋃ {result}

      parent(result) := p

      name(result) := n

    end

Reachability in transition systems

Debugging models with proof and judgement

Inductive

Non-inductive

Initialisation: n := 0

Inc:

    when n != 3

    then n := n + 1

n <= 3

The initialisation holds this invariant, and there does not exist a state s1 (that holds the invariants), and an event such that:

s1 → s2

where s2 breaks the invariants.

Initialisation: n := 0

Inc:

    when n != 3

    then n := n + 1

n <= 4

Initialisation holds the invariant, but on the state where n = 4, the Inc event can break this invariant by making n = 5.

Refinement in Event-B

Extension refinement

  1. Augment existing functionality
  2. Explain how some purpose is achieved (that’s data refinement, which is next)

  1. Extension
  1. Extension with Guard Modification
  1. Variable Replacement / Data Reification
  1. Variable Removal

Data refinement in Event-B

Event Convergence and Deadlock-freeness in Event-B

Reasoning about Programs

Contracts and Programs

<PRE> PROG <POST>

<PRE> x := E(x) <POST>

PRE[x:=old(x)] ∧ x=E(old(x)) ⇒ POST

<PRE> PROG1 ; PROG2 <POST>

<PRE> PROG1 <PRED>

<PRED> PROG2 <POST>

<???> PROG <POST>

<POST[x:=E(x), old(x):=x]> x:=E(x) <POST>

<PRE> if cond PROG1 else PROG2 <POST>

<PRE ∧ cond> PROG1 <POST>

<PRE ∧ ¬cond> PROG2 <POST>

Reasoning about Loops

Init;

WHILE Grd DO

        INVARIANT Inv

        Body

        ENSURES Post

END

  1. Init establishes Inv
  2. Body preserves Inv when Grd holds
  3. Inv and not(Grd) implies Post
  1. <Pre> Init <Inv>
  2. <Inv ∧ Grd> Body <Inv>
  3. Inv ∧ ¬Grd ⇒ Post

  1. The loop variant Var is decreased each loop iteration
  2. Var never goes below 0
  1. <Inv ∧ Grd> Body <Var < old(Var)>
  2. Inv ⇒ Var ≥ 0

Verification in Dafny

method Max(x: int, y: int) returns (z: int)

    requires x >= 0

    requires y >= 0

    ensures y > x ==> z == y

    ensures x >= y ==> z == x

{

    if (y > x) then {

        z := y;

    } else {

        z := x;

    }

}

function sum(x: int): int

    requires x >= 0

    decreases x

{

    if x == 0 then 0 else x + sum(x - 1)

}

while (n < a.Length)

    invariant 0 <= n <= a.Length

    invariant r == product(a,n)

    decreases a.Length-n

{

    r := r * a[n];

    n := n + 1;

}

forall k :: Boolean expression

exists k :: Boolean expression

Event-B to Dafny

Requirements Analysis and Dependable Systems

What is Requirements Engineering?

Dependable Systems

If your co-worker starts looking like this, you might need to loosen the purse strings a little and invest in some dependability for your system.

Redundancy and Diversity

Formal Methods and Dependability

Safety critical systems

Safety critical systems and requirements

Safety engineering processes

Safety cases

Security Engineering

Security and dependability

  1. Vulnerability avoidance - system is designed so vulnerability does not occur (highest level of security assurance)
  2. Attack detection and elimination - detect attack and eliminate effect of that attack before it does any damage (e.g. malicious emails put in junk after being detected)
  3. Exposure limitation and recovery - detect attack and minimise the effects of the attack (e.g. backups are kept when data is deleted/modified)

Security and organisations

Security requirements

Secure systems design

Secure systems programming

Security testing and assurance

STPA

STAMP

STPA

Safety Control Structure

  1. Identify “Unsafe Control Actions“
  1. Action not performed causing a hazard
  2. Action is performed causing a hazard
  3. Action performed too late / too early
  4. Action performed for too long / too short
  1. Determine how the “Unsafe Control Action”s above could occur

  1. Define the Safety Control Structure
  2. Derive the Safety Constraints from the Functional Requirements using STPA step 1 (from above)
  3. Model the Safety Constraints in Event-B
  4. Determine how Unsafe Control Actions could occur using STPA step 2 (from above)
  5. Refine the model and safety constraints to ensure concrete Control Actions are safe in the presence of hazards

Action

Not provided

Provided

Too late / too early

Too long / too short

No more greasy fingertips! But is this system secure...?

  1. There must be a packet in the slot when the button is pressed
  2. There must be a person in the seat when the button is pressed
  3. The person and crisp packet must stay in place (be locked) until all crisps in the packet are eaten

Action

Not provided causing a hazard

Provided causing a hazard

Too late / too early

Too long / too short

Move the robotic arm

System won’t do anything; not hazardous

Arm could try to feed the person before they are sat down or before a crisp packet is in the slot; the arm could hit someone and hurt them.

Arm could hit the person outside of eating times.

Too long: person will eventually get bored and thirsty, which is uncomfortable and in some cases painful

Too short: could accidentally punch the person in the face with the crisp

Lock the crisp packet

Crisp packet could be taken out while the arm is moving, therefore no crisps will be taken. Not hazardous.

Crisp packet slot might lock while person is putting the packet in, therefore locking their hand in the slot.

Too late: crisp packet can be taken out before it’s locked and before eating process

Too early: crisp packet could be locked before the person even starts eating; maybe they changed their mind and wanted it back again? Additionally, see left

N/A (discrete action)

Lock the person

The person could jump out and then the machine would feed thin air, or even hit the person

The person could get locked in the chair before they even put crisps in the slot

Too late: the person could jump out and then the machine would feed thin air, or hit the person

Too early: see left

N/A (discrete action)

Unlock the crisp packet

The crisps would be forever locked, leaving empty crisp packet rubbish in the slot and not allowing other crisp packets in the slot. Doesn’t hurt the person, so not hazardous.

The empty crisp packets can be unlocked during eating, resulting in the arm accidentally feeding the person the packet itself and poisoning them.

Too late: the crisp packet is just released a little later

Too early: read the left

N/A (discrete action)

Unlock the person

The person would be locked in the machine forever, and eventually die of thirst. Not starvation, because they’ll be fed crisps. Then again, it’s only one packet, so yeah; starvation too.

Could unlock the person too early, and they’ll get up and get hit by the arm

Too late: the person will just get up later. Inconvenient, though.

Too early: see left

N/A (discrete action)

Push the button

Can’t kick-start the eating process, therefore unlocking is not triggered, person and crisp packet will never leave the system

Person presses the button and starts the eating process. No hazard.

Too late: eating process starts a little later. No hazard

Too early: eating process won’t start until person and crisp packet are in their places. No hazard

N/A (discrete action)

Insert crisp packet

Machine will never start eating process, so machine will never move. No hazard

Machine locks crisp packet in place. No hazard.

Too late: can’t start the eating process without crisp packet. No hazard

Too early: No hazard

N/A (discrete action)

Person gets in seat

Machine will never start eating process, so machine will never move. No hazard

Person will get in the seat. No hazard.

Too late: can’t start the eating process without person. No hazard

Too early: No hazard

N/A (discrete action)

  1. The arm speed should be no faster than around 10 cm per second
  2. Arm should not move before the person and crisp packet is locked
  3. The person and crisp packet should stay locked during eating, and become unlocked after the packet is empty
  4. Only lock when both person and crisp packet are in their locations