import type { MergeableRecord } from '../objects';
import type { QuadSerializationConfiguration } from '../quads';
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
import type { NormalizedAst, ParentInformation } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
import { RFalse, RTrue } from '../../r-bridge/lang-4.x/convert-values';
import type { DataflowGraph } from '../../dataflow/graph/graph';
export declare const enum CfgVertexType {
    /** Marks a break point in a construct (e.g., between the name and the value of an argument, or the formals and the body of a function)  */
    MidMarker = "mid-marker",
    /** The explicit exit-nodes to ensure the hammock property */
    EndMarker = "end-marker",
    /** something like an if, assignment, ... even though in the classical sense of R they are still expressions */
    Statement = "statement",
    /** something like an addition, ... */
    Expression = "expression"
}
export interface CfgVertex {
    id: NodeId;
    type: CfgVertexType;
    name: string;
    /** in case of a function definition */
    children?: NodeId[];
}
interface CfgFlowDependencyEdge extends MergeableRecord {
    label: 'FD';
}
interface CfgControlDependencyEdge extends MergeableRecord {
    label: 'CD';
    /** the id which caused the control dependency */
    caused: NodeId;
    when: typeof RTrue | typeof RFalse;
}
export type CfgEdge = CfgFlowDependencyEdge | CfgControlDependencyEdge;
/**
 * This class represents the control flow graph of an R program.
 * The control flow may be hierarchical when confronted with function definitions (see {@link CfgVertex} and {@link CFG#rootVertexIds|rootVertexIds()}).
 */
export declare class ControlFlowGraph {
    private rootVertices;
    private vertexInformation;
    private edgeInformation;
    addVertex(vertex: CfgVertex, rootVertex?: boolean): this;
    addEdge(from: NodeId, to: NodeId, edge: CfgEdge): this;
    outgoing(node: NodeId): ReadonlyMap<NodeId, CfgEdge> | undefined;
    rootVertexIds(): ReadonlySet<NodeId>;
    vertices(): ReadonlyMap<NodeId, CfgVertex>;
    edges(): ReadonlyMap<NodeId, ReadonlyMap<NodeId, CfgEdge>>;
    merge(other: ControlFlowGraph, forceNested?: boolean): this;
}
export interface ControlFlowInformation extends MergeableRecord {
    returns: NodeId[];
    breaks: NodeId[];
    nexts: NodeId[];
    /** intended to construct a hammock graph, with 0 exit points representing a block that should not be part of the CFG (like a comment) */
    entryPoints: NodeId[];
    /** See {@link ControlFlowInformation#entryPoints|entryPoints} */
    exitPoints: NodeId[];
    graph: ControlFlowGraph;
}
export declare function emptyControlFlowInformation(): ControlFlowInformation;
/**
 * Given a normalized AST this approximates the control flow graph of the program.
 * This few is different from the computation of the dataflow graph and may differ,
 * especially because it focuses on intra-procedural analysis.
 *
 * @param ast - the normalized AST
 * @param graph - additional dataflow facts to consider by the control flow extraction
 */
export declare function extractCFG<Info = ParentInformation>(ast: NormalizedAst<Info>, graph?: DataflowGraph): ControlFlowInformation;
/**
 * Returns true if the given CFG equals the other CFG. False otherwise.
 */
export declare function equalCfg(a: ControlFlowGraph | undefined, b: ControlFlowGraph | undefined): boolean;
/**
 * @see df2quads
 * @see serialize2quads
 * @see graph2quads
 */
export declare function cfg2quads(cfg: ControlFlowInformation, config: QuadSerializationConfiguration): string;
export {};
