Recursion and Induction: Program Development; Variable Ordering - - PowerPoint PPT Presentation

recursion and induction program development variable
SMART_READER_LITE
LIVE PREVIEW

Recursion and Induction: Program Development; Variable Ordering - - PowerPoint PPT Presentation

Recursion and Induction: Program Development; Variable Ordering Greg Plaxton Theory in Programming Practice, Fall 2005 Department of Computer Science University of Texas at Austin Program Development Today we will develop a Haskell program


slide-1
SLIDE 1

Recursion and Induction: Program Development; Variable Ordering

Greg Plaxton Theory in Programming Practice, Fall 2005 Department of Computer Science University of Texas at Austin

slide-2
SLIDE 2

Program Development

  • Today we will develop a Haskell program for the satisfiability problem
  • As discussed in the previous lecture, we will assume that the input is a

CNF formula – Such a formula is a conjunction of clauses – Each clause is a disjunction of literals – Each literal is either a variable or the negation of a variable

  • Our implementation will use the Davis-Putnam procedure outlined last

time

Theory in Programming Practice, Plaxton, Fall 2005

slide-3
SLIDE 3

Representation of a Formula

  • Each variable will be represented by an arbitrary string
  • Each literal will be represented by a string consisting of a ’+’ or ’-’

symbol followed by the associated variable name – The prefix ’+’ indicates a variable that is not negated – The prefix ’-’ indicates a negated variable

  • A clause will be represented as a list of literals
  • A formula will be represented as a list of clauses

Theory in Programming Practice, Plaxton, Fall 2005

slide-4
SLIDE 4

Example of a Formula

  • Consider the formula f equal to

(¬p ∨ q ∨ r) ∧ (p ∨ ¬r) ∧ (¬q ∨ r) ∧ (¬p ∨ ¬q ∨ ¬r) ∧ (p ∨ q ∨ r)

  • We represent the formula f as follows

[ ["-p", "+q", "+r"], ["+p", "-r"], ["-q", "+r"], ["-p", "-q", "-r"], ["+p", "+q", "+r"] ]

Theory in Programming Practice, Plaxton, Fall 2005

slide-5
SLIDE 5

Types

  • In our previous examples we have allowed Haskell to deduce the types
  • In this example we will show how to define the types explicitly
  • We use the following type definitions

type Literal = String type Clause = [Literal] type Formula = [Clause]

Theory in Programming Practice, Plaxton, Fall 2005

slide-6
SLIDE 6

Top-Down Design

  • Let us define a function that accepts a formula as input and returns a

boolean indicating whether the formula is satisfiable

  • If the formula is empty, then the result is True
  • If it contains an empty clause, then the result is False
  • Otherwise, we choose some literal of the formula, decompose the

formula into two subformulae based on this literal, solve each subformula recursively for satisfiability, and return True if either returns True

Theory in Programming Practice, Plaxton, Fall 2005

slide-7
SLIDE 7

The Top-Level Function dp

  • We define our top-level function dp as follows

dp :: Formula -> Bool dp xss | xss == [] = True | emptyin xss = False | otherwise = (dp yss) || (dp zss) where v = literal xss yss = reduce v xss zss = reduce (neg v) xss

  • We have introduced a number of auxiliary functions that are discussed

in greater detail on the next slide

Theory in Programming Practice, Plaxton, Fall 2005

slide-8
SLIDE 8

Functions used in dp

  • emptyin xss: returns True if xss has an empty clause
  • literal xss: returns a literal from xss, where xss is nonempty and

does not contain an empty clause

  • neg v: returns the string corresponding to the negation of v
  • reduce v xss, where v is a literal: returns the formula obtained from

xss by dropping any clause containing the literal v and dropping any

  • ccurrence of the literal neg v in each remaining clause

Theory in Programming Practice, Plaxton, Fall 2005

slide-9
SLIDE 9

The emptyin Function

  • The code for emptyin is straightforward:
  • - Does the formula contain an empty list?

emptyin :: Formula -> Bool emptyin [] = False emptyin ([]: xss) = True emptyin (xs: xss) = emptyin xss

Theory in Programming Practice, Plaxton, Fall 2005

slide-10
SLIDE 10

The literal Function

  • Function literal can return any literal from the formula
  • It is easy to return the first literal of the first clause of its argument
  • Since the formula is not empty and has no empty clause, this procedure

is valid {- Returns a literal from a formula. It returns the first literal of the first list. The list is not empty, and it does not contain an empty list.

  • }

literal :: Formula -> Literal literal ((x: xs):xss) = x

Theory in Programming Practice, Plaxton, Fall 2005

slide-11
SLIDE 11

The neg Function

  • The neg function is easy to code:
  • - negate a literal

neg :: Literal -> Literal neg (’+’: var) = ’-’: var neg (’-’: var) = ’+’: var

Theory in Programming Practice, Plaxton, Fall 2005

slide-12
SLIDE 12

The reduce Function

  • A call to reduce v xss scans through the clauses of xss
  • If xss is empty, the result is the empty formula
  • Otherwise, for each clause xs,

– If v appears in xs, drop the clause – If the negation of v appears in xs then modify xs by removing the negation of v – If neither of the above conditions hold, retain the clause

Theory in Programming Practice, Plaxton, Fall 2005

slide-13
SLIDE 13

The reduce Function

  • Here is the code for the reduce function:
  • - reduce a literal through a formula

reduce :: Literal -> Formula -> Formula reduce v [] = [] reduce v (xs:xss) | inl v xs = reduce v xss | inl (neg v) xs = (remove (neg v) xs): (reduce v xss) | otherwise = xs : (reduce v xss)

Theory in Programming Practice, Plaxton, Fall 2005

slide-14
SLIDE 14

Functions used in reduce

  • Function reduce introduces two new functions, which will be developed

next – inl v xs, where v is a literal and xs is a clause: returns True iff v appears in xs – remove u xs, where u is a literal known to be in clause xs: return the clause obtained by removing u from xs.

Theory in Programming Practice, Plaxton, Fall 2005

slide-15
SLIDE 15

The inl Function

  • Here is the code for the inl function:
  • - check if a literal is in a clause

inl :: Literal -> Clause -> Bool inl v [] = False inl v (x:xs) = (v == x) || (inl v xs)

Theory in Programming Practice, Plaxton, Fall 2005

slide-16
SLIDE 16

The remove Function

  • Here is the code for the remove function:
  • - remove a literal u from clause xs. u is in xs.

remove :: Literal -> Clause -> Clause remove u (x:xs) | x == u = xs | otherwise = (x : (remove u xs))

Theory in Programming Practice, Plaxton, Fall 2005

slide-17
SLIDE 17

Refining our Implementation

  • Currently we scan a clause to find a given literal
  • Suppose we impose an order on the variables/literals
  • Then we could search more efficiently
  • Furthermore, we get to choose which variable to eliminate

– Use the order imposed above to determine the order of elimination – When we eliminate a particular variable, it is guaranteed to be associated with the first literal of any clause in which it appears

Theory in Programming Practice, Plaxton, Fall 2005

slide-18
SLIDE 18

The dp2 Function

  • Function dp2, given below, does the job of dp, but it needs an

extra argument, like [ "p", "q" ,"r" ], which defines the variable

  • rdering

dp2 vlist xss | xss == [] = True | emptyin xss = False | otherwise = (dp2 wlist yss) || (dp2 wlist zss) where v:wlist = vlist yss = reduce2 (’+’: v) xss zss = reduce2 (’-’: v) xss

  • We no longer need the functions inl, remove, and literal

Theory in Programming Practice, Plaxton, Fall 2005

slide-19
SLIDE 19

The reduce2 Function

  • Here is the code for the reduce2 function:
  • - reduce a literal through a formula

reduce2 :: Literal -> Formula -> Formula reduce2 w [] = [] reduce2 w ((x:xs):xss) | w == x = reduce2 w xss | (neg w) == x = xs: (reduce2 w xss) | otherwise = (x:xs): (reduce2 w xss)

Theory in Programming Practice, Plaxton, Fall 2005

slide-20
SLIDE 20

A Further Improvement

  • Note that reduce2 scans its argument list twice, once for w and again

for neg w

  • We define reduce3 to scan the given list only once, checking for both

w and neg w simultaneously, and creating two lists reduce3 v [] = ([],[]) reduce3 v ((x:xs):xss) | ’+’: v == x = (yss , xs:zss) | ’-’: v == x = (xs:yss, zss ) | otherwise = ((x:xs):yss, (x:xs):zss) where (yss,zss) = reduce3 v xss

  • Note that the interface to reduce3 is slightly different; also, we have

eliminated the use of function neg

Theory in Programming Practice, Plaxton, Fall 2005

slide-21
SLIDE 21

The dp3 Function

  • Here is the code for the dp3 function:

dp3 vlist xss | xss == [] = True | emptyin xss = False | otherwise = (dp3 wlist yss) || (dp3 wlist zss) where v:wlist = vlist (yss,zss) = reduce3 v xss

Theory in Programming Practice, Plaxton, Fall 2005