type 'node graph = ('node * 'node list) list; exception NotANode; (* succ(a,G) looks up the list of successors of node a in graph G *) fun succ(a,nil) = raise NotANode | succ(a,(b,L)::tail) = if a=b then L else succ(a,tail); (* member(a,L) determines whether a is on list L *) fun member(a,nil) = false | member(a,b::bs) = if a=b then true else member(a,bs); (* search1(L,R,G) finds all the nodes reachable from any of the list of nodes L in graph G, but does not search from the set R of nodes that have already been reached. R is included in the set of reached nodes that is eventually returned. *) fun search1(nil,R,G) = R | search1(x::xs,R,G) = if member(x,R) then search1(xs,R,G) else (* x is a new node, never before seen *) search1(succ(x,G)@xs, x::R, G); (* search(a,G) finds the set of nodes reachable from a in graph G *) fun search(a,G) = search1([a],nil,G);