Professional Documents
Culture Documents
Reference Books:
Course instructor
Published By:
www.vumultan.com
1 CS709 – Formal Methods of Software Engineering
Lecture 1
Some Notations
while (!sorted) { // 2
sorted = true;
for (int i = 0; i < SIZE-1; i++) { // 3
if (a[i] > a[i+1]) { // 4
swap(a[i], a[i+1]); // 5
sorted = false;
} // 6
} // 7
} // 8
2N Paths
Dijkstra’s Game
Lecture 2
A Three Ball Game
Mathematical Model
(2 black out, 1 black in) b-2+1, w b-1, w
f(b,w) = (2 white out, 1 black in) b+1, w-2
(1 of each out, 1 white in) b-1, w-1+1 b-1, w
Propositional Calculus
• A compound proposition that is always true, irrespective of the truth values of the comprising
propositions, is called a tautology. Contradiction is inverse of tautology.
pp pp
• The propositions p and q are called logically equivalent if p q is tautology.
• It is written as ,
pq
• For example: (p q) p q
Distributivity of Associativity of
• and over or • , , and
• or over and
• or over Commutativity of
• over and • , , and
• over or Demorgan’s law
• over • Implication
• over • if and only if
Lecture 3
• A is a knight: A
• A eats his hat: H
• If I am a knight then I’ll eat my hat: AH
• We have seen that (X S) therefore (A A H)
• Objective is to logically deduce H
Truth Table
A H AH A (A H)
T T T T
F T T F
T F F F
F F T F
Introduction Introduction
p q p q
_______ _______ _______
p and q p or q p or q
Elimination Elimination
p and q p and q p pq
________ _________ _________
p q q
Introduction Elimination
[p]
p not p false
q
_______ ______
_________
false p
pq
2. Assume X
Use Elimination Rules to break No. 1 down into 5 premises
3. (W and A) E
4. (not A) I
5. (not W) M
6. not E
7. X not (I or M)
Now application of elimination on 2 and 7 derives another simple proposition
2. Assume X
7. X not (I or M)
8. not (I or M)
Now proving I or M will result in a contradiction
We will now analyze W
9. Assume not W
10. M (from 5 and 9)
11. I or M (from 10 - introduction)
12. Assume W
13. Assume A
14. W and A (12 and 13)
15. E (3 and 14)
16. false (6 and 15)
17. I or M (16)
Lecture 4
A G A↔G A (A ↔ G)
T T T T
F T F T
T F F F
F F T F
Associativity of Equivalence
• ABC
can be evaluated as
(A B) C
or
A (B C)
ABC
A B C AB (A B) C
F F F T F
F F T T T
F T F F T
F T T F F
T F F F T
T F T F F
T T F T F
T T T T T
Full Adder
• a 1; A
• b 1; B
• c 1; C
• d 1; D
• D (A B C)
Properties of equivalence
• constant true
true p p
true = (p p)
(true p) = p
ppqprq
pppqqr
true p true r
pr
Replace the term which is repeated odd number of times by a single occurrence of the term and any
terms which is repeated an even number of times by removing all occurrences.
• A is a knight A
• A says “I am a knight.” A
AA
• Since this is always true, no meaningful conclusion can be made.
• A is a knight A
• B is a knight B
• A says “I am the same type as B” AB
AAB
B
Lecture 5
Negation
• p p false
• p (p false)
• (p p) false
• p p q p r q
• p p p q q r
• true p false r
• pr
• There are two natives A and B. A says, “B is a knight is the same as I am a knave.”
• What can you determine about A and B?
• A’s statement is: BA
• So, we have: ABA
AAB
false B
B
A?
Golden Rule
• pqpqpq
Implication
• pqppq
• pqqpq
• If I am a knight, B is a knight
• AB
• AAB
• AAAB
• AB
• Three of the inhabitants – A, B, and C – were standing together in a garden. A stranger passed by
and asked A, “Are you a knight or a knave?” A answered but the stranger could not understand.
The stranger then asked B, “What did A say?”. B replied, “A said that he is a knave”. At this point,
the third C, said, “Don’t believe B; he is lying!” What are A, B, and C?
Lecture 6
Conditional Correctness:
• {P} S {Q}
where
P = initial state
S = set of statements
Q = final state
Express the conditional correctness of S
Weakest Precondition:
• Wp( z := x, z ≥ y) x≥y
• Wp( t := x, t x0) x = x0
• Wp( i := i+1, i ≤ n ) i<n
• Wp( i := 0, i = 0 ) true ~least restrictive, i.e. true for all values
• Wp( i := 0, i = 1 ) false ~impossible
Lecture 7
Example:
• {x = x0 and y = y0}
t := x ; x := y ; y := t ;
{y = x0 and x = y0}
• { x = x0 and y = y0} t := x { t = x0 and y = y0}
• { t = x0 and y = y0}
x := y ; y :=t
{y = x0 and x = y0}
• { t = x0 and y = y0} x := y { t = x0 and x = y0}
• { t = x0 and x = y0} y := t { y = x0 and x = y0}
P→Q Q→R
{Q} S {R} {P} S {R}
{P} S {R} {P} S {R}
Verification:
• Invariant
✓ Something which is unchanging
✓ Key to the proofs for programs containing loops (iteration or recursion)
Lecture 8
A Classical Problem:
Question: Can you completely cover the chessboard with these dominoes without partially using a
domino? If so how, if not, prove that you cannot.
• if i <= j then
m := i;
else
m := j;
• (m ≤ i and m ≤ j) and (m = i or m = j)
ELSE PART
• (i > j)
m = j;
• (m = i or m = j) and (m ≤ j and m ≤ j)
• (i>j) and (j = i or j = j) and (j ≤ i and j ≤ j)
• (i>j) and (true) and (j ≤ i and true)
• (i>j) and (j ≤ i)
• (i>j)
IF PART
• (i <= j)
m = i;
• (m = i or m = j) and (m ≤ i and m ≤ i)
• (i ≤ j) and (i = i or i = j) and (i ≤ i and i ≤ j)
• (i ≤ j) and (true) and (true and i ≤ j)
• (i ≤ j) and (i ≤ j)
• (i ≤ j)
Lecture 9
Loop Invariants:
• s = 0;
for i := 1 to n do
s = s + a[i];
• a = 0;
• i = 0;
• while (i < N)
a = a + i++;
N −1
• Loop Invariant: a = i
i =0
Lecture 10
Verification of Functions
• Specification of a system as a set of functions where the internal state is hidden.
• Each function is specified as a set of pre and post conditions.
• Pre-condition must hold if the post-condition is to be true.
Example – minimum
• function min (X: in INTEGER_ARRAY) return INTEGER
Pre: True
Post: j in X’First .. X’Last : min(X) = X( j ) and
i in X’First .. X’Last : min(X) X(i) and X = X’’
Lecture 11
Loop Invariant:
(found AND X(L) = key) OR
(NOT found AND
j in X'First..bot-1, top+1..X'Last: X(j) key))
Pre-Condition:
X'Last >= X'First and Ordered(X)
begin
bot: INTEGER := X'First;
top: INTEGER := X'Last;
mid: INTEGER;
L := (bot + top) / 2;
found := X(L) = key ;
(found AND X(L) = key) OR (NOT found AND j in X'First..X'Last: X(j) key))
if b then S else T
if b → S
[] not b → T
fi
Conditional Rule
{P}
if b1 → S1
[] b2 → S2
fi
{Q}
Lecture 12
Output Variables
• {true} S {i = j}
i := j; or j := i;
• Which one is the input variable and which one is the output variable?
Ghost Variables
• Suppose we want to specify that the sum of two variables i and j should remain constant
• We specify this by introducing a ghost variable C
• This variable should not be used anywhere else in the program.
• Then S specified by { i + j = C} S { i + j = C}
Simultaneous Assignment
• The left side is a list of variables and the right side is a list of expressions of the same length as the
list of variables.
x, y, z := 2*y, x+y, 3*z
• The assignment x, y := y, x
has the effect of swapping the values of x and y
Calculating Assignments
• Suppose that the requirement is to maintain the value of j+k constant while incrementing k by 1.
• Our task is to calculate and expression X such that
{j + k = C} j , k := X, k + 1 { j + k = C}
• Applying the assignment axiom, we get
{X + k + 1 = C} j , k := X, k + 1 { j + k = C}
j+k = C X + k + 1 = C
• Now
j+k
= j+k+1–1
= (j - 1) + k + 1
• Thus a suitable value of X is j – 1
• So,
{ j + k = C} j , k := j – 1, k + 1 { j + k = C}
Example:
• Suppose variables s and n satisfy the property
s = n2
• We want to increment n by 1 whilst maintaining this relationship between s and n
• Our goal is to calculate an expression X involving only addition such that
{ s = n2 } s, n := s + X, n+1 { s = n2 }
• Applying the assignment axiom we get
{ s + X = (n + 1)2 } s, n := s + X, n + 1 { s = n2 }
• So, we need
s = n2 s + X = (n + 1)2
• Now
(n + 1)2
= n2 + 2*n + 1
• That is
s = n2 s + 2*n + 1 = (n + 1)2
• So,
{ s = n2 } s, n := s + 2*n + 1, n+1 { s = n2 }
{true}
if x y → z := e1 {z = max(x,y)}
[] y x → z := e2 {z = max(x,y)}
fi
{z = max(x,y)}
Iteration
• The do-od statement
• do b → S od
Constructing Loops
• Invariant property and bound function
• Loops are designed so that each iteration of the loop body maintains the invariant whilst making
progress to the required post-condition by always decreasing the bound function.
• Suppose a problem is specified by precondition P and post-condition Q.
• We identify and invariant property inv and the bound function bf.
• The bound function is an integer-value function of the program variables and is a measure of the
size of the problem to be solved.
✓It is guaranteed to be greater than zero when loop is executed.
✓A guarantee that the value of such a bound function is always decreased at each iteration
is a guarantee that the loop will terminate.
• The post condition Q is split into a termination condition, say done, and the invariant property
inv, in such a way that
inv done Q
• The invariant property is designed, in combination with the termination condition, by generalizing
the required post-condition.
• The termination condition is typically related to the bound function.
• The invariant should also guarantee that the value of the bound function is greater than zero
unless the loop has terminated. That is:
inv (bf > 0) done
• The invariant property is chosen so that it is easy to design an initialization statement, S, that
establishes the invariant property
{P} S {inv}
• The design is completed by constructing a loop body T that maintains the invariant whilst making
progress towards the termination condition.
{inv done bf = C} T {inv (done bf < C)}
• If the termination condition, done, the bound function, bf, the invariant, inv, and the loop body,
T, have all been constructed as above, then we have
{inv} do done → T od {Q}
• Moreover, if S has been constructed then
{P} S; do done → T od {Q}
Lecture 13
Constructing Loops:
• Pre-condition: P
• Post-condition: Q
• Loop-invariant: inv
• Bound-function: bf
• Termination-condition: done
• Initialization-statement: S
Some rules:
• inv done → Q
• inv → (done > 0) done
• {P} S {inv}
Loop body:
• {inv done bf = C}
T // loop statements
{inv (done bf < C}
i
• inv: Sum = X i
j = X / FIRST
Lecture 14
Dutch National Flag Problem:
• This the final arrangement that we want
Invariant
• Partition the array into four segments, three of the segments corresponding to the three colors
and containing values of that color only, and the fourth containing a mixture of colors.
• Final state: the mixed partition is empty.
Algorithm
• Progress requires reducing the size of the mixed segment by at least one in each iteration
• Examine the color of the ball at index w and put it in its right partition
• Three cases:
✓ white(w) → w := w + 1;
✓ red(w) → swap(r, w); r := r + 1; w := w + 1;
✓ blue(w) → swap(b - 1,w); b := b – 1;
• {0 N}
r:= 0; w := 0; b := N;
{Invariant:
0rwbN
(i: 0 i < r: red(i))
(i: r i < w: white(i))
(i: b i < N: blue(i))
Bound Function: b – w}
do w < b →
if white(w) → w := w + 1;
[] blue(w) → swap(b - 1,w); b := b – 1;
[] red(w) → swap(r, w); r := r + 1; w := w + 1;
fi
od
{ 0rwN
(i: 0 i < r: red(i))
(i: r i < w: white(i))
(i: w i < N: blue(i))
}
Lecture 15
Applications of Formal Techniques
Good Programs
• Reusability
• Reliability
• Defensive Programing
✓ Self-defeating
✓ Obtaining and guaranteeing reliability requires a more systematic approach
✓ Design by construct
Design by Construct
Lecture 16
Design by Construct
• Client – Server
• Obligation and Benefits
• Per-Condition
• Post-Condition
• Class Invariant
Class Invariants
• Pre-conditions and post-conditions describe the properties of individual methods.
• A class invariant is a global property of the instances of a class, which must be preserved by all
methods.
• A class invariant is an assertion in the class definition.
✓ E.g. a stack class might have the following class invariant:
count >= 0 and
count <= capacity and
stack_is_empty = (count = 0)
• An invariant for a class C must be satisfied by every instance of C at all “stable” times.
• “Stable” times are those in which the instance is in an observable state
Example
• A (mutable) class representing a range of real numbers:
public class RealRange {
private RealNumber min, max;
public RealRange(RealNumber min, RealNumber max) {
this.min = min;
this.max = max;
}
public void setRange(RealNumber newMin, RealNumber newMax) {
this.min = newMin;
this.max = newMax;
}
}
• invariant: min <= max
Invariants
• The invariants of all the parents of a class apply to the class itself.
• The parents’ invariants are added (logically “and”ed) to the class’s own invariants.
Pre-condition Post-condition
Replace the original pre-condition Replace the original post-condition
by one equal or weaker by one equal or stronger
The new version must accept all The new version must guarantee at
calls that were acceptable to the least as much as the original.
original.
It may, but does not have to, accept It may, but does not have to,
more cases. guarantee more.
e.g. replace pre: x<10 by pre: e.g. replace post: x<=10 by post:
x<=10 x=10
Summary
• Software reliability requires precise specifications which are honored by both the supplier and the
client.
• DbC uses assertions (pre and post conditions, invariants) as a contract between supplier and
client.
• DbC works equally well under inheritance.
Lecture 17
jContractor
Preconditions
• Naming convention
✓ methodName_Precondition
✓ e.g. for method X the precondition will be X_Precondition
✓ Returns a boolean
✓ It has to be protected
• A precondition method takes the same arguments as the method it is associated with and returns
a boolean.
class Stack implements Cloneable {
private Stack OLD;
private Vector implementation;
public Stack () { … }
public Stack (Object [ ] initialContents) { … }
public void push (Object o) { … }
public Object pop () { … }
public Object peek () { … }
public void clear () { … }
public int size () { … }
public Object clone () { … }
private int serachStack (Object o) { … }
}
Pre-condition Example
• Preconditions for the Stack push method can be introduced by adding the following method to
the Stack or Stack_CONTRACT class:
protected boolean push_Precondition (Object o) {
return o != null;
}
• Pre-condition for Constructor
Stack_Precondition (Object[] initialContents) {
Return(initialContents != null) && (IinitialContents.length > 0);
}
Some additional rules about preconditions
• Contract methods may not have preconditions.
• Native methods may not have preconditions.
• The main(String [] args) method may not have a precondition.
• The precondition for a static method must be static.
• The precondition for a non-static method must not be static.
• The precondition for a non-private method must be protected.
• The precondition for a private method must be private.
Post-condition Example
• An example postcondition method for the Stack push is shown below:
protected boolean
push_Postcondition (Object o, Void RESULT) {
return implementation.contains(o) &&
(size() == OLD.size() + 1);
}
Example of Invariant
• An example invariant for the Stack class:
protected boolean _Invariant () {
return size() >= 0;
}
Invariants
• An invariant method is similar to a post condition but does not take any arguments and is implicitly
associated with all public methods.
• It is evaluated at the beginning and end of every public method.
• It is the responsibility of the implementation class that the invariant checks succeed.
• jContractor instruments each method to enforce contract checking based on the following
operational view.
• A subclass method’s contract must:
✓Allow all input valid for its superclass method.
✓Ensure all guarantees of the superclass methods.
Interfaces
• Interfaces may also have contracts
• Contracts from interfaces are logically or-ed with the superclass and subclass contracts in the case
of preconditions.
• For post-conditions and invariants they are logically and-ed.
protected boolean
Stack_Postcondition (Object [] initialContents, Void RESULT) {
return size() == initialContents.length;
}
protected boolean
Stack_Postcondition (Object [] initialContents) {
return size() == (initialContents != null) && (initialContent.length > 0);
}
protected boolean
push_Precondition (Object o) {
return o != null;
}
protected boolean
push_postcondition(Object o, Void RESULT) {
return implementation.contains(o) && (size() == OLD.size() + 1);
}
private boolean
searchStack_Precondition (Object o) {
return != null;
}
• The separate contract class methods can reference the variables and methods of the class with
which it is associated.
• However, to get the compiler to accept the code, it is sometimes necessary to provide fake
variables and methods, such as implementation and searchStack(Object) in the contract class.
Lecture 18
BankAccount.java
Public Class BankAccount implements Cloneable {
Private int balance;
Public BankAccount() {
Supper();
balance = 0;
}
Public BankAccount (int amount) {
balance = amount;
}
Public void deposit (int amount) {
balance += amount;
}
Public void withdraw (int amount) {
balance -= amount;
}
Public int getBalance () {
return balance;
}
Protected boolean _Invariant () {
return (balance >= 0);
}
Protected boolean deposit_Precondition (int amount) {
Return (amount >=0);
}
} // end of the class
AccountUsage.java
Public Class AccountUsage {
Public static void main(String[] args) {
BankAccount myAccount = new BankAccount (1000);
System.out.println(“Starting Balance = ” + myAccount.getBalance() );
myAccount.deposit(500); // if the value is (-500), Violating the deposit_Precondtion
System.out.println(“Starting Balance = ” + myAccount.getBalance() );
myAccount.withdraw(1000);
System.out.println(“Starting Balance = ” + myAccount.getBalance() );
myAccount.withdraw(1000); // balance = -500, Violating the invariant condition
System.out.println(“Starting Balance = ” + myAccount.getBalance() );
}
} // end of the class
> java jContractor AccountUsage //cmd
MyStack.java
import java.util.vector;
class MyStack implements Cloneable {
Private Object [] elems;
Private int top, max;
Pulic MyStack() {
Super();
top = 0;
max = 10;
elems = new Object [max];
}
Public MyStack (int sz) {
max = sz;
top = 0;
elems = new Object [max];
}
Public void push (Object obj) {
try {
OLD = (MyStack) Clone();
}
Catch (Exception ex) {
}
elems [Top++] = obj; // add the elements that we passed
}
Public Object pop() {
Object temp;
temp = elems [--top];
return temp;
}
Public Boolean isFull() {
return top == max;
}
Public Boolean isEmpty() {
return top == 0;
}
Public int size() {
return top;
}
}
StackUsage.java
Public Class StackUsage {
Public static void main(String[] args) {
MyStack S = new MyStack(2); // can push at most two elements
// S.pop();
System.out.println(“push”);
S.push (new integer (1));
System.out.println(“pop”);
S.pop();
System.out.println(“push”);
S.push(new integer (23));
//S.pop();
System.out.println(“push”);
S.push(new integer (24));
System.out.println(“push”);
S.push(new integer (0)); // going out of bound
}
}
Lecture 19
Object Constraint Language (OCL)
• For example, the contextual type for all expressions in above Figure is the class LoyaltyAccount.
The precondition (pre: i>0) has as context the operation earn. When it is evaluated, the contextual
instance is the instance of LoyaltyAccount for which the operation has been called. The initial
value (init: 0) has as context the attribute points. The contextual instance will be the instance of
LoyaltyAccount that is newly created.
Invariants on attributes
• The simplest constraint is an invariant on an attribute.
• Suppose our model contains a class Customer with an attribute age, then the following constraint
restricts the value of the attribute:
context Customer inv:
age >= 18
Invariants on associations
• One may also put constraints on associated objects.
• Suppose in our model contains the class Customer has an association to class Salesperson, with
role name salesrep and multiplicity 1, then the following constraint restricts the value of the
attribute knowledgelevel of the associated instance of Salesperson:
context Customer inv:
Salesrep.knowledgelevel >= 5
Collections of objects
• In most of the cases the multiplicity of an association is not 1, but more than 1.
• Evaluating a constraint in these cases will result in a collection of instances of the associated class.
• Constraints can be put on either the collection itself, e.g. limiting the size, or on the elements of
the collection.
• Suppose in our model the association between Salesperson and Customer has role name clients
and multiplicity 1..* on the side of the Customer class, then we might restrict this relationship by
the following constraint.
context Salesperson inv:
clients->size() <= 100 and
clients->forAll(c: Customer | c.age >= 40)
Derivation Rules
• Models often define derived attributes and associations.
• A derived element does not stand alone.
• The value of a derived element must always be determined from other (base) values in the model.
• Omitting the way to derive the element value results in an incomplete model.
• Using OCL, the derivation can be expressed in a derivation rule.
• In the following example, the value of a derived element usedServices is defined to be all services
that have generated transactions on the account:
context LoyaltyAccount::usedServices : Set(Services)
derive: transactions.service->asSet()
Initial Values
• In the model information, the initial value of an attribute or association role can be specified by
an OCL expression.
• In the following examples, the initial value for the attribute points is 0, and for the association end
transactions, it is an empty set:
context LoyaltyAccount::points : Integer
init: 0
context LoyaltyAccount::transactions : Set(Transaction)
init: Set{}
• Note the difference between an initial value and a derivation rule.
✓ A derivation rule states an invariant:
✓ The derived element should always have the same value that the rule expresses.
✓ An initial value, however, must hold only at the moment when the contextual instance is
created. After that moment, the attribute may have a different value at any point in time.
Broken constraints
• Evaluating a constraint does not change any values in the system.
• A constraint states "this should be so".
• If for a certain object the constraint is not true, in other words, it is broken, then the only thing
we can conclude is that the object is not correct, it does not conform to our specification.
• Whether this is a fatal error or a minor mistake, and what should be done to correct the situation
is not expressed in the OCL.
Lecture 20
• An association between class Flight and class Person, indicating that a certain group of persons
are the passengers on a flight, will have multiplicity many (0..*) on the side of the Person class.
• This means that the number of passengers is unlimited.
• In reality, the number of passengers will be restricted to the number of seats on the airplane that
is associated with the flight.
• It is impossible to express this restriction in the diagram.
• In this example, the correct way to specify the multiplicity is to add to the diagram the following
OCL constraint:
context Flight
inv: passengers->size() <= plane.numberOfSeats
• A person may have a mortgage on a house only if that house is owned by him- or herself;
✓One cannot obtain a mortgage on the house of one's neighbor or friend.
• The start date for any mortgage must be before the end date.
• The ID card number of all persons must be unique.
• A new mortgage will be allowed only when the person's income is sufficient.
• A new mortgage will be allowed only when the counter-value of the house is sufficient.
context Mortgage
inv: security.owner = borrower
context Mortgage
inv: startDate < endDate
context Person
inv: Person::allInstances()->isUnique(socSecNr)
Constraints on Classifiers
• Each OCL expression must have some sense of context that an expression relates to.
• Often the context can be determined by where the expression is written.
• For example, you can link a constraint to an element using a note.
• You can refer to an instance of the context classifier using the keyword self.
• For example, if you had a constraint on Student that their GPA must always be higher than 2.0,
you can attach an OCL expression to Student using a note and refer to the GPA as follows:
self.GPA >= 2.0
Constraints
• if you had a constraint on Student that their GPA must always be higher than 2.0, you can attach
an OCL expression to Student using a note to refer to the GPA as follows:
self.GPA > 2.0
• Note:
✓If you want to allow a GPA of less than 2.0 and send out a letter to the student’s parents in
the event such a low GPA is achieved, you would model such behavior using a UML
diagram such as an activity or interaction diagram.
• The following invariant on Course ensures that the instructor is being paid:
self.instructor.salary > 0.00
Business Rule
• The following expressions verify that a student’s tuition was paid before registering for a course
and that the operation registerStudent returned true:
context Course::registerStudent(s: Student): boolean
pre: s.tuitionPaid = true
post: result = true
• We can name pre and post conditions by placing a label after the pre or post keywords:
context Course::registerStudent(s: Student): boolean
pre hasPaidTuition: s.tuitionPaid = true
post studentHasRegistered: result = true
• Postconditions can use the @pre keyword to refer to the value of some element before an
operation executes.
• The following expression ensures that a student was registered and the number of students in the
course has increased by 1.
context Course::registerStudent(s: Student): boolean
pre hasPaidTuition: s.tuitionPaid = true
post studentHasRegistered: result = true AND
self.students = self.students@pre + 1
• We may specify the results of a query operation using the keyword body.
• Because OCL doesn’t have syntax for program flow, we are limited to relatively simple
expressions.
• The following expressions indicate that the honors students are students with GPAs higher than
3.5.
context Course::getHonorsStudents(s: Student): boolean
body: self.students->select(GPA > 3.5)
Conditionals
• OCL supports basic Boolean expression evaluation using the if-then-else-endif keywords.
• The conditional are used only to determine which expression is evaluated; they can’t be used to
influence the underlying system or to affect program flow.
• The following invariant enforces that a student’s year of graduation is valid only if she has paid
her tuition:
context Student inv:
if tuitionPaid = true then
yearOfGraduation = 2005
else
yearOfGraduation = 0000
endif
• OCL supports several complex constructs you can use to make your constraints more expressive
and easier to write.
• You can break complex expressions into reusable pieces (within the same expression) by using
the let and in keywords to declare a variable.
• You declare a variable by giving it a name, followed by a colon (:), its type, an expression for its
value, and the in keyword.
• The following example declares an expression that ensures a teacher of a high-level course has
an appropriate salary:
context Course inv:
let salary : float = self.instructor.salary in
if self.courseLevel > 4000 then
salary > 100000.00
else
salary < 100000.00
endif
Lecture 21
Algebraic Specification
The Structure of an Algebraic Specification
• Constructors
✓ Change the state of an object, i.e. CREATE, ASSIGN (in above example)
• Inspectors
✓ Do not change the state of an object, i.e. FIRST, LAST, EVAL (in above example)
• Rule of thumb for writing axioms
✓ Write axioms for inspectors in term of constructors
• If m Constructors and n inspectors then
✓ Total number of axioms = m * n
Specification of Array
Sort Array
Imports INTEGER
Lecture 22
Specification of Stack
sort Stack
Create () → Stack
Push (Stack, Elem) → Stack
POP (Stack) → Stack
Top (Stack) → Elem
IsEmpty (Stack) → Boolean
Specification of List
sort List
Imports INTEGER
• LENGTH(CREATE()) = 0
• LENGTH(CONS(L, e)) = LENGTH(L) + 1
• LENGTH(TAIL(L)) = If L == CREATE() return 0 Else return LENGTH(L) – 1
• HEAD(CREATE() = Undefined
• HEAD(CONS(L, e) = If L==CREATE return e Else return HEAD(L)
• HEAD(TAIL(L)=?
✓ We will write axiom for TAIL in term of CREATE and CONS
• TAIL(CREATE()) = CREATE
• TAIL(CONS(L, e)) = CONS(TAIL(L), e)
Lecture 23
Specification of Binary Search Tree
Operation Description
Create Creates an empty tree
Add(Binary_tree, Elem) Adds a node to the binary tree using the usual ordering principles.
Left(Binary_tree) Returns the left sub-tree of the top of the tree
Data(Binary_tree) Returns the value of the data element at the top of the tree
Right(Binary_tree) Returns the right sub-tree of the top of the tree
IsEmpty(Binary_tree) Returns true of the tree does not contain any elements
Contains(Binary_tree, Elem) Returns true of the tree contains the given element
Specification of Coord
COORD
sort Coord
imports INTEGER, BOOLEAN
This specification defines a sort called Coord representing a Cartesian coordinate. The
operations defined on Coord are X and Y which evaluate the X and Y attributes of an entity of
this sort and Eq which compares two entities of sort Coord for equality.
X (Create(x,y)) = x
Y(Create(x,y) = y
Eq (Create(x1, y1), Create(x2, y2)) = ((x1 == x2) and (y1 == y2))
CURSOR
sort Cursor
imports INTEGER, COORD, BITMAP
Lecture 24
New_List Specification
Operation Description
Create Brings a list into existence
Cons(New_list, Elem) Adds an element to the end of the list
Add(New_list, Elem) Adds an element to the front of the list
Head(New_List) Returns the first element in the list
Tail(New_list) Return the list with the first element removed
Member(New_list, Elem) Returns true if element is present in the list
Length(New_list) Returns the number of elements in the list
Queue Specification
Operation Description
Create Brings a queue into existence
Cons(Queue, Elem) Adds an element to the end of the queue
Head (Queue) Returns the element at the front of the queue
Tail (Queue) Returns the queue minus its front element
Length (Queue) Returns the number of elements in the queue
Get (Queue) Returns a tuple composed of the element at the head of the queue
and the queue with the front element removed
This specification defines a queue which is first-in, first-out data structure. It can therefore be
specified as a LIST where the insert operation adds a member to the end of the queue
Error Specification
• Error may be tackled in three ways
✓ Use a special distinguished constant operation (Undefined) which conforms to the type
of the returned value.
✓ Define operation evaluation to be a tuple, where an element indicates success or failure.
✓ Include a special failure section in the specification
sort List
imports INTEGER
Create → List
Cons (List, Elem) → List
Tail (List) → List
Head (List) → Elem
Length (List) → Integer
LIST ( Elem )
sort List
imports INTEGER
Create → List
Cons (List, Elem) → List
Tail (List) → List
Head (List) → Elem
Length (List) → Integer
exceptions
Length(L) = 0 failure (Head(L))
BOOLEAN
BOOLEAN
sort Bool
constants true: Bool;
false: Bool
not(not(a)) =a
or(a,or(b, c)) = or(or(a,b),c)
or(a, b) = or(b,a)
not(false) = true
and(a, b) = not(or(not(a), not(b))
impl(a, b) = or(not(a), b)
equal(a, b) = and(impl(a,b), impl(b,a))
or(a, true) = true
or(a, false) =a
Lecture 25
sort List
uses BOOLEAN
constants
0 : → List // generates an empty list
undef : → List
first(0) = undef
rest(0) = undef
first(undef) = undef
rest(undef) = undef
first(a.b) =a
rest(a.b) =b
atEnd(0) = true
atEnd(undef) = false
atEnd(a.b) = false
a.b == c.d = (a==c) and (b==d)
0 == 0 = true
a.b == 0 = false
(a == b) = (b == a)
e memberOf undef = false
e memberOf 0 = false
e memberOf a.b = (e == a) or (e memberOf b)
Lecture 26
Pair Specification
sort Pair
constants undef : Pair
uses BOOLEAN
first : Pair → A
second : Pair → B
pair : A, B → Pair
- == - : Pair, Pair → Bool
first(pair(x, y)) =x
second(pair(x, y)) =y
pair(undef, undef) = undef
pair(x, y) == pair(u, v) = (x == u) and (y == v)
Quad Specification
sort Quad
constants undef : Quad
uses BOOLEAN
first : Quad → A
second : Quad → B
third : Quad → C
fourth : Quad → D
Quad : A, B, C, D → Quad
- == - : Quad, Quad → Bool
BIMAP
BIMAP (src with { -==- : src, src → Bool},
targ1 with {-==- : targ1, targ1 → Bool; undef :→ targ1},
targ2 with {-==- : targ2, targ2 → Bool; undef :→ targ2})
sort Bimap
uses BOOLEAN
pair1 = PAIR(src, targ1), list1 = LIST(pair1)
pair2 = PAIR(src, targ2), list2 = LIST(pair2)
constants
undef : Bimap
Lecture 27
File System
listregions(s) = list1(s)
listfiles(s, rid) = list1(retrieve2(s, rid))
listdocs(s, rid, fid) = list1(retrieve2(retrieve2(s, rid), fid))
addregion(s, aheader) = <mkregionid(s), aheader, undef> * s
addfile(s, rid, aheader) = s[rid <mkfileid(retrieve2(s, rid)), aheader, undef> * retrieve2(s, rid))]2
Lecture 28
Larch Family of Languages
Sub-system Interfaces
Example – Table
Table: trait
includes Integer
introduces
new: → Tab
add: Tab, Ind, Val → Tab
- -: Ind, Tab → Bool
lookup: Tab, Ind → Val
size: Tab → Int
Lecture 29
uses TaskQueue;
mutable type queue;
immutable type task;
task *getTask(queue q) {
modifies q;
ensures
if isEmpty(q^)
then result = NIL unchanged(q)
else (*resylt)’ = first(q^) q’ = tail(q^);
}
TaskQueue: trait
includes Nat
task tuple of id: Nat, important: Bool
introduces
new: → queue
- ┤-: task, queue → queue
isEmpty, hasImportant: queue → Bool
first: queue → task
tail: queue → queue
asserts
queue generated by new, ┤
t: task, q: queue
isEmpty(new);
isEmpty(t ┤ q);
hasImportant(new);
• Based on the information in this LSL specification, one can deduce that the task pointed to by the
result of getTask is the most recently inserted important task, if such a task exists. Otherwise it is
the most recently inserted task.
Specification checker
• While some Larch specifications can be executed, most of them cannot.
• To make it possible to validate specifications before implementing or executing them, Larch
permits specifiers to make assertions about specifications that are intended to be redundant.
• These assertions can be checked mechanically.
• Several tools that assist specifiers in checking these assertions as they debug specifications are
already in use.
Example - Table
Table: trait
includes Integer
introduces
new: → Tab
add: Tab, Ind, Val → Tab
- - : Ind, Tab → Bool
lookup: Tab, Ind → Val
size: Tab → Int
table table_create(void) {
ensures result’ = new fresh(result);
}
Lecture 30
Interface specifications
• At the core of each Larch interface language is a model of the state manipulated by the associated
programming language.
• Each specification must provide the information needed to use an interface and to write programs
that implement it.
States
• States are mappings from locs (abstract storage locations, also known as objects) to values.
• Each variable identifier has a type and is associated with a loc of that type.
• The major kinds of values that can be stored in locs are:
✓ Basic values: These are mathematical constants, like the integer 3 and the letter A. Such
values are independent of the state of any computation.
✓ Exposed types: These are data structures that are fully described by the type constructors
of the programming language (e.g., C’s int * or Modula-3’s ARRAY [1..10] OF INTEGER).
The representation is visible to, and may be relied on by, clients.
✓ Abstract types: data types are best thought of as collections of related operations on
collections of related values. Abstract types are used to hide representation information
from clients.
• Each loc’s type defines the kind of values it can map to in any state.
• Just as each loc has a unique type, each LSL term has a unique sort.
• To connect the two tiers in a Larch specification, there is a mapping from interface language types
(including abstract types) to LSL sorts.
• Each type of basic value, exposed type, and abstract type is based on an LSL sort.
• Interface specifications are written using types and values.
• Properties of these values are defined in LSL, using operators on the corresponding sorts.
• For each interface language, a standard LSL trait defines operators that can be applied to values
of the sorts that the programming language’s basic types and other exposed types are based on.
Procedure Specification
• A specification consists of a procedure header (declaring the types of its arguments and results)
followed by a body of the form:
requires reqP
modifies modList
ensures ensP
• They relate two states, the state when the procedure is called, the pre-state, and the state when
it terminates, the post-state.
• A requires clause refers only to values in the pre-state.
• An ensures clause may also refer to values in the post-state.
• A modifies clause says what locs a procedure is allowed to change (its target list).
✓ It says that the procedure must not change the value of any locs visible to the client except
for those in the target list.
Nat: Trait
includes AC(+, Nat)
introduces
0: → Nat
s: Nat → Nat
- < -: Nat, Nat → Bool
asserts
Nat generated by 0, s
i, j, k: Nat
i + 0 == i;
i + s(j) == s(i + j);
(i < 0);
0 < s(i);
s(i) < s(j) == i < j
implies i, j, k: Nat
i < j i < (j + k)
• The declare commands introduce the variables and operators in the LSL specification.
• The assert commands supply the LSL axioms relating the operators; the Nat generated by
assertion provides an induction scheme for Nat.
Lecture 31
OBJ Family of Specification
• first-order functional language
• based on equational logic
• parameterized programming
• supports declarative style that facilitates verification and allows OBJ to be used as a theorem-
prover
• can include LISP code
• provides flexible environment – convenient for specification and rapid prototyping
Equational Calculus
• Calculus of replacing terms by equal terms.
• Equational calculus derives (proves) a term equation from a conditional-equational axiom
set.
• The deduction rules in this calculus are:
✓ Reflexivity: Any term is provably equal to itself (t = t).
✓ Transitivity: If t1 is provably equal to t2 and t2 is provably equal to t3, then t1 is
provably equal to t3.
✓ Symmetry: If t1 is provably equal to t2, then t2 is provably equal to t1.
✓ Congruence: If t1 is provably equal to t2, then any two terms are provably equal
which consist of some context built around t1 and t2.
• For parameterized objects, the name is a simple identifier, such as STACK-OF-INT, PHRASE, or
OBJ14.
• Parameterized objects have an interface specification in place of a simple name.
Sort
• declared with the syntax
sorts <SortIDList>
sorts Nat Int Rat .
sort <SortID>
sort Int .
Subsort Example
obj BITS1 is
sorts BIT Bits .
subsorts Bit < Bits .
ops 0 1 : -> Bits .
ops -- : Bit Bits -> Bits .
endo
Term Evaluation
• reduce [in <ModExp> :] <Term>
• Reduce command is executed by matching the given term with the left sides of the equations and
then replacing the matched subterm with the corresponding right side.
• This is called application of rewrite rules
• The operational semantics for a conditional rewrite rule is as follows:
✓ first find a match for the left side
✓ then evaluate the condition after substituting the binding determined by the match
✓ if it evaluates to true then do the replacement by the right side, again using the values for
the variables determined by the match.
• Evaluating the condition could require non-trivial further rewriting the cases.
Lecture 32
• An alternative approach to exceptions involves introducing supersorts that contain specific error
messages for exceptional conditions.
• obj STACK-OF-NAT is
sorts Stack Stack? Nat? .
subsort Stack < Stack? .
protecting NAT .
subsort Nat < Nat? .
op empty : -> Stack .
op push : Nat Stack -> Stack .
• This example illustrates a striking advantage of using a logical language; every computation is a
proof and interesting theorem can be proved by applying the right programs to be right data.
• Even if the given equations do not define a decision procedure for a given theory, so long as they
are all correct with respect to the theory, then the result of the reduction is correct.
• -- sort [ Nat ]
-- operations
op 0 : -> Nat .
op s_ : Nat -> Nat .
• Nat = { 0 , s 0, s s 0, s s s 0, … ,
0 + 0, 0 + (s 0) , 0 + (s s 0) , 0 + (s s s 0), … ,
(s 0) + 0, (s 0) + (s 0), (s 0) + (s s 0), … ,
(s s 0) + 0, (s s 0) + (s 0), (s s 0) + (s s 0), …,
…
0 + (0 + 0), 0 + (0 + (s 0)), …
…
}
• mod! NAT+ {
-- sort [ Nat ]
-- operations
op 0 : -> Nat .
op s_ : Nat -> Nat .
op _+_ : Nat Nat -> Nat .
-- equations
eq N: Nat + 0 = N .
eq N: Nat + (s M: Nat) = s (N + M) .
}
Lecture 33
Model Base Specification
Example – Incubator
• The temperature needs to be carefully controlled and monitored in order to provide the correct
conditions for a particular biological experiment to be undertaken.
• The temperature of the incubator increments or decrements in response to instructions and each
time a change of one degree has been achieved, the software is informed of the change, which it
duly records.
• Safety requirements dictate that the IncubatorMonitor
temperature of the incubator must temp: integer
never be allowed to rise above 10 C, nor
increment()
fall below -10 C.
decrement()
• UML Specifications
getTemp(): int
State Definition
• state IncubatorMonitor of
temp : Z
end
• increment()
ext wr temp: Z
pre temp < 10
post temp = temp + 1
• deccrement()
ext wr temp: Z
pre temp > -10
post temp = temp − 1
• getTemp() currentTemp: Z
ext rd temp: Z
pre true
post temp = currentTemp
Lecture 34
Z Specification
The Structure of Z Scheme
A Birthday Book
Lecture 35
Find the person with birthday with a given date and generate card
Success
Lecture 36
An Insulin Pump
Schema invariant
• Each Z schema has an invariant part which defines conditions that are always true
• For the insulin pump schema, it is always true that
✓ The dose must be less than or equal to the capacity of the insulin reservoir
✓ No single dose may be more than 5 units of insulin and the total dose delivered in a time
period must not exceed 50 units of insulin. This is a safety constraint.
✓ display1! shows the status of the insulin reservoir.
Output schemas
• The output schemas model the system displays and the alarm that indicates some potentially
dangerous condition
• The output displays show the dose computed and a warning message
• The alarm is activated if blood sugar is very low - this indicates that the user should eat something
to increase their blood sugar level
Schema consistency
• It is important that schemas are consistent. Inconsistency suggests a problem with the system
requirements
• The INSULIN_PUMP schema and the DISPLAY are inconsistent
✓ display1! shows a warning message about the insulin reservoir (INSULIN_PUMP)
✓ display1! Shows the state of the blood sugar (DISPLAY)
• This must be resolved before implementation of the system
Lecture 37
Refinement
• Refine a formal specification by adding more information
• Consistency and correctness
• The refinement leads us towards implementation
• Refinement relation
✓ Data type B is called a refined of A iff every interaction with B could have been an
interaction with A, A⊑B
• Proper Refinement
✓ It is quite possible that A ⊑ B but B⋢A
✓ This will be the case when description B has resolved some of the uncertainty present in A
✓ The effect of at least one of the operations is now more precisely defined.
• Refinement Ordering
✓ If B is a refinement of A, and C is a refined of B, then C is also a refinement of A.
• Example
✓ If there is more than one available resource then this specification is non-deterministic
✓ It is also partial – does not state what is to be done if there are no free resources
Lecture 38
Totalization
• To define refinement for partial relations, we consider their totalised forms:
where X = X ⋃ { ⊥} Y = Y ⋃ { ⊥}
Example:
Refinement
• Having decided upon totalization using ⊥, we may derive the conditions for one partial relation
to be a correct refinement of another.
•
• If σ and ρ are two partial relations of the same type then σ refines ρ precisely when is a subset
•
of .
• This is true if and only if the domain of σ is at least as big as that of ρ and σ agrees with ρ on dom
ρ.
• Provided some additional information by extending the domain and removed some non-
determinism
Not a Refinement
Using Totalization
•
• If σ and ρ are two partial relations of the same type then σ refines ρ precisely when is a subset
•
of .
Example
• We may corrupt a bit – an element of set
{0, 1} – by changing its value.
• The relation corruptsto associates two sequences of bits if the second is no longer than the first,
and no two adjacent bits have been corrupted.
• For example,
<1, 0, 0, 0, 1, 1> corruptsto <1, 0, 1, 0, 0, 1>
<1, 1, 0, 1, 1, 1, 0, 0> corruptsto <0, 1, 0, 0, 1>
• The relation changesto associates two sequences of bits if the second is no longer than the first,
and every bit with an odd index has been corrupted.
• For example,
<1, 1, 0, 1, 1, 1, 0, 0> changesto <0, 1, 1, 1, 0>
<1, 0, 0, 0, 1, 1> changesto <0, 0, 1, 0, 0, 1>
Lecture 39
Program Refinement
• A sequence of operations on a data type.
• An abstract data type X is a tuple:
(X, xi, xf, { i: I ∙ xoi})
D = (D, di, df, {do1, do2})
di ; do1 ; do2 ; df
P(X) = xi ; xo1; xo2 ; xf Parameters
• If two abstract data types A and C use the same index set for their operations, then they will
support the same selection of programs: for every program P(A), there must be a corresponding
program P(C). What is more, any two programs P(A) and P(C) will be comparable, since they have
the same source and target sets.
• We may find that the effect of P(C) is defined whenever the effect of P(A) is defined.
• We may also find that P(C) resolves some of the non-determinism in P(A).
• If this is the case for every choice of P, then it is reasonable to say that C is worthy replacement
of A.
Totalisation
• Since xi and xf are total, the process of totalisation does nothing but augment each of them with
the set of pairs {⊥} and X ⊥
Refinement
Example
A == seq Bit X Action X seq Bit
C == seq Bit X Action X seq Bit
Action ::= yes | no
• Initially, the whole of the input sequence waits to be consumed, the output sequence is empty,
the next bit may be corrupted.
• Finalisation
• Finally, the remaining input as well as the action component are discarded. The accumulated
output is all that remains.
Reduces to: c0 a 0
Lifting
• Augment to allow undefined-ness
• To ensure that the definition is applicable to data types with partial operations.
• Not necessary to totalize
Example
Forward Simulation
Lecture 40
Specification of OS Components using Z-Specification
• Our system will deal with up to n processes, where n is a natural number.
|n:N
• Each process will be associated with a process identifier, or pid.
PId == 1 .. N
nullPId == 0 no process has this value
OptPId == PId ⋃ {nullPId}
Operations
• Create a process, adding it to the set of ready process
• Dispatch one of the ready processes to the processor
• Timeout a process, removing it from the processor and ret
• Block a process, removing it from the processor and adding it to the set of blocked processes
• Wake up a blocked process, moving it into the set of ready processes
• Destroy a process
Design
• our program will use a simple data structure: an array and a few counters
• our use of this data structure can be modeled using chains:
• finite injections from PId to PId
• unique start and a unique end
Operations
• push an element onto the end of a chain
• pop an element from the front of a chain
• delete an element from a chain
Lecture 41
Chain
• Delete from the start
• Delete from the end
• Delete from the middle
• If this element is the first element in the chain, then the delete operation has an effect that is
similar to Pop:
• The previous element which is identified as links~ p? will be mapped to the next element which
is identified as links p?.
• In this schema, p? itself is removed using domain restriction
Design
• A design for the scheduler based upon the chain data type.
• Our design will involve three chains: one each for the sets of ready, blocked, and free processes.
• The initial states of the ready and blocked chains are defined in terms of the initialization
schema ChainInit
• We will require push and pop operations on the ready and free chains, and push and delete
operations on the blocked chain.
• We may define these by renaming the components of the corresponding operations on Chain:
• The state of the concrete scheduler comprises the three chains, together with an optional
current process
• It is also useful to identify the working space used: the component chainstore is the union of the
three chain functions, plus an optional map to nullPId.
• Initially, there is no current process, and all chains are empty:
• When a process is dispatched to the processor, the ready chain is popped; the result becomes
the current process.
• When a process is created, an identifier is popped o the free chain and pushed onto the ready
chain.
Lecture 42
Petri Nets – An Introduction
Concurrency
• Independent inputs permit “concurrent” firing of transitions
Conflict
• Overlapping inputs put transitions in conflict
Modeling FSMs
Bounded Buffers
1 2
3 4
5 6
7 8
9 10
Lecture 43
Behavioral Properties
• Reachability
✓ “Can we reach one particular state from another?”
• Boundedness
✓ “Will a storage place overflow?”
• Liveness
✓ “Will the system die in a particular state?”
Lecture 44
Reachability Example with Petri Net
Another Example
Zero-testing Nets
Initial marking
Lecture 45
Activities of Formal Methods
• The main activities of Formal methods are
✓ Writing a formal specification
✓ Proving properties about the specification
✓ Constructing a program by mathematically manipulating the specification
✓ Verifying a program by mathematical argument
Key points
• Formal system specification complements informal specification techniques
• Formal specifications are precise and unambiguous. They remove areas of doubt in a specification
• Formal specifications force an analysis of the system requirements at an early stage. That helps
us in correcting errors at this stage is cheaper than modifying a delivered system
• Formal specification techniques are most applicable in the development of critical systems and
standards.
• Algebraic techniques are suited to interface specification where the interface is defined as a set
of object classes
• Model-based techniques model the system using sets and functions. This simplifies some types of
behavioural specification