world champion chess player garry...world champion chess player garry kasparov was defeated by...
TRANSCRIPT
World Champion chess player Garry Kasparov was defeated by IBM’s Deep Blue chess-playing computer in a six-game match in May, 1997. The match received enormous media coverage, much of which emphasized the notion that Kasparov was defending humanity’s honor. http://www.computerhistory.org/chess/stl-431e1a07b22e1/
Minimax for 2-player games
Minimax is a standard AI strategy for 2-player games that arealternating: players take turnsdeterministic: each move has a well-defined outcome (there is no randomness)perfect-information: each player knows the complete state of the game (there is no hidden informationzero-sum: if I win you lose, and vice versa — what’s good for me is bad for you (but draws are allowed)
Example: Nim
• Start with 15 pebbles• To make a move you pick up 1, 2, or 3 pebbles• Whoever picks up the last pebble loses• e.g.,
1. You pick up 3 (12 left)2. I pick up 3 (9 left)3. You pick up 2 (7 left)4. I pick up 2 (5 left)5. You pick up 1 (4 left)6. I pick up 3 (1 left)7. You pick 1 (0 left)8. I win!
Example: Nim
Nim actually has a winning strategy for the player going first!Consider Nim with 5 pebbles.If it’s your turn and there are 5 pebbles left then you lose:
if you take 1, I take 3, and there is 1 left;if you take 2, I take 2;if you take 3 I take 1.
Similarly: 9…5, 13...9, etc.The pattern:
if it’s your turn and pebbles mod 4 ≅ 1 then I have a winning strategy: choose always to leave the number of pebbles congruent to 1 mod 4.
Example: Nim
Nim is special: a quick calculation tells who will win.For a game like chess (or Kalaha!) you can’t tell (in constant time) just by looking at a board who will win.So, we must use computation to search possible future states.Build a game tree where nodes are states and edges are moves.Each row is labeled with the player whose turn it is.
Example: Nim
Next assign each node a value, saying who wins.
Maxie wins if the value is 1.Minnie wins if the value is -1.
First label the leaves.
3
0 1 2
0 0 1
0
Maxie
Minnie
Maxie
Minnie
-1
1 1
-1
Example: Nim
Then propagate the labels up the tree.
If it’s Maxie’s turn the value is the maximum of the children (because Maxie will choose the maximising move).If it’s Minnie’s it is the minimum.
First level.
3
0 1 2
0 0 1
0
Maxie
Minnie
Maxie
Minnie
-1
1 1
-1
-1
Example: Nim
Next level.
For example, on the rightmost subtree if there are two pebbles left then Minnie should take 1, leaving 1, rather than 2, leaving 0.
3
0 1 2
0 0 1
0
Maxie
Minnie
Maxie
Minnie
-1
1 1
-1
-1
1 -1
Example: Nim
Next level.
Maxie should take 2, leaving 1, rather than taking 3 or 1.
3
0 1 2
0 0 1
0
Maxie
Minnie
Maxie
Minnie
-1
1 1
-1
-1
1 -1
1
Minimax algorithm
Minimax computes the value of a game state assuming both players will play optimally.It does not account for things like
“that chess board is confusing, so it will be easy to make a mistake”For a game with a bigger search space than this we can’t draw out the whole tree!Instead, a heuristic must approximate the value of the board.Nim has a perfect heuristic: number of pebbles congruent to 1 mod 4.
Minimax algorithm
The overall algorithm is:1. explore the game tree up to a certain depth2. use the heuristic to approximate the value when the depth is
reached.For chess, a given heuristic would include which pieces are left, where they are positioned, etc.
Information Hiding
Abstract data types (ADTs) allow information hiding on types.They hide the representation (or model) behind an abstract set of operations.Separates:• data type definition from
representation• function declaration from
implementation
Application
Specification
Implementation
Interface
User
Implementor
Information Hiding
Consider modeling a computer’s Random Access Memory (RAM), which stores values in memory variables.We might model RAM in different ways:
[(Integer,Var)] -- a list of integer/variable pairs(Var -> Integer) -- a function from vars to integers
Regardless of the model, operations to obtain an initial store and access/update variables have well-defined specifications:
initial :: Storeread :: Store -> Var -> Integerwrite :: Store -> Var -> Integer -> Store
Information Hiding
The operation signatures specify the interface, upon which users and implementers agree, allowing them to work independently.But we want to isolate users from the model:• allows evolution of the model without affecting users• prevents manipulating the model in unintended ways
e.g., prevent list operations on list model, composition on function model
Example: Signature
Modules support information hiding by exposing only operations in the signature of the module header:
module Store ( Store,
initial, -- Storevalue, -- Store -> Var -> Integerupdate -- Store -> Var -> Integer -> Store
) where
Example: Implementation I
data Store = Store [ (Integer,Var) ]initial :: Storeinitial = Store []value :: Store -> Var -> Integervalue (Store []) v = 0value (Store ((n,w):s)) v| v==w = n| otherwise = value (Store s) v
update :: Store -> Var -> Integer -> Storeupdate (Store s) v n = Store ((n,v):s)
Example: Implementation II
data Store = Store (Var -> Integer)initial :: Store initial = Store (\v -> 0)value :: Store -> Var -> Integervalue (Store s) v = s vupdate :: Store -> Var -> Integer -> Storeupdate (Store s) v n
= Store (\w -> if v==w then n else s w)
Example: Implementations I and II
Note that in both implementations storing more than once to the same variable will result in adding the new value to the store, but not removing the old one!• Implementation I prepends to the list• Implementation II constructs a new function as a conditional
expression with the old function as the condition’s “else” part
Queues: First-In First-Out (FIFO)
module Queue( Queue,
emptyQ, -- Queue aisEmptyQ, -- Queue a -> BooladdQ, -- a -> Queue a -> Queue aremQ -- Queue a -> ( a , Queue a )
) where
Queues: Implementation I
newtype Queue a = Queue [a]emptyQ :: Queue aemptyQ = Queue []isEmptyQ :: Queue a -> BoolisEmptyQ (Queue []) = TrueisEmptyQ _ = FalseaddQ :: a -> Queue a -> Queue aaddQ x (Queue xs) = Queue (xs++[x])remQ :: Queue a -> ( a , Queue a )remQ q@(Queue xs)
| not (isEmptyQ q) = (head xs , Queue (tail xs))| otherwise = error "remQ"
Queues: Implementation II
addQ x (Queue xs) = Queue (x:xs)remQ q@(Queue xs)
| not (isEmptyQ q) = (last xs , Queue (init xs))| otherwise = error "remQ"
Queues: a two-list queue
Remove from left.Add to right.Only case of empty queue on left is expensive: reverse right list to left list.
Queues: Implementation III
data Queue a = Queue [a] [a]emptyQ :: Queue aemptyQ = Queue [] []isEmptyQ :: Queue a -> BoolisEmptyQ (Queue [] []) = TrueisEmptyQ _ = FalseaddQ :: a -> Queue a -> Queue aaddQ x (Queue xs ys) = Queue xs (x:ys)remQ :: Queue a -> ( a , Queue a )remQ (Queue (x:xs) ys) = (x , Queue xs ys)remQ (Queue [] ys@(z:zs)) = remQ (Queue (reverse ys) [])remQ (Queue [] []) = error "remQ"
Designing ADTs to solve problems
1. Identify and name the types in the system.2. Informally describe them.3. Write the signature of each ADT.What belongs in the signature? What doesn’t?• Create an instance• Discriminate instances• Get state from an instance• Transform an instance• Combine instances• Collapse instances
Tree module
module Tree (Tree,nil, -- Tree aisNil, -- Tree a -> Bool isNode, -- Tree a -> BoolleftSub, -- Tree a -> Tree a rightSub, -- Tree a -> Tree a treeVal, -- Tree a -> ainsTree, -- Ord a => a -> Tree a -> Tree a delete, -- Ord a => a -> Tree a -> Tree aminTree, -- Ord a => Tree a -> Maybe a
) where
ADT signatures should be minimal
Omit operations that can be defined in terms of other operations, so independent of implementation:
size :: Tree a -> Integersize t
| isNil t = 0| otherwise
= 1 + size (leftSub t) + size (rightSub t)
Search Trees
A binary search tree is a binary tree whose elements are ordered.Recall:
data Tree a = Nil | Node a (Tree a) (Tree a)A tree (Node val t1 t2) is ordered if:• all values in t1 are smaller than val,• all values in t2 are larger than val, and• the trees t1 and t2 are also orderedwhere the tree Nil is trivially ordered.We can use an ADT to enforce order, by making sure implementations of operations in the interface preserve order.
Search Trees: Signaturemodule Tree (Tree,nil, -- Tree aisNil, -- Tree a -> Bool isNode, -- Tree a -> BoolleftSub, -- Tree a -> Tree a rightSub, -- Tree a -> Tree a treeVal, -- Tree a -> ainsTree, -- Ord a => a -> Tree a -> Tree a delete, -- Ord a => a -> Tree a -> Tree aminTree, -- Ord a => Tree a -> Maybe aelemT -- Ord a => a -> Tree a -> Bool) where
Search Trees: Insertion
2 9
73
3
7
2 9
7
2 9
3
insTree val (Node v t1 t2)| v==val = Node v t1 t2| val > v = Node v t1 (insTree val t2)| val < v = Node v (insTree val t1) t2
Search Trees: Deletion7
2 9
8
2 9
8
2 9
8 2 9
8
delete val (Node v t1 t2)| val < v = Node v (delete val t1) t2| val > v = Node v t1 (delete val t2)| isNil t2 = t1| isNil t1 = t2| otherwise = join t1 t2
join t1 t2 = Node mini t1 newt
where(Just mini) = minTree t2newt = delete mini t2
Sets
Lists impose order, and allow multiplicity.[Joe, Sue, Ben] [Ben, Sue, Joe][Joe, Sue, Sue, Ben] [Joe, Sue, Ben, Sue]
Whereas, there is only one set containing these people:{Ben, Joe, Sue}
So, an implementation of the Set ADT must ensure uniqueness of elements.
Relations
A binary relation is a relationship among elements of a set.e.g., parents and children in a familyisParent = {(Ben, Sue), (Ben,Leo), (Sue, Joe)}
In general:type Relation a = Set (a,a)
So, all set operations are available on Relation values.
Relations
The image of an element: all elements related to a given elemente.g., all of Ben’s childrenimage isParent Ben = {Sue, Leo}
The image of a set of elements: all elements related to a set of elements: the union of the images (sets) of each of the elements:
unionSet {s1, … , sn} = s1 ∪ … ∪ sn = s1 `union` … `union` sne.g., addChildren: take image of a set of people under isParent and add
Relations: defining isAncestor
The transitive closure of the isParent relation.First, consider grandparent starting from parents:
e.g., (Ben,Sue), (Sue, Joe)isGrandParent = isParent `compose` isParent
e.g., {(Ben,Joe)}Set product is used by compose to pair elements of a first set with elements of a second set.
e.g., setProduct {Ben,Suzie} {Sue,Joe} = {(Ben,Sue),(Ben,Joe),(Suzie,Sue),(Suzie,Joe)}
Relations: transitive closure and limits
A relation rel is transitive if for all (a,b) and (b,c) in rel, then (a,c) is also in rel.The transitive closure of a relation rel is the smallest relation extending rel that is transitive: repeat compose until nothing more is added.To do this, we can use limit f x to give the limit of the sequence:
x, f x, f (f x), f (f (f x)), … , fn xwhich is the value the sequence settles to if it exists, computed by taking the first element in the sequence whose successor is equal to the element itself:
fn x = fn+1 x
Relations: example
Given {(Ben,Sue), (Sue,Joe)}addChildren {Joe,Ben} = {Joe,Sue,Ben}limit addChildren {Ben}
?? {Ben}=={Ben,Sue} ➝ False➝ limit addChildren {Ben,Sue}
?? {Ben,Sue}=={Ben,Joe,Sue} ➝ False➝ limit addChildren {Ben,Joe,Sue}
?? {Ben,Joe,Sue}=={Ben,Joe,Sue} ➝ True➝ {Ben,Joe,Sue}
Graphs
Another way of thinking of relations is as directed graphs:e.g., graph1 = {(1,2),(1,3),(3,2),(3,4),(4,2),(2,4)}
Here, transitive closure represents paths of reachability in the graph:e.g., the transitive closure contains (1,4), but not (2,1)
1 2
3 4
Graphs: strongly connected components
Nodes connected by a path to all other nodes in the component:e.g., the components of graph1 are {1}, {3}, {2,4}
1 2
3 4
Computing strongly connected components
• First form the relation that links points in the same componentThere is a path from x to y and vice versa if both (x,y) and (y,x) are in the closure:
connect :: Ord a => Relation a -> Relation aconnect rel = clos `inter` solc
whereclos = tClosure relsolc = inverse clos
where inverse swaps all pairs in the relation:inverse = mapSet swap
whereswap (x,y) = (y,x)
Computing strongly connected components
• Next form the components (or equivalance classes) generated by this relation
Start with the nodes (e.g., {{1},{2},{3},{4}}) and close over them using the relation:
classes :: Ord a => Relation a -> Set (Set a)classes rel
= limit (addImages rel) startwherestart = mapSet sing (eles rel)