1 / 31

Reading Mathematical Contracts

Reading Mathematical Contracts. Annatala Wolf – 2231 Lecture 1. 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.

ebony
Download Presentation

Reading Mathematical Contracts

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Reading Mathematical Contracts Annatala Wolf – 2231 Lecture 1

  2. 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, -18or falsemean 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).

  3. 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.

  4. 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.

  5. Our Contracts (Review) Preconditionsare given in our custom @requires annotations, and postconditionsare 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 implementershould 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).

  6. 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.

  7. 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 (notJava String) • tuple: a group of different things that can be distinguished (like the columns of a database)

  8. Examples of Mathematical Models • String: string of character • NaturalNumber: non-negative integer • Queue<T>: string of T • Stack<T>: string of T • Sequence<T>: string of T • Set<T>: finite set of T • Map<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)

  9. 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.

  10. Mathematical Notation • Setsuse curly braces: {a, b, …}. The set with no items, { }, is called the empty set. • Stringsuse 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. • Tuplesuse 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.

  11. More Symbols • The * symbol means concatenation when it appears between two strings. It means multiplywhen it appears between two integers. There is never ambiguity, because we always specify types. • The entriesof a string are all the unique bits of the string, taken as a set. (Remove order and forget duplicates, in other words.) • A permutationof 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!”).

  12. One Last Symbol • The parallel lines |x| can mean three different things, depending on context: • x is a set implies |x| is the sizeof the set • x is a string implies |x| is the lengthof the string • x is a numeric type implies |x| is the absolutevalue • 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).

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

  14. 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) {...}

  15. 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

  16. 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.

  17. 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 s1so that there is an <i> next to a <j>. • In other words, “consider all consecutive pairs of integers iand 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 alli, j: integer, a, b: string of integer where (s1 = a * <i> * <j> * b) ...

  18. “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 alli, 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

  19. 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 s2must be, based on s1. there existsc, 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

  20. 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

  21. 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|

  22. 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.

  23. Recursively-Defined Specifications /** updatesseq 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).

  24. 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.

  25. 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”

  26. 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

  27. 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>)

  28. 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.

  29. 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))

  30. 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 methodwould be both simpler and more efficient if written iteratively.

  31. Really Hard Contracts… TODO (will add Project 3 contract reading stuff here)

More Related