\begin{sloppypar}
\raggedright\obeylines\setlength{\parindent}{0in}\setlength{\parskip}{0in}\setlength{\topsep}{0in}
wt\_digraph = {\bf cluster is} create, add\_node, add\_edge, add\_node\_and\_edge,
\hspace*{0.4in} remove\_node, remove\_edge, change\_weight, edge\_weight, nodes,
\hspace*{0.4in} successors\_and\_weight, unparse
\hspace*{1pc}

\hspace*{0.4in} \% Overview:
\hspace*{0.4in} \% wt\_digraph is a mutable directed graph with weighted edges. Each node
\hspace*{0.4in} \% is named by a string. The graph is implemented as a string\_table
\hspace*{0.4in} \% of named nodes, where each node is itself a string\_table of integers
\hspace*{0.4in} \% representing the final end of an edge.
\hspace*{0.4in} \%
\hspace*{0.4in} \% Abstraction functions:
\hspace*{0.4in} \% 
\hspace*{0.4in} \% Representation invariant:
\hspace*{0.4in} \%
\hspace*{1pc}

\hspace*{0.4in} node=string\_table[int]
\hspace*{0.4in} {\bf rep}=string\_table[node]
\hspace*{1pc}

\hspace*{0.4in} create = {\bf proc} () {\bf returns} ({\bf cvt})
\hspace*{0.8in} \% effects: Creates and returns an empty digraph.
\hspace*{1pc}

\hspace*{0.8in} {\bf return}({\bf rep}\$create())
\hspace*{0.8in} {\bf end} create
\hspace*{1pc}

\hspace*{0.4in} add\_node = {\bf proc} (g:wt\_digraph, name:string) {\bf signals} (duplicate)
\hspace*{0.8in} \% modifies: \{$\backslash$em g\}
\hspace*{0.8in} \% effects: Modifies \{$\backslash$em g\} by inserting a node named \{$\backslash$em name\}.
\hspace*{0.8in} \%\hspace*{0.7in} Signals \{$\backslash$em duplicate\} if there is already a node
\hspace*{0.8in} \%\hspace*{0.7in} of that name.
\hspace*{1pc}

\hspace*{0.8in} {\bf rep}\$insert(g,name,node\$create()) {\bf resignal} duplicate
\hspace*{0.8in} {\bf end} add\_node
\hspace*{1pc}

\hspace*{0.4in} add\_edge = {\bf proc} (g:{\bf cvt},initial,final:string, w:int)
\hspace*{0.8in} {\bf signals} (no\_node(string),duplicate)
\hspace*{1pc}

\hspace*{0.8in} \% modifies: \{$\backslash$em g\}
\hspace*{0.8in} \% effects: Modifies \{$\backslash$em g\} by inserting an edge from the node named
\hspace*{0.8in} \%\hspace*{0.7in} \{$\backslash$em initial\} to the node named \{$\backslash$em final\} with edge weight
\hspace*{0.8in} \%\hspace*{0.7in} \{$\backslash$em w\}. Signals \{$\backslash$em no\_node\} if \{$\backslash$em initial\} or
\hspace*{0.8in} \%\hspace*{0.7in} \{$\backslash$em final\} is not the name of a node in \{$\backslash$em g\}, and
\hspace*{0.8in} \%\hspace*{0.7in} returns the name of the missing node. Signals \{$\backslash$em duplicate\}
\hspace*{0.8in} \%\hspace*{0.7in} if the edge already exists. \{$\backslash$em g\} is not modified if
\hspace*{0.8in} \%\hspace*{0.7in} either exception is raised.
\hspace*{1pc}

\hspace*{0.8in} initial\_node:node := {\bf rep}\$lookup(g,initial)
\hspace*{0.9in} {\bf except when} not\_found: {\bf signal} no\_node(initial) {\bf end}
\hspace*{1pc}

\hspace*{0.8in} final\_node:node := {\bf rep}\$lookup(g,initial)
\hspace*{0.9in} {\bf except when} not\_found: {\bf signal} no\_node(final) {\bf end}
\hspace*{1pc}

\hspace*{0.8in} node\$insert(initial\_node,final,w) {\bf resignal} duplicate
\hspace*{0.8in} {\bf end} add\_edge
\hspace*{1pc}

\hspace*{0.4in} add\_node\_and\_edge = {\bf proc} (g:{\bf cvt}, initial,new:string, w:int)
\hspace*{0.8in} {\bf signals} (no\_node(string),duplicate)
\hspace*{1pc}

\hspace*{0.8in} \% modifies: \{$\backslash$em g\}
\hspace*{0.8in} \% effects: Modifies \{$\backslash$em g\} by inserting a node named
\hspace*{0.8in} \%\hspace*{0.7in} \{$\backslash$em new\} and inserting an edge from the node named \{$\backslash$em
\hspace*{0.8in} \%\hspace*{0.7in} initial\} to the node named \{$\backslash$em new\} with edge weight \{$\backslash$em w\}.
\hspace*{0.8in} \%\hspace*{0.7in} Signals \{$\backslash$em no\_node\} if \{$\backslash$em initial\} is not the name of a
\hspace*{0.8in} \%\hspace*{0.7in} node in \{$\backslash$em g\}, and returns the name of the missing node.
\hspace*{0.8in} \%\hspace*{0.7in} Signals \{$\backslash$em duplicate\} if a node named \{$\backslash$em new\} already
\hspace*{0.8in} \%\hspace*{0.7in} exists. \{$\backslash$em g\} is not modified if either exception is
\hspace*{0.8in} \%\hspace*{0.7in} raised.
\hspace*{1pc}

\hspace*{0.8in} initial\_node:node := {\bf rep}\$lookup(g,initial)
\hspace*{0.9in} {\bf except when} not\_found: {\bf signal} no\_node(initial) {\bf end}
\hspace*{1pc}

\hspace*{0.8in} {\bf rep}\$insert(g,new,node\$create()) {\bf resignal} duplicate
\hspace*{1pc}

\hspace*{0.8in} node\$insert(initial\_node,new,w)
\hspace*{0.8in} {\bf end} add\_node\_and\_edge
\hspace*{1pc}

\hspace*{0.4in} remove\_node = {\bf proc} (g:{\bf cvt}, name:string) {\bf signals} (no\_node(string))
\hspace*{0.8in} \% modifies: \{$\backslash$em g\}
\hspace*{0.8in} \% requires: The node named \{$\backslash$em name\} have no connections to
\hspace*{0.8in} \%\hspace*{0.7in} it anywhere in the graph
\hspace*{0.8in} \% effects: Modifies \{$\backslash$em g\} by removing the node named \{$\backslash$em name\}
\hspace*{0.8in} \%\hspace*{0.7in} and all edges originating from that node from \{$\backslash$em g\}
\hspace*{0.8in} \%\hspace*{0.7in} If the node is not in \{$\backslash$em g\}, signals \{$\backslash$em no\_node\} and
\hspace*{0.8in} \%\hspace*{0.7in} returns the name of the missing node. If the signal is
\hspace*{0.8in} \%\hspace*{0.7in} raised, \{$\backslash$em g\} is not modified.
\hspace*{1pc}

\hspace*{0.8in} {\bf rep}\$delete(g,name)
\hspace*{0.9in} {\bf except when} not\_found: {\bf signal} no\_node(name) {\bf end}
\hspace*{0.8in} {\bf end} remove\_node
\hspace*{1pc}

\hspace*{0.4in} remove\_edge = {\bf proc} (g:{\bf cvt}, initial,final:string) {\bf signals} (no\_edge)
\hspace*{0.8in} \% modifies: \{$\backslash$em g\}
\hspace*{0.8in} \% effects: Modifies \{$\backslash$em g\} by removing the edge from the node named
\hspace*{0.8in} \%\hspace*{0.7in} \{$\backslash$em initial\} to the node named \{$\backslash$em final\}. Signals
\hspace*{0.8in} \%\hspace*{0.7in} \{$\backslash$em no\_edge\} and leaves \{$\backslash$em g\} unmodified if the edge
\hspace*{0.8in} \%\hspace*{0.7in} does not exist.
\hspace*{1pc}

\hspace*{0.8in} initial\_node:node := {\bf rep}\$lookup(g,initial)
\hspace*{0.9in} {\bf except when} not\_found: {\bf signal} no\_edge {\bf end}
\hspace*{1pc}

\hspace*{0.8in} node\$delete(initial\_node,final)
\hspace*{0.9in} {\bf except when} not\_found: {\bf signal} no\_edge {\bf end}
\hspace*{0.8in} {\bf end} remove\_edge
\hspace*{1pc}

\hspace*{0.4in} change\_weight = {\bf proc} (g:{\bf cvt}, initial,final:string, w:int) {\bf signals} (no\_edge)
\hspace*{0.8in} \% modifies: \{$\backslash$em g\}
\hspace*{0.8in} \% effects: Modifies \{$\backslash$em g\} by changing the weight to \{$\backslash$em w\} on
\hspace*{0.8in} \%\hspace*{0.7in} the edge from the node named \{$\backslash$em initial\} to the node
\hspace*{0.8in} \%\hspace*{0.7in} named \{$\backslash$em final\}. Signals \{$\backslash$em no\_edge\} and leaves \{$\backslash$em g\}
\hspace*{0.8in} \%\hspace*{0.7in} unmodified if the edge does not exist.
\hspace*{1pc}

\hspace*{0.8in} initial\_node:node := {\bf rep}\$lookup(g,initial)
\hspace*{0.9in} {\bf except when} not\_found: {\bf signal} no\_edge {\bf end}
\hspace*{1pc}

\hspace*{0.8in} node\$change(initial\_node,final,w)
\hspace*{0.9in} {\bf except when} not\_found: {\bf signal} no\_edge {\bf end}
\hspace*{0.8in} {\bf end} change\_weight
\hspace*{1pc}

\hspace*{0.4in} edge\_weight = {\bf proc} (g:{\bf cvt}, initial,final:string) {\bf returns} (int)
\hspace*{0.8in} {\bf signals} (no\_edge)
\hspace*{1pc}

\hspace*{0.8in} \% effects: Returns the weight on the edge from the node named
\hspace*{0.8in} \%\hspace*{0.7in} \{$\backslash$em initial\} to the node named \{$\backslash$em final\} in \{$\backslash$em g\}.
\hspace*{0.8in} \%\hspace*{0.7in} Signals \{$\backslash$em no\_edge\} if the edge does not exist.
\hspace*{1pc}

\hspace*{0.8in} initial\_node:node := {\bf rep}\$lookup(g,initial)
\hspace*{0.9in} {\bf except when} not\_found: {\bf signal} no\_edge {\bf end}
\hspace*{1pc}

\hspace*{0.8in} w:int := node\$lookup(initial\_node,final)
\hspace*{0.9in} {\bf except when} not\_found: {\bf signal} no\_edge {\bf end}
\hspace*{1pc}

\hspace*{0.8in} {\bf return}(w)
\hspace*{0.8in} {\bf end} edge\_weight
\hspace*{1pc}

\hspace*{0.4in} nodes = {\bf iter} (g:{\bf cvt}) {\bf yields} (string)
\hspace*{0.8in} \% effects: Yields the name of each node in \{$\backslash$em g\} exactly once.
\hspace*{1pc}

\hspace*{0.8in} {\bf for} name:string,n:node {\bf in rep}\$entries(g) {\bf do}
\hspace*{1.2in} {\bf yield}(name)
\hspace*{1.2in} {\bf end}
\hspace*{0.8in} {\bf end} nodes
\hspace*{1pc}

\hspace*{0.4in} successors\_and\_weight = {\bf iter} (g:{\bf cvt}, initial:string)
\hspace*{0.8in} {\bf yields} (string,int) {\bf signals} (no\_node(string))
\hspace*{1pc}

\hspace*{0.8in} \% effect: Yields each direct successor in \{$\backslash$em g\} of the node named
\hspace*{0.8in} \%\hspace*{0.7in} \{$\backslash$em initial\} exactly once together with the weight on the
\hspace*{0.8in} \%\hspace*{0.7in} edge to it from \{$\backslash$em initial\}. Signals \{$\backslash$em no\_node\} if
\hspace*{0.8in} \%\hspace*{0.7in} the node named \{$\backslash$em initial\} does not exist, and returns
\hspace*{0.8in} \%\hspace*{0.7in} the name of the missing node.
\hspace*{1pc}

\hspace*{0.8in} initial\_node:node := {\bf rep}\$lookup(g,initial)
\hspace*{0.9in} {\bf except when} not\_found: {\bf signal} no\_node(initial) {\bf end}
\hspace*{1pc}

\hspace*{0.8in} {\bf for} name:string,w:int {\bf in rep}\$entries(initial\_node) {\bf do}
\hspace*{1.2in} {\bf yield}(name,w)
\hspace*{1.2in} {\bf end}
\hspace*{0.8in} {\bf end} successors\_and\_weight
\hspace*{1pc}

\hspace*{0.4in} unparse = {\bf proc} (g:{\bf cvt}) {\bf returns} (string)
\hspace*{0.8in} \% effects: returns a human-readable string that describes the
\hspace*{0.8in} \%\hspace*{0.7in} current contents of \{$\backslash$em g\}.
\hspace*{1pc}

\hspace*{0.8in} out:string := ``\{''
\hspace*{1pc}

\hspace*{0.8in} {\bf for} name:string,n:node {\bf in rep}\$entries(g) {\bf do}
\hspace*{1.2in} out := out $|$$|$ ``$\backslash$n $\backslash$'''' $|$$|$ name $|$$|$ ``$\backslash$'':$\backslash$t''
\hspace*{1.2in} {\bf for} succ:string,w:int {\bf in rep}\$entries(n) {\bf do}
\hspace*{1.6in} out := out $|$$|$ ``[$\backslash$'''' $|$$|$ succ $|$$|$ ``$\backslash$'','' $|$$|$ int\$unparse(w) $|$$|$ ``] ''
\hspace*{1.6in} {\bf end}
\hspace*{1.2in} {\bf end}
\hspace*{1pc}

\hspace*{0.8in} out := out $|$$|$ ``$\backslash$n\}$\backslash$n''
\hspace*{0.8in} {\bf return}(out)
\hspace*{0.8in} {\bf end} unparse
\hspace*{1pc}

\hspace*{0.4in} {\bf end} wt\_digraph
\end{sloppypar}
