CS 342 Lecture -*- Outline -*- * techniques for systematic programming ** Problem Analysis *** What is the problem? (What is the unknown?) **** Can you give an example? e.g., what are sample inputs, what would be the outputs? **** What type of thing is that? what are the types of the arguments, what are the types of the results? **** Is the problem solvable? are there solutions for some examples? *** Problem Specification **** How would you describe the problem? Develop a notion that describes the characteristics of the problem e.g., FOPC, Prolog **** How would you describe the solution e.g., ordered(x) means x[1] < ... < x[n] **** Formally specify the problem e.g., permutation(x,sort(x)) & ordered(sort(x)) e.g., subset(x,y) == for all e in x, e in y ** Problem solving strategies *** Have you seen something like this before? reuse the code if you can *** Build from examples? Start with simple instance of problem, construct solution by hand, generalize to program; what other cases are there?... *** What would a good plan be? some of these turn up as "tricks" on exams...and in real life what subroutine would help? (can you solve a simpler problem?) what intermediate data structure would help? (if the inputs or outputs were different, would that make the problem easier?) (what are the objects or things in the problem?) have you seen any problems like this before? (perhaps you can reuse the plan) would this be easier in another language? (switch languages or design that language feature as part of your program, or build an interpreter for a new language) what is the major concern? efficiency? ease of modification? *** Type analysis argument types suggest what functions to use to look at them if function takes a list, use null?, car, and cdr if function takes a number use =, <, etc. if it takes a set use member?, union, etc. result types suggest functions to use in body if returns a list use cons, use same type on both arms of an if... *** Transformation **** Transform specification get spec into constructive form and translate into code e.g., manipulate spec into a recursive definition with no choices left unspecified e.g., subset(x,y) == for all e in x, e in y == empty(x) or there is a z in x such that z in y and subset(residue(z,x),y) ==> (set subset (lambda (x y) (if (null? x) 'T (and (member? (pick x) y) (subset (residue (pick x) x) y))))) **** Transform imperative program into program in desired language while ==> if+recursive call, with stmts after while as else part set ==> parameter to (tail) recursive call function with local variables + initializations ==> function that calls auxilliary function with initial vals local variable ==> formal of auxilliary function *** Reuse of general parts **** Can you use pre-defined higher order functions? e.g., mapcar, combine **** Can you define a higher-order homomorphism scheme? e.g., combine for lists for-loop for integers all-elements for sets (see papers by Bird...) **** Can you use lazy lists to combine subparts of a solution? filter, map, ... *** Think abstractly! **** Is there a subproblem whose solution would help? then use procedure abstraction! break out subparts of problem into procedures **** Is there some more convenient kind of data that would help? Then use a data abstraction (rep + operations) raise level of language e.g., sets instead of lists... ** Problem solution checking questions *** How does the code match the specifification/problem? *** Checking recursion/iteration (inductive proofs) **** What's the basis of a recursion/iteration? **** How does the recursive/iterative step make progress? **** What property is preserved by the recursive calls? *** Is the type the desired type? use type inference *** Testing **** Does it work for simple examples? **** Does it work for boundary cases? **** Off by one?