15 150 fall 2020 lecture 12
play

15-150 Fall 2020 Lecture 12 Stephen Brookes Midterm 1 Tuesday, - PowerPoint PPT Presentation

15-150 Fall 2020 Lecture 12 Stephen Brookes Midterm 1 Tuesday, October 13 No class that day MIT study says if you get more Zs, youll get more As Font of all knowledge? Australian researchers developed a typeface to help students


  1. 15-150 Fall 2020 Lecture 12 Stephen Brookes Midterm 1 Tuesday, October 13 No class that day MIT study says if you get more Z’s, you’ll get more A’s

  2. Font of all knowledge? Australian researchers developed a typeface to help students cramming for exams. A study found a small increase in the amount remembered. The font has a back slant and gaps. “If something is too easy to read, it doesn’t create a memory trace.” Study for the Midterm!

  3. and now… • Generalizing the subset-sum problem • Developing specs and code together • A lesson in program design We’re dealing with functions for problems that need careful specifications We may be informal (“positive integer x”) or more formal (“x > 0”) But whatever we do, MUST be clear

  4. making change • Given a non-negative integer n, a list L of positive integers, and a constraint p : int list -> bool • Is there a sublist of L that satisfies p and adds up to n?

  5. making change • Given a non-negative integer n, a list L of positive integers, and a constraint p : int list -> bool • Is there a sublist of L that satisfies p and adds up to n? fun sublists L = foldr ( fn (x, S) => S @ (map ( fn A => x::A) S)) [ [ ] ] L

  6. making change • Given a non-negative integer n, a list L of positive integers, and a constraint p : int list -> bool • Is there a sublist of L that satisfies p and adds up to n? fun sublists L = foldr ( fn (x, S) => S @ (map ( fn A => x::A) S)) [ [ ] ] L val sublists = fn : 'a list -> 'a list list - sublists [1,2,3]; val it = [[],[3],[2],[2,3],[1],[1,3],[1,2],[1,2,3]] : int list list

  7. badchange : int * int list -> (int list -> bool) -> bool A non-recursive function that returns a boolean

  8. badchange : int * int list -> (int list -> bool) -> bool A non-recursive function that returns a boolean fun exists q = foldl ( fn (x, t) => q x orelse t) false val sum = foldl ( op + ) 0

  9. badchange : int * int list -> (int list -> bool) -> bool A non-recursive function that returns a boolean fun exists q = foldl ( fn (x, t) => q x orelse t) false val sum = foldl ( op + ) 0 fun badchange (n, L) p = exists ( fn A => sum A = n andalso p A) (sublists L)

  10. badchange : int * int list -> (int list -> bool) -> bool A non-recursive function that returns a boolean fun exists q = foldl ( fn (x, t) => q x orelse t) false val sum = foldl ( op + ) 0 fun badchange (n, L) p = exists ( fn A => sum A = n andalso p A) (sublists L) badchange satisfies the spec

  11. badchange : int * int list -> (int list -> bool) -> bool A non-recursive function that returns a boolean fun exists q = foldl ( fn (x, t) => q x orelse t) false val sum = foldl ( op + ) 0 fun badchange (n, L) p = exists ( fn A => sum A = n andalso p A) (sublists L) badchange satisfies the spec but it’s inefficient!

  12. critique badchange (300, [1,2,3,...,24]) ( fn _ => true ) ========>* true (VERY SLOW!)

  13. critique badchange (300, [1,2,3,...,24]) ( fn _ => true ) ========>* true (VERY SLOW!) brute force search • generates the list of all sublists • and tests them, sequentially

  14. critique badchange (300, [1,2,3,...,24]) ( fn _ => true ) ========>* true (VERY SLOW!) brute force search • generates the list of all sublists (2 24 ) • and tests them, sequentially

  15. critique badchange (300, [1,2,3,...,24]) ( fn _ => true ) ========>* true (VERY SLOW!) brute force search • generates the list of all sublists (2 24 ) • and tests them, sequentially … only the final sublist will work!

  16. critique badchange (300, [1,2,3,...,24]) ( fn _ => true ) ========>* true (VERY SLOW!) brute force search • generates the list of all sublists (2 24 ) • and tests them, sequentially … only the final sublist will work! 1 + 2 + … + 24 = 300

  17. specification “can we make change for (n, L) that satisfies p?” change : int * int list -> (int list -> bool) -> bool REQUIRES p is total , n ≥ 0, L a list of positive integers ENSURES change (n, L) p = true if there is a sublist A of L with sum A = n and p A = true change (n, L) p = false , otherwise + must be faster!

  18. a better strategy Avoid building the list of sublists • only call p on sublists with the correct sum Deal with special cases first • n = 0 • n > 0, L = [ ] For n > 0, L = x::R, use recursion ... the spec suggests this might be feasible!

  19. change : int * int list -> (int list -> bool) -> bool A recursive function that returns a boolean p [ ] fun change (0, L) p = | change (n, [ ]) p = false | change (n, x::R) p = if x <= n then change (n-x, R) ( fn A => p(x::A)) orelse change (n, R) p else change (n, R) p

  20. change : int * int list -> (int list -> bool) -> bool A recursive function that returns a boolean p [ ] fun change (0, L) p = | change (n, [ ]) p = false | change (n, x::R) p = if x <= n then change (n-x, R) ( fn A => p(x::A)) orelse change (n, R) p else change (n, R) p change (300, [1,2,3,...,24]) ( fn _ => true )

  21. change : int * int list -> (int list -> bool) -> bool A recursive function that returns a boolean p [ ] fun change (0, L) p = | change (n, [ ]) p = false | change (n, x::R) p = if x <= n then change (n-x, R) ( fn A => p(x::A)) orelse change (n, R) p else change (n, R) p change (300, [1,2,3,...,24]) ( fn _ => true ) (very fast) ⟹ true

  22. equivalently fun change (0, L) p = p [ ] | change (n, [ ]) p = false | change (n, x::R) p = if x <= n then case change (n-x, R) ( fn A => p(x::A)) of true => true | false => change (n, R) p else change (n, R) p (you’ll soon see why we mention this)

  23. type check change : int * int list -> (int list -> bool) -> bool fun change (0, L) p = p [ ] | change (n, [ ]) p = false | change (n, x::R) p = if x <= n then change (n-x, R) ( fn A => p(x::A)) orelse change (n, R) p else change (n, R) p CHECK that each clause fits this type: the LHS patterns match types int * int list and int list -> bool, and give bindings such that, assuming change : int * int list -> (int list -> bool) -> bool, the RHS expression gets type bool

  24. spec check fun change (0, L) p = p [ ] | change (n, [ ]) p = false | change (n, x::R) p = if x <= n then change (n-x, R) ( fn A => p(x::A)) orelse change (n, R) p else change (n, R) p REQUIRES p is total , n ≥ 0, L a list of positive integers ENSURES change (n, L) p = true iff there is a sublist A of L with sum A = n and p A = true CHECK if requires holds for (n, L, p) and then requires holds for (n ’ , L ’ , p ’ ) change (n, L) p calls change (n ’ ,L ’ ) p ’ and original call satisfies ensures and recursive call satisfies ensures

  25. benefits • The type check shows that the function has the intended type(!) - Use type check to guide the code design - ML will give same type (or a more general one) • The spec check is basically a sketch of an inductive correctness proof - Use spec check to guide the code design - Will then be easy to give a fully detailed proof of correctness

  26. correctness For all positive integer lists L, n ≥ 0, and total functions p : int list -> bool, change (n, L) p = true if there is a sublist A of L with sum A = n and p A = true change (n, L) p = false , otherwise • PROOF: induction on L why?

  27. examples change (10, [5,2,5]) ( fn _ => true ) = true change (210, [1,2,3,...,20]) ( fn _ => true ) ⟹ * true (FAST!) change (10, [10,5,2,5]) ( fn A => length(A)>1) = true change (10, [10,5,2]) ( fn A => length(A)>1) = false

  28. the right question? change : int * int list -> (int list -> bool) -> bool

  29. the right question? change : int * int list -> (int list -> bool) -> bool I s there a sublist that adds to 300?

  30. the right question? change : int * int list -> (int list -> bool) -> bool I s there a val it = true sublist that (YES) adds to 300?

  31. the right question? change : int * int list -> (int list -> bool) -> bool I s there a val it = true sublist that (YES) adds to 300? What is it?

  32. the right question? change : int * int list -> (int list -> bool) -> bool I s there a val it = true sublist that (YES) adds to 300? Y ou What is it? didn’t ask

  33. boolean blindness • A truth value only gives a bit of information • From the context, we know true (yes) means “it’s possible to make change...” • But what if we want more information ? • “a list that works, if there is one”

  34. boolean blindness • A truth value only gives a bit of information • From the context, we know true (yes) means “it’s possible to make change...” • But what if we want more information ? • “a list that works, if there is one” NEED a function that computes a suitable sublist, if there is one

  35. boolean blindness • A truth value only gives a bit of information • From the context, we know true (yes) means “it’s possible to make change...” • But what if we want more information ? • “a list that works, if there is one” NEED PLAN a function that a function that computes a suitable sublist, returns an if there is one (int list) option

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend