140 likes | 265 Views
Fundamentals of Perfect Developer. A one-day hands-on tutorial Answers to Exercises. Suggested answers to Exercise 1. const zeroToOneHundred: seq of int ^= 0..100; property assert 42 in zeroToOneHundred, 101 ~ in zeroToOneHundred;
E N D
Fundamentals of Perfect Developer A one-day hands-on tutorial Answers to Exercises
Suggested answers to Exercise 1 const zeroToOneHundred: seq of int ^= 0..100; property assert 42 in zeroToOneHundred, 101 ~in zeroToOneHundred; function divides(i, j: int): boolpre j > 0^= i % j = 0; const squaresOfPrimes: seq of int^= forthose i::2..100 :- forall j::2..<i :- ~divides(i, j)yield i ^ 2; function max(S: set of int): intpre ~S.empty^= that x::S :- forall y::S :- y <= x;
Suggested answers to Exercise 4 • A recursive solution to the first problem is: function numLeadingSpaces(s: string): natdecrease #s^= ( [s.empty | s.head ~= ` `]: 0, []: 1 + numLeadingSpaces(s.tail) ); • A non-recursive solution to the first is: function numLeadingSpaces(s: string): nat^= that j::0..#s :- (j = #s | s[j] ~= ` `) & (forall k::0..<j :- s[k] = ` `); • The following member functions may be useful: take drop findFirst prepend
Suggested answers 4 (cont’d) function removeLeadingSpaces(s: string): string^= s.drop(numLeadingSpaces(s)); function firstWord(s: string): string^= ( let n ^= s.findFirst(` `); [n < 0]: s, []: s.take(n) );
Suggested answers 4 (cont’d) function splitIntoWords(s: string): seq of stringdecrease #s^= ( let stripped ^= removeLeadingSpaces(s); [stripped.empty]:seq of string{}, []: ( let w ^= firstWord(stripped); splitIntoWords(stripped.drop(#w)) .prepend(w) ) );
Suggested answers to Exercise 5 function min2a(x, y: int): int satisfyresult <= x, result <= y, result = x | result = y via if [x > y]: value y; []: value x fi end; function min2b(x, y: int): int satisfy result <= x, result <= y, result = x | result = y via value ([x > y]: y, []: x) end;
Suggested answers 5 (cont’d) function findFirst1(s: seq of int, x: int): int satisfy 0 <= result <= #s, result = #s | s[result] = x, forall j::0..<result :- s[j] ~= x via loop var i: (nat in 0..#s)! = 0; keep forall j::0..<i' :- s[j] ~= x until i' = #s decrease #s - i'; if [s[i] = x]: value i; [] fi; i! + 1 end; value #s end;
Suggested answers 5 (cont’d) function findFirst1(s: seq of int, x: int): int satisfy 0 <= result <= #s, result = #s | s[result] = x, forall j::0..<result :- s[j] ~= x via var i: (nat in 0..#s)! = 0; loop change i keep forall j::0..<i' :- s[j] ~= x until i' = #s | s[i']= x decrease #s - i'; i! + 1 end; value i end;
Suggested answers 5 (cont’d) function numLeadingSpaces(s: string): nat ^= that j::0..#s :- (j = #s | s[j] ~= ` `) & (forall k::0..<j :- s[k] = ` `) via var i: (nat in 0..#s)! = 0; loop change i keep forall j::0..<i':- s[j] ~= ` ` until i'= #s | s[i'] = ` ` decrease #s - i'; i! + 1 end; value i end;
Suggested answers 5 (cont’d) function splitIntoWords(s: string): seq of string decrease #s ^= ( let stripped ^= removeLeadingSpaces(s); [stripped.empty]: seq of string{}, []: ( let w ^= firstWord(stripped); assert ~w.empty; splitIntoWords(stripped.drop(#w)).prepend(w) ) ) ...
Suggested answers 5 (cont’d) via var rslt: seq of string ! = seq of string{}; loop var i: (nat in 0..#s)! = 0; change rslt keep splitIntoWords(s) = rslt' ++ splitIntoWords(s.drop(i')) until i'= #s decrease #s - i'; i! + numLeadingSpaces(s.drop(i)); if [i < #s]: let w ^= firstWord(s.drop(i)); rslt! = rslt.append(w), i! + #w; [] fi end; value rslt end;
Suggested answers to Exercise 6 function longest(s: seq of string): stringdecrease #s ^= ( [s.empty]: "", []: ( let temp ^= longest(s.front); [#s.last >= #temp]: s.last, []: temp ) );
Suggested answers 6 (cont’d) class ListOfStrings ^=abstractvar list: seq of string; internalvar long: string; invariant long = longest(list); interface build{}post list! = seq of string{}via list! = seq of string{}, long! = "“end; …
Suggested answers 6 (cont’d) … schema !add(s: string)post list! = list.append(s)via list! = list.append(s);if [#s >= #long]: long! = s; [] fiend; function longest: string ^= longest(list)viavalue longend; end;