/** * Interpreting trees to graphs and configuring graphs to trees. * * In order to serialize graphs into the PENMAN format, a tree-like * layout of the graph must be decided. Deciding a layout includes * choosing the order of the edges from a node and the paths to get to a * node definition (the position in the tree where a node's concept and * edges are specified). For instance, the following graphs for "The dog * barked loudly" have different edge orders on the `b` node: * * ``` * (b / bark-01 (b / bark-01 * :ARG0 (d / dog) :mod (l / loud) * :mod (l / loud)) :ARG0 (d / dog)) * ``` * * With re-entrancies, there are choices about which location of a * re-entrant node gets the full definition with its concept (node * label), etc. For instance, the following graphs for "The dog tried to * bark" have different locations for the definition of the `d` node: * * ``` * (t / try-01 (t / try-01 * :ARG0 (d / dog) :ARG0 d * :ARG1 (b / bark-01 :ARG1 (b / bark-01 * :ARG0 d)) :ARG0 (d / dog)) * ``` * * With inverted edges, there are even more possibilities, such as: * * ``` * (t / try-01 (t / try-01 * :ARG0 (d / dog :ARG1 (b / bark-01 * :ARG0-of b) :ARG0 (d / dog * :ARG1 (b / bark-01)) :ARG0-of t))) * ``` * * This module introduces two epigraphical markers so that a pure graph * parsed from PENMAN can retain information about its tree layout * without altering its graph properties. The first marker type is * `Push`, which is put on a triple to indicate that the triple * introduces a new node context, while the sentinel `POP` * indicates that a triple is at the end of one or more node contexts. * These markers only work if the triples in the graph's data are * ordered. For instance, one of the graphs above (repeated here) has the * following data: * * ``` * PENMAN Graph Epigraph * (t / try-01 [('t', ':instance', 'try-01'), : * :ARG0 (d / dog) ('t', ':ARG0', 'd'), : Push('d') * :ARG1 (b / bark-01 ('d', ':instance', 'dog'), : POP * :ARG0 d)) ('t', ':ARG1', 'b'), : Push('b') * ('b', ':instance', 'bark-01'), : * ('b', ':ARG0', 'd')] : POP * ``` */ import { Epidatum } from './epigraph'; import { Graph } from './graph'; import { Model } from './model'; import { Tree } from './tree'; import { Role, Triple, Variable } from './types'; /**Epigraph marker for layout choices. */ export declare class LayoutMarker extends Epidatum { } /**Epigraph marker to indicate a new node context.*/ export declare class Push extends LayoutMarker { variable: Variable; constructor(variable: Variable); toString(): string; } /** Epigraph marker to indicate the end of a node context. */ export declare class Pop extends LayoutMarker { toString(): string; } /** A singleton instance of `Pop`. */ export declare const POP: Pop; export interface InterpretOptions { model?: Model; } /** * Interpret tree `t` as a graph using `model`. * * Tree interpretation is the process of transforming the nodes and * edges of a tree into a directed graph. A semantic model determines * which edges are inverted and how to deinvert them. If `model` is * not provided, the default model will be used. * * The `options` param consists of an object with a single `model` property. * * @param t - The `Tree` object to interpret. * @param options - An object with an optional `model` property, used to interpret `t`. * @returns The interpreted `Graph` object. * @example * import { Tree, interpret } from 'penman-js'; * * const t = new Tree('b', [ * ['/', 'bark-01'], * ['ARG0', new Tree('d', [ * ['/', 'dog'] * ])] * ]); * * const g = interpret(t); * for (const triple of g.triples) { * console.log(triple); * } * // ['b', ':instance', 'bark-01'] * // ['b', ':ARG0', 'd'] * // ['d', ':instance', 'dog'] */ export declare function interpret(t: Tree, options?: InterpretOptions): Graph; export interface ConfigureOptions { top?: Variable; model?: Model; } /** * Create a tree from a graph by making as few decisions as possible. * * A graph interpreted from a valid tree using `interpret` will * contain epigraphical markers that describe how the triples of a * graph are to be expressed in a tree, and thus configuring this * tree requires only a single pass through the list of triples. If * the markers are missing or out of order, or if the graph has been * modified, then the configuration process will have to make * decisions about where to insert tree branches. These decisions are * deterministic, but may result in a tree different than the one * expected. * * `options` consists of an object with optional `top` and `model` properties. * - `top` is the variable to use as the top of the graph; if `null`, the top of `g` will be used. * - `model` is the `Model` used to configure the tree. * * @param g - The `Graph` object to configure. * @param options - An object with optional `top` and `model` properties. * - `top` is the variable to use as the top of the graph; if `null`, the top of `g` will be used. * - `model` is the `Model` used to configure the tree. * @returns The configured `Tree` object. * @example * import { Graph, configure } from 'penman-js'; * * const g = new Graph([ * ['b', ':instance', 'bark-01'], * ['b', ':ARG0', 'd'], * ['d', ':instance', 'dog'] * ]); * * const t = configure(g); * console.log(t); * // Tree('b', [['/', 'bark-01'], [':ARG0', new Tree('d', [['/', 'dog']])]]) */ export declare function configure(g: Graph, options?: ConfigureOptions): Tree; export interface ReconfigureOptions { top?: Variable; model?: Model; key?: (role: Role) => any; } /** * Create a tree from a graph after any discarding layout markers. * * `options` consists of an object with optional `top`, `model`, and `key` properties. * If `key` is provided, triples are sorted according to the key. * * @param graph - The `Graph` object to reconfigure. * @param options - An object with optional `top`, `model`, and `key` properties. */ export declare function reconfigure(graph: Graph, options?: ReconfigureOptions): Tree; export interface RearrangeOptions { key?: (role: Role) => any; attributesFirst?: boolean; } /** * Sort the branches at each node in tree `t` according to `key`. * * Each node in a tree contains a list of branches. This function sorts * those lists in-place using the `key` function, which accepts a role and * returns some sortable criterion. * * `options` consists of an object with optional `key` and `attributesFirst` properties. * - If the `attributesFirst` argument is `true`, attribute branches will appear before any edges. * - `key` is a function used for sorting branches. * * Instance branches (`/`) always appear before any other branches. * * @param t - The tree to rearrange. * @param options - An object with optional `key` and `attributesFirst` properties. * @example * import { rearrange, Model, PENMANCodec } from 'penman-js'; * * const c = new PENMANCodec(); * const t = c.parse(` * (s / see-01 * :ARG1 (c / cat) * :ARG0 (d / dog))`); * rearrange(t, { key: Model().canonicalOrder, attributesFirst: true }); * console.log(c.format(t)); * // (s / see-01 * // :ARG0 (d / dog) * // :ARG1 (c / cat)) */ export declare function rearrange(t: Tree, options?: RearrangeOptions): void; /** * Return the variable pushed by `triple`, if any, otherwise `null`. * * @param g - A graph object. * @param triple - The triple to check for a pushed variable. * @returns The variable pushed by `triple`, or `null` if none. * @example * import { decode, getPushedVariable } from 'penman-js'; * * const g = decode('(a / alpha :ARG0 (b / beta))'); * console.log(getPushedVariable(g, ['a', ':instance', 'alpha'])); // Outputs: null * console.log(getPushedVariable(g, ['a', ':ARG0', 'b'])); // Outputs: 'b' */ export declare function getPushedVariable(g: Graph, triple: Triple): Variable | null; /** * Return `true` if `triple` appears inverted in serialization. * * More specifically, this function returns `true` if `triple` has * a `Push` epigraphical marker in graph `g` whose associated * variable is the source variable of `triple`. This should be * accurate when testing a triple in a graph interpreted using * `interpret` (including `PENMANCodec.decode` and similar methods), * but it does not guarantee that a new serialization of `g` will * express `triple` as inverted as it can change if the graph or its * epigraphical markers are modified, if a new top is chosen, etc. * * @param g - A `Graph` object containing `triple`. * @param triple - The triple that does or does not appear inverted. * @returns `true` if `triple` appears inverted in graph `g`. */ export declare function appearsInverted(g: Graph, triple: Triple): boolean; /** * Return the list of node contexts corresponding to triples in `g`. * * If a node context is unknown, the value `null` is substituted. * * @param g - A graph object. * @returns An array of node contexts corresponding to triples in `g`. * @example * import { decode, nodeContexts } from 'penman-js'; * * const g = decode(` * (a / alpha * :attr val * :ARG0 (b / beta :ARG0 (g / gamma)) * :ARG0-of g)`); * for (const [ctx, trp] of zip(nodeContexts(g), g.triples)) { * console.log(ctx, ':', trp); * } * * // a : ['a', ':instance', 'alpha'] * // a : ['a', ':attr', 'val'] * // a : ['a', ':ARG0', 'b'] * // b : ['b', ':instance', 'beta'] * // b : ['b', ':ARG0', 'g'] * // g : ['g', ':instance', 'gamma'] * // a : ['g', ':ARG0', 'a'] */ export declare function nodeContexts(g: Graph): Array;