<COMMENT>{-</COMMENT>
<COMMENT>    This file is part of Sarasvati.</COMMENT>
<COMMENT></COMMENT>
<COMMENT>    Sarasvati is free software: you can redistribute it and/or modify</COMMENT>
<COMMENT>    it under the terms of the GNU Lesser General Public License as</COMMENT>
<COMMENT>    published by the Free Software Foundation, either version 3 of the</COMMENT>
<COMMENT>    License, or (at your option) any later version.</COMMENT>
<COMMENT></COMMENT>
<COMMENT>    Sarasvati is distributed in the hope that it will be useful,</COMMENT>
<COMMENT>    but WITHOUT ANY WARRANTY; without even the implied warranty of</COMMENT>
<COMMENT>    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</COMMENT>
<COMMENT>    GNU Lesser General Public License for more details.</COMMENT>
<COMMENT></COMMENT>
<COMMENT>    You should have received a copy of the GNU Lesser General Public</COMMENT>
<COMMENT>    License along with Sarasvati.  If not, see &lt;http://www.gnu.org/licenses/&gt;.</COMMENT>
<COMMENT></COMMENT>
<COMMENT>    Copyright 2008 Paul Lorenz</COMMENT>
<COMMENT>-}</COMMENT>

<COMMENT>-- Author: Paul Lorenz</COMMENT>

<KEYWORD>module</KEYWORD> <TYPE>Workflow</TYPE><FUNCTION>.</FUNCTION><TYPE>Sarasvati</TYPE><FUNCTION>.</FUNCTION><TYPE>Engine</TYPE> (
                        <TYPE>GuardResponse</TYPE>(<FUNCTION>.</FUNCTION><FUNCTION>.</FUNCTION>),
                        <TYPE>NodeExtra</TYPE>(<FUNCTION>.</FUNCTION><FUNCTION>.</FUNCTION>),
                        <TYPE>Node</TYPE>(<FUNCTION>.</FUNCTION><FUNCTION>.</FUNCTION>),
                        <TYPE>NodeType</TYPE>(<FUNCTION>.</FUNCTION><FUNCTION>.</FUNCTION>),
                        <TYPE>Arc</TYPE>(<FUNCTION>.</FUNCTION><FUNCTION>.</FUNCTION>),
                        <TYPE>Token</TYPE>(<FUNCTION>.</FUNCTION><FUNCTION>.</FUNCTION>),
                        <TYPE>TokenAttr</TYPE>(<FUNCTION>.</FUNCTION><FUNCTION>.</FUNCTION>),
                        <TYPE>NodeToken</TYPE>(<FUNCTION>.</FUNCTION><FUNCTION>.</FUNCTION>),
                        <TYPE>ArcToken</TYPE>(<FUNCTION>.</FUNCTION><FUNCTION>.</FUNCTION>),
                        <TYPE>WfGraph</TYPE>(<FUNCTION>.</FUNCTION><FUNCTION>.</FUNCTION>),
                        <TYPE>ProcessState</TYPE>(<FUNCTION>.</FUNCTION><FUNCTION>.</FUNCTION>),
                        <TYPE>WfProcess</TYPE>(<FUNCTION>.</FUNCTION><FUNCTION>.</FUNCTION>),
                        <TYPE>WfEngine</TYPE>(<FUNCTION>.</FUNCTION><FUNCTION>.</FUNCTION>),
                        <TYPE>WfException</TYPE>(<FUNCTION>.</FUNCTION><FUNCTION>.</FUNCTION>),
                        tokenAttrValue,
                        tokenAttrValueReq,
                        completeExecution,
                        completeDefaultExecution,
                        evalGuardLang,
                        getNodeTokenForId,
                        graphFromArcs,
                        handleWfError,
                        isWfComplete,
                        makeNodeExtra,
                        nodeForToken,
                        processAttrValue,
                        startWorkflow,
                        replaceTokenAttrs,
                        tokenAttrs
                        ) <KEYWORD>where</KEYWORD>

<KEYWORD>import</KEYWORD> <TYPE>Control</TYPE><FUNCTION>.</FUNCTION><TYPE>Exception</TYPE>
<KEYWORD>import</KEYWORD> <TYPE>Control</TYPE><FUNCTION>.</FUNCTION><TYPE>Monad</TYPE>
<KEYWORD>import</KEYWORD> <TYPE>Data</TYPE><FUNCTION>.</FUNCTION><TYPE>Dynamic</TYPE>
<KEYWORD>import</KEYWORD> <KEYWORD>qualified</KEYWORD> <TYPE>Data</TYPE><FUNCTION>.</FUNCTION><TYPE>Map</TYPE> <KEYWORD>as</KEYWORD> <TYPE>Map</TYPE>
<KEYWORD>import</KEYWORD> <KEYWORD>qualified</KEYWORD> <TYPE>Workflow</TYPE><FUNCTION>.</FUNCTION><TYPE>Sarasvati</TYPE><FUNCTION>.</FUNCTION><TYPE>GuardLang</TYPE> <KEYWORD>as</KEYWORD> <TYPE>GuardLang</TYPE>
<KEYWORD>import</KEYWORD> <KEYWORD>qualified</KEYWORD> <TYPE>Workflow</TYPE><FUNCTION>.</FUNCTION><TYPE>Sarasvati</TYPE><FUNCTION>.</FUNCTION><TYPE>ListUtil</TYPE> <KEYWORD>as</KEYWORD> <TYPE>ListUtil</TYPE>

<COMMENT>-- | Every 'Node' has a guard function which is called when a token arrives</COMMENT>
<COMMENT>--   and the node is ready to be activated. Guard functions must return a</COMMENT>
<COMMENT>--   'GuardResponse'. Guard functions are contained in 'NodeType' instances.</COMMENT>
<COMMENT>--   The nodeType attribute of a 'Node' is mapped to a 'NodeType' via the</COMMENT>
<COMMENT>--   nodeTypes map in a 'WfProcess'.</COMMENT>
<COMMENT>--</COMMENT>
<COMMENT>--   * 'AcceptToken'  - The token is passed on to the accept function</COMMENT>
<COMMENT>--</COMMENT>
<COMMENT>--   * 'DiscardToken' - The token is discarded and the accept function is not called</COMMENT>
<COMMENT>--</COMMENT>
<COMMENT>--   * 'SkipNode' arcName - The accept function is not called. The token is not discarded,</COMMENT>
<COMMENT>--                          the 'completeExecution' function is called instead with the</COMMENT>
<COMMENT>--                          given arc name</COMMENT>

<KEYWORD>data</KEYWORD> <TYPE>GuardResponse</TYPE> <OPERATOR>=</OPERATOR> <TYPE>AcceptToken</TYPE> <FUNCTION>|</FUNCTION> <TYPE>DiscardToken</TYPE> <FUNCTION>|</FUNCTION> <TYPE>SkipNode</TYPE> <TYPE>String</TYPE>
  <KEYWORD>deriving</KEYWORD> (<TYPE>Show</TYPE>)

<COMMENT>-- | 'NodeExtra' is a place to store any extra data that a given 'Node' may</COMMENT>
<COMMENT>-- require. The only requirement is that the 'extra data' be a 'Typeable'</COMMENT>
<COMMENT>-- so it can encapsulated in a 'Dynamic'.</COMMENT>

<KEYWORD>data</KEYWORD> <TYPE>NodeExtra</TYPE> <OPERATOR>=</OPERATOR> <TYPE>NoNodeExtra</TYPE> <FUNCTION>|</FUNCTION> <TYPE>NodeExtra</TYPE> <TYPE>Dynamic</TYPE>

<COMMENT>-- | Represents a node in a workflow graph. A Node is part of a process definition, as stored in</COMMENT>
<COMMENT>--   a 'WfGraph'. The 'Arc' type models connections between Nodes.</COMMENT>
<COMMENT>--</COMMENT>
<COMMENT>--   Members:</COMMENT>
<COMMENT>--</COMMENT>
<COMMENT>--     * 'nodeId'   - An Int id, which should be unique across all workflows. Used for testing equality.</COMMENT>
<COMMENT>--</COMMENT>
<COMMENT>--     * 'nodeType' - String which used to get the associated 'NodeType' stored in the 'WfProcess'</COMMENT>
<COMMENT>--</COMMENT>
<COMMENT>--     * 'nodeName' - String identifier which should be unique within a single process definition.</COMMENT>
<COMMENT>--</COMMENT>
<COMMENT>--     * 'nodeIsJoin' - If true, when an 'ArcToken' arrives at a 'Node', the node will wait for an 'ArcToken' to</COMMENT>
<COMMENT>--                      be waiting on every 'Arc' that shares the name of the 'Arc' that the current, incoming</COMMENT>
<COMMENT>--                      'ArcToken' points to. If false, every incoming 'ArcToken' will immediately generate a new</COMMENT>
<COMMENT>--                      'NodeToken' upon which the approprate guard function will be called.</COMMENT>
<COMMENT>--</COMMENT>
<COMMENT>--     * 'nodeIsStart' - If true a 'NodeToken' will e placed in this 'Node' when the workflow is started.</COMMENT>
<COMMENT>--</COMMENT>
<COMMENT>--     * 'nodeIsExternal' - True if this 'Node' was defined in an external process definition, False otherwise.</COMMENT>
<COMMENT>--</COMMENT>
<COMMENT>--     * 'nodeGuard' - May contain a string which can be interpreted by the guard function. For example, it may</COMMENT>
<COMMENT>--                     be a GuardLang script, which can be evaluated by the 'evalGuardLang' guard function.</COMMENT>
<COMMENT>--</COMMENT>
<COMMENT>--     * 'nodeExtra' - A 'NodeExtra', which may be nothing, or something 'Typeable', which the guard or accept</COMMENT>
<COMMENT>--                     functions may use to do their work.</COMMENT>

<KEYWORD>data</KEYWORD> <TYPE>Node</TYPE> <OPERATOR>=</OPERATOR>
    <TYPE>Node</TYPE> {
        nodeId         <OPERATOR>::</OPERATOR> <TYPE>Int</TYPE>,
        nodeType       <OPERATOR>::</OPERATOR> <TYPE>String</TYPE>,
        nodeName       <OPERATOR>::</OPERATOR> <TYPE>String</TYPE>,
        nodeIsJoin     <OPERATOR>::</OPERATOR> <TYPE>Bool</TYPE>,
        nodeIsStart    <OPERATOR>::</OPERATOR> <TYPE>Bool</TYPE>,
        nodeIsExternal <OPERATOR>::</OPERATOR> <TYPE>Bool</TYPE>,
        nodeGuard      <OPERATOR>::</OPERATOR> <TYPE>String</TYPE>,
        nodeExtra      <OPERATOR>::</OPERATOR> <TYPE>NodeExtra</TYPE>
    }

<COMMENT>-- | Encapsulates the behavior for a specific 'Node' type. Each type of 'Node' can have</COMMENT>
<COMMENT>--   different behaviour for guards and for accept.</COMMENT>
<COMMENT>--</COMMENT>
<COMMENT>--   * 'guardFunction' - Called when a 'NodeToken' is created in a 'Node'. The 'GuardResponse'</COMMENT>
<COMMENT>--                       result determines if the related 'acceptFunction' is called, if the</COMMENT>
<COMMENT>--                       token is discarded, if accept is skipped and 'completeExecution' is</COMMENT>
<COMMENT>--                       is called.</COMMENT>
<COMMENT>--</COMMENT>
<COMMENT>--   * 'acceptFunction' - Called if 'guardFunction' returns 'AcceptToken'. The function may</COMMENT>
<COMMENT>--                        end with a call to 'completeExecution', or it may be called later.</COMMENT>

<KEYWORD>data</KEYWORD> <TYPE>NodeType</TYPE> a <OPERATOR>=</OPERATOR>
    <TYPE>NodeType</TYPE> {
        guardFunction  <OPERATOR>::</OPERATOR> (<TYPE>NodeToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> <TYPE>GuardResponse</TYPE>),
        acceptFunction <OPERATOR>::</OPERATOR> (<TYPE>WfEngine</TYPE> engine) <OPERATOR>=&gt;</OPERATOR> (engine <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>NodeToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> (<TYPE>WfProcess</TYPE> a))
    }


<COMMENT>-- | An 'Arc' represents an directed edge in a workflow graph.</COMMENT>
<COMMENT>--   It has an id, a label and two node id endpoints.</COMMENT>
<COMMENT>--</COMMENT>
<COMMENT>-- * 'arcId' - *Int* id, which should be unique for that process definition.</COMMENT>
<COMMENT>--</COMMENT>
<COMMENT>-- * 'arcName' - Every 'Arc' has a name, though that name will often be the default name,</COMMENT>
<COMMENT>--               which is just the empty string. When 'completeExecution' is called on a</COMMENT>
<COMMENT>--               'NodeToken' an arc name must be specified. More than one 'Arc' may have</COMMENT>
<COMMENT>--               the same name. Every arc with the given name will have an 'ArcToken'</COMMENT>
<COMMENT>--               placed on it. There may also be no arcs with that name.</COMMENT>
<COMMENT>--</COMMENT>
<COMMENT>-- * startNodeId - The id of the *Node* at the beginning of this arc.</COMMENT>
<COMMENT>--</COMMENT>
<COMMENT>-- * endNodeId   - The id of the *Node* at the end of this arc.</COMMENT>

<KEYWORD>data</KEYWORD> <TYPE>Arc</TYPE> <OPERATOR>=</OPERATOR>
    <TYPE>Arc</TYPE> {
        arcId        <OPERATOR>::</OPERATOR> <TYPE>Int</TYPE>,
        arcName      <OPERATOR>::</OPERATOR> <TYPE>String</TYPE>,
        startNodeId  <OPERATOR>::</OPERATOR> <TYPE>Int</TYPE>,
        endNodeId    <OPERATOR>::</OPERATOR> <TYPE>Int</TYPE>
    }
 <KEYWORD>deriving</KEYWORD> (<TYPE>Show</TYPE>)


<COMMENT>-- Tokens are split into NodeTokens and ArcTokens. NodeTokens are sitting at</COMMENT>
<COMMENT>-- nodes in the workflow graph while ArcTokens are 'in-transit' and are on</COMMENT>
<COMMENT>-- Arcs.</COMMENT>
<COMMENT>--</COMMENT>
<COMMENT>-- The Token class allows NodeTokens and ArcTokens to share an id lookup function</COMMENT>

<KEYWORD>class</KEYWORD> <TYPE>Token</TYPE> a <KEYWORD>where</KEYWORD>
   tokenId   <OPERATOR>::</OPERATOR> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>Int</TYPE>

<KEYWORD>data</KEYWORD> <TYPE>TokenAttr</TYPE> <OPERATOR>=</OPERATOR>
    <TYPE>TokenAttr</TYPE> {
        attrSetId           <OPERATOR>::</OPERATOR> <TYPE>Int</TYPE>,
        tokenAttributeKey   <OPERATOR>::</OPERATOR> <TYPE>String</TYPE>,
        tokenAttributeValue <OPERATOR>::</OPERATOR> <TYPE>String</TYPE>
    }
  <KEYWORD>deriving</KEYWORD> (<TYPE>Show</TYPE>)

<COMMENT>-- NodeToken represents tokens which are at node</COMMENT>
<COMMENT>--   The NodeToken constructor takes three parameters</COMMENT>
<COMMENT>--   token id :: Int          - The id should be unique among node tokens for this process</COMMENT>
<COMMENT>--   node  id :: Int          - This should be the id of a node in the graph for this process</COMMENT>
<KEYWORD>data</KEYWORD> <TYPE>NodeToken</TYPE> <OPERATOR>=</OPERATOR> <TYPE>NodeToken</TYPE> <TYPE>Int</TYPE> <TYPE>Int</TYPE>
    <KEYWORD>deriving</KEYWORD> (<TYPE>Show</TYPE>)

<COMMENT>-- ArcToken represents tokens which are between nodes (on an arc)</COMMENT>

<KEYWORD>data</KEYWORD> <TYPE>ArcToken</TYPE> <OPERATOR>=</OPERATOR> <TYPE>ArcToken</TYPE> <TYPE>Int</TYPE> <TYPE>Arc</TYPE> <TYPE>NodeToken</TYPE>
    <KEYWORD>deriving</KEYWORD> (<TYPE>Show</TYPE>)


<COMMENT>-- WFGraph</COMMENT>
<COMMENT>--   Has the set of nodes as well as maps of node input arcs and node output arcs</COMMENT>
<COMMENT>--   keyed by node id.</COMMENT>

<KEYWORD>data</KEYWORD> <TYPE>WfGraph</TYPE> <OPERATOR>=</OPERATOR>
    <TYPE>WfGraph</TYPE> {
       graphId         <OPERATOR>::</OPERATOR> <TYPE>Int</TYPE>,
       graphName       <OPERATOR>::</OPERATOR> <TYPE>String</TYPE>,
       graphNodes      <OPERATOR>::</OPERATOR> <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><TYPE>Map</TYPE> <TYPE>Int</TYPE> <TYPE>Node</TYPE>,
       graphInputArcs  <OPERATOR>::</OPERATOR> <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><TYPE>Map</TYPE> <TYPE>Int</TYPE> <OPERATOR>[</OPERATOR><TYPE>Arc</TYPE><OPERATOR>]</OPERATOR>,
       graphOutputArcs <OPERATOR>::</OPERATOR> <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><TYPE>Map</TYPE> <TYPE>Int</TYPE> <OPERATOR>[</OPERATOR><TYPE>Arc</TYPE><OPERATOR>]</OPERATOR>
    }

<KEYWORD>data</KEYWORD> <TYPE>ProcessState</TYPE> <OPERATOR>=</OPERATOR> <TYPE>ProcessCreated</TYPE> <FUNCTION>|</FUNCTION> <TYPE>ProcessExecuting</TYPE> <FUNCTION>|</FUNCTION> <TYPE>ProcessComplete</TYPE> <FUNCTION>|</FUNCTION> <TYPE>ProcessCanceled</TYPE>
    <KEYWORD>deriving</KEYWORD> (<TYPE>Eq</TYPE>, <TYPE>Show</TYPE>)

<COMMENT>-- A WfProcess tracks the current state of the workflow. It has the workflow graph as well</COMMENT>
<COMMENT>-- as the tokens representing the current state. A slot for user data is also defined.</COMMENT>

<KEYWORD>data</KEYWORD> <TYPE>WfProcess</TYPE> a <OPERATOR>=</OPERATOR>
    <TYPE>WfProcess</TYPE> {
        processId    <OPERATOR>::</OPERATOR> <TYPE>Int</TYPE>,
        processState <OPERATOR>::</OPERATOR> <TYPE>ProcessState</TYPE>,
        nodeTypes    <OPERATOR>::</OPERATOR> <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><TYPE>Map</TYPE> <TYPE>String</TYPE> (<TYPE>NodeType</TYPE> a),
        wfGraph      <OPERATOR>::</OPERATOR> <TYPE>WfGraph</TYPE>,
        nodeTokens   <OPERATOR>::</OPERATOR> <OPERATOR>[</OPERATOR><TYPE>NodeToken</TYPE><OPERATOR>]</OPERATOR>,
        arcTokens    <OPERATOR>::</OPERATOR> <OPERATOR>[</OPERATOR><TYPE>ArcToken</TYPE><OPERATOR>]</OPERATOR>,
        attrMap      <OPERATOR>::</OPERATOR> <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><TYPE>Map</TYPE> <TYPE>String</TYPE> <TYPE>String</TYPE>,
        tokenAttrMap <OPERATOR>::</OPERATOR> <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><TYPE>Map</TYPE> <TYPE>Int</TYPE> <OPERATOR>[</OPERATOR><TYPE>TokenAttr</TYPE><OPERATOR>]</OPERATOR>,
        predicateMap <OPERATOR>::</OPERATOR> <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><TYPE>Map</TYPE> <TYPE>String</TYPE> (<TYPE>NodeToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> <TYPE>Bool</TYPE>),
        userData     <OPERATOR>::</OPERATOR> a
    }

<KEYWORD>class</KEYWORD> <TYPE>WfEngine</TYPE> a <KEYWORD>where</KEYWORD>
    createWfProcess     <OPERATOR>::</OPERATOR> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfGraph</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION>
                                <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><TYPE>Map</TYPE> <TYPE>String</TYPE> (<TYPE>NodeType</TYPE> b) <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION>                          <COMMENT>-- Map of type name to NodeType</COMMENT>
                                <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><TYPE>Map</TYPE> <TYPE>String</TYPE> (<TYPE>NodeToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> b <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> <TYPE>Bool</TYPE>) <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <COMMENT>-- Map of predicate names to predicate functions. Used by GuardLang</COMMENT>
                                b <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION>                                                    <COMMENT>-- The initial user data</COMMENT>
                                <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><TYPE>Map</TYPE> <TYPE>String</TYPE> <TYPE>String</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION>                                <COMMENT>-- The initial process attributes</COMMENT>
                                <TYPE>IO</TYPE> (<TYPE>WfProcess</TYPE> b)
    createNodeToken     <OPERATOR>::</OPERATOR> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> b <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>Node</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <OPERATOR>[</OPERATOR><TYPE>ArcToken</TYPE><OPERATOR>]</OPERATOR> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> (<TYPE>WfProcess</TYPE> b, <TYPE>NodeToken</TYPE>)
    createArcToken      <OPERATOR>::</OPERATOR> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> b <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>Arc</TYPE>  <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>NodeToken</TYPE>  <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> (<TYPE>WfProcess</TYPE> b, <TYPE>ArcToken</TYPE>)
    completeNodeToken   <OPERATOR>::</OPERATOR> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>NodeToken</TYPE>   <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> ()
    completeArcToken    <OPERATOR>::</OPERATOR> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>ArcToken</TYPE>    <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> ()
    recordGuardResponse <OPERATOR>::</OPERATOR> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>NodeToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>GuardResponse</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> ()
    transactionBoundary <OPERATOR>::</OPERATOR> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> ()
    setProcessAttr      <OPERATOR>::</OPERATOR> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> b <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>String</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>String</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> (<TYPE>WfProcess</TYPE> b)
    removeProcessAttr   <OPERATOR>::</OPERATOR> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> b <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>String</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> (<TYPE>WfProcess</TYPE> b)
    setTokenAttr        <OPERATOR>::</OPERATOR> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> b <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>NodeToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>String</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>String</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> (<TYPE>WfProcess</TYPE> b)
    removeTokenAttr     <OPERATOR>::</OPERATOR> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> b <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>NodeToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>String</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> (<TYPE>WfProcess</TYPE> b)
    setProcessState     <OPERATOR>::</OPERATOR> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> b <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>ProcessState</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> (<TYPE>WfProcess</TYPE> b)


<KEYWORD>instance</KEYWORD> <TYPE>Show</TYPE> (<TYPE>NodeExtra</TYPE>) <KEYWORD>where</KEYWORD>
    <FUNCTION>show</FUNCTION> <TYPE>NoNodeExtra</TYPE> <OPERATOR>=</OPERATOR> <STRING>"NoNodeExtra"</STRING>
    <FUNCTION>show</FUNCTION> _           <OPERATOR>=</OPERATOR> <STRING>"NodeExtra: Dynamic"</STRING>


<KEYWORD>instance</KEYWORD> <TYPE>Show</TYPE> (<TYPE>Node</TYPE>) <KEYWORD>where</KEYWORD>
    <FUNCTION>show</FUNCTION> a <OPERATOR>=</OPERATOR> <STRING>"|Node id: "</STRING> <FUNCTION>++</FUNCTION> (<OBJ>show</OBJ><FUNCTION>.</FUNCTION><OO>nodeId</OO>) a <FUNCTION>++</FUNCTION> <STRING>" name: "</STRING> <FUNCTION>++</FUNCTION> nodeName a <FUNCTION>++</FUNCTION> <STRING>" type: "</STRING> <FUNCTION>++</FUNCTION> nodeType a <FUNCTION>++</FUNCTION>
             <STRING>"  isJoin: "</STRING> <FUNCTION>++</FUNCTION> (<OBJ>show</OBJ><FUNCTION>.</FUNCTION><OO>nodeIsJoin</OO>) a <FUNCTION>++</FUNCTION> <STRING>"  isStart: "</STRING> <FUNCTION>++</FUNCTION> (<OBJ>show</OBJ><FUNCTION>.</FUNCTION><OO>nodeIsStart</OO>) a <FUNCTION>++</FUNCTION>
             <STRING>"  isExternal: "</STRING> <FUNCTION>++</FUNCTION> (<OBJ>show</OBJ><FUNCTION>.</FUNCTION><OO>nodeIsExternal</OO>) a <FUNCTION>++</FUNCTION> <STRING>"|"</STRING>

<KEYWORD>instance</KEYWORD> <TYPE>Token</TYPE> (<TYPE>NodeToken</TYPE>) <KEYWORD>where</KEYWORD>
    tokenId (<TYPE>NodeToken</TYPE> tokId _) <OPERATOR>=</OPERATOR> tokId

<KEYWORD>instance</KEYWORD> <TYPE>Eq</TYPE> (<TYPE>NodeToken</TYPE>) <KEYWORD>where</KEYWORD>
    tok1 <FUNCTION>==</FUNCTION> tok2 <OPERATOR>=</OPERATOR> (tokenId tok1) <FUNCTION>==</FUNCTION> (tokenId tok2)

<KEYWORD>instance</KEYWORD> <TYPE>Token</TYPE> (<TYPE>ArcToken</TYPE>) <KEYWORD>where</KEYWORD>
    tokenId (<TYPE>ArcToken</TYPE> tokId _ _) <OPERATOR>=</OPERATOR> tokId

<KEYWORD>instance</KEYWORD> <TYPE>Eq</TYPE> (<TYPE>ArcToken</TYPE>) <KEYWORD>where</KEYWORD>
    tok1 <FUNCTION>==</FUNCTION> tok2 <OPERATOR>=</OPERATOR> (tokenId tok1) <FUNCTION>==</FUNCTION> (tokenId tok2)

<KEYWORD>data</KEYWORD> <TYPE>WfException</TYPE> <OPERATOR>=</OPERATOR> <TYPE>WfException</TYPE> <TYPE>String</TYPE>
  <KEYWORD>deriving</KEYWORD> (<TYPE>Show</TYPE>,<TYPE>Typeable</TYPE>)

wfError <OPERATOR>::</OPERATOR> <TYPE>String</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> a
wfError msg <OPERATOR>=</OPERATOR> throwDyn <FUNCTION>$</FUNCTION> <TYPE>WfException</TYPE> msg

handleWfError <OPERATOR>::</OPERATOR> (<TYPE>WfException</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> a) <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> a
handleWfError f a <OPERATOR>=</OPERATOR> catchDyn a f

makeNodeExtra <OPERATOR>::</OPERATOR> (<TYPE>Typeable</TYPE> a) <OPERATOR>=&gt;</OPERATOR> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>NodeExtra</TYPE>
makeNodeExtra extra <OPERATOR>=</OPERATOR> <TYPE>NodeExtra</TYPE> <FUNCTION>$</FUNCTION> toDyn extra

tokenAttrs <OPERATOR>::</OPERATOR> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>NodeToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <OPERATOR>[</OPERATOR><TYPE>TokenAttr</TYPE><OPERATOR>]</OPERATOR>
tokenAttrs wfProcess token <OPERATOR>=</OPERATOR> (tokenAttrMap wfProcess) <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OPERATOR>!</OPERATOR> (tokenId token)

tokenAttrValueReq <OPERATOR>::</OPERATOR> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>NodeToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>String</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>String</TYPE>
tokenAttrValueReq process nodeToken key <OPERATOR>=</OPERATOR>
    <KEYWORD>case</KEYWORD> (attr) <KEYWORD>of</KEYWORD> (<TYPE>TokenAttr</TYPE> _ _ value) <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> value
    <KEYWORD>where</KEYWORD>
        attr  <OPERATOR>=</OPERATOR> <FUNCTION>head</FUNCTION> <FUNCTION>$</FUNCTION> <FUNCTION>filter</FUNCTION> (<FUNCTION>\tokenAttr</FUNCTION> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> tokenAttributeKey tokenAttr <FUNCTION>==</FUNCTION> key) (tokenAttrs process nodeToken)

tokenAttrValue <OPERATOR>::</OPERATOR> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>NodeToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>String</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>Maybe</TYPE> <TYPE>String</TYPE>
tokenAttrValue process nodeToken key <OPERATOR>=</OPERATOR>
    <KEYWORD>case</KEYWORD> (attr) <KEYWORD>of</KEYWORD>
        <OPERATOR>[</OPERATOR>(<TYPE>TokenAttr</TYPE> _ _ value)<OPERATOR>]</OPERATOR> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>Just</TYPE> value
        _                       <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>Nothing</TYPE>
    <KEYWORD>where</KEYWORD>
        attr  <OPERATOR>=</OPERATOR> <FUNCTION>filter</FUNCTION> (<FUNCTION>\tokenAttr</FUNCTION> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> tokenAttributeKey tokenAttr <FUNCTION>==</FUNCTION> key) (tokenAttrs process nodeToken)

processAttrValue <OPERATOR>::</OPERATOR> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>String</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>Maybe</TYPE> <TYPE>String</TYPE>
processAttrValue process key
    <FUNCTION>|</FUNCTION> <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OO>member</OO> key (attrMap process) <OPERATOR>=</OPERATOR> <TYPE>Just</TYPE> <FUNCTION>$</FUNCTION> (attrMap process) <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OPERATOR>!</OPERATOR> key
    <FUNCTION>|</FUNCTION> <FUNCTION>otherwise</FUNCTION>                        <OPERATOR>=</OPERATOR> <TYPE>Nothing</TYPE>

replaceTokenAttrs <OPERATOR>::</OPERATOR> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>NodeToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <OPERATOR>[</OPERATOR><TYPE>TokenAttr</TYPE><OPERATOR>]</OPERATOR> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> a
replaceTokenAttrs process token attrList <OPERATOR>=</OPERATOR>
    process { tokenAttrMap <OPERATOR>=</OPERATOR> <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OO>insert</OO> (tokenId token) attrList (tokenAttrMap process) }

<COMMENT>-- showGraph</COMMENT>
<COMMENT>--   Print prints a graph</COMMENT>

<KEYWORD>instance</KEYWORD> <TYPE>Show</TYPE> (<TYPE>WfGraph</TYPE>) <KEYWORD>where</KEYWORD>
  <FUNCTION>show</FUNCTION> graph <OPERATOR>=</OPERATOR> graphName graph <FUNCTION>++</FUNCTION> <STRING>":<ESC>\n</ESC>"</STRING> <FUNCTION>++</FUNCTION>
                 <FUNCTION>concatMap</FUNCTION> (<FUNCTION>\a-&gt;show</FUNCTION> a <FUNCTION>++</FUNCTION> <STRING>"<ESC>\n</ESC>"</STRING>) (<TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OO>elems</OO> (graphNodes graph)) <FUNCTION>++</FUNCTION> <STRING>"<ESC>\n</ESC>"</STRING> <FUNCTION>++</FUNCTION>
                 <FUNCTION>concatMap</FUNCTION> (<FUNCTION>\a-&gt;show</FUNCTION> a <FUNCTION>++</FUNCTION> <STRING>"<ESC>\n</ESC>"</STRING>) (<TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OO>elems</OO> (graphInputArcs graph)) <FUNCTION>++</FUNCTION> <STRING>"<ESC>\n</ESC>"</STRING> <FUNCTION>++</FUNCTION>
                 <FUNCTION>concatMap</FUNCTION> (<FUNCTION>\a-&gt;show</FUNCTION> a <FUNCTION>++</FUNCTION> <STRING>"<ESC>\n</ESC>"</STRING>) (<TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OO>elems</OO> (graphOutputArcs graph))

<COMMENT>-- | Given a name, version, and lists of nodes and arcs, builds the lookup lists</COMMENT>
<COMMENT>--   and returns a 'WfGraph'.</COMMENT>

graphFromArcs <OPERATOR>::</OPERATOR> <TYPE>Int</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>String</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <OPERATOR>[</OPERATOR><TYPE>Node</TYPE><OPERATOR>]</OPERATOR> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <OPERATOR>[</OPERATOR><TYPE>Arc</TYPE><OPERATOR>]</OPERATOR> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfGraph</TYPE>
graphFromArcs graphId name nodes arcs <OPERATOR>=</OPERATOR> <TYPE>WfGraph</TYPE> graphId name nodeMap inputsMap outputsMap
    <KEYWORD>where</KEYWORD>
        nodeMap  <OPERATOR>=</OPERATOR> <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OO>fromList</OO> <FUNCTION>$</FUNCTION> <FUNCTION>zip</FUNCTION> (<FUNCTION>map</FUNCTION> nodeId nodes) nodes

        inputsMap             <OPERATOR>=</OPERATOR> <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OO>fromList</OO> <FUNCTION>$</FUNCTION> <FUNCTION>zip</FUNCTION> (<FUNCTION>map</FUNCTION> nodeId nodes) (<FUNCTION>map</FUNCTION> inputArcsForNode nodes)
        inputArcsForNode node <OPERATOR>=</OPERATOR> <FUNCTION>filter</FUNCTION> (<FUNCTION>\arc</FUNCTION> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> endNodeId arc <FUNCTION>==</FUNCTION> nodeId node) arcs

        outputsMap <OPERATOR>=</OPERATOR> <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OO>fromList</OO> <FUNCTION>$</FUNCTION> <FUNCTION>zip</FUNCTION> (<FUNCTION>map</FUNCTION> nodeId nodes) (<FUNCTION>map</FUNCTION> outputArcsForNode nodes)
        outputArcsForNode node <OPERATOR>=</OPERATOR> <FUNCTION>filter</FUNCTION> (<FUNCTION>\arc</FUNCTION> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> startNodeId arc <FUNCTION>==</FUNCTION> nodeId node) arcs

<COMMENT>-- getTokenForId</COMMENT>
<COMMENT>--  | Given a token id and a workflow instance gives back the actual token</COMMENT>
<COMMENT>--    corresponding to that id</COMMENT>

getNodeTokenForId <OPERATOR>::</OPERATOR> <TYPE>Int</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>NodeToken</TYPE>
getNodeTokenForId tokId wf <OPERATOR>=</OPERATOR>
  <FUNCTION>head</FUNCTION> <FUNCTION>$</FUNCTION> <FUNCTION>filter</FUNCTION> (<FUNCTION>\t</FUNCTION> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> (tokenId t) <FUNCTION>==</FUNCTION> tokId) (nodeTokens wf)

<COMMENT>-- Convenience lookup methods for the data pointed to by tokens</COMMENT>

nodeForToken <OPERATOR>::</OPERATOR> <TYPE>NodeToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfGraph</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>Node</TYPE>
nodeForToken (<TYPE>NodeToken</TYPE> _ nodeId) graph <OPERATOR>=</OPERATOR> (graphNodes graph) <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OPERATOR>!</OPERATOR> nodeId

arcForToken <OPERATOR>::</OPERATOR> <TYPE>ArcToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>Arc</TYPE>
arcForToken  (<TYPE>ArcToken</TYPE> _ arc _)           <OPERATOR>=</OPERATOR> arc

<COMMENT>-- startWorkflow</COMMENT>
<COMMENT>--   Given a workflow definition (WfGraph) and initial userData, gives</COMMENT>
<COMMENT>--   back a new in progress workflow instance for that definition.</COMMENT>

startWorkflow <OPERATOR>::</OPERATOR> (<TYPE>WfEngine</TYPE> engine) <OPERATOR>=&gt;</OPERATOR>
                   engine <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION>
                   <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><TYPE>Map</TYPE> <TYPE>String</TYPE> (<TYPE>NodeType</TYPE> a) <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION>
                   <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><TYPE>Map</TYPE> <TYPE>String</TYPE> (<TYPE>NodeToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> <TYPE>Bool</TYPE>) <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION>
                   <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><TYPE>Map</TYPE> <TYPE>String</TYPE> <TYPE>String</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION>
                   <TYPE>WfGraph</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> ( <TYPE>Either</TYPE> <TYPE>String</TYPE> (<TYPE>WfProcess</TYPE> a))
startWorkflow engine nodeTypes predicates attrs graph userData
    <FUNCTION>|</FUNCTION> typesMissing          <OPERATOR>=</OPERATOR> <FUNCTION>return</FUNCTION> <FUNCTION>$</FUNCTION> <TYPE>Left</TYPE> (<STRING>"Missing entries in nodeType for: "</STRING> <FUNCTION>++</FUNCTION> missingMsg)
    <FUNCTION>|</FUNCTION> <FUNCTION>null</FUNCTION> startNodes       <OPERATOR>=</OPERATOR> <FUNCTION>return</FUNCTION> <FUNCTION>$</FUNCTION> <TYPE>Left</TYPE> <STRING>"Error: Workflow has no start node"</STRING>
    <FUNCTION>|</FUNCTION> <FUNCTION>length</FUNCTION> startNodes <FUNCTION>&gt;</FUNCTION> <NUMERIC>1</NUMERIC> <OPERATOR>=</OPERATOR> <FUNCTION>return</FUNCTION> <FUNCTION>$</FUNCTION> <TYPE>Left</TYPE> <STRING>"Error: Workflow has more than one start node"</STRING>
    <FUNCTION>|</FUNCTION> <FUNCTION>otherwise</FUNCTION>             <OPERATOR>=</OPERATOR> <KEYWORD>do</KEYWORD> wf <FUNCTION>&lt;</FUNCTION><FUNCTION>-</FUNCTION> createWfProcess engine graph nodeTypes predicates userData attrs
                                 (wf,startToken) <FUNCTION>&lt;</FUNCTION><FUNCTION>-</FUNCTION> createNodeToken engine wf startNode <OPERATOR>[]</OPERATOR>
                                 wf <FUNCTION>&lt;</FUNCTION><FUNCTION>-</FUNCTION> setProcessState engine wf <TYPE>ProcessExecuting</TYPE>
                                 wf <FUNCTION>&lt;</FUNCTION><FUNCTION>-</FUNCTION> acceptWithGuard engine startToken (wf { nodeTokens <OPERATOR>=</OPERATOR> <OPERATOR>[</OPERATOR>startToken<OPERATOR>]</OPERATOR> })
                                 wf <FUNCTION>&lt;</FUNCTION><FUNCTION>-</FUNCTION> <KEYWORD>if</KEYWORD> (isWfComplete wf)
                                           <KEYWORD>then</KEYWORD> setProcessState engine wf <TYPE>ProcessComplete</TYPE>
                                           <KEYWORD>else</KEYWORD> <FUNCTION>return</FUNCTION> wf
                                 <FUNCTION>return</FUNCTION> <FUNCTION>$</FUNCTION> <TYPE>Right</TYPE> wf
  <KEYWORD>where</KEYWORD>
    startNodes   <OPERATOR>=</OPERATOR> <FUNCTION>filter</FUNCTION> (<FUNCTION>\node</FUNCTION> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> nodeIsStart node) <FUNCTION>$</FUNCTION> <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OO>elems</OO> (graphNodes graph)
    startNode    <OPERATOR>=</OPERATOR> <FUNCTION>head</FUNCTION> startNodes
    typesMissing <OPERATOR>=</OPERATOR> (<OBJ>not</OBJ><FUNCTION>.</FUNCTION><OO>null</OO>) missingTypes
    missingTypes <OPERATOR>=</OPERATOR> <FUNCTION>filter</FUNCTION> (<FUNCTION>\node-&gt;</FUNCTION> <FUNCTION>not</FUNCTION> (<TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OO>member</OO> (nodeType node) nodeTypes)) (<TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OO>elems</OO> (graphNodes graph))
    missingMsg   <OPERATOR>=</OPERATOR> <FUNCTION>concatMap</FUNCTION> (<FUNCTION>\node</FUNCTION> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> nodeType node <FUNCTION>++</FUNCTION> <STRING>" "</STRING>) missingTypes


isWfComplete <OPERATOR>::</OPERATOR> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>Bool</TYPE>
isWfComplete process <OPERATOR>=</OPERATOR> <FUNCTION>null</FUNCTION> (nodeTokens process) <FUNCTION>&amp;&amp;</FUNCTION> <FUNCTION>null</FUNCTION> (arcTokens process)

<COMMENT>-- removeNodeToken</COMMENT>
<COMMENT>--   Removes the node token from the list of active node tokens in the given process</COMMENT>

removeNodeToken <OPERATOR>::</OPERATOR> <TYPE>NodeToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> a
removeNodeToken token wf <OPERATOR>=</OPERATOR> wf { nodeTokens <OPERATOR>=</OPERATOR> <TYPE>ListUtil</TYPE><FUNCTION>.</FUNCTION><OO>removeFirst</OO> (<FUNCTION>\t-&gt;t</FUNCTION> <FUNCTION>==</FUNCTION> token) (nodeTokens wf) }

completeDefaultExecution <OPERATOR>::</OPERATOR> (<TYPE>WfEngine</TYPE> engine) <OPERATOR>=&gt;</OPERATOR> engine <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>NodeToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> (<TYPE>WfProcess</TYPE> a)
completeDefaultExecution engine token wf <OPERATOR>=</OPERATOR> completeExecution engine token <OPERATOR>[]</OPERATOR> wf

<COMMENT>-- completeExecution</COMMENT>
<COMMENT>--   Generates a new token for each output node of the current node of the given</COMMENT>
<COMMENT>--   token.</COMMENT>

completeExecution <OPERATOR>::</OPERATOR> (<TYPE>WfEngine</TYPE> e) <OPERATOR>=&gt;</OPERATOR> e <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>NodeToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>String</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> (<TYPE>WfProcess</TYPE> a)
completeExecution engine token outputArcName wf <OPERATOR>=</OPERATOR>
  <KEYWORD>if</KEYWORD> ( processState wf <FUNCTION>/=</FUNCTION> <TYPE>ProcessExecuting</TYPE> )
      <KEYWORD>then</KEYWORD> <FUNCTION>return</FUNCTION> wf
      <KEYWORD>else</KEYWORD> <KEYWORD>do</KEYWORD> completeNodeToken engine token
              newWf <FUNCTION>&lt;</FUNCTION><FUNCTION>-</FUNCTION> foldM (split) newWf outputArcs
              <KEYWORD>if</KEYWORD> (isWfComplete newWf)
                 <KEYWORD>then</KEYWORD> setProcessState engine newWf <TYPE>ProcessComplete</TYPE>
                 <KEYWORD>else</KEYWORD> <FUNCTION>return</FUNCTION> newWf
  <KEYWORD>where</KEYWORD>
    graph        <OPERATOR>=</OPERATOR> wfGraph wf
    currentNode  <OPERATOR>=</OPERATOR> nodeForToken token graph
    outputArcs   <OPERATOR>=</OPERATOR> <FUNCTION>filter</FUNCTION> (<FUNCTION>\arc</FUNCTION> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> arcName arc <FUNCTION>==</FUNCTION> outputArcName ) <FUNCTION>$</FUNCTION>
                   (graphOutputArcs graph) <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OPERATOR>!</OPERATOR> (nodeId currentNode)

    newWf        <OPERATOR>=</OPERATOR> removeNodeToken token wf

    split wf arc <OPERATOR>=</OPERATOR> <KEYWORD>do</KEYWORD> (wf, arcToken) <FUNCTION>&lt;</FUNCTION><FUNCTION>-</FUNCTION> createArcToken engine wf arc token
                      acceptToken engine arcToken wf

<COMMENT>-- acceptToken</COMMENT>
<COMMENT>--   Called when a token arrives at a node. The node is checked to see if it requires</COMMENT>
<COMMENT>--   tokens at all inputs. If it doesn't, the acceptSingle function is called. Otherwise</COMMENT>
<COMMENT>--   it calls acceptJoin.</COMMENT>

acceptToken <OPERATOR>::</OPERATOR> (<TYPE>WfEngine</TYPE> e) <OPERATOR>=&gt;</OPERATOR> e <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>ArcToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> (<TYPE>WfProcess</TYPE> a)
acceptToken engine token wf
    <FUNCTION>|</FUNCTION> isAcceptSingle <OPERATOR>=</OPERATOR> acceptSingle engine token wf
    <FUNCTION>|</FUNCTION> <FUNCTION>otherwise</FUNCTION>      <OPERATOR>=</OPERATOR> acceptJoin   engine token wf
  <KEYWORD>where</KEYWORD>
    isAcceptSingle <OPERATOR>=</OPERATOR> <FUNCTION>not</FUNCTION> <FUNCTION>$</FUNCTION> nodeIsJoin targetNode
    targetNode     <OPERATOR>=</OPERATOR> ((<OBJ>graphNodes</OBJ><FUNCTION>.</FUNCTION><OO>wfGraph</OO>) wf) <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OPERATOR>!</OPERATOR> ((<OBJ>endNodeId</OBJ><FUNCTION>.</FUNCTION><OO>arcForToken</OO>) token)

<COMMENT>-- acceptSingle</COMMENT>
<COMMENT>--   Called when a node requires only a single incoming token to activate.</COMMENT>
<COMMENT>--   Moves the token into the node and calls the guard function</COMMENT>

acceptSingle <OPERATOR>::</OPERATOR> (<TYPE>WfEngine</TYPE> e) <OPERATOR>=&gt;</OPERATOR> e <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>ArcToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> (<TYPE>WfProcess</TYPE> a)
acceptSingle engine token process <OPERATOR>=</OPERATOR>
  <KEYWORD>do</KEYWORD> (process,newToken) <FUNCTION>&lt;</FUNCTION><FUNCTION>-</FUNCTION> createNodeToken engine process node <OPERATOR>[</OPERATOR>token<OPERATOR>]</OPERATOR>
     completeArcToken engine token
     acceptWithGuard engine newToken process { nodeTokens <OPERATOR>=</OPERATOR> newToken<OPERATOR>:</OPERATOR>(nodeTokens process) }
  <KEYWORD>where</KEYWORD>
    graph <OPERATOR>=</OPERATOR> wfGraph process
    node  <OPERATOR>=</OPERATOR> (graphNodes graph) <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OPERATOR>!</OPERATOR> ((<OBJ>endNodeId</OBJ><FUNCTION>.</FUNCTION><OO>arcForToken</OO>) token)

<COMMENT>-- acceptJoin</COMMENT>
<COMMENT>--   Called when a node requires that a token exist at all inputs before activating.</COMMENT>
<COMMENT>--   If the condition is met, joins all the input tokens into a single token in the</COMMENT>
<COMMENT>--   node then calls the guard function.</COMMENT>
<COMMENT>--   If all inputs don't yet have inputs, adds the current token to the workflow</COMMENT>
<COMMENT>--   instance and returns.</COMMENT>

acceptJoin <OPERATOR>::</OPERATOR> (<TYPE>WfEngine</TYPE> e) <OPERATOR>=&gt;</OPERATOR> e <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>ArcToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> (<TYPE>WfProcess</TYPE> a)
acceptJoin engine token process
    <FUNCTION>|</FUNCTION> areAllInputsPresent <OPERATOR>=</OPERATOR> <KEYWORD>do</KEYWORD> (process,newToken) <FUNCTION>&lt;</FUNCTION><FUNCTION>-</FUNCTION> createNodeToken engine process targetNode inputTokens
                               <KEYWORD>let</KEYWORD> newProcess <OPERATOR>=</OPERATOR> process { nodeTokens <OPERATOR>=</OPERATOR> newToken<OPERATOR>:</OPERATOR>(nodeTokens process), arcTokens <OPERATOR>=</OPERATOR> outputArcTokens }
                               <FUNCTION>mapM</FUNCTION> (completeArcToken engine) inputTokens
                               acceptWithGuard engine newToken newProcess
    <FUNCTION>|</FUNCTION> <FUNCTION>otherwise</FUNCTION>           <OPERATOR>=</OPERATOR> <FUNCTION>return</FUNCTION> process { arcTokens <OPERATOR>=</OPERATOR> allArcTokens }
  <KEYWORD>where</KEYWORD>
    allArcTokens          <OPERATOR>=</OPERATOR> token<OPERATOR>:</OPERATOR>(arcTokens process)
    areAllInputsPresent   <OPERATOR>=</OPERATOR> <FUNCTION>length</FUNCTION> inputTokens <FUNCTION>==</FUNCTION> <FUNCTION>length</FUNCTION> inputArcs

    fstInputArcToken arc  <OPERATOR>=</OPERATOR> <TYPE>ListUtil</TYPE><FUNCTION>.</FUNCTION><OO>firstMatch</OO> (<FUNCTION>\arcToken</FUNCTION> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> (<OBJ>arcId</OBJ><FUNCTION>.</FUNCTION><OO>arcForToken</OO>) arcToken <FUNCTION>==</FUNCTION> arcId arc) allArcTokens

    inputTokens           <OPERATOR>=</OPERATOR> <TYPE>ListUtil</TYPE><FUNCTION>.</FUNCTION><OO>removeNothings</OO> <FUNCTION>$</FUNCTION> <FUNCTION>map</FUNCTION> (fstInputArcToken) inputArcs

    targetNodeId          <OPERATOR>=</OPERATOR> (<OBJ>endNodeId</OBJ><FUNCTION>.</FUNCTION><OO>arcForToken</OO>) token
    targetNode            <OPERATOR>=</OPERATOR> (graphNodes (wfGraph process)) <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OPERATOR>!</OPERATOR> targetNodeId
    allInputArcs          <OPERATOR>=</OPERATOR> (graphInputArcs (wfGraph process)) <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OPERATOR>!</OPERATOR> targetNodeId
    inputArcs             <OPERATOR>=</OPERATOR> <FUNCTION>filter</FUNCTION> (<FUNCTION>\arc-&gt;</FUNCTION> arcName arc <FUNCTION>==</FUNCTION> (<OBJ>arcName</OBJ><FUNCTION>.</FUNCTION><OO>arcForToken</OO>) token) allInputArcs
    outputArcTokens       <OPERATOR>=</OPERATOR> <FUNCTION>filter</FUNCTION> (<FUNCTION>\t</FUNCTION> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <FUNCTION>not</FUNCTION> <FUNCTION>$</FUNCTION> <FUNCTION>elem</FUNCTION> t inputTokens) (arcTokens process)

<COMMENT>-- acceptWithGuard</COMMENT>
<COMMENT>--   This is only called once the node is ready to fire. The given token is now in the node</COMMENT>
<COMMENT>--   and exists in the workflow instance.</COMMENT>
<COMMENT>--   The node guard method is now called and the appropriate action will be taken based on</COMMENT>
<COMMENT>--   what kind of GuardResponse is returned.</COMMENT>

acceptWithGuard <OPERATOR>::</OPERATOR> (<TYPE>WfEngine</TYPE> e) <OPERATOR>=&gt;</OPERATOR> e <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>NodeToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> (<TYPE>WfProcess</TYPE> a)
acceptWithGuard engine token wf <OPERATOR>=</OPERATOR>
    <KEYWORD>do</KEYWORD> guardResponse <FUNCTION>&lt;</FUNCTION><FUNCTION>-</FUNCTION> guard token wf
       <KEYWORD>case</KEYWORD> guardResponse <KEYWORD>of</KEYWORD>
           <TYPE>AcceptToken</TYPE>    <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> accept engine token wf
           <TYPE>DiscardToken</TYPE>   <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <KEYWORD>do</KEYWORD> completeNodeToken engine token
                                <FUNCTION>return</FUNCTION> <FUNCTION>$</FUNCTION> removeNodeToken token wf
           (<TYPE>SkipNode</TYPE> arc) <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> completeExecution engine token arc wf
    <KEYWORD>where</KEYWORD>
        currentNode  <OPERATOR>=</OPERATOR> nodeForToken token (wfGraph wf)
        guard        <OPERATOR>=</OPERATOR> guardFunction  currNodeType
        accept       <OPERATOR>=</OPERATOR> acceptFunction currNodeType
        currNodeType <OPERATOR>=</OPERATOR> (nodeTypes wf) <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OPERATOR>!</OPERATOR> (nodeType currentNode)

evalGuardLang <OPERATOR>::</OPERATOR> <TYPE>NodeToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> <TYPE>GuardResponse</TYPE>
evalGuardLang token wf
    <FUNCTION>|</FUNCTION> <FUNCTION>null</FUNCTION> guard <OPERATOR>=</OPERATOR> <FUNCTION>return</FUNCTION> <FUNCTION>$</FUNCTION> <TYPE>AcceptToken</TYPE>
    <FUNCTION>|</FUNCTION> <FUNCTION>otherwise</FUNCTION>  <OPERATOR>=</OPERATOR> <KEYWORD>do</KEYWORD> result <FUNCTION>&lt;</FUNCTION><FUNCTION>-</FUNCTION> evalGuardLangStmt token wf <FUNCTION>$</FUNCTION> <TYPE>GuardLang</TYPE><FUNCTION>.</FUNCTION><OO>evalGuard</OO> (<TYPE>GuardLang</TYPE><FUNCTION>.</FUNCTION><OO>lexer</OO> guard)
                      <FUNCTION>return</FUNCTION> <FUNCTION>$</FUNCTION> resultToResponse result
    <KEYWORD>where</KEYWORD>
        node  <OPERATOR>=</OPERATOR> nodeForToken token (wfGraph wf)
        guard <OPERATOR>=</OPERATOR> nodeGuard node

resultToResponse <OPERATOR>::</OPERATOR> <TYPE>GuardLang</TYPE><FUNCTION>.</FUNCTION><TYPE>Result</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>GuardResponse</TYPE>
resultToResponse <TYPE>GuardLang</TYPE><FUNCTION>.</FUNCTION><TYPE>Accept</TYPE>     <OPERATOR>=</OPERATOR> <TYPE>AcceptToken</TYPE>
resultToResponse <TYPE>GuardLang</TYPE><FUNCTION>.</FUNCTION><TYPE>Discard</TYPE>    <OPERATOR>=</OPERATOR> <TYPE>DiscardToken</TYPE>
resultToResponse (<TYPE>GuardLang</TYPE><FUNCTION>.</FUNCTION><TYPE>Skip</TYPE> arc) <OPERATOR>=</OPERATOR> <TYPE>SkipNode</TYPE> arc

evalGuardLangStmt <OPERATOR>::</OPERATOR> <TYPE>NodeToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>GuardLang</TYPE><FUNCTION>.</FUNCTION><TYPE>Stmt</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> <TYPE>GuardLang</TYPE><FUNCTION>.</FUNCTION><TYPE>Result</TYPE>
evalGuardLangStmt _     _  (<TYPE>GuardLang</TYPE><FUNCTION>.</FUNCTION><TYPE>StmtResult</TYPE> result)           <OPERATOR>=</OPERATOR> <FUNCTION>return</FUNCTION> result
evalGuardLangStmt token wf (<TYPE>GuardLang</TYPE><FUNCTION>.</FUNCTION><TYPE>StmtIF</TYPE> expr ifStmt elseStmt) <OPERATOR>=</OPERATOR>
    <KEYWORD>do</KEYWORD> result <FUNCTION>&lt;</FUNCTION><FUNCTION>-</FUNCTION> evalGuardLangExpr token wf expr
       <KEYWORD>case</KEYWORD> result <KEYWORD>of</KEYWORD>
          <TYPE>True</TYPE>  <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> evalGuardLangStmt token wf ifStmt
          <TYPE>False</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> evalGuardLangStmt token wf elseStmt

evalGuardLangExpr <OPERATOR>::</OPERATOR> <TYPE>NodeToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>GuardLang</TYPE><FUNCTION>.</FUNCTION><TYPE>Expr</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> <TYPE>Bool</TYPE>
evalGuardLangExpr token wf (<TYPE>GuardLang</TYPE><FUNCTION>.</FUNCTION><TYPE>ExprSymbol</TYPE> symbol)   <OPERATOR>=</OPERATOR> evalGuardLangPred token wf symbol
evalGuardLangExpr token wf (<TYPE>GuardLang</TYPE><FUNCTION>.</FUNCTION><TYPE>ExprOR</TYPE>  exprL exprR) <OPERATOR>=</OPERATOR>
    <KEYWORD>do</KEYWORD> result <FUNCTION>&lt;</FUNCTION><FUNCTION>-</FUNCTION> evalGuardLangExpr token wf exprL
       <KEYWORD>case</KEYWORD> result <KEYWORD>of</KEYWORD>
           <TYPE>True</TYPE>  <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <FUNCTION>return</FUNCTION> <TYPE>True</TYPE>
           <TYPE>False</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> evalGuardLangExpr token wf exprR
evalGuardLangExpr token wf (<TYPE>GuardLang</TYPE><FUNCTION>.</FUNCTION><TYPE>ExprAND</TYPE> exprL exprR) <OPERATOR>=</OPERATOR>
    <KEYWORD>do</KEYWORD> result <FUNCTION>&lt;</FUNCTION><FUNCTION>-</FUNCTION> evalGuardLangExpr token wf exprL
       <KEYWORD>case</KEYWORD> result <KEYWORD>of</KEYWORD>
           <TYPE>True</TYPE>  <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> evalGuardLangExpr token wf exprR
           <TYPE>False</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <FUNCTION>return</FUNCTION> <TYPE>False</TYPE>
evalGuardLangExpr token wf (<TYPE>GuardLang</TYPE><FUNCTION>.</FUNCTION><TYPE>ExprNOT</TYPE> expr) <OPERATOR>=</OPERATOR>
    <KEYWORD>do</KEYWORD> result <FUNCTION>&lt;</FUNCTION><FUNCTION>-</FUNCTION> evalGuardLangExpr token wf expr
       <FUNCTION>return</FUNCTION> <FUNCTION>$</FUNCTION> <FUNCTION>not</FUNCTION> result

evalGuardLangPred <OPERATOR>::</OPERATOR> <TYPE>NodeToken</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>WfProcess</TYPE> a <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>String</TYPE> <FUNCTION>-</FUNCTION><FUNCTION>&gt;</FUNCTION> <TYPE>IO</TYPE> <TYPE>Bool</TYPE>
evalGuardLangPred token wf predicate
    <FUNCTION>|</FUNCTION> invalidPredicate <OPERATOR>=</OPERATOR> wfError <FUNCTION>$</FUNCTION> <STRING>"Predicate "</STRING> <FUNCTION>++</FUNCTION> predicate <FUNCTION>++</FUNCTION> <STRING>" not defined"</STRING>
    <FUNCTION>|</FUNCTION> <FUNCTION>otherwise</FUNCTION>        <OPERATOR>=</OPERATOR> (predMap <TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OPERATOR>!</OPERATOR> predicate) token wf
    <KEYWORD>where</KEYWORD>
        predMap <OPERATOR>=</OPERATOR> predicateMap wf
        invalidPredicate <OPERATOR>=</OPERATOR> <FUNCTION>not</FUNCTION> (<TYPE>Map</TYPE><FUNCTION>.</FUNCTION><OO>member</OO> predicate predMap)