Top Banner
ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts
31

ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

Dec 13, 2015

Download

Documents

Ryan Jester
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

ANNATALA WOLF – 2231 LECTURE 1

Reading Mathematical Contracts

Page 2: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

Contracts (specs) ≠ Code!

It’s easy to get contracts and code confused because we use a strict language for both of them. In contracts, we use mathematical notation. In code, we use Java syntax and grammar.

Often, the two coincide. For example, -18 or false mean the same thing in both contracts and code.

But sometimes, the two do not coincide! In contracts, { -1/2 } refers to the set { -½ }. In code, { -1/2 } is likely an array initialization statement,

which produces this string of integer: < 0 >. Notice that even the value of the string’s entry is different (think about why).

Page 3: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

Specifications vs. Code

Since our specs are written in a formal and precise manner, you might wonder how they differ from code. In fact, they are another form of code.

The difference is that specifications describe what code does, not how it does it. Specifications can be more abstract than code.

Consider the relational behavior of the removeAny() spec for Set.

One can even write a specification for a problem that can’t be solved at all, like the halting problem.

Page 4: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

Why formal (mathematical) contracts?

Formal contracts are the only thing we use in this course that you won’t see anytime soon in industry. Computer scientists are

expected to read math, so the formal specifications we require are appropriate for the course.

The good news is that, unlike English, math is totally unambiguous.

The bad news? You have to learn how to read this shit.

Page 5: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

Our Contracts (Review)

Preconditions are given in our custom @requires annotations, and postconditions are given in our custom @ensures annotations.

The client (user) of an operation is told only one thing: if they meet the precondition, the operation guarantees the postcondition will hold. If not, any behavior is permitted, including non-termination.

The implementer should not check preconditions, because the contract does not need to be fulfilled. We use asserts to help the developer during design (they are removed from the final product).

Page 6: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

Who does what?

In design by contract (DBC), remember:

Failing to follow any one of these directives shows you don’t understand DBC, and will cost you points.

Client Implementer

precondition(@requires) must check

should assume

postcondition(@ensures)

should assume

mustmake true

Page 7: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

Mathematical Types

Every object or primitive type we use is modeled by an underlying mathematical type: Boolean: either true or false integer: a positive or negative whole number character: a single Unicode character, like ‘@’ or ‘\t’ set: an unordered collection of items

(sets have no order and don’t maintain/understand duplicates)

string: a totally-ordered collection of items (not Java String) tuple: a group of different things that can be distinguished

(like the columns of a database)

Page 8: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

Examples of Mathematical Models

String: string of characterNaturalNumber: non-negative integerQueue<T>: string of TStack<T>: string of TSequence<T>: string of TSet<T>: finite set of TMap<K, V>: partial function of K

V (you can think of this as a finite set of pairs (i.e. 2-

tuples) (K,V), where each K value is associated with at most one V)

Page 9: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

Use correct math notation!

The mathematical notation we use is very precise.

If you don’t usethe correct notationon exams or otherassignments, youcan lose significantpoints – so makesure you know howto do this.

Page 10: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

Mathematical Notation

Sets use curly braces: {a, b, …}. The set with no items, { }, is called the empty set.

Strings use angle brackets: <a, b, …>. The string with no items, < >, is called the empty string.

A string or set with a single element, such as <x>, is not the same as the element x by itself.

Tuples use parentheses: (a, b, …). A tuple may contain different types. Order identifies which item is which, but the order chosen is arbitrary. A 2-tuple is often called a pair, a 3-tuple a triple, etc.

Page 11: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

More Symbols

The * symbol means concatenation when it appears between two strings. It means multiply when it appears between two integers. There is never ambiguity, because we always specify types.

The entries of a string are all the unique bits of the string, taken as a set. (Remove order and forget duplicates, in other words.)

A permutation of a string means a string with all the same elements, in possibly a different order.

A string of character (like <‘H’, ‘i’, ‘!’>) can be abbreviated using double quotes (like “Hi!”).

Page 12: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

One Last Symbol

The parallel lines |x| can mean three different things, depending on context: x is a set implies |x| is the size of the set x is a string implies |x| is the length of the string x is a numeric type implies |x| is the absolute value

It may seem like “size of a set” and “length of a string” are the same thing, but mathematically the concepts are different. The idea is very similar for finite sets and strings, though: it just counts the number of items (though don’t forget: duplicates are ignored in sets, but differentiated in strings).

Page 13: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

Understanding Quantifiers

TODO (will explain quantification in detail here, probably with two or three slides)

Page 14: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

Reading Specifications

/** * @replaces s2 * @requires * |s1| > 0 * @ensures * |s2| = |s1| - 1 and * for all i, j: integer, a, b: string of integer * where (s1 = a * <i> * <j> * b) * (there exists c, d: string of integer * (|c| = |a| and s2 = c * <(i+j)/2> * d)) */

public static void smooth(Sequence<Integer> s1, Sequence<Integer> s2) {...}

Page 15: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

Breaking The Specification Down

Sequence is modeled by string of T (in this case Integer), so s1 and s2 are type “string of integer” in this specification.

|s2| = |s1| - 1 and

for all i, j: integer, a, b: string of integer where (s1 = a * <i> * <j> * b) (there exists c, d: string of integer (|c| = |a| and (s2 = c * <(i+j)/2> * d))

Part 1

Part 2

Page 16: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

The easy part

@requires |s1| > 0 @ensures |s2| = |s1| - 1 ...This tells us s2 will be one item shorter than s1.

It makes sense because s1 can’t be empty to start.

Clearly, if s1 has one item in it, s2 must become the empty string of integer. But for longer s1 values, we need more information.

Since s2 is replaces-mode, its incoming value should not affect the result. The values that appear in s2 must come from s1 or from the contract itself.

Page 17: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

Quantified Strings

When we model strings of items, frequently we will want to talk about what happens throughout the entire string. In this case, we are talking about all possible ways that you can arrange s1 so that there is an <i> next to a <j>. In other words, “consider all consecutive pairs of integers i and

j, in s1”.

The strings a and b are merely placeholders. It doesn’t matter what they contain—they’re just there so we can say “let’s talk about each consecutive pair of integers in s1”.

for all i, j: integer, a, b: string of integer where (s1 = a * <i> * <j> * b) ...

Page 18: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

“Vacuously True”

If no integers and strings canfit the for all quantifier, then there are no cases for us to test. This makes the statement vacuously true.

This could only happen when |s1| < 2. But we already know what happens when |s1| = 1, and |s1| can’t be 0, so this shouldn’t cause a problem.

for all i, j: integer, a, b: string of integer where (s1 = a * <i> * <j> * b) ...

we need at least two integers in s1 for this case to even occur

Page 19: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

Quantifiers: There Exists

With “there exists”, we’re making some assertion about the state of an object. Here, we say what part of the value of s2 must be, based on s1.

there exists c, d: string of integer(|c| = |a| and s2 = c * <(i+j)/2> * d)

this part tells us what we should find in s2

this part tells us where it should be found in s2

Page 20: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

What are the values?

The values in s2 are just the smoothed (averaged) values of each pair of integers. This is why s2 is one shorter than s1. For example, if there are six integers in s1, there are only five consecutive pairs.

s2 = c * <(i+j)/2> * d

each integer in s2 is the average of two consecutive

integers from s1

Page 21: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

Where do the values go?

By adding some information about those placeholder string variables, we can describe exactly how the two strings match up.

Can you see how they line up?(Hint: Just ignore b and d!) s1 = a * <i> * <j> * b s2 = c * <(i+j)/2> * d |c| = |a|

Page 22: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

The Meaning of smooth( )

This procedure averages the consecutive values of s1, and produces s2 with the averaged values in the same order in which the pairs appeared in s1.

This spec is a good example because it’s just about the hardest thing you will be expected to read and interpret on an exam. Don’t let the quantifiers scare you. Most of the “string” variables we create with quantifiers are only there as placeholders, so we can talk about multiple cases at the same time.

Page 23: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

Recursively-Defined Specifications

/** updates seq requires (|seq| mod 2) = 0 ensures seq = SWITCH(#seq)

math_function SWITCH(string of integer s): string of integer if |s| = 0 then SWITCH(s) = empty string else if |s| = 2 then there exists a, b: integer where (s = <a> * <b> and SWITCH = <b> * <a>) else there exists a, b: integer; t: string of integer where (s = <a> * <b> * t and SWITCH(s) = <b> * <a> * SWITCH(t))!*/public static method weird(Sequence<Integer> seq) { ... }

A math_function is just a piece of a specification. It is used to make specs easier to read. It is not code. You can’t make a “call” to SWITCH(s).

Page 24: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

The Specification for Weird( )

requires

(|seq| mod 2) = 0

The sequence must contain an even number of integer elements.

ensures

seq = SWITCH(#seq)

Note that #seq means “the incoming value of seq’s object”.

The weird() method will update the sequence object by doing whatever SWITCH describes.

Page 25: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

Interpreting SWITCH(s)

SWITCH changes one string of integer into a different string of integer.

math_function SWITCH(string of integer s): string of integer

if |s| = 0 then SWITCH(s) = empty string

else if |s| = 2 then there exists a, b: integer

where (s = <a> * <b> and SWITCH(s) = <b> * <a>)

else

there exists a, b: integer; t: string of integer

where (s = <a> * <b> * t and

SWITCH(s) = <b> * <a> * SWITCH(t))

case 1: |s| = 0

case 2:|s| = 2

case 3:“other”

Page 26: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

SWITCH(s) Case 1

If you SWITCH(< >), it returns < >. In other words, it does not change s when s is the empty string of integer.

if |s| = 0 then SWITCH(s) = empty string

Page 27: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

SWITCH(s) Case 2

If s has two elements, SWITCH(s) returns a string consisting of those same two integer elements, in reverse order.

else if |s| = 2 then

there exists a, b: integer where

(s = <a> * <b> and

SWITCH(s) = <b> * <a>)

Page 28: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

Limiting Complexity

SWITCH(s) doesn’t make any sense at all when the length of s is odd. But that’s okay, because we’re only using it to describe what happens when its length is even.

In other words, we don’t need to bother reasoning about cases that won’t come up.

Page 29: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

SWITCH(s) Case 3

If s has more than two elements, we call the first two a and b. We reverse these two, then recurse to append SWITCH(t), where t is the rest of the string. It’s safe, since |s| is even implies |s|-2 is even.

else there exists a, b: integer; t: string of integer where (s = <a> * <b> * t and SWITCH(s) = <b> * <a> * SWITCH(t))

Page 30: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

The Meaning of SWITCH(s)

Given a string of integer of even length, SWITCH takes every two integers and swaps them, like so:

SWITCH(< 1, 2, 3, 4, 5, 6 >) =< 2, 1, 4, 3, 6, 5 >

Note: just because a spec is recursive doesn’t mean you need to use recursion to write code that implements it. This method would be both simpler and more efficient if written iteratively.

Page 31: ANNATALA WOLF – 2231 LECTURE 1 Reading Mathematical Contracts.

Really Hard Contracts…

TODO (will add Project 3 contract reading stuff here)