1 / 27

Advanced Functional Programming

Advanced Functional Programming. Tim Sheard Oregon Graduate Institute of Science & Technology. Lecture 17: Erwig style - Functional Graphs DFS – style of depth first search. References. The style of representing graphs, and most of the examples, come from the work of Martin Erwig

hazel
Download Presentation

Advanced Functional Programming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Advanced Functional Programming • Tim Sheard • Oregon Graduate Institute of Science & Technology • Lecture 17: • Erwig style - Functional Graphs • DFS – style of depth first search

  2. References • The style of representing graphs, and most of the examples, come from the work of Martin Erwig • http://www.cs.orst.edu/~erwig/ • Functional Programming with Graphs • 2nd ACM SIGPLAN Int. Conf. on Functional Programming(ICFP'97), 52-65, 1997 • Inductive Graphs and Functional Graph Algorithms, Martin Erwig Journal of Functional Programming,

  3. 1 2 right a b left down up c 3 Graphs • Nodes = 1,2,3 • Edges = (1,2),(2,1),(3,1),(2,3) • Node Labels = a,b,c • Edge Labels = right,left,up,down

  4. Types • type Node = Int • type LNode a = (Node,a) • type UNode = LNode () • type Edge = (Node,Node) • type LEdge b = (Node,Node,b) • type UEdge = LEdge ()

  5. More Types • data Graph a b -- Abstract Type • --unlabled Graph • type UGraph = Graph () () • type Path = [Node] • type LPath a = [LNode a] • type UPath = [UNode]

  6. 1 right 2 a b left down up c 3 Making Graphs • ex1 = mkGraph [(1,"a"),(2,"b"),(3,"c")] • [(1,2,"right"),(2,1,"left"), • (2,3,"down"),(3,1,"up")] • Main> ex1 • 1:"a"->[("right",2)] • 2:"b"->[("left",1),("down",3)] • 3:"c"->[("up",1)]

  7. Looking inside • noNodes :: Graph a b -> Int • nodes :: Graph a b -> [Node] • labNodes :: Graph a b -> [LNode a] • -- [(Node,a)] • edges :: Graph a b -> [Edge] • --[(Node,Node)] • labEdges :: Graph a b -> [LEdge b] • -– [(Node,Node,b)]

  8. 1 right 2 a b left down up c 3 Examples • Main> noNodes ex1 • 3 • Main> nodes ex1 • [1,2,3] • Main> labEdges ex1 • [(1,2,"right"),(2,1,"left"), • (2,3,"down"),(3,1,"up")]

  9. Decomposing Graphs edge label • type Adj b = [(b,Node)] • type Context a b = (Adj b,Node,a,Adj b) • type MContext a b = Maybe (Context a b) • type Decomp a b = (MContext a b,Graph a b) • type GDecomp a b = (Context a b,Graph a b) • type UContext = ([Node],Node,[Node]) • type UDecomp = (Maybe UContext,UGraph) • match :: Node -> Graph a b -> Decomp a b Its predecessors The node Its succesors Its label

  10. 1 2 right a b left down up c 3 (Just(ps,n,lab,ss),ex2) = match 2 ex1 • Main> ps • [("right",1)] --predecessors • Main> ss --successors • [("left",1),("down",3)] • Main> n –- the node • 2 • Main> lab -- its label • "b" • Main> ex2 • 1:"a"->[] • 3:"c"->[("up",1)]

  11. 1 a up c 3 (Just(ps2,n2,lab2,ss2),ex3) = match 3 ex2 • Main> ps2 • [] • Main> n2 • 3 • Main> lab2 • "c" • Main> ss2 • [("up",1)] • Main> ex3 • 1:"a"->[]

  12. Constructing Graphs Inductively • empty :: Graph a b • embed :: Context a b -> Graph a b -> Graph a b • infixr & • c & g = embed c g • ex4 = (ps2,n2,lab2,ss2) & ex3 • Main> ex4 • 1:"a"->[] • 3:"c"->[("up",1)] 1 a up c 3

  13. Operations on graphs • -- maps on nodes • nmap :: (a->c) -> Graph a b -> Graph c b • -- maps on edges • emap :: (b->c) -> Graph a b -> Graph a c • -- graph reversal • grev :: Graph a b -> Graph a b

  14. Example • ex5 = nmap (ord . head) ex1 • Main> ex5 • 1:97->[("right",2)] • 2:98->[("down",3),("left",1)] • 3:99->[("up",1)] • Main> ex1 • 1:"a"->[("right",2)] • 2:"b"->[("left",1),("down",3)] • 3:"c"->[("up",1)]

  15. Example 2 • ex6 = emap length ex1 • Main> ex6 • 1:"a"->[(5,2)] • 2:"b"->[(4,3),(4,1)] • 3:"c"->[(2,1)] • Main> ex1 • 1:"a"->[("right",2)] • 2:"b"->[("left",1),("down",3)] • 3:"c"->[("up",1)]

  16. Roll your own • mymap f g • | isEmpty g = empty • | otherwise = • let ns = nodes g • (Just(ps,n,lab,ss),g2) • = match (head ns) g • in (ps,n,f lab,ss) & (mymap f g2)

  17. Depth First Search • data Tree a = Branch a [Tree a] deriving Show • df :: Node -> Graph b a -> (Tree b,Graph b a) • df root g = • let (Just(_,v,lab,ss), g') = match root g • (r,g1) = dff ss g' • in (Branch lab r,g1) • dff :: [(c,Node)] -> Graph b c -> ([Tree b],Graph b c) • dff [] g = ([],g) • dff ((lab,v):l) g = • let (x,g1) = df v g • (y,g2) = dff l g1 • in (x:y,g2)

  18. Example • ex7 = fst (df 1 ex1) • Main> ex7 • Branch "c" [Branch "b" [Branch "a" []]]

  19. Launchbury & King • “Structuring Depth-First Search Algorithms in Haskell” • David King and John Launchbury - POPL ’95 – pp 344--354 • Graph algorithms based upon Depth First Search. • Asymtotically efficient – uses lazy state

  20. 1 2 3 4 5 8 6 7 9 10 Representing Graphs • import ST • import qualified Array as A • type Vertex = Int • -- Representing graphs: • type Table a = A.Array Vertex a • type Graph = Table [Vertex] • -- Array Int [Int] Index for each node Edges (out of) that index

  21. Functions on graphs • type Vertex = Int • type Edge = (Vertex,Vertex) • vertices :: Graph -> [Vertex] • indices :: Graph -> [Int] • edges :: Graph -> [Edge]

  22. 1 2 6 3 5 4 7 8 10 9 Building Graphs • buildG :: Bounds -> [Edge] -> Graph • graph = buildG (1,10) • [ (1, 2), (1, 6), (2, 3), • (2, 5), (3, 1), (3, 4), • (5, 4), (7, 8), (7, 10), • (8, 6), (8, 9), (8, 10) ]

  23. 1 2 6 3 5 4 7 8 10 9 DFS and Forests • data Tree a = Node a (Forest a) • type Forest a = [Tree a] • nodesTree (Node a f) ans = • nodesForest f (a:ans) • nodesForest [] ans = ans • nodesForest (t : f) ans = • nodesTree t (nodesForest f ans) • Note how any tree can be spanned • by a Forest. The Forest is not always • unique.

  24. DFS • The DFS algorithm finds a spanning forest for a graph, from a set of roots. • dfs :: Graph -> [Vertex] -> Forest Vertex • dfs :: Graph -> [Vertex] -> Forest Vertex • dfs g vs = prune (A.bounds g) (map (generate g) vs) • generate :: Graph -> Vertex -> Tree Vertex • generate g v = Node v (map (generate g) (g `aat` v))

  25. Sets of nodes already visited • type Set s = STArray s Vertex Bool • mkEmpty :: Bounds -> ST s (Set s) • mkEmpty bnds = newSTArray bnds False • contains :: Set s -> Vertex -> ST s Bool • contains m v = readSTArray m v • include :: Set s -> Vertex -> ST s () • include m v = writeSTArray m v True

  26. Pruning already visited paths • prune :: Bounds -> Forest Vertex -> Forest Vertex • prune bnds ts = • runST (do { m <- mkEmpty bnds; chop m ts }) • chop :: Set s -> Forest Vertex -> ST s (Forest Vertex) • chop m [] = return [] • chop m (Node v ts : us) • do { visited <- contains m v • ; if visited • then chop m us • else do { include m v • ; as <- chop m ts • ; bs <- chop m us • ; return(Node v as : bs) • } • }

  27. Topological Sort • postorder :: Tree a -> [a] • postorder (Node a ts) = postorderF ts ++ [a] • postorderF :: Forest a -> [a] • postorderF ts = concat (map postorder ts) • postOrd :: Graph -> [Vertex] • postOrd = postorderF . Dff • dff :: Graph -> Forest Vertex • dff g = dfs g (vertices g)

More Related