15-150 Fall 2020 Stephen Brookes Lecture 4 Proving correctness - - PowerPoint PPT Presentation

15 150 fall 2020
SMART_READER_LITE
LIVE PREVIEW

15-150 Fall 2020 Stephen Brookes Lecture 4 Proving correctness - - PowerPoint PPT Presentation

15-150 Fall 2020 Stephen Brookes Lecture 4 Proving correctness Last time Specification format for a function F type assumption (REQUIRES) guarantee (ENSURES) For all (properly typed ) x satisfying the assumption , F x satisfies


slide-1
SLIDE 1

15-150 Fall 2020

Stephen Brookes Lecture 4

Proving correctness

slide-2
SLIDE 2

Last time

  • Specification format for a function F
  • type
  • assumption (REQUIRES)
  • guarantee (ENSURES)

For all (properly typed) x satisfying the assumption, F x satisfies the guarantee

slide-3
SLIDE 3

Remember…

  • Can use equivalence (a.k.a. equality, written = )

to specify applicative behavior of functions

  • Equality is compositional
  • Equality is defined in terms of evaluation
  • ⟹* is consistent with = and ML evaluation
slide-4
SLIDE 4

Example

fun f(x:int):int = if x=0 then 1 else f(x-1) f : int -> int REQUIRES x ≥ 0 ENSURES f x = 1 f x = 1 means the same as f x ⟹* 1

slide-5
SLIDE 5

eval spec

fun eval ([ ]:int list) : int = 0 | eval (d::L) = d + 10 * (eval L) eval : int list -> int REQUIRES L is a list of decimal digits ENSURES (eval L) ⟹* a non-negative integer

slide-6
SLIDE 6

eval spec

fun eval ([ ]:int list) : int = 0 | eval (d::L) = d + 10 * (eval L) eval : int list -> int REQUIRES L is a list of decimal digits ENSURES (eval L) ⟹* a non-negative integer

a sufficient REQUIRES for the given ENSURES, but not the most general

slide-7
SLIDE 7

eval spec

fun eval ([ ]:int list) : int = 0 | eval (d::L) = d + 10 * (eval L) eval : int list -> int REQUIRES L is a list of decimal digits ENSURES (eval L) ⟹* a non-negative integer

slide-8
SLIDE 8

eval spec

fun eval ([ ]:int list) : int = 0 | eval (d::L) = d + 10 * (eval L) eval : int list -> int REQUIRES L is a list of decimal digits ENSURES (eval L) ⟹* a non-negative integer

—————————- non-negative integers

slide-9
SLIDE 9

decimal spec

fun decimal (n:int) : int list = if n<10 then [n] else (n mod 10) :: decimal (n div 10)

decimal : int -> int list REQUIRES n >= 0 ENSURES decimal n = a list L of decimal digits such that (eval L) = n

slide-10
SLIDE 10

decimal spec

fun decimal (n:int) : int list = if n<10 then [n] else (n mod 10) :: decimal (n div 10)

decimal : int -> int list REQUIRES n >= 0 ENSURES decimal n = a list L of decimal digits such that (eval L) = n

This REQUIRES property is just right, for the given ENSURES

slide-11
SLIDE 11

Problem

  • Solution: Use induction to prove it
  • we offer templates to help with accuracy
  • We focus on examples…

program structure guides proof How to show that a spec for a recursive function is valid But first, what’s a proof?

slide-12
SLIDE 12

What is a proof?

A proof is a logical sequence of steps, leading to a conclusion.

  • Each step must follow logically

from math facts,

  • r the results of earlier steps.
slide-13
SLIDE 13

Simple induction

  • To prove a property of the form
  • First, prove P(0).
  • Then show that, for k ≥ 0,

P(k+1) follows logically from P(k). ∀n≥0. P(n) base inductive step

slide-14
SLIDE 14

Why this works

  • P(0) gets a direct proof base
  • P(0) implies P(1) step (with k=0)
  • P(1) implies P(2) step (with k=1)

For each n≥0 we can establish P(n)

(follows from base after n uses of step)

slide-15
SLIDE 15

Example

  • To prove:

fun f(x:int):int = if x=0 then 1 else f(x-1) REQUIRES n ≥ 0 ENSURES f(n) = 1 For all n:int such that n≥0, f(n) = 1 type REQUIRES ENSURES

slide-16
SLIDE 16

proof (part 1)

Let P(n) be “f(n) = 1” Theorem: ∀n≥0. P(n) Proof: By simple induction on n.

  • Base: we prove P(0). Here’s a proof:

fun f(x:int):int = if x=0 then 1 else f(x-1)

slide-17
SLIDE 17

proof (part 1)

Let P(n) be “f(n) = 1” Theorem: ∀n≥0. P(n) Proof: By simple induction on n.

  • Base: we prove P(0). Here’s a proof:

fun f(x:int):int = if x=0 then 1 else f(x-1) f 0

slide-18
SLIDE 18

proof (part 1)

Let P(n) be “f(n) = 1” Theorem: ∀n≥0. P(n) Proof: By simple induction on n.

  • Base: we prove P(0). Here’s a proof:

fun f(x:int):int = if x=0 then 1 else f(x-1) = (fn x => if x=0 then 1 else f(x-1)) 0 f 0

slide-19
SLIDE 19

proof (part 1)

Let P(n) be “f(n) = 1” Theorem: ∀n≥0. P(n) Proof: By simple induction on n.

  • Base: we prove P(0). Here’s a proof:

fun f(x:int):int = if x=0 then 1 else f(x-1) = (fn x => if x=0 then 1 else f(x-1)) 0 = if 0=0 then 1 else f(0-1) f 0

slide-20
SLIDE 20

proof (part 1)

Let P(n) be “f(n) = 1” Theorem: ∀n≥0. P(n) Proof: By simple induction on n.

  • Base: we prove P(0). Here’s a proof:

fun f(x:int):int = if x=0 then 1 else f(x-1) = (fn x => if x=0 then 1 else f(x-1)) 0 = if 0=0 then 1 else f(0-1) = if true then 1 else f(0-1) f 0

slide-21
SLIDE 21

proof (part 1)

Let P(n) be “f(n) = 1” Theorem: ∀n≥0. P(n) Proof: By simple induction on n.

  • Base: we prove P(0). Here’s a proof:

fun f(x:int):int = if x=0 then 1 else f(x-1) = (fn x => if x=0 then 1 else f(x-1)) 0 = if 0=0 then 1 else f(0-1) = if true then 1 else f(0-1) = 1 f 0

slide-22
SLIDE 22

proof (part 1)

Let P(n) be “f(n) = 1” Theorem: ∀n≥0. P(n) Proof: By simple induction on n.

  • Base: we prove P(0). Here’s a proof:

So f(0) = 1. That’s P(0). fun f(x:int):int = if x=0 then 1 else f(x-1) = (fn x => if x=0 then 1 else f(x-1)) 0 = if 0=0 then 1 else f(0-1) = if true then 1 else f(0-1) = 1 f 0

slide-23
SLIDE 23

proof (part 1)

Let P(n) be “f(n) = 1” Theorem: ∀n≥0. P(n) Proof: By simple induction on n.

  • Base: we prove P(0). Here’s a proof:

So f(0) = 1. That’s P(0). fun f(x:int):int = if x=0 then 1 else f(x-1) = (fn x => if x=0 then 1 else f(x-1)) 0 = if 0=0 then 1 else f(0-1) = if true then 1 else f(0-1) = 1

justifications?

f 0

slide-24
SLIDE 24

proof (part 2)

  • Inductive step:

Let k≥0 and assume P(k), f k = 1. We prove P(k+1), f(k+1) = 1.

  • Let v be the value of k+1, so v = k+1.

f(k+1) fun f(x:int):int = if x=0 then 1 else f(x-1)

slide-25
SLIDE 25

proof (part 2)

  • Inductive step:

Let k≥0 and assume P(k), f k = 1. We prove P(k+1), f(k+1) = 1.

  • Let v be the value of k+1, so v = k+1.

f(k+1) fun f(x:int):int = if x=0 then 1 else f(x-1) = (fn x => if x=0 then 1 else f(x-1))(k+1)

slide-26
SLIDE 26

proof (part 2)

  • Inductive step:

Let k≥0 and assume P(k), f k = 1. We prove P(k+1), f(k+1) = 1.

  • Let v be the value of k+1, so v = k+1.

f(k+1) fun f(x:int):int = if x=0 then 1 else f(x-1) = (fn x => if x=0 then 1 else f(x-1))(k+1) = (fn x => if x=0 then 1 else f(x-1))(v)

slide-27
SLIDE 27

proof (part 2)

  • Inductive step:

Let k≥0 and assume P(k), f k = 1. We prove P(k+1), f(k+1) = 1.

  • Let v be the value of k+1, so v = k+1.

f(k+1) fun f(x:int):int = if x=0 then 1 else f(x-1) = if v=0 then 1 else f(v-1) = (fn x => if x=0 then 1 else f(x-1))(k+1) = (fn x => if x=0 then 1 else f(x-1))(v)

slide-28
SLIDE 28

proof (part 2)

  • Inductive step:

Let k≥0 and assume P(k), f k = 1. We prove P(k+1), f(k+1) = 1.

  • Let v be the value of k+1, so v = k+1.

f(k+1) = if false then 1 else f(v-1) fun f(x:int):int = if x=0 then 1 else f(x-1) = if v=0 then 1 else f(v-1) = (fn x => if x=0 then 1 else f(x-1))(k+1) = (fn x => if x=0 then 1 else f(x-1))(v)

slide-29
SLIDE 29

proof (part 2)

  • Inductive step:

Let k≥0 and assume P(k), f k = 1. We prove P(k+1), f(k+1) = 1.

  • Let v be the value of k+1, so v = k+1.

f(k+1) = f(v-1) = if false then 1 else f(v-1) fun f(x:int):int = if x=0 then 1 else f(x-1) = if v=0 then 1 else f(v-1) = (fn x => if x=0 then 1 else f(x-1))(k+1) = (fn x => if x=0 then 1 else f(x-1))(v)

slide-30
SLIDE 30

proof (part 2)

  • Inductive step:

Let k≥0 and assume P(k), f k = 1. We prove P(k+1), f(k+1) = 1.

  • Let v be the value of k+1, so v = k+1.

f(k+1) = f(v-1) = f(k) = if false then 1 else f(v-1) fun f(x:int):int = if x=0 then 1 else f(x-1) = if v=0 then 1 else f(v-1) = (fn x => if x=0 then 1 else f(x-1))(k+1) = (fn x => if x=0 then 1 else f(x-1))(v)

slide-31
SLIDE 31

proof (part 2)

  • Inductive step:

Let k≥0 and assume P(k), f k = 1. We prove P(k+1), f(k+1) = 1.

  • Let v be the value of k+1, so v = k+1.

f(k+1) = f(v-1) = f(k) = if false then 1 else f(v-1) since v=k+1 fun f(x:int):int = if x=0 then 1 else f(x-1) = if v=0 then 1 else f(v-1) = (fn x => if x=0 then 1 else f(x-1))(k+1) = (fn x => if x=0 then 1 else f(x-1))(v)

slide-32
SLIDE 32

proof (part 2)

  • Inductive step:

Let k≥0 and assume P(k), f k = 1. We prove P(k+1), f(k+1) = 1.

  • Let v be the value of k+1, so v = k+1.

f(k+1) = f(v-1) = f(k) = if false then 1 else f(v-1) = 1 by assumption P(k) since v=k+1 fun f(x:int):int = if x=0 then 1 else f(x-1) = if v=0 then 1 else f(v-1) = (fn x => if x=0 then 1 else f(x-1))(k+1) = (fn x => if x=0 then 1 else f(x-1))(v)

slide-33
SLIDE 33

proof (part 2)

  • Inductive step:

Let k≥0 and assume P(k), f k = 1. We prove P(k+1), f(k+1) = 1.

  • Let v be the value of k+1, so v = k+1.

f(k+1) = f(v-1) = f(k) = if false then 1 else f(v-1) = 1 by assumption P(k) So P(k+1) holds. since v=k+1 fun f(x:int):int = if x=0 then 1 else f(x-1) = if v=0 then 1 else f(v-1) = (fn x => if x=0 then 1 else f(x-1))(k+1) = (fn x => if x=0 then 1 else f(x-1))(v)

slide-34
SLIDE 34

Notes

  • State the induction hypothesis clearly
  • Use induction hypothesis
  • nly when justified
  • Use equations and rules only when justified
  • Use math and logic accurately
  • Give explanation for non-trivial steps
slide-35
SLIDE 35

Warning

  • It’s easy to write bogus proofs
  • We want you to learn how to write

excellent proofs

  • Here are some bad examples,

not to be copied…

slide-36
SLIDE 36

Is this a proof of f 0 = 1?

slide-37
SLIDE 37

Is this a proof of f 0 = 1?

f 0 = 1

slide-38
SLIDE 38

Is this a proof of f 0 = 1?

(fn x => if x=0 then 1 else f(x-1)) 0 = 1 f 0 = 1

slide-39
SLIDE 39

Is this a proof of f 0 = 1?

(fn x => if x=0 then 1 else f(x-1)) 0 = 1 if 0=0 then 1 else f(0-1) = 1 f 0 = 1

slide-40
SLIDE 40

Is this a proof of f 0 = 1?

(fn x => if x=0 then 1 else f(x-1)) 0 = 1 if 0=0 then 1 else f(0-1) = 1 if true then 1 else f(0-1) = 1 f 0 = 1

slide-41
SLIDE 41

Is this a proof of f 0 = 1?

(fn x => if x=0 then 1 else f(x-1)) 0 = 1 if 0=0 then 1 else f(0-1) = 1 if true then 1 else f(0-1) = 1 f 0 = 1 1 = 1

slide-42
SLIDE 42

Is this a proof of f 0 = 1?

true (fn x => if x=0 then 1 else f(x-1)) 0 = 1 if 0=0 then 1 else f(0-1) = 1 if true then 1 else f(0-1) = 1 f 0 = 1 1 = 1

slide-43
SLIDE 43

Is this a proof of f 0 = 1?

true (fn x => if x=0 then 1 else f(x-1)) 0 = 1 if 0=0 then 1 else f(0-1) = 1 if true then 1 else f(0-1) = 1 f 0 = 1 1 = 1

slide-44
SLIDE 44

Is this a proof of f 0 = 1?

true (fn x => if x=0 then 1 else f(x-1)) 0 = 1 if 0=0 then 1 else f(0-1) = 1 if true then 1 else f(0-1) = 1 f 0 = 1 1 = 1 No, this just shows that “if f 0 = 1 then true is true”

slide-45
SLIDE 45

Is this a proof of f 0 = 1?

true (fn x => if x=0 then 1 else f(x-1)) 0 = 1 if 0=0 then 1 else f(0-1) = 1 if true then 1 else f(0-1) = 1 f 0 = 1 1 = 1 No, this just shows that “if f 0 = 1 then true is true” The first line in this “proof” isn’t (yet) a math fact!

slide-46
SLIDE 46

is this a proof?

2 = 1 1 = 2 2+1 = 1+2 3=3 true by symmetry by adding by arithmetic Is this a proof that 2 = 1?

slide-47
SLIDE 47

is this a proof?

2 = 1 1 = 2 2+1 = 1+2 3=3 true by symmetry by adding by arithmetic Is this a proof that 2 = 1?

slide-48
SLIDE 48

Every non-empty set of dinosaurs has the same colo(u)r.

Theorem Induction step:

slide-49
SLIDE 49

The proof is wrong

  • The inductive step is inaccurate

P(2) does not follow from P(1)

slide-50
SLIDE 50

Is this a proof?

fun silly(x:int):int = silly(x) fun hitchhiker(n:int):int = 42 For all values x : int, hitchhiker(silly x) = 42. Proof hitchhiker(silly x) = (fn n => 42) (silly x) = [(silly x)/n] 42 Claim = 42 … QED

slide-51
SLIDE 51

Is this a proof?

fun silly(x:int):int = silly(x) fun hitchhiker(n:int):int = 42 For all values x : int, hitchhiker(silly x) = 42. Proof hitchhiker(silly x) = (fn n => 42) (silly x) = [(silly x)/n] 42 Claim = 42 … QED

No! The substitution step isn’t justified, because (silly x) is not a value.

slide-52
SLIDE 52

What is a proof?

A proof is a logical sequence of steps, leading to a conclusion.

  • Each step must follow logically

from math facts,

  • r the results of earlier steps.

(again)

A bogus proof can have a false conclusion An excellent proof has a true conclusion

slide-53
SLIDE 53

Using simple induction

  • Q: When can I use simple induction to

prove a property of a recursive function f ?

  • A: When we can find a non-negative

measure of argument size and show that if f(x) calls f(y) then size(y) = size(x)-1

pick a notion of size appropriate for f

slide-54
SLIDE 54

Examples

fun fact (x:int) : int = if x=0 then 1 else x * fact(x-1) fun sum [ ] = 0 | sum (x::R) = x + sum R

slide-55
SLIDE 55

Examples

fun fact (x:int) : int = if x=0 then 1 else x * fact(x-1) fun sum [ ] = 0 | sum (x::R) = x + sum R Which of the following can be proven by simple induction?

slide-56
SLIDE 56

Examples

fun fact (x:int) : int = if x=0 then 1 else x * fact(x-1) fun sum [ ] = 0 | sum (x::R) = x + sum R fact is total Which of the following can be proven by simple induction?

slide-57
SLIDE 57

Examples

fun fact (x:int) : int = if x=0 then 1 else x * fact(x-1) fun sum [ ] = 0 | sum (x::R) = x + sum R Which of the following can be proven by simple induction?

slide-58
SLIDE 58

Examples

fun fact (x:int) : int = if x=0 then 1 else x * fact(x-1) fun sum [ ] = 0 | sum (x::R) = x + sum R Which of the following can be proven by simple induction? For all n≥0, fact n evaluates to an integer value

slide-59
SLIDE 59

Examples

fun fact (x:int) : int = if x=0 then 1 else x * fact(x-1) fun sum [ ] = 0 | sum (x::R) = x + sum R Which of the following can be proven by simple induction?

slide-60
SLIDE 60

Examples

fun fact (x:int) : int = if x=0 then 1 else x * fact(x-1) fun sum [ ] = 0 | sum (x::R) = x + sum R Which of the following can be proven by simple induction? sum is total

slide-61
SLIDE 61

Examples

fun fact (x:int) : int = if x=0 then 1 else x * fact(x-1) fun sum [ ] = 0 | sum (x::R) = x + sum R Which of the following can be proven by simple induction?

slide-62
SLIDE 62

Examples

fun fact (x:int) : int = if x=0 then 1 else x * fact(x-1) fun sum [ ] = 0 | sum (x::R) = x + sum R Which of the following can be proven by simple induction? For all n≥0, fact n > n

slide-63
SLIDE 63

Examples

fun fact (x:int) : int = if x=0 then 1 else x * fact(x-1) fun sum [ ] = 0 | sum (x::R) = x + sum R Which of the following can be proven by simple induction?

slide-64
SLIDE 64

Examples

fun fact (x:int) : int = if x=0 then 1 else x * fact(x-1) fun sum [ ] = 0 | sum (x::R) = x + sum R Which of the following can be proven by simple induction? For all n>1, fact n > n

slide-65
SLIDE 65

eval again

fun eval [ ] = 0 | eval (d::L) = d + 10 * (eval L)

To prove: For all integer lists L there is an integer n such that eval L ⟹* n

eval :int list -> int

slide-66
SLIDE 66

eval again

fun eval [ ] = 0 | eval (d::L) = d + 10 * (eval L)

(The length of the argument list decreases in the recursive call)

To prove: For all integer lists L there is an integer n such that eval L ⟹* n

eval :int list -> int

slide-67
SLIDE 67

Exercise

  • Prove the specification for eval
  • It’s a simple induction on list length

This shows that eval : int list -> int is a total function.

For all values L : int list, eval L evaluates to a value.

slide-68
SLIDE 68

Life’s not simple

You cannot use simple induction on n for

fun decimal (n:int) : int list = if n<10 then [n] else (n mod 10) :: decimal (n div 10)

Why not? We need a stronger form of induction…

slide-69
SLIDE 69

Strong induction

  • To prove a property of the form

Show that, for all k ≥ 0, P(k) follows logically from P(0), ... , P(k-1). P(n), for all non-negative integers n you can use any, all, or none to establish P(k) inductive step

slide-70
SLIDE 70

Why this works

  • P(0) gets a direct proof WHY?
  • P(0) implies P(1)
  • P(0), P(1) imply P(2)
  • P(0), P(1), P(2) imply P(3)

step step step For each k ≥ 0 we can establish P(k) with k uses of step

slide-71
SLIDE 71

Using strong induction

  • Q: When can I use strong induction to

prove a property of a recursive function f ?

  • A: When we can find a non-negative

measure of argument size and show that if f(x) calls f(y) then size(y) < size(x)

slide-72
SLIDE 72

Notes

  • Sometimes, even for simple induction,

it’s convenient to handle several “base” cases at the same time

  • A proof using strong induction

may not need a separate “base” case analysis

  • can sometimes handle all possible

arguments in the “inductive step”

slide-73
SLIDE 73

Example

fun decimal (n:int) : int list = if n<10 then [n] else (n mod 10) :: decimal (n div 10)

To prove: For all values n≥0, eval(decimal n) = n

slide-74
SLIDE 74

Example

fun decimal (n:int) : int list = if n<10 then [n] else (n mod 10) :: decimal (n div 10)

To prove: For all values n≥0, eval(decimal n) = n When n≥10, we get 0 ≤ n div 10 < n

slide-75
SLIDE 75

Example

fun decimal (n:int) : int list = if n<10 then [n] else (n mod 10) :: decimal (n div 10)

To prove: For all values n≥0, eval(decimal n) = n When n≥10, we get 0 ≤ n div 10 < n

so the argument value decreases, stays non-negative, in the recursive call

slide-76
SLIDE 76

Proof by strong induction

  • For 0 ≤ n < 10, show directly that

eval(decimal n) = n

  • For n ≥ 10, assume that

For each m such that 0 ≤ m < n, eval(decimal m) = m Then show that eval(decimal n) = n

multiple base cases handled together

use inductive analysis for cases that make a recursive call

slide-77
SLIDE 77

Reminder

fun eval [ ] = 0 | eval (d::L) = d + 10 * (eval L)

fun decimal n = if n<10 then [n] else (n mod 10) :: decimal (n div 10)

For all values n≥0, eval(decimal n) = n Proof: will be by strong induction on n We want to prove:

slide-78
SLIDE 78

Proof sketch

  • For 0 ≤ n < 10 we have

eval(decimal n) = eval [n] = n

(the base cases)

(That was easy!)

(We used the function definitions!)

slide-79
SLIDE 79

Proof sketch

(the inductive part)

slide-80
SLIDE 80

Proof sketch

  • For n ≥ 10 let r = n mod 10, q = n div 10.

(the inductive part)

slide-81
SLIDE 81

Proof sketch

  • For n ≥ 10 let r = n mod 10, q = n div 10.

eval(decimal n) = eval ((n mod 10) :: decimal(n div 10)) = eval (r :: decimal q)

(the inductive part)

slide-82
SLIDE 82

Proof sketch

  • For n ≥ 10 let r = n mod 10, q = n div 10.
  • Since 0 ≤ q < n it follows from IH that

eval(decimal n) = eval ((n mod 10) :: decimal(n div 10)) = eval (r :: decimal q)

(the inductive part)

slide-83
SLIDE 83

Proof sketch

  • For n ≥ 10 let r = n mod 10, q = n div 10.
  • Since 0 ≤ q < n it follows from IH that

eval(decimal n) = eval ((n mod 10) :: decimal(n div 10)) = eval (r :: decimal q) eval(decimal q) = q

(the inductive part)

slide-84
SLIDE 84

Proof sketch

  • For n ≥ 10 let r = n mod 10, q = n div 10.
  • Since 0 ≤ q < n it follows from IH that
  • Hence there is a list value Q such that

eval(decimal n) = eval ((n mod 10) :: decimal(n div 10)) = eval (r :: decimal q) eval(decimal q) = q

(the inductive part)

slide-85
SLIDE 85

Proof sketch

  • For n ≥ 10 let r = n mod 10, q = n div 10.
  • Since 0 ≤ q < n it follows from IH that
  • Hence there is a list value Q such that

eval(decimal n) = eval ((n mod 10) :: decimal(n div 10)) = eval (r :: decimal q) eval(decimal q) = q decimal q = Q and eval Q = q

(the inductive part)

slide-86
SLIDE 86

Proof sketch

  • For n ≥ 10 let r = n mod 10, q = n div 10.
  • Since 0 ≤ q < n it follows from IH that
  • Hence there is a list value Q such that

eval(decimal n) = eval ((n mod 10) :: decimal(n div 10)) = eval (r :: decimal q) eval(decimal q) = q decimal q = Q and eval Q = q So

(the inductive part)

slide-87
SLIDE 87

Proof sketch

  • For n ≥ 10 let r = n mod 10, q = n div 10.
  • Since 0 ≤ q < n it follows from IH that
  • Hence there is a list value Q such that

eval(decimal n) = eval ((n mod 10) :: decimal(n div 10)) = eval (r :: decimal q) eval(decimal q) = q decimal q = Q and eval Q = q So eval (r :: decimal q) = eval (r::Q) = r + 10 * (eval Q) = r + 10 * q = n

(the inductive part)

slide-88
SLIDE 88

Proof sketch

  • For n ≥ 10 let r = n mod 10, q = n div 10.
  • Since 0 ≤ q < n it follows from IH that
  • Hence there is a list value Q such that

eval(decimal n) = eval ((n mod 10) :: decimal(n div 10)) = eval (r :: decimal q) eval(decimal q) = q decimal q = Q and eval Q = q So eval (r :: decimal q) = eval (r::Q) = r + 10 * (eval Q) = r + 10 * q = n This shows that eval(decimal n) = n

(the inductive part)

slide-89
SLIDE 89

Proof sketch

  • The base analysis shows P(0), P(1),…, P(9)
  • The inductive analysis shows that for n ≥ 10,

P(n) follows from {P(0),…P(n-1)}

  • Hence, for all n ≥ 0, P(n) holds

(conclusion)

Let P(n) be “eval(decimal n) = n”

slide-90
SLIDE 90

Notes

  • We used equational reasoning to show that

for all values n ≥ 0, eval(decimal n) = n

  • It follows that for all expressions e : int,

if e ⟹* n and n ≥ 0, then eval(decimal e) ⟹* n

slide-91
SLIDE 91

So far

  • Simple and strong induction
  • Examples of their use
  • Just the beginning…
slide-92
SLIDE 92

fun log(x:int):int = if x=1 then 0 else 1 + log(x div 2)

Next

  • What would you do?
slide-93
SLIDE 93

log

fun log(x:int):int = if x=1 then 0 else 1 + log(x div 2)

slide-94
SLIDE 94

log

fun log(x:int):int = if x=1 then 0 else 1 + log(x div 2) log : int -> int

slide-95
SLIDE 95

log

fun log(x:int):int = if x=1 then 0 else 1 + log(x div 2) log : int -> int REQUIRES n > 0

slide-96
SLIDE 96

log

fun log(x:int):int = if x=1 then 0 else 1 + log(x div 2) log : int -> int REQUIRES n > 0 ENSURES log n keeps dividing n by 2 until it gets to 1

slide-97
SLIDE 97

log

fun log(x:int):int = if x=1 then 0 else 1 + log(x div 2) log : int -> int REQUIRES n > 0 ENSURES log n keeps dividing n by 2 until it gets to 1 too vague… doesn’t describe the result

slide-98
SLIDE 98

log

fun log(x:int):int = if x=1 then 0 else 1 + log(x div 2) log : int -> int REQUIRES n > 0

slide-99
SLIDE 99

log

fun log(x:int):int = if x=1 then 0 else 1 + log(x div 2) log : int -> int REQUIRES n > 0 ENSURES log n evaluates to an integer k

slide-100
SLIDE 100

log

fun log(x:int):int = if x=1 then 0 else 1 + log(x div 2) log : int -> int REQUIRES n > 0 ENSURES log n evaluates to an integer k such that 2k ≤ n < 2k+1

slide-101
SLIDE 101

log

fun log(x:int):int = if x=1 then 0 else 1 + log(x div 2) log : int -> int REQUIRES n > 0 ENSURES log n evaluates to an integer k such that 2k ≤ n < 2k+1 describes the key properties

  • f the result value
slide-102
SLIDE 102

Exercise

  • Show that for each integer n > 0, there is

a unique integer k such that 2k ≤ n < 2k+1

  • this k is called the logarithm (base 2) of n
  • Prove the spec for log

log computes logarithms (base 2)