import { DefaultMap } from '../../util/collections/defaultmap';
import type { BuiltIn } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
import { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
import { Identifier, type IdentifierReference } from '../environments/identifier';
import { type DataflowGraph, FunctionArgument } from '../graph/graph';
import type { RParameter } from '../../r-bridge/lang-4.x/ast/model/nodes/r-parameter';
import type { AstIdMap, ParentInformation } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
import { type DataflowGraphVertexFunctionCall, type DataflowGraphVertexFunctionDefinition, type DataflowGraphVertexInfo } from '../graph/vertex';
import type { REnvironmentInformation } from '../environments/environment';
import type { ExitPoint } from '../info';
export type NameIdMap = DefaultMap<Identifier, IdentifierReference[]>;
/**
 * Find all reads within the graph that do not reference a local definition in the graph.
 */
export declare function findNonLocalReads(graph: DataflowGraph, ignores?: ReadonlySet<NodeId>): IdentifierReference[];
/**
 * Produces a map from names to all identifier references sharing that name.
 */
export declare function produceNameSharedIdMap(references: IdentifierReference[]): NameIdMap;
/**
 * Links the given arguments to the given parameters within the given graph.
 * This follows the `pmatch` semantics of R
 * @see https://cran.r-project.org/doc/manuals/R-lang.html#Argument-matching
 * This returns the resolved map from argument ids to parameter ids.
 * If you just want to match by name, use {@link pMatch}.
 */
export declare function linkArgumentsOnCall(args: readonly FunctionArgument[], params: readonly RParameter<ParentInformation>[], graph: DataflowGraph): Map<NodeId, NodeId>;
/**
 * Links the given arguments to the given parameters within the given graph by name only.
 * @example
 * ```ts
 * const parameterSpec = {
 *   'paramName':         'paramId',
 *   'anotherParamName':  'anotherParamId',
 *   // we recommend to always add '...' to your specification
 *   // this way you can collect all arguments that could not be matched!
 *   '...':               '...'
 * } as const;
 *
 * const match = pMatch(convertFnArguments(args), parameterSpec);
 * const addParam = match.get('paramId');
 * ```
 * @note
 * To obtain the arguments from a {@link RFunctionCall}[], either use {@link processAllArguments} (also available via {@link processKnownFunctionCall})
 * or convert them with {@link convertFnArguments}.
 */
export declare function pMatch<Targets extends NodeId>(args: readonly FunctionArgument[], params: Record<string, Targets>): Map<Targets, NodeId[]>;
/**
 * Links a function call with a single target function definition.
 */
export declare function linkFunctionCallWithSingleTarget(graph: DataflowGraph, { subflow: fnSubflow, exitPoints, id: fnId, params }: DataflowGraphVertexFunctionDefinition, info: DataflowGraphVertexFunctionCall, idMap: AstIdMap): ExitPoint[];
/**
 * Returns the called functions within the current graph, which can be used to merge the environments with the call.
 * Furthermore, it links the corresponding arguments.
 * @param graph     - The graph to use for search and resolution traversals (ideally a superset of the `thisGraph`)
 * @param idMap     - The map to resolve ids to names
 * @param thisGraph - The graph to search for function calls in
 */
export declare function linkFunctionCalls(graph: DataflowGraph, idMap: AstIdMap, thisGraph: DataflowGraph): {
    functionCall: NodeId;
    called: readonly DataflowGraphVertexInfo[];
    propagateExitPoints: readonly ExitPoint[];
}[];
/**
 * convenience function returning all known call targets, as well as the name source which defines them
 */
export declare function getAllFunctionCallTargets(call: NodeId, graph: DataflowGraph, environment?: REnvironmentInformation): NodeId[];
/**
 * Finds all linked function definitions starting from the given set of read ids.
 * This is a complicated function, please only call it if you know what you are doing.
 * For example, if you are interested in the called functions of a function call, use {@link getAllFunctionCallTargets} instead.
 * This function here expects you to handle the accessed objects yourself (e.g,. already resolve the first layer of reads/returns/calls/... or resolve the identifier by name)
 * and then pass in the relevant read ids.
 * @example
 * Consider a scenario like this:
 * ```R
 * x <- function() 3
 * x()
 * ```
 * To resolve the call `x` in the second line, use {@link getAllFunctionCallTargets}!
 * To know what fdefs the definition of `x` in the first line links to, you can use {@link getAllLinkedFunctionDefinitions|this function}.
 */
export declare function getAllLinkedFunctionDefinitions(functionDefinitionReadIds: ReadonlySet<NodeId>, dataflowGraph: DataflowGraph): [Set<Required<DataflowGraphVertexFunctionDefinition>>, Set<BuiltIn>];
/**
 * This method links a set of read variables to definitions in an environment.
 * @param referencesToLinkAgainstEnvironment - The set of references to link against the environment
 * @param environmentInformation             - The environment information to link against
 * @param givenInputs                        - The existing list of inputs that might be extended
 * @param graph                              - The graph to enter the found links
 * @param maybeForRemaining                  - Each input that can not be linked, will be added to `givenInputs`. If this flag is `true`, it will be marked as `maybe`.
 * @returns the given inputs, possibly extended with the remaining inputs (those of `referencesToLinkAgainstEnvironment` that could not be linked against the environment)
 */
export declare function linkInputs(referencesToLinkAgainstEnvironment: readonly IdentifierReference[], environmentInformation: REnvironmentInformation, givenInputs: IdentifierReference[], graph: DataflowGraph, maybeForRemaining: boolean): IdentifierReference[];
/**
 * all loops variables which are open read (not already bound by a redefinition within the loop) get a maybe read marker to their last definition within the loop
 * e.g. with:
 * ```R
 * for(i in 1:10) {
 *  x_1 <- x_2 + 1
 * }
 * ```
 * `x_2` must get a read marker to `x_1` as `x_1` is the active redefinition in the second loop iteration.
 */
export declare function linkCircularRedefinitionsWithinALoop(graph: DataflowGraph, openIns: NameIdMap, outgoing: readonly IdentifierReference[]): void;
/**
 * Reapplies the loop exit points' control dependencies to the given identifier references.
 */
export declare function reapplyLoopExitPoints(exits: readonly ExitPoint[], references: readonly IdentifierReference[], graph: DataflowGraph): void;
