chiasmus 0.1.1 → 0.1.4
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.
- package/README.md +48 -11
- package/dist/formalize/engine.d.ts.map +1 -1
- package/dist/formalize/engine.js +32 -38
- package/dist/formalize/engine.js.map +1 -1
- package/dist/formalize/feedback.d.ts +8 -0
- package/dist/formalize/feedback.d.ts.map +1 -0
- package/dist/formalize/feedback.js +43 -0
- package/dist/formalize/feedback.js.map +1 -0
- package/dist/graph/analyses.d.ts +18 -0
- package/dist/graph/analyses.d.ts.map +1 -0
- package/dist/graph/analyses.js +145 -0
- package/dist/graph/analyses.js.map +1 -0
- package/dist/graph/extractor.d.ts +7 -0
- package/dist/graph/extractor.d.ts.map +1 -0
- package/dist/graph/extractor.js +246 -0
- package/dist/graph/extractor.js.map +1 -0
- package/dist/graph/facts.d.ts +8 -0
- package/dist/graph/facts.d.ts.map +1 -0
- package/dist/graph/facts.js +92 -0
- package/dist/graph/facts.js.map +1 -0
- package/dist/graph/parser.d.ts +7 -0
- package/dist/graph/parser.d.ts.map +1 -0
- package/dist/graph/parser.js +69 -0
- package/dist/graph/parser.js.map +1 -0
- package/dist/graph/types.d.ts +32 -0
- package/dist/graph/types.d.ts.map +1 -0
- package/dist/graph/types.js +2 -0
- package/dist/graph/types.js.map +1 -0
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +222 -76
- package/dist/mcp-server.js.map +1 -1
- package/dist/skills/learner.d.ts.map +1 -1
- package/dist/skills/learner.js +4 -18
- package/dist/skills/learner.js.map +1 -1
- package/dist/skills/library.d.ts +3 -0
- package/dist/skills/library.d.ts.map +1 -1
- package/dist/skills/library.js +5 -0
- package/dist/skills/library.js.map +1 -1
- package/dist/skills/relationships.d.ts +8 -0
- package/dist/skills/relationships.d.ts.map +1 -0
- package/dist/skills/relationships.js +36 -0
- package/dist/skills/relationships.js.map +1 -0
- package/dist/skills/starters.d.ts.map +1 -1
- package/dist/skills/starters.js +153 -73
- package/dist/skills/starters.js.map +1 -1
- package/dist/skills/types.d.ts +4 -0
- package/dist/skills/types.d.ts.map +1 -1
- package/dist/solvers/correction-loop.d.ts +1 -1
- package/dist/solvers/correction-loop.d.ts.map +1 -1
- package/dist/solvers/correction-loop.js +1 -1
- package/dist/solvers/correction-loop.js.map +1 -1
- package/dist/solvers/prolog-solver.d.ts.map +1 -1
- package/dist/solvers/prolog-solver.js +58 -1
- package/dist/solvers/prolog-solver.js.map +1 -1
- package/dist/solvers/types.d.ts +3 -0
- package/dist/solvers/types.d.ts.map +1 -1
- package/dist/solvers/z3-solver.d.ts.map +1 -1
- package/dist/solvers/z3-solver.js +14 -2
- package/dist/solvers/z3-solver.js.map +1 -1
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
# Chiasmus
|
|
2
2
|
|
|
3
|
-
MCP server that gives LLMs access to formal verification via Z3 (SMT solver) and Tau Prolog. Translates natural language problems into formal logic using a template-based pipeline, verifies results with mathematical certainty.
|
|
3
|
+
MCP server that gives LLMs access to formal verification via Z3 (SMT solver) and Tau Prolog, plus tree-sitter-based source code analysis. Translates natural language problems into formal logic using a template-based pipeline, verifies results with mathematical certainty, and analyzes call graphs for reachability, dead code, and impact analysis.
|
|
4
|
+
|
|
5
|
+
### Example use cases
|
|
6
|
+
|
|
7
|
+
- **"Can our RBAC rules ever conflict?"** → Z3 finds the exact role/action/resource triple where allow and deny both fire
|
|
8
|
+
- **"Find compatible package versions"** → Z3 solves dependency constraints with incompatibility rules, returns a valid assignment or proves none exists
|
|
9
|
+
- **"Can user input reach the database?"** → Prolog traces all paths through the call graph, flags taint flows to sensitive sinks
|
|
10
|
+
- **"Are our frontend and backend validations consistent?"** → Z3 finds concrete inputs that pass one but fail the other (e.g. age=15 passes frontend min=13 but fails backend min=18)
|
|
11
|
+
- **"Does our workflow have dead-end or unreachable states?"** → Prolog checks reachability from the initial state, identifies orphaned and terminal nodes
|
|
12
|
+
- **"What's the dead code in this module?"** → tree-sitter parses source files, Prolog finds functions unreachable from any entry point
|
|
13
|
+
- **"What breaks if I change this function?"** → call graph impact analysis shows all transitive callers
|
|
4
14
|
|
|
5
15
|
## Setup
|
|
6
16
|
|
|
@@ -60,34 +70,53 @@ Add to `opencode.json`:
|
|
|
60
70
|
|
|
61
71
|
## Tools
|
|
62
72
|
|
|
63
|
-
**`chiasmus_verify`** — Submit raw SMT-LIB or Prolog, get a verified result.
|
|
73
|
+
**`chiasmus_verify`** — Submit raw SMT-LIB or Prolog, get a verified result. Z3 UNSAT results include an `unsatCore` showing which assertions conflict. Prolog supports `explain=true` for derivation traces showing which rules fired.
|
|
64
74
|
|
|
65
75
|
```
|
|
66
76
|
chiasmus_verify solver="z3" input="
|
|
67
77
|
(declare-const x Int)
|
|
68
|
-
(
|
|
69
|
-
(assert (
|
|
70
|
-
(assert (> x 0))
|
|
71
|
-
(assert (> y 0))
|
|
78
|
+
(assert (! (> x 10) :named gt10))
|
|
79
|
+
(assert (! (< x 5) :named lt5))
|
|
72
80
|
"
|
|
73
|
-
→ { status: "
|
|
81
|
+
→ { status: "unsat", unsatCore: ["gt10", "lt5"] }
|
|
74
82
|
```
|
|
75
83
|
|
|
76
84
|
```
|
|
77
85
|
chiasmus_verify solver="prolog"
|
|
78
86
|
input="parent(tom, bob). parent(bob, ann). ancestor(X,Y) :- parent(X,Y). ancestor(X,Y) :- parent(X,Z), ancestor(Z,Y)."
|
|
79
87
|
query="ancestor(tom, Who)."
|
|
80
|
-
|
|
88
|
+
explain=true
|
|
89
|
+
→ { status: "success", answers: [...], trace: ["ancestor(tom,bob)", "ancestor(bob,ann)", "ancestor(tom,ann)"] }
|
|
81
90
|
```
|
|
82
91
|
|
|
83
|
-
**`
|
|
92
|
+
**`chiasmus_graph`** — Analyze source code call graphs via tree-sitter + Prolog. Parses TS/JS files, extracts cross-module call graphs, runs formal analyses.
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
chiasmus_graph files=["src/server.ts", "src/db.ts"] analysis="callers" target="query"
|
|
96
|
+
→ { analysis: "callers", result: ["handleRequest"] }
|
|
84
97
|
|
|
85
|
-
|
|
98
|
+
chiasmus_graph files=["src/**/*.ts"] analysis="dead-code"
|
|
99
|
+
→ { analysis: "dead-code", result: ["unusedHelper", "legacyParser"] }
|
|
100
|
+
|
|
101
|
+
chiasmus_graph files=["src/**/*.ts"] analysis="reachability" from="handleRequest" to="dbQuery"
|
|
102
|
+
→ { analysis: "reachability", result: { reachable: true } }
|
|
103
|
+
|
|
104
|
+
chiasmus_graph files=["src/**/*.ts"] analysis="impact" target="validate"
|
|
105
|
+
→ { analysis: "impact", result: ["handleRequest", "main"] }
|
|
106
|
+
```
|
|
86
107
|
|
|
87
|
-
|
|
108
|
+
Analyses: `summary`, `callers`, `callees`, `reachability`, `dead-code`, `cycles`, `path`, `impact`, `facts`.
|
|
109
|
+
|
|
110
|
+
**`chiasmus_skills`** — Search the template library. Ships with 8 starter templates covering authorization, configuration, dependency resolution, validation, rule inference, and graph reachability. By-name lookups include related template suggestions.
|
|
111
|
+
|
|
112
|
+
**`chiasmus_formalize`** — Find the best template for a problem, get slot-filling instructions plus suggestions for related verification checks. Fill the slots using your context, then call `chiasmus_verify`.
|
|
113
|
+
|
|
114
|
+
**`chiasmus_solve`** — End-to-end: selects template, fills slots via LLM, runs lint and correction loops with enriched feedback (unsat cores, structured error classification), returns a verified result. Optional — the same result is achieved by using `chiasmus_formalize` → fill slots → `chiasmus_verify`, which is the recommended workflow since the calling LLM has full conversation context.
|
|
88
115
|
|
|
89
116
|
**`chiasmus_learn`** — Extract a reusable template from a verified solution. Candidates get promoted after 3+ successful reuses.
|
|
90
117
|
|
|
118
|
+
**`chiasmus_lint`** — Fast structural validation of specs without running the solver.
|
|
119
|
+
|
|
91
120
|
## Recommended Workflow
|
|
92
121
|
|
|
93
122
|
The calling LLM (Claude, GPT, etc.) drives the process — no API key needed:
|
|
@@ -106,6 +135,14 @@ Use a solver when the LLM alone can't guarantee correctness:
|
|
|
106
135
|
- **"Can X reach Y through any path?"** — transitive closure / reachability
|
|
107
136
|
- **Access control, configs, dependencies** — where correctness is non-negotiable
|
|
108
137
|
|
|
138
|
+
Use `chiasmus_graph` when you need structural reasoning about code:
|
|
139
|
+
|
|
140
|
+
- **"What calls this function?"** — impact analysis before refactoring
|
|
141
|
+
- **"What's dead code?"** — find functions unreachable from entry points
|
|
142
|
+
- **"Can user input reach this SQL query?"** — taint analysis via call graph reachability
|
|
143
|
+
- **"What breaks if I change X?"** — blast radius via reverse reachability
|
|
144
|
+
- **"Are there circular dependencies?"** — cycle detection in call graphs
|
|
145
|
+
|
|
109
146
|
## Configuration
|
|
110
147
|
|
|
111
148
|
| Variable | Default | Purpose |
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/formalize/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAe,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/formalize/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAe,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAIvE,0EAA0E;AAC1E,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,aAAa,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,sEAAsE;AACtE,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,wDAAwD;IACxD,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB;AAmBD,qBAAa,mBAAmB;IAE5B,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,GAAG;gBADH,OAAO,EAAE,YAAY,EACrB,GAAG,EAAE,UAAU;IAGzB;;;OAGG;IACG,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAU1D;;;OAGG;IACG,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,SAAI,GAAG,OAAO,CAAC,WAAW,CAAC;IAwCjE,OAAO,CAAC,iBAAiB;YAwCX,OAAO;YAUP,MAAM;IAwBpB,OAAO,CAAC,gBAAgB;IAsBxB;;;OAGG;YACW,QAAQ;IAuCtB,gEAAgE;IAChE,OAAO,CAAC,aAAa;CAMtB"}
|
package/dist/formalize/engine.js
CHANGED
|
@@ -1,30 +1,21 @@
|
|
|
1
1
|
import { correctionLoop } from "../solvers/correction-loop.js";
|
|
2
2
|
import { lintSpec } from "./validate.js";
|
|
3
|
-
|
|
3
|
+
import { classifyFeedback } from "./feedback.js";
|
|
4
|
+
const FORMALIZE_SYSTEM = `Formalization engine. Translate natural language → formal logic.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
2. Read the template skeleton and slot descriptions
|
|
8
|
-
3. Use the template as a STARTING POINT — fill the slots, but also adapt the structure if the problem requires it
|
|
9
|
-
4. You may add extra variables, assertions, or rules beyond what the template defines
|
|
10
|
-
5. You may remove or restructure parts of the skeleton that don't fit the specific problem
|
|
11
|
-
6. Return ONLY the complete specification — no explanation, no markdown fences, no comments outside the spec
|
|
6
|
+
Template = starting point. Fill slots, but adapt structure if needed. Add/remove variables, assertions, rules.
|
|
7
|
+
Output ONLY complete spec. No explanation, no markdown fences.
|
|
12
8
|
|
|
13
|
-
|
|
9
|
+
Z3: valid SMT-LIB. No (check-sat)/(get-model). Use (= flag (or ...)) not (=> ... flag).
|
|
10
|
+
Prolog: valid ISO Prolog. All clauses end with period.
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
Precise syntax — spec goes directly to solver.`;
|
|
13
|
+
const FIX_SYSTEM = `Fix failed formal spec. Return ONLY corrected spec. No explanation, no fences.
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
Common issues:
|
|
24
|
-
- Type mismatches: ensure all comparisons use matching types
|
|
25
|
-
- Missing declarations: every constant must be declared before use
|
|
26
|
-
- Syntax errors: check parentheses, commas, periods
|
|
27
|
-
- For Prolog: ensure all clauses end with a period`;
|
|
15
|
+
Common fixes by feedback type:
|
|
16
|
+
- Solver error: type mismatches → matching types | missing declarations → declare before use | unbalanced parens | Prolog missing periods
|
|
17
|
+
- UNSAT with core: conflicting assertions identified → remove or weaken one of the conflicting constraints
|
|
18
|
+
- No Prolog solutions: missing facts/rules → add covering clauses | wrong query pattern → fix unification`;
|
|
28
19
|
export class FormalizationEngine {
|
|
29
20
|
library;
|
|
30
21
|
llm;
|
|
@@ -57,8 +48,9 @@ export class FormalizationEngine {
|
|
|
57
48
|
// Build solver input
|
|
58
49
|
const initialInput = this.buildSolverInput(template, filledSpec);
|
|
59
50
|
// Run correction loop with LLM as fixer
|
|
60
|
-
const correctionResult = await correctionLoop(initialInput, async (attempt, error) => {
|
|
61
|
-
const
|
|
51
|
+
const correctionResult = await correctionLoop(initialInput, async (attempt, error, _round, result) => {
|
|
52
|
+
const feedback = result ? classifyFeedback(result) : error;
|
|
53
|
+
const fixed = await this.llmFix(attempt, feedback, template);
|
|
62
54
|
// Lint the fix before resubmitting to the solver
|
|
63
55
|
const linted = await this.lintLoop(fixed, template, 2);
|
|
64
56
|
return this.buildSolverInput(template, linted);
|
|
@@ -85,28 +77,30 @@ export class FormalizationEngine {
|
|
|
85
77
|
.map((n) => ` - ${n.source}: ${n.transform}`)
|
|
86
78
|
.join("\n");
|
|
87
79
|
const queryNote = template.solver === "prolog"
|
|
88
|
-
? `\
|
|
80
|
+
? `\nAlso provide Prolog query goal (ending with period) for the question.`
|
|
81
|
+
: "";
|
|
82
|
+
const tipsSection = template.tips?.length
|
|
83
|
+
? `\n⚠ TIPS:\n${template.tips.map((t) => ` ${t}`).join("\n")}`
|
|
84
|
+
: "";
|
|
85
|
+
const exampleSection = template.example
|
|
86
|
+
? `\nEXAMPLE (reference only — write your own):\n${template.example}`
|
|
89
87
|
: "";
|
|
90
|
-
return
|
|
91
|
-
DESCRIPTION: ${template.signature}
|
|
88
|
+
return `${template.name} (${template.solver}) — ${template.signature}
|
|
92
89
|
|
|
93
90
|
SKELETON:
|
|
94
91
|
${template.skeleton}
|
|
95
92
|
|
|
96
|
-
SLOTS
|
|
93
|
+
SLOTS:
|
|
97
94
|
${slotDescs}
|
|
98
95
|
|
|
99
|
-
|
|
100
|
-
${
|
|
101
|
-
${queryNote}
|
|
96
|
+
NORMALIZE: ${normGuidance}
|
|
97
|
+
${tipsSection}${exampleSection}${queryNote}
|
|
102
98
|
|
|
103
99
|
PROBLEM: ${problem}
|
|
104
100
|
|
|
105
|
-
Fill
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
${template.solver === "z3" ? "Do NOT include (check-sat) or (get-model) — the tool adds these automatically." : "Ensure all clauses end with a period."}
|
|
109
|
-
Return only the complete filled specification.`;
|
|
101
|
+
Fill {{SLOT:name}} markers. Template = starting point — adapt if needed. Add/remove parts freely.
|
|
102
|
+
${template.solver === "z3" ? "No (check-sat)/(get-model)." : "All clauses end with period."}
|
|
103
|
+
Output ONLY filled spec.`;
|
|
110
104
|
}
|
|
111
105
|
async llmFill(problem, template) {
|
|
112
106
|
const instructions = this.buildInstructions(problem, template);
|
|
@@ -115,7 +109,7 @@ Return only the complete filled specification.`;
|
|
|
115
109
|
]);
|
|
116
110
|
return this.cleanResponse(response);
|
|
117
111
|
}
|
|
118
|
-
async llmFix(attempt,
|
|
112
|
+
async llmFix(attempt, feedback, template) {
|
|
119
113
|
const spec = attempt.type === "z3" ? attempt.smtlib : attempt.program;
|
|
120
114
|
const response = await this.llm.complete(FIX_SYSTEM, [
|
|
121
115
|
{
|
|
@@ -124,8 +118,8 @@ Return only the complete filled specification.`;
|
|
|
124
118
|
SPECIFICATION:
|
|
125
119
|
${spec}
|
|
126
120
|
|
|
127
|
-
|
|
128
|
-
${
|
|
121
|
+
FEEDBACK:
|
|
122
|
+
${feedback}
|
|
129
123
|
|
|
130
124
|
Fix the specification and return only the corrected version.`,
|
|
131
125
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/formalize/engine.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/formalize/engine.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAmBjD,MAAM,gBAAgB,GAAG;;;;;;;;+CAQsB,CAAC;AAEhD,MAAM,UAAU,GAAG;;;;;0GAKuF,CAAC;AAE3G,MAAM,OAAO,mBAAmB;IAEpB;IACA;IAFV,YACU,OAAqB,EACrB,GAAe;QADf,YAAO,GAAP,OAAO,CAAc;QACrB,QAAG,GAAH,GAAG,CAAY;IACtB,CAAC;IAEJ;;;OAGG;IACH,KAAK,CAAC,SAAS,CAAC,OAAe;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC;YACjC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ;YACrB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,6BAA6B;QAElE,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC/D,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;IACpC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,KAAK,CAAC,OAAe,EAAE,SAAS,GAAG,CAAC;QACxC,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAEnD,+BAA+B;QAC/B,IAAI,UAAU,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAEvD,2DAA2D;QAC3D,UAAU,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;QAElE,qBAAqB;QACrB,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAEjE,wCAAwC;QACxC,MAAM,gBAAgB,GAAG,MAAM,cAAc,CAC3C,YAAY,EACZ,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YACvC,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YAC3D,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAC7D,iDAAiD;YACjD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;YACvD,OAAO,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACjD,CAAC,EACD,EAAE,SAAS,EAAE,CACd,CAAC;QAEF,sBAAsB;QACtB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAElE,OAAO;YACL,MAAM,EAAE,gBAAgB,CAAC,MAAM;YAC/B,SAAS,EAAE,gBAAgB,CAAC,SAAS;YACrC,MAAM,EAAE,gBAAgB,CAAC,MAAM;YAC/B,OAAO,EAAE,gBAAgB,CAAC,OAAO;YACjC,YAAY,EAAE,QAAQ,CAAC,IAAI;YAC3B,OAAO,EAAE,gBAAgB,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS;gBACnD,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,OAAO;gBACjC,CAAC,CAAC,EAAE;SACP,CAAC;IACJ,CAAC;IAEO,iBAAiB,CAAC,OAAe,EAAE,QAAuB;QAChE,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK;aAC7B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,WAAW,kBAAkB,CAAC,CAAC,MAAM,EAAE,CAAC;aAC/E,IAAI,CAAC,MAAM,CAAC,CAAC;QAEhB,uCAAuC;QACvC,MAAM,YAAY,GAAG,QAAQ,CAAC,cAAc;aACzC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC;aAC7C,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,KAAK,QAAQ;YAC5C,CAAC,CAAC,yEAAyE;YAC3E,CAAC,CAAC,EAAE,CAAC;QAEP,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,EAAE,MAAM;YACvC,CAAC,CAAC,cAAc,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC/D,CAAC,CAAC,EAAE,CAAC;QAEP,MAAM,cAAc,GAAG,QAAQ,CAAC,OAAO;YACrC,CAAC,CAAC,iDAAiD,QAAQ,CAAC,OAAO,EAAE;YACrE,CAAC,CAAC,EAAE,CAAC;QAEP,OAAO,GAAG,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,MAAM,OAAO,QAAQ,CAAC,SAAS;;;EAGtE,QAAQ,CAAC,QAAQ;;;EAGjB,SAAS;;aAEE,YAAY;EACvB,WAAW,GAAG,cAAc,GAAG,SAAS;;WAE/B,OAAO;;;EAGhB,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,8BAA8B;yBAClE,CAAC;IACxB,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,OAAe,EAAE,QAAuB;QAC5D,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAE/D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,gBAAgB,EAAE;YACzD,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE;SACxC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC;IAEO,KAAK,CAAC,MAAM,CAClB,OAAoB,EACpB,QAAgB,EAChB,QAAuB;QAEvB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;QAEtE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,EAAE;YACnD;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,WAAW,QAAQ,CAAC,MAAM;;EAEzC,IAAI;;;EAGJ,QAAQ;;6DAEmD;aACtD;SACF,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC;IAEO,gBAAgB,CAAC,QAAuB,EAAE,IAAY;QAC5D,IAAI,QAAQ,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YAC7B,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACtC,CAAC;QAED,sEAAsE;QACtE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,OAAO,GAAG,IAAI,CAAC;QACnB,IAAI,KAAK,GAAG,OAAO,CAAC;QAEpB,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAChC,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7B,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;gBACxC,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC9C,MAAM;YACR,CAAC;QACH,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5C,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,QAAQ,CACpB,IAAY,EACZ,QAAuB,EACvB,WAAmB;QAEnB,IAAI,OAAO,GAAG,IAAI,CAAC;QACnB,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;QAErC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;YACvD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;YAChD,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,mBAAmB;YAExC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC7B,OAAO,OAAO,CAAC,CAAC,2BAA2B;YAC7C,CAAC;YAED,wEAAwE;YACxE,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC9C,IAAI,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7B,OAAO,OAAO,CAAC,CAAC,+CAA+C;YACjE,CAAC;YACD,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAEzB,sCAAsC;YACtC,MAAM,WAAW,GAAG;gBAClB,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBAC7C,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC;aAC1C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEb,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CACzB,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,EACxC,sDAAsD,WAAW,EAAE,EACnE,QAAQ,CACT,CAAC;QACJ,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,gEAAgE;IACxD,aAAa,CAAC,QAAgB;QACpC,OAAO,QAAQ;aACZ,OAAO,CAAC,4CAA4C,EAAE,EAAE,CAAC;aACzD,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;aACxB,IAAI,EAAE,CAAC;IACZ,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SolverResult } from "../solvers/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Classify a SolverResult into a human-readable feedback string
|
|
4
|
+
* for the correction loop. This helps the LLM understand what went
|
|
5
|
+
* wrong and how to fix it.
|
|
6
|
+
*/
|
|
7
|
+
export declare function classifyFeedback(result: SolverResult): string;
|
|
8
|
+
//# sourceMappingURL=feedback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../../src/formalize/feedback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAwC7D"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Classify a SolverResult into a human-readable feedback string
|
|
3
|
+
* for the correction loop. This helps the LLM understand what went
|
|
4
|
+
* wrong and how to fix it.
|
|
5
|
+
*/
|
|
6
|
+
export function classifyFeedback(result) {
|
|
7
|
+
switch (result.status) {
|
|
8
|
+
case "error":
|
|
9
|
+
return `Solver error: ${result.error}`;
|
|
10
|
+
case "unsat": {
|
|
11
|
+
// Forward-compatible with Phase 1 unsatCore
|
|
12
|
+
const core = result.unsatCore;
|
|
13
|
+
if (core && core.length > 0) {
|
|
14
|
+
return `UNSAT — these assertions conflict:\n${core.map((c) => ` - ${c}`).join("\n")}\nThe specification is over-constrained. Remove or weaken one of the conflicting assertions.`;
|
|
15
|
+
}
|
|
16
|
+
return "UNSAT — the constraints are contradictory. The specification is over-constrained.";
|
|
17
|
+
}
|
|
18
|
+
case "sat": {
|
|
19
|
+
const entries = Object.entries(result.model);
|
|
20
|
+
if (entries.length === 0) {
|
|
21
|
+
return "SAT — the constraints are satisfiable (trivially, no variables).";
|
|
22
|
+
}
|
|
23
|
+
const modelStr = entries.map(([k, v]) => `${k} = ${v}`).join(", ");
|
|
24
|
+
return `SAT — the solver found a satisfying assignment: ${modelStr}. If this was unexpected, the spec may be under-constrained.`;
|
|
25
|
+
}
|
|
26
|
+
case "success": {
|
|
27
|
+
if (result.answers.length === 0) {
|
|
28
|
+
return "No Prolog solutions found. Check if facts and rules cover the query pattern. Verify clause heads match.";
|
|
29
|
+
}
|
|
30
|
+
const ansStr = result.answers
|
|
31
|
+
.slice(0, 5)
|
|
32
|
+
.map((a) => a.formatted)
|
|
33
|
+
.join("; ");
|
|
34
|
+
const suffix = result.answers.length > 5
|
|
35
|
+
? ` (and ${result.answers.length - 5} more)`
|
|
36
|
+
: "";
|
|
37
|
+
return `Prolog found ${result.answers.length} answer(s): ${ansStr}${suffix}`;
|
|
38
|
+
}
|
|
39
|
+
case "unknown":
|
|
40
|
+
return "Solver returned UNKNOWN — the problem may be too complex or outside the solver's decidable fragment. Try simplifying constraints.";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=feedback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.js","sourceRoot":"","sources":["../../src/formalize/feedback.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAoB;IACnD,QAAQ,MAAM,CAAC,MAAM,EAAE,CAAC;QACtB,KAAK,OAAO;YACV,OAAO,iBAAiB,MAAM,CAAC,KAAK,EAAE,CAAC;QAEzC,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,4CAA4C;YAC5C,MAAM,IAAI,GAAI,MAAc,CAAC,SAAiC,CAAC;YAC/D,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC5B,OAAO,uCAAuC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,8FAA8F,CAAC;YACrL,CAAC;YACD,OAAO,mFAAmF,CAAC;QAC7F,CAAC;QAED,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC7C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO,kEAAkE,CAAC;YAC5E,CAAC;YACD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnE,OAAO,mDAAmD,QAAQ,8DAA8D,CAAC;QACnI,CAAC;QAED,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAChC,OAAO,yGAAyG,CAAC;YACnH,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO;iBAC1B,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;iBACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;iBACvB,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;gBACtC,CAAC,CAAC,SAAS,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,QAAQ;gBAC5C,CAAC,CAAC,EAAE,CAAC;YACP,OAAO,gBAAgB,MAAM,CAAC,OAAO,CAAC,MAAM,eAAe,MAAM,GAAG,MAAM,EAAE,CAAC;QAC/E,CAAC;QAED,KAAK,SAAS;YACZ,OAAO,mIAAmI,CAAC;IAC/I,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { CodeGraph } from "./types.js";
|
|
2
|
+
export type AnalysisType = "summary" | "callers" | "callees" | "reachability" | "dead-code" | "cycles" | "path" | "impact" | "facts";
|
|
3
|
+
export interface AnalysisRequest {
|
|
4
|
+
analysis: AnalysisType;
|
|
5
|
+
target?: string;
|
|
6
|
+
from?: string;
|
|
7
|
+
to?: string;
|
|
8
|
+
entryPoints?: string[];
|
|
9
|
+
}
|
|
10
|
+
export interface AnalysisResult {
|
|
11
|
+
analysis: AnalysisType;
|
|
12
|
+
result: unknown;
|
|
13
|
+
}
|
|
14
|
+
/** Run a graph analysis on the given source files */
|
|
15
|
+
export declare function runAnalysis(filePaths: string[], request: AnalysisRequest): Promise<AnalysisResult>;
|
|
16
|
+
/** Also accept pre-built graph + program for testing without file I/O */
|
|
17
|
+
export declare function runAnalysisFromGraph(graph: CodeGraph, request: AnalysisRequest): Promise<AnalysisResult>;
|
|
18
|
+
//# sourceMappingURL=analyses.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyses.d.ts","sourceRoot":"","sources":["../../src/graph/analyses.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,MAAM,YAAY,GACpB,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,cAAc,GAClD,WAAW,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,qDAAqD;AACrD,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EAAE,EACnB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAiCzB;AAED,yEAAyE;AACzE,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAuBzB"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { extractGraph } from "./extractor.js";
|
|
3
|
+
import { graphToProlog } from "./facts.js";
|
|
4
|
+
import { createPrologSolver } from "../solvers/prolog-solver.js";
|
|
5
|
+
/** Run a graph analysis on the given source files */
|
|
6
|
+
export async function runAnalysis(filePaths, request) {
|
|
7
|
+
// Read files from disk
|
|
8
|
+
const files = filePaths.map((p) => ({
|
|
9
|
+
path: p,
|
|
10
|
+
content: readFileSync(p, "utf-8"),
|
|
11
|
+
}));
|
|
12
|
+
const graph = extractGraph(files);
|
|
13
|
+
const program = graphToProlog(graph, request.entryPoints);
|
|
14
|
+
if (request.analysis === "facts") {
|
|
15
|
+
return { analysis: "facts", result: program };
|
|
16
|
+
}
|
|
17
|
+
if (request.analysis === "summary") {
|
|
18
|
+
return {
|
|
19
|
+
analysis: "summary",
|
|
20
|
+
result: buildSummary(graph),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const query = buildQuery(request);
|
|
24
|
+
if (!query) {
|
|
25
|
+
return { analysis: request.analysis, result: { error: "Missing required parameters" } };
|
|
26
|
+
}
|
|
27
|
+
const solver = createPrologSolver();
|
|
28
|
+
try {
|
|
29
|
+
const solverResult = await solver.solve({ type: "prolog", program, query });
|
|
30
|
+
return { analysis: request.analysis, result: formatResult(request.analysis, solverResult) };
|
|
31
|
+
}
|
|
32
|
+
finally {
|
|
33
|
+
solver.dispose();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** Also accept pre-built graph + program for testing without file I/O */
|
|
37
|
+
export async function runAnalysisFromGraph(graph, request) {
|
|
38
|
+
const program = graphToProlog(graph, request.entryPoints);
|
|
39
|
+
if (request.analysis === "facts") {
|
|
40
|
+
return { analysis: "facts", result: program };
|
|
41
|
+
}
|
|
42
|
+
if (request.analysis === "summary") {
|
|
43
|
+
return { analysis: "summary", result: buildSummary(graph) };
|
|
44
|
+
}
|
|
45
|
+
const query = buildQuery(request);
|
|
46
|
+
if (!query) {
|
|
47
|
+
return { analysis: request.analysis, result: { error: "Missing required parameters" } };
|
|
48
|
+
}
|
|
49
|
+
const solver = createPrologSolver();
|
|
50
|
+
try {
|
|
51
|
+
const solverResult = await solver.solve({ type: "prolog", program, query });
|
|
52
|
+
return { analysis: request.analysis, result: formatResult(request.analysis, solverResult) };
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
solver.dispose();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function buildSummary(graph) {
|
|
59
|
+
const files = new Set(graph.defines.map((d) => d.file));
|
|
60
|
+
const functions = graph.defines.filter((d) => d.kind === "function" || d.kind === "method").length;
|
|
61
|
+
const classes = graph.defines.filter((d) => d.kind === "class").length;
|
|
62
|
+
return {
|
|
63
|
+
files: files.size,
|
|
64
|
+
functions,
|
|
65
|
+
classes,
|
|
66
|
+
callEdges: graph.calls.length,
|
|
67
|
+
imports: graph.imports.length,
|
|
68
|
+
exports: graph.exports.length,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function buildQuery(request) {
|
|
72
|
+
switch (request.analysis) {
|
|
73
|
+
case "callers":
|
|
74
|
+
if (!request.target)
|
|
75
|
+
return null;
|
|
76
|
+
return `caller_of(${request.target}, X).`;
|
|
77
|
+
case "callees":
|
|
78
|
+
if (!request.target)
|
|
79
|
+
return null;
|
|
80
|
+
return `callee_of(${request.target}, X).`;
|
|
81
|
+
case "reachability":
|
|
82
|
+
if (!request.from || !request.to)
|
|
83
|
+
return null;
|
|
84
|
+
return `reaches(${request.from}, ${request.to}).`;
|
|
85
|
+
case "dead-code":
|
|
86
|
+
return "dead(X).";
|
|
87
|
+
case "cycles":
|
|
88
|
+
return "reaches(X, X).";
|
|
89
|
+
case "path":
|
|
90
|
+
if (!request.from || !request.to)
|
|
91
|
+
return null;
|
|
92
|
+
return `path(${request.from}, ${request.to}, Path).`;
|
|
93
|
+
case "impact":
|
|
94
|
+
if (!request.target)
|
|
95
|
+
return null;
|
|
96
|
+
return `reaches(X, ${request.target}).`;
|
|
97
|
+
default:
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function formatResult(analysis, solverResult) {
|
|
102
|
+
if (solverResult.status === "error") {
|
|
103
|
+
return { error: solverResult.error };
|
|
104
|
+
}
|
|
105
|
+
if (solverResult.status !== "success") {
|
|
106
|
+
return { error: `Unexpected solver status: ${solverResult.status}` };
|
|
107
|
+
}
|
|
108
|
+
const answers = solverResult.answers;
|
|
109
|
+
switch (analysis) {
|
|
110
|
+
case "callers":
|
|
111
|
+
case "callees":
|
|
112
|
+
case "dead-code":
|
|
113
|
+
return extractUniqueValues(answers, "X");
|
|
114
|
+
case "reachability":
|
|
115
|
+
return { reachable: answers.length > 0 };
|
|
116
|
+
case "cycles": {
|
|
117
|
+
return extractUniqueValues(answers, "X");
|
|
118
|
+
}
|
|
119
|
+
case "path": {
|
|
120
|
+
if (answers.length === 0)
|
|
121
|
+
return { paths: [] };
|
|
122
|
+
// Path binding is a Prolog list — parse it
|
|
123
|
+
return {
|
|
124
|
+
paths: answers.map((a) => a.bindings.Path ?? a.formatted),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
case "impact":
|
|
128
|
+
return extractUniqueValues(answers, "X");
|
|
129
|
+
default:
|
|
130
|
+
return answers.map((a) => a.bindings);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function extractUniqueValues(answers, variable) {
|
|
134
|
+
const seen = new Set();
|
|
135
|
+
const result = [];
|
|
136
|
+
for (const a of answers) {
|
|
137
|
+
const val = a.bindings[variable];
|
|
138
|
+
if (val && !seen.has(val)) {
|
|
139
|
+
seen.add(val);
|
|
140
|
+
result.push(val);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return result;
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=analyses.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyses.js","sourceRoot":"","sources":["../../src/graph/analyses.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAqBjE,qDAAqD;AACrD,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,SAAmB,EACnB,OAAwB;IAExB,uBAAuB;IACvB,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAClC,IAAI,EAAE,CAAC;QACP,OAAO,EAAE,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC;KAClC,CAAC,CAAC,CAAC;IAEJ,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAE1D,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAChD,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACnC,OAAO;YACL,QAAQ,EAAE,SAAS;YACnB,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC;SAC5B,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,6BAA6B,EAAE,EAAE,CAAC;IAC1F,CAAC;IAED,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5E,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE,CAAC;IAC9F,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC;AACH,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,KAAgB,EAChB,OAAwB;IAExB,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAE1D,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAChD,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACnC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;IAC9D,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,6BAA6B,EAAE,EAAE,CAAC;IAC1F,CAAC;IAED,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5E,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE,CAAC;IAC9F,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,KAAgB;IACpC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAC;IACnG,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;IACvE,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,IAAI;QACjB,SAAS;QACT,OAAO;QACP,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM;QAC7B,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM;QAC7B,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM;KAC9B,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,OAAwB;IAC1C,QAAQ,OAAO,CAAC,QAAQ,EAAE,CAAC;QACzB,KAAK,SAAS;YACZ,IAAI,CAAC,OAAO,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC;YACjC,OAAO,aAAa,OAAO,CAAC,MAAM,OAAO,CAAC;QAE5C,KAAK,SAAS;YACZ,IAAI,CAAC,OAAO,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC;YACjC,OAAO,aAAa,OAAO,CAAC,MAAM,OAAO,CAAC;QAE5C,KAAK,cAAc;YACjB,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE;gBAAE,OAAO,IAAI,CAAC;YAC9C,OAAO,WAAW,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,EAAE,IAAI,CAAC;QAEpD,KAAK,WAAW;YACd,OAAO,UAAU,CAAC;QAEpB,KAAK,QAAQ;YACX,OAAO,gBAAgB,CAAC;QAE1B,KAAK,MAAM;YACT,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE;gBAAE,OAAO,IAAI,CAAC;YAC9C,OAAO,QAAQ,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,EAAE,UAAU,CAAC;QAEvD,KAAK,QAAQ;YACX,IAAI,CAAC,OAAO,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC;YACjC,OAAO,cAAc,OAAO,CAAC,MAAM,IAAI,CAAC;QAE1C;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,QAAsB,EAAE,YAA0B;IACtE,IAAI,YAAY,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QACpC,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,EAAE,CAAC;IACvC,CAAC;IAED,IAAI,YAAY,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACtC,OAAO,EAAE,KAAK,EAAE,6BAA6B,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC;IACvE,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC;IAErC,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,SAAS,CAAC;QACf,KAAK,SAAS,CAAC;QACf,KAAK,WAAW;YACd,OAAO,mBAAmB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAE3C,KAAK,cAAc;YACjB,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAE3C,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,OAAO,mBAAmB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC3C,CAAC;QAED,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;YAC/C,2CAA2C;YAC3C,OAAO;gBACL,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,CAAC;aAC1D,CAAC;QACJ,CAAC;QAED,KAAK,QAAQ;YACX,OAAO,mBAAmB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAE3C;YACE,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAAC,OAAuB,EAAE,QAAgB;IACpE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACjC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../../src/graph/extractor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAkE,MAAM,YAAY,CAAC;AAE5G,8DAA8D;AAC9D,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,SAAS,CAsBvF"}
|