Information --- Staff --- Homework --- Reading/Lecture note --- Newsgroup --- Feedback
; Recall:
; Def'n of NatNum:
;  - 0
;  - add1(k), where k is a NatNum.
; 
; 
; How do programs look, which use this def'n?

;; sumA: NatNum -> NatNum
;; Return the sum of the natNums in [0,n].
;;
(define (sumA n)
  (cond [(zero?     n) 0]
        [(positive? n) (+ n (sumA (sub1 n)))]))
; 
; Calling sumA(4) calls sumA(3) calls sumA(2) ... calls sumA(0).

;; sumB: NatNum -> NatNum
;; Return the sum of the natNums in [0,n].
;;
(define (sumB n)
  (* n (add1 n) 1/2))


   ; See test cases in lect15-sum-test.ss


; Clearly sumB is a better solution than sumA --
; but is it correct?  Can we prove it correct?
; (Are there some implicit assumptions?  If so, what?)



How do proofs look, about natural numbers?

Let P(n) be the statement "(sumA n) = (sumB n)."

Here's the battle plan of proofs by induction:
First we'll show P(0);
then we'll show forall k ≥ 0, P(k) → P(k+1);
thus we'll conclude by induction forall n, P(n).

Proof of  forall n.P(n), by induction:

Base case:
   P(0): (sumA 0) = 0 = 0*1/2 = (sumB n).  Check.
         (= (sumA 0) (sumB 0)) evaluates to true.

Inductive step:  For all k, P(k) → P(k+1):
   Need to show that (sumA k+1) = (sumB k+1)
   Our inductive hypothesis P(k) gives us
        (sumA k) = (sumB k)

   Okay, here goes: For k≥0,
      (sumA k+1) 
    = (+ k+1 (sumA (sub1 k+1)))  [by code of sumA]
    = (k+1) + (sumA k)           [by language's-implementation-of-arithmetic]
    = (k+1) + (sumB k)           [by inductive hypothesis P(k)]
    = (k+1) + (* k (add1 k) 1/2) [by code of sumB]
    = (k+1) +  k(k+1)/2          [by langauge's-implementation-of-arithmetic]
    = (k+1)*(1 + k/2)
    = (k+1)*(2/2 + k/2)
    = (k+1)*(k+2)/2
    = (* k+1 (add1 k+1) 1/2)
    = (sumB k+1)

    Following that entire chain of equalities, we see that
    we have P(k+1).

Thus, by induction, P(n) holds for all n in N.



Really, this is a new inference rule (particular to N):
If you know...                       Then you can conclude...
  P(0)                            }
  forall k. (P(k) → P(k+1))     }  forall n.P(n)

Read Rosen for more number examples.


  By the way, a note on Sum_1^n (k) = n(n+1)/2:
      *****
      ****
      ***
      **
      *
  This is Sum_{k=1}^5 (k).
  Visually: If I take twice this sum (another stairway-triangle),
      turn it around and fit the stairways together,
      I have a n by n+1 rectangle.
  This is the visual analog of writing S = 1 + 2 + ... + n,
  writing below it the same sum reversed, adding column-wise,
   and getting 2S = n copies of (n+1).

  Note: For arithmetic progression:
     Sum is (first-term + last-term) * number-of-terms / 2.
     My mantra: ``first plus last times n over two.''



Example2: board tiling, from Rosen.
P(n) = "A checkerboard 2^n x 2^n with one corner removed,
  can be exactly tiled by L-shaped tri-ominoes."

P(1).  Check.
P(k) → P(k+1), forall k>0:
  ...
Thus, Forall n in N, n≥1, P(n).

    (Actually, this holds for n=0 as well;
     in fact the proof is unchanged!  Though it probably takes
     more consideration of that special case, than just
     handling n=0 as a lemma.)
    


Example 3: hw exercise:
   Show: Sum_1^n 2^k = 2^{k+1}-1.
   Show: Sum_1^n b^k = b^{k+1}/(b-1)-1.
        (E.g., 1+10+100+1000 = 1111 = 1/9*9999.
             [Hey, that's similar, for any base!]
        This means that for exponentially growing terms,
        the last one dominates all the previous,
        and is a pretty good approximation to the sum.
        Alternatively: 
          the next term is nearly b times bigger than
          the entire sum of previous terms!
          [More precisely, it's nearly b-1 times bigger.]

   (Again, there's a direct-method algebraic proof:
      Look at S; on next line write bS; shift columns and substract.
    Hmm, a visual analog?  
      Collecting an exponential-growth petri colonies (a 1-day old,
       a 2-day old, a 3-day old, ...)
       Most of your biomass comes from the very last day, if b≥2.)


Example 4, an inequality:
Harmonic series (in Rosen):
  H_{2^k} ≥ 1+(k/2).

Note that this can be re-stated as,
  H_{n} ≥ 1+lg(n)/2, though we'd need to show this for all n 
                      (not just powers-of-2).
 




More complicated example

Sketch the scheduling problem mentioned in Rosen. - Sketch the problem. (Imagine allocating supercomputer time; this is stronger than a web-server since you know all requests in advance) Goal: schedule as many jobs as possible. - Greedy alg: choose next possible job w/ lowest end-time. (define-struct request [start stop name]) ; See greedy-schedule-test.ss, for examples of data, and test cases. ;; greedy-sched-v1: ;; Given a list of requests, ;; return a list of requests that can be scheduled. ;; ;; Implementation: ;; Use the greedy algorithm as given in Rosen 5ed, Section 3.3, Example 12: ;; Schedule the first jobs with smallest ending time, ;; and then recur on the other consistent jobs (those ;; whose start-time is >= the stop-time of the job just scheduled. ;; (define (greedy-sched-v1 reqs) (cond [(empty? reqs) empty] [else (let* {[stop0 (apply min (map request-stop reqs))] ; Now recover the (well, a) job which stop-time of stop0: [job0 (first (filter (lambda (r) (= stop0 (request-stop r))) reqs))] ; Gather the jobs whose start-time is > the current stop time. [others (filter (lambda (r) (> (request-start r) stop0)) reqs)]} (cons job0 (greedy-sched-v1 others)))])) - How to phrase it precisely, so we can even begin? - set up P(n): "given n jobs, greedy algorithm gives an optimal sol'n". - Think a bit: Hmm, will be tough, getting the inductive step. - Alternate: P(n) is "given a list, if greedy schedules n jobs, they're optimal" This will let us get through. Sometimes people write "Proof by induction on ..."; we'll obviate this by spelling out P(n). Key step: if the smaller step has k optimal, then we schedule k+1; it's impossible to have a schedule with k+2 [explain]. A more involved example: if all cities connected in one direction or the other, then there is some city which is connected to all others in either one or two steps. Show how we work towards a clearer proof. Include definitions: A graph is "well-connected" if for all vertices v,w E(v,w) or E(w,v). (Corollary: every vertex of a well-connected graph has a self-loop.) A hub h is a vertex such that for all vertices v, there is a path of length <= 2 *from* h *to* v. [Will probably take beyond this lecture.] Given a well-connected graph G, choose an arbitrary vertex v. Note that G-{v} is well-connected. [Aside: Def'n of G-{v} ?] Let h0 be "old" hub of G-{v}. Case 1: E(h0,v). Done; h0 is still hub for all G. Case 2: E(v,h0). Consider H1, set of all 1-neighbors of h0 in G-{v}, and H2, set of all 2-neighobors of h0. Note that {h0},H1,H2 partition G-{v}. Case 2a: for some n in H1, E(n,v). Done: h0 is still hub for all G. Case 2b: v is new hub: It has an path of length one to each of H1 u {h0}, and it has a path of length two to each of H2.

False proofs-by-induction

What's wrong with this inductive proof: P(n) is "n > 1000". (After all, it's easy to show P(k) → P(k+1).) Okay, we'll patch that problem; what's wrong with the induction proof of: P(n) is "n>1000 or n=0". False proof: All horses are the same color. Proof by induction for n>1: let P(n) be "for a set of n horses, they all have the same color". * P(1) -- yep, in a singleton set {h1}, every horse is h1's color. * P(k) → P(k+1): We need to show P(k+1). Start with *any* set of k+1 horses; we'll show every member of H = { h_1, ..., h_k, h_{k+1} } has the same color as h_1. First, h_1 through h_k all have the same color as h_1 (by inductive hypothesis regarding the set H - {h_{k+1}}). It only remains to show that h_{k+1} is the same color. But again by P(k) to the k-element set H-{h_k} = {h_1, ..., h_{k-1}, h_{k+1} } all have the same color as h_1 (which includes h_{k+1}). Since "has the same color as" is transitive, all elements of H are the same color as h_1. Q.E.D. ------------------- A question, about writing inductive proofs on the hw: | ...how formal should this step in showing that B ≤ C be? | For inequalities you can state "B ≤ C" as obvious when the right-hand-side C is: - B + some-positive-amount, or - like B but a (bunch of) subterms replaced with larger amounts. Thus like in today's class example with the harmonic-number sum: 1 + 1/2 + 1/3 +...+ 1/2^k + 1/((2^k)+1) + 1/((2^k)+2) +...+ 1/(2^k+2^k) ≥ 1 + 1/2 + 1/3 +...+ 1/2^k + 1/2^(k+1) + 1/2^(k+1) +...+ 1/2^(k+1) is fine, with the explanation "Replacing some terms by larger ones". Also, indenting can go a long way in making it clear how you're doing the replacement. Similarly, it's fine to say blah ≤ blah + (a^2 - 1) (in this case, need to take care that a^2-1 is non-negative; you might need to mention why a isn't zero.) Tip: when using < vs ≤, use the strongest statement possible -- e.g. use < when the inequality really is strict. (So in the harmonic example above, is the "<" actually true for k=0?)
Information --- Staff --- Homework --- Reading/Lecture note --- Newsgroup --- Feedback

Comp280 Home Please notify us of any broken links, etc. Last modified 2004.Feb.26.