14
www.eschertech.com Fundamentals of Perfect Developer A one-day hands-on tutorial Answers to Exercises

Fundamentals of Perfect Developer

Embed Size (px)

DESCRIPTION

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; - PowerPoint PPT Presentation

Citation preview

Page 1: Fundamentals of  Perfect Developer

www.eschertech.com

Fundamentals of Perfect Developer

A one-day hands-on tutorial

Answers to Exercises

Page 2: Fundamentals of  Perfect Developer

www.eschertech.com

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^= for those 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;

Page 3: Fundamentals of  Perfect Developer

www.eschertech.com

Suggested answers to Exercise 4

• A recursive solution to the first problem is:function numLeadingSpaces(s: string): nat

decrease #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

Page 4: Fundamentals of  Perfect Developer

www.eschertech.com

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) );

Page 5: Fundamentals of  Perfect Developer

www.eschertech.com

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) ) );

Page 6: Fundamentals of  Perfect Developer

www.eschertech.com

Suggested answers to Exercise 5

function min2a(x, y: int): intsatisfy result <= x,

result <= y,result = x | result = y

viaif [x > y]: value y; []: value x fi

end;

function min2b(x, y: int): intsatisfy result <= x,

result <= y,result = x | result = y

viavalue ([x > y]: y, []: x)

end;

Page 7: Fundamentals of  Perfect Developer

www.eschertech.com

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

vialoop

var i: (nat in 0..#s)! = 0;keep forall j::0..<i' :- s[j] ~= xuntil i' = #sdecrease #s - i';if [s[i] = x]: value i; [] fi;i! + 1

end;value #s

end;

Page 8: Fundamentals of  Perfect Developer

www.eschertech.com

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;

loopchange ikeep forall j::0..<i' :- s[j] ~= xuntil i' = #s | s[i']= xdecrease #s - i';i! + 1

end; value i

end;

Page 9: Fundamentals of  Perfect Developer

www.eschertech.com

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 ikeep forall j::0..<i':- s[j] ~= ` `until i'= #s | s[i'] = ` `decrease #s - i';i! + 1

end;value i

end;

Page 10: Fundamentals of  Perfect Developer

www.eschertech.com

Suggested answers 5 (cont’d)

function splitIntoWords(s: string): seq of stringdecrease #s^= ( let stripped ^= removeLeadingSpaces(s);

[stripped.empty]:seq of string{},

[]:( let w ^= firstWord(stripped); assert ~w.empty;

splitIntoWords(stripped.drop(#w)).prepend(w) )

) ...

Page 11: Fundamentals of  Perfect Developer

www.eschertech.com

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; [] fiend;value rslt

end;

Page 12: Fundamentals of  Perfect Developer

www.eschertech.com

Suggested answers to Exercise 6

function longest(s: seq of string): string decrease #s ^= ( [s.empty]: "", []: ( let temp ^= longest(s.front); [#s.last >= #temp]: s.last, []: temp ) );

Page 13: Fundamentals of  Perfect Developer

www.eschertech.com

Suggested answers 6 (cont’d)

class ListOfStrings ^=abstract var list: seq of string;

internal var long: string;

invariant long = longest(list);

interface

build{} post list! = seq of string{} via list! = seq of string{}, long! = "“ end;

Page 14: Fundamentals of  Perfect Developer

www.eschertech.com

Suggested answers 6 (cont’d)

schema !add(s: string) post list! = list.append(s) via list! = list.append(s); if [#s >= #long]: long! = s; [] fi end;

function longest: string ^= longest(list) via value long end;

end;