import { AgencyNode, ParallelBlock } from "../types.js";
export declare function resetParallelCounter(): void;
/**
 * Validate a parallel block: enforce statement allowlist at the top level,
 * then check cross-arm references. Throws on violation.
 */
export declare function validateParallelBlock(pb: ParallelBlock): void;
/**
 * Collect every let/const variable name introduced anywhere in the subtree of
 * the given node. Crosses into seqBlock, parallelBlock, ifElse branches, loop
 * bodies — but NOT into nested function/graphNode definitions (those
 * introduce their own scope). For nested parallel/seq, all bindings declared
 * inside are still considered bindings of the outer arm because they're
 * hoisted out.
 */
export declare function collectBindings(node: AgencyNode): Set<string>;
/**
 * Collect every variable name referenced (read) anywhere in the subtree.
 * "Referenced" means a `variableName` literal — i.e., a use of the name as a
 * value. Excludes the LHS of declarations (those are bindings, not refs).
 */
export declare function collectReferences(node: AgencyNode): Set<string>;
/**
 * Recursively desugar `parallel { ... }` and `seq { ... }` blocks within an
 * AgencyNode array. Replaces each top-level `parallelBlock` with the desugared
 * fork+destructuring sequence. Replaces each top-level `seqBlock` with its
 * body inlined (recursively desugared). Recurses into nested control-flow
 * bodies for any other node types so deeply-nested parallel/seq blocks
 * inside if/for/while/etc. also get processed.
 *
 * Note: `seqBlock` nodes that appear directly as arms of a `parallelBlock`
 * are NOT inlined here — they're handled by `desugarOneParallel`, which
 * treats each arm (including a `seqBlock` arm) as a single arm whose body is
 * the seq's body. Inlining at this level would flatten arm boundaries and
 * confuse the cross-arm reference check.
 */
export declare function desugarParallelInBody(body: AgencyNode[]): AgencyNode[];
