functional design and programming lecture 11: functional reasoning

Post on 17-Dec-2015

226 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Functional Design and Programming

Lecture 11:

Functional reasoning

Literature

Paulson, chapter 6

Exercises

Paulson: 6.5-6.8, 6.9, 6.12

Overview

Induction principles Program verification Transformational programming

Logical Notation: Formulas

¬ A not A A B A and B A B A or B A -> B A implies B A <-> B A if and only if B x. A(x) for all x, A(x) x. A(x) for some x, A(x)

Free and Bound Variables

All variable occurrences in the scope of a or -binding are bound; e.g. n and m inm n. m > n.

All other variable occurrences in a formula are free.

Bound-variable renaming

Bound variables (variable binding plus all associated bound variable occurrences) can be renamed without changing the meaning of the formula.

Example: m n. m > n. q p. q > p. m’ n’. m’ > n’.

Precedence of Connectives

The logical connectives bind weaker and weaker in the order given before.

Natural Numbers

Basis: (n = 0) 0 is a natural number. Rule: (n -> n+1) If n is a natural number,

then n+1 is a natural number. Nothing else is a natural number.

0

basis

1

rule

2

rule

3 4 5 6 7 ...

rule rule ...

Mathematical Induction

We want to prove n N. P(n) by mathematical induction on n.

Basis: (n = 0) Prove P(0).

Induction: (n = m +1) Assume that P(m) holds. (Induction hypothesis) Show that P(m+1) holds.

Mathematical Induction...

0

basis

P(0)

1

rule

P(1)

3 4 5 6 7 ...

rule rule ...

P(3) P(4) P(5) P(6) P(7) ...

2

P(2)

rule

Example: Factorials

fun fact 0 = 1 | fact n = n * fact (n-1)

fun facti (0, p) = p | facti (n, p) = facti (n-1, n*p)

Example: Fibonacchi Numbers

fun fib 0 = 0 | fib 1 = 1 | fib n = fib (n-1) + fib (n-2)

fun itfib (1, prev, curr) = curr | itfib (n, prev, curr) = itfib (n-1, curr, prev + curr)

Complete Induction

We want to prove nN. P(n) by complete induction on n.

Induction: Assume that k < n. P(k) holds. (Induction

hypothesis) Show that P(n) holds.

Complete Induction...

0

P(0)

1

P(1)

3 4 5 6 7 ...

P(3) P(4) P(5) P(6) P(7) ...

2

P(2)

We may assume that P(0),..., P(n-1)have already been proved when proving P(n).(Consider n=7 above.)

Structural Induction: Lists

We want to prove la list. P(l) by structural induction on l.

Basis: (l = nil) Prove P(nil).

Induction: (l = x :: xs) Assume that P(xs) holds. (Induction hypothesis) Show that P(x :: xs) holds.

List functions

fun nlength nil = 0 | nlength (x::xs) = 1 + nlength xs

fun nil @ ys = ys | (x :: xs) @ ys = x :: (xs @ ys)

fun nrev nil = nil | nrev (x::xs) = (nrev xs) @ [x]

fun revAppend (nil, ys) = ys | revAppend (x::xs, ys) = revAppend (xs, x::ys)

Structural Induction: Trees

We want to prove t a tree. P(t) by structural induction on t.

Basis: (t = Lf) Prove P(Lf).

Induction: (t = Br(x, t1, t2)) Assume that P(t1) and P(t2) hold. (Induction

hypotheses) Show that P(Br(x, t1, t2)) holds.

Tree functions

fun size Lf = 0 | size (Br (v, t1, t2)) = 1 + size t1 + size t2

fun depth Lf = 0 | depth (Br (v, t1, t2)) = 1 + Int.max (depth t1, depth t2)

Transformational Programming

Goal: Transforming specifications into programs that are guaranteed to be correct by construction.

Method: Apply transformation rules on functional programs (specifications) that are guaranteed to preserve their semantics (correctness).

Transformational Programming: Example

fun preorder Lf = nil | preorder (Br (x, t1, t2)) = [x] @ preorder t1 @ preorder t2

Idea: Find function preorder’ such that

preorder’(t, l) = preorder t @ l

for all trees t and lists l.

(Formal) Program Verification

Specification: Precise description of result of program execution.

Verification: Did we build the system right? Proof or test that a program satisfies the given specification.

Validation: Did we build the right system? Test that program has the intended behavior.

(Formal) Program Verification...

Ingredients: Program: The program at hand Specification: What properties should the

program satisfy to be considered correct? Assumptions: What properties about the

programming language, hardware, context, etc., are assumed to hold?

Input/Output Relations

Many specifications can be expressed as input/output (I/O) predicates together with a domain of inputs for which the predicate must be satisfied.

Example: Predicate: P(t, l) <=> l = preorder t Domain: a tree (all a trees, for arbitrary a)

Total Program Correctness

A functional program f is totally correct wrt. I/O specification (P, X) if: for all x in X, P(x, f(x))

Example: for all t in a tree, preorder’ (t, nil) = preorder t

Partial Program Correctness

A functional program f is partially correct wrt. I/O specification (P, X) if: for all x in X, if f(x) terminates then P(x, f(x)).

Example: for all t in a tree, if undef(t) terminates then

undef(t) = preorder t where fun undef (t: a tree) = undef t.

Program Correctness: Sorting

Correctness predicate and domain: sorted(l, l’) <=>

ordered(l’)bag(l) = bag(l’)

t list, where t is totally ordered by operation <=: t * t -> bool

Example: forall l in t list, sorted(l, tmergesort l).

Sorting...

fun ordered nil = true | ordered [x] = true | ordered (x::y::ys) = x <= y andalso ordered (y::ys)

bag(l) = the multiset consisting of all the elements in list l.

Sorting...

fun split k nil = (nil, nil) | split 0 l = (nil, l) | split k (x :: xs) = let val (l1, l2) = split (k-1) xs in (x :: l1, l2) end

Sorting...

fun merge (nil, ys) = ys | merge (xs, nil) = xs | merge (x::xs, y::ys) = if x <= y then x :: merge(xs, y::ys) else y :: merge(x::xs, ys)

Sorting...

fun mergesort nil = nil | mergesort [x] = [x] | mergesort xs = let val k = length xs div 2 val (l1, l2) = split k xs in merge (mergesort l1, mergesort l2) end

Value of Specification

Specification requires making requirements explicit (and thus thinking about the job, before beginning with something or other)

Specifications may pinpoint: ambiguities inconsistencies incompleteness

Limitations of Specification

Not all problems can be specified completely and rigorously (e.g., where specification and validation interact)

Specifications may be counterproductive (e.g., premature or excessive formalization, not human readable and/or with no tool support)

Specification may be wrong or incomplete.

Value of Verification

Verification of simple properties can pinpoint and eliminate very costly errors (e.g. type checking).

Verification provides hard assurances under explicit assumptions.

Verification by construction (e.g., transformational programming) provides concrete design methods.

Limits of Verification

Full verification may be extraordinarily more complex than the programs and their specifications.

Manual verification is tedious and error-prone.

Correctness Driven Program Design

Start with (mathematical) specification. Refine/transform step-by-step specification

to efficient program. Verify that each step is correct.

Correctness Driven Program Design: Logical basis

Imperative programming: Floyd-Hoare logic Weakest preconditions (Dijkstra)

Functional programming: Lambda calculus Type theory Fold/unfold transformations (Burstall,

Darlington)

top related