Motivate:
[review the algorithm of insert-sort some more]

Okay, the running time of insert is T(n)=3n+2;
the running time of insert-sort is 
S(n)=Sum_{i=0}^{n-1}T(i) = 3n(n-1)/2+2n = 3/2 n^2 + n/2.

What is S(10)?
What is S(100)?
What is S(1000)?


Really, the "+n/2" becomes less important for large inputs,
and the "3/2" is an artifact of what we consider 
the time to execute one 'instruction';
since that can vary from one processor to another,
and we want to talk about the performance of the *algorithm* 
(separate from technology),
we'll even ignore the factor of 3/2.



We say: S ∈ O(λn.n²).
This captures the *important* part of the running time,
and throws away the irrelevent terms and the
technology-dependent constant.


Def'n: For functions f,g : NN,
we say
   f ∈ O(g)
iff
  ∃c.∃n.∀(n>n).f(n)≤cċg(n).

Note that this is a statement about functions,
not merely functions-about-running-time-of-algorithms.
However, in most of CS, big-Oh is *usually* used for run-times.

Task: Using this definition, prove that λn.(3/2)n+n/2 ∈ O(λn.n).

Sol'n: we'll prove this ∃c∃n formula is true by finding particular values.
In particular, take c=87,n=1.

n>1
...
(3/2)n+n/2 ≤ 87n


But how to fill in the  to get 
from our premise to our conclusion? 
(Tip: we'll work backwards from our final presentation here:)

  n>1            Premise.
⇒ 4 ≤ 174     Fact.
⇒ 4n ≤ 174n
⇒ 4n ≤ 174n
⇒ 3n+n ≤ 174n
⇒ 3n+1 ≤ 174n  // Since by line 1, n>1.
⇒ 3n+1 ≤ 174n
⇒ 3n+n ≤ 174n
⇒ 3n+n ≤ 174n
⇒ (3/2)n+n/2 ≤ 87n
Prove: λn.7300n ∈ O(λn.n). Take c=7300, and n=1. Then... 1 < n n [premise] 7300n < 7300n (multiplying both sides by a positive preserves <) 7300n < cn (by our previous choice of c) Thus we've shown that there exist c,n such that ∀n>n, 7300n ≤ cn, meeting our definition of λn.7300n ∈ O(λn.n).