simple-graph-query 2.5.2 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -66,6 +66,7 @@ export declare class ForgeExprEvaluator extends AbstractParseTreeVisitor<EvalRes
66
66
  visitQualName(ctx: QualNameContext): EvalResult;
67
67
  private evaluateBinaryOperation;
68
68
  private evaluateUnaryOperation;
69
+ private evaluateSetOperation;
69
70
  }
70
71
  export declare class NameNotFoundError extends Error {
71
72
  constructor(message: string);
@@ -0,0 +1,71 @@
1
+ import { AbstractParseTreeVisitor } from "antlr4ts/tree/AbstractParseTreeVisitor";
2
+ import { ParseTree } from "antlr4ts/tree/ParseTree";
3
+ import { ForgeVisitor } from "./forge-antlr/ForgeVisitor";
4
+ import { Expr1Context, Expr1_5Context, Expr2Context, Expr3Context, Expr4Context, Expr5Context, Expr6Context, Expr7Context, Expr8Context, Expr9Context, Expr11Context, Expr12Context, Expr14Context, Expr15Context, Expr17Context, Expr18Context, ExprContext, NameContext, BlockContext } from "./forge-antlr/ForgeParser";
5
+ import { IForgeSchema } from "./types";
6
+ type Abstract = {
7
+ kind: "bool";
8
+ value: boolean;
9
+ } | {
10
+ kind: "num";
11
+ value: number;
12
+ } | {
13
+ kind: "empty";
14
+ } | {
15
+ kind: "typed";
16
+ arity: number;
17
+ columnTypes?: readonly string[];
18
+ } | {
19
+ kind: "ill-typed";
20
+ reason: string;
21
+ } | {
22
+ kind: "unknown";
23
+ };
24
+ export type StaticAnalysis = {
25
+ status: "unsat";
26
+ reason: string;
27
+ } | {
28
+ status: "tautology";
29
+ reason: string;
30
+ } | {
31
+ status: "empty";
32
+ reason: string;
33
+ } | {
34
+ status: "ill-typed";
35
+ reason: string;
36
+ } | {
37
+ status: "unknown";
38
+ };
39
+ export declare class ForgeExprStaticAnalyzer extends AbstractParseTreeVisitor<Abstract> implements ForgeVisitor<Abstract> {
40
+ private readonly schema?;
41
+ constructor(schema?: IForgeSchema);
42
+ private collectNamesFromList;
43
+ private collectBoundNames;
44
+ private illTypedIfBindsReservedName;
45
+ analyze(ctx: ParseTree): StaticAnalysis;
46
+ private static arityOf;
47
+ protected defaultResult(): Abstract;
48
+ private static bailIfIllTyped;
49
+ protected aggregateResult(aggregate: Abstract, nextResult: Abstract): Abstract;
50
+ visitExpr(ctx: ExprContext): Abstract;
51
+ private foldQuantifier;
52
+ visitBlock(ctx: BlockContext): Abstract;
53
+ visitExpr1(ctx: Expr1Context): Abstract;
54
+ visitExpr1_5(ctx: Expr1_5Context): Abstract;
55
+ visitExpr2(ctx: Expr2Context): Abstract;
56
+ visitExpr3(ctx: Expr3Context): Abstract;
57
+ visitExpr4(ctx: Expr4Context): Abstract;
58
+ visitExpr5(ctx: Expr5Context): Abstract;
59
+ visitExpr6(ctx: Expr6Context): Abstract;
60
+ visitExpr7(ctx: Expr7Context): Abstract;
61
+ visitExpr8(ctx: Expr8Context): Abstract;
62
+ visitExpr9(ctx: Expr9Context): Abstract;
63
+ visitExpr12(ctx: Expr12Context): Abstract;
64
+ visitExpr11(ctx: Expr11Context): Abstract;
65
+ visitExpr14(ctx: Expr14Context): Abstract;
66
+ visitExpr15(ctx: Expr15Context): Abstract;
67
+ visitExpr17(ctx: Expr17Context): Abstract;
68
+ visitExpr18(ctx: Expr18Context): Abstract;
69
+ visitName(ctx: NameContext): Abstract;
70
+ }
71
+ export {};
@@ -110,12 +110,13 @@ export declare class ForgeLexer extends Lexer {
110
110
  static readonly COMMA_TOK = 105;
111
111
  static readonly SLASH_TOK = 106;
112
112
  static readonly NUM_CONST_TOK = 107;
113
- static readonly IDENTIFIER_TOK = 108;
114
- static readonly WS = 109;
115
- static readonly CCOMMENT = 110;
116
- static readonly COMMENT = 111;
117
- static readonly MULTCOMMENT = 112;
118
- static readonly LANG_DECL = 113;
113
+ static readonly QUOTED_IDENTIFIER_TOK = 108;
114
+ static readonly IDENTIFIER_TOK = 109;
115
+ static readonly WS = 110;
116
+ static readonly CCOMMENT = 111;
117
+ static readonly COMMENT = 112;
118
+ static readonly MULTCOMMENT = 113;
119
+ static readonly LANG_DECL = 114;
119
120
  static readonly channelNames: string[];
120
121
  static readonly modeNames: string[];
121
122
  static readonly ruleNames: string[];
@@ -116,12 +116,13 @@ export declare class ForgeParser extends Parser {
116
116
  static readonly COMMA_TOK = 105;
117
117
  static readonly SLASH_TOK = 106;
118
118
  static readonly NUM_CONST_TOK = 107;
119
- static readonly IDENTIFIER_TOK = 108;
120
- static readonly WS = 109;
121
- static readonly CCOMMENT = 110;
122
- static readonly COMMENT = 111;
123
- static readonly MULTCOMMENT = 112;
124
- static readonly LANG_DECL = 113;
119
+ static readonly QUOTED_IDENTIFIER_TOK = 108;
120
+ static readonly IDENTIFIER_TOK = 109;
121
+ static readonly WS = 110;
122
+ static readonly CCOMMENT = 111;
123
+ static readonly COMMENT = 112;
124
+ static readonly MULTCOMMENT = 113;
125
+ static readonly LANG_DECL = 114;
125
126
  static readonly RULE_predDecl = 0;
126
127
  static readonly RULE_parseExpr = 1;
127
128
  static readonly RULE_alloyModule = 2;
@@ -855,7 +856,8 @@ export declare class OptionDeclContext extends ParserRuleContext {
855
856
  accept<Result>(visitor: ForgeVisitor<Result>): Result;
856
857
  }
857
858
  export declare class NameContext extends ParserRuleContext {
858
- IDENTIFIER_TOK(): TerminalNode;
859
+ IDENTIFIER_TOK(): TerminalNode | undefined;
860
+ QUOTED_IDENTIFIER_TOK(): TerminalNode | undefined;
859
861
  constructor(parent: ParserRuleContext | undefined, invokingState: number);
860
862
  get ruleIndex(): number;
861
863
  enterRule(listener: ForgeListener): void;
@@ -0,0 +1,28 @@
1
+ import { NameContext } from './ForgeParser';
2
+ /**
3
+ * Extracts the identifier string from a NameContext.
4
+ * Handles both regular identifiers and backtick-quoted identifiers (for reserved keywords).
5
+ *
6
+ * Examples:
7
+ * - Regular: `myVar` -> "myVar"
8
+ * - Quoted: `` `set` `` -> "set"
9
+ * - Quoted with escape: `` `my\`name` `` -> "my`name"
10
+ *
11
+ * @param ctx The NameContext to extract the identifier from
12
+ * @returns The identifier string with backticks and escapes processed
13
+ */
14
+ export declare function getIdentifierName(ctx: NameContext): string;
15
+ /**
16
+ * Quotes an identifier if it conflicts with a reserved keyword.
17
+ * Use this when generating Forge expressions that might contain reserved words.
18
+ *
19
+ * @param identifier The identifier to potentially quote
20
+ * @param reservedKeywords Set of reserved keywords to check against
21
+ * @returns The identifier, quoted with backticks if necessary
22
+ */
23
+ export declare function quoteIfReserved(identifier: string, reservedKeywords: Set<string>): string;
24
+ /**
25
+ * Set of all reserved keywords in Forge.
26
+ * Use with quoteIfReserved() when generating Forge expressions.
27
+ */
28
+ export declare const FORGE_RESERVED_KEYWORDS: Set<string>;
package/dist/index.d.ts CHANGED
@@ -1,19 +1,79 @@
1
1
  import { ForgeListenerImpl } from './forge-antlr/ForgeListenerImpl';
2
2
  import { ParseTreeWalker } from 'antlr4ts/tree/ParseTreeWalker';
3
3
  import { EvalResult } from './ForgeExprEvaluator';
4
- import { IDataInstance } from './types';
4
+ import { ForgeExprStaticAnalyzer, StaticAnalysis } from './ForgeExprStaticAnalyzer';
5
+ import { IDataInstance, IForgeSchema } from './types';
5
6
  export type ErrorResult = {
6
7
  error: Error;
7
8
  stackTrace?: string;
8
9
  };
9
10
  export type EvaluationResult = EvalResult | ErrorResult;
11
+ /**
12
+ * Evaluates Forge expressions against an `IDataInstance`.
13
+ *
14
+ * ## Caching contract (important for correctness)
15
+ *
16
+ * For performance, this class caches an inner evaluator (with its relation
17
+ * index and subexpression cache) across `evaluateExpression` calls. The
18
+ * cache is invalidated when the `datum` field is reassigned to a different
19
+ * reference, but **not** when the underlying `IDataInstance` is mutated in
20
+ * place (e.g. adding/removing atoms or tuples on the same object).
21
+ *
22
+ * If you mutate the underlying data in place, you **must** call
23
+ * {@link invalidate} (or reassign `datum` to a new object) before the next
24
+ * `evaluateExpression` call. Otherwise queries may return stale results.
25
+ *
26
+ * Recommended patterns:
27
+ * - Treat `IDataInstance` as immutable; create a new instance on data
28
+ * changes and construct a new `SimpleGraphQueryEvaluator` (or assign to
29
+ * `.datum`).
30
+ * - Or, if you mutate in place, call `invalidate()` after each mutation
31
+ * batch.
32
+ */
10
33
  export declare class SimpleGraphQueryEvaluator {
34
+ /**
35
+ * The data instance evaluated against. Reassigning this field is a
36
+ * supported invalidation signal — the inner evaluator cache is rebuilt
37
+ * on the next `evaluateExpression` call. **In-place mutation of the
38
+ * existing object is NOT detected**; call {@link invalidate} in that
39
+ * case.
40
+ */
11
41
  datum: IDataInstance;
12
42
  forgeListener: ForgeListenerImpl;
13
43
  walker: ParseTreeWalker;
14
44
  private parseTreeCache;
45
+ private cachedEvaluator;
46
+ private cachedEvaluatorDatum;
15
47
  constructor(datum: IDataInstance);
48
+ /**
49
+ * Discard the cached inner evaluator (and its relation index /
50
+ * subexpression cache). Call this after mutating the underlying
51
+ * `IDataInstance` in place, so the next `evaluateExpression` sees the
52
+ * updated data.
53
+ *
54
+ * Cheap: just nulls a couple of references. The caches rebuild lazily
55
+ * on the next query.
56
+ */
57
+ invalidate(): void;
16
58
  getExpressionParseTree(forgeExpr: string): import("./forge-antlr/ForgeParser").ParseExprContext;
17
59
  evaluateExpression(forgeExpr: string): EvaluationResult;
18
60
  }
61
+ /**
62
+ * Run a static analysis on a Forge expression.
63
+ *
64
+ * Returns `unsat` when the expression provably reduces to `false`, `empty`
65
+ * when it provably reduces to the empty set, `tautology` when it provably
66
+ * reduces to `true`, `ill-typed` for static type errors (e.g. arity
67
+ * mismatch), and `unknown` otherwise (including parse errors).
68
+ *
69
+ * When `schema` is provided, the analyzer also uses the type lattice and
70
+ * relation declarations to detect type-disjoint intersections, subtype
71
+ * tautologies in `in`, join column-type mismatches, and arity errors.
72
+ * Disjointness uses a closed-world rule (A ∩ B = ∅ iff no type in the
73
+ * lattice has both A and B in its lineage).
74
+ */
75
+ export declare function analyzeForgeExpression(forgeExpr: string, schema?: IForgeSchema): StaticAnalysis;
76
+ export { ForgeExprStaticAnalyzer, StaticAnalysis };
77
+ export type { IForgeSchema };
19
78
  export { synthesizeSelector, synthesizeBinaryRelation, synthesizeBinaryRelationWithWhy, synthesizeSelectorWithWhy, AtomSelectionExample, BinaryRelationExample, SelectorSynthesisError, SynthesisWhy, SynthesisWhyExample, WhyNode, } from './SelectorSynthesizer';
79
+ export { getIdentifierName, quoteIfReserved, FORGE_RESERVED_KEYWORDS, } from './forge-antlr/utils';