@cogitator-ai/neuro-symbolic

中文文档
17.1.40发布于 2026/10/29MITTypeScriptES Module近 30 天下载 1.2万

Neuro-symbolic AI for hybrid neural-symbolic reasoning

原始使用文档
文档目录30 节
  1. Installation
  2. Features
  3. Quick Start
  4. Logic Programming
  5. Loading Programs
  6. Querying
  7. Proof Trees
  8. Built-in Predicates
  9. Knowledge Graph Queries
  10. Query Builder
  11. Query Strings
  12. Natural Language Queries
  13. Reasoning Engine
  14. Constraint Solving
  15. Building Constraints
  16. Solver Selection
  17. Expression Types
  18. Plan Verification
  19. Action Schemas
  20. Plan Validation
  21. Invariant Checking
  22. Plan Repair
  23. Main Orchestrator
  24. Agent Tools
  25. Available Tools
  26. Factory Options
  27. Graph Adapters
  28. Module Imports
  29. Type Reference
  30. License

@cogitator-ai/neuro-symbolic

Neuro-symbolic AI package for hybrid neural-symbolic reasoning. Combines LLM-based understanding with formal methods for verifiable, explainable AI.

Installation

pnpm add @cogitator-ai/neuro-symbolic

Z3 SMT support is an optional dependency. If it is not installed automatically, add it explicitly:

pnpm add z3-solver

Without Z3 the package falls back to the built-in solver (exact search for finite domains, local search otherwise).

The Postgres and Neo4j graph adapters need their drivers (optional peer dependencies):

pnpm add pg            # createPostgresGraphAdapter
pnpm add neo4j-driver  # createNeo4jGraphAdapter

Website docs: Neuro-Symbolic.

Features

  • Logic Programming - Prolog engine with ISO operator precedence, cut, if-then-else, negation, findall/3, between/3 and proof trees
  • Knowledge Graph Queries - SPARQL-like query language, natural language questions, path finding and rule-based inference
  • Constraint Solving - SAT/SMT solving with Z3 (WASM) or a pure-TS fallback, including optimisation and soft constraints
  • Plan Verification - PDDL-like action schemas with validation, ordering-threat detection, invariant checking and automatic repair

Quick Start

import { createNeuroSymbolic } from '@cogitator-ai/neuro-symbolic';

const ns = createNeuroSymbolic();

ns.loadLogicProgram(`
  parent(tom, mary).
  parent(mary, ann).
  grandparent(X, Z) :- parent(X, Y), parent(Y, Z).
`);

const result = ns.queryLogic('grandparent(tom, X)?');
console.log(result.data?.solutions[0].get('X')); // { type: 'atom', value: 'ann' }
console.log(ns.getLogicSolutions('grandparent(tom, X)')); // "X = ann."

const builder = ns.createConstraintProblem('sum');
const x = builder.int('x', 1, 10);
const y = builder.int('y', 1, 10);
builder.assert(x.add(y).eq(15));
builder.maximize(x);

const solution = await ns.solve(builder.build());
if (solution.data?.status === 'sat') {
  console.log(solution.data.model.assignments); // { x: 10, y: 5 }
}

Logic Programming

Prolog-style logic programming with SLD resolution, unification and standard operator syntax.

Loading Programs

ns.loadLogicProgram(`
  % Facts
  human(socrates).
  human(plato).

  % Rules
  mortal(X) :- human(X).

  % Arithmetic uses ISO precedence: * binds tighter than +
  total(Price, Qty, T) :- T is Price * Qty + 5.

  % Cut is local to the clause that executes it
  grade(S, a) :- S >= 90, !.
  grade(S, b) :- S >= 75, !.
  grade(_, c).

  % If-then-else commits to the condition
  label(S, L) :- ( S >= 50 -> L = pass ; L = fail ).
`);

loadLogicProgram returns { success, errors }; syntax errors include the line and column.

Querying

Queries may be written with or without a trailing ./? and an optional ?- prefix.

const result = ns.queryLogic('mortal(X)?');
for (const solution of result.data?.solutions ?? []) {
  console.log(solution.get('X')); // socrates, plato
}

ns.proveLogic('mortal(socrates)').data; // true
ns.getLogicSolutions('append(X, Y, [1, 2])');
// "X = [], Y = [1, 2] ;\nX = [1], Y = [2] ;\nX = [1, 2], Y = []."

ns.queryLogic('findall(X, human(X), L), length(L, N)', { maxSolutions: 1 });

Variables starting with _ (including the anonymous _) are not reported in answers. When a query runs out of time or depth, result.error / result.data.explanation says so.

Proof Trees

Enable traceExecution to capture the proof tree:

import {
  createNeuroSymbolic,
  formatProofTree,
  proofTreeToMermaid,
} from '@cogitator-ai/neuro-symbolic';

const traced = createNeuroSymbolic({ config: { logic: { traceExecution: true } } });
traced.loadLogicProgram(
  'parent(tom, mary). parent(mary, ann). grandparent(X, Z) :- parent(X, Y), parent(Y, Z).'
);

const proof = traced.queryLogic('grandparent(tom, X)').data?.proofTree;
if (proof) {
  console.log(formatProofTree(proof));
  console.log(proofTreeToMermaid(proof));
}

Built-in Predicates

CategoryPredicates
Control,/2, ;/2, ->/2, !/0, \+/1, not/1, call/1..8, findall/3, forall/2, between/3
Unification=/2, \=/2, ==/2, \==/2, @</2, @>/2, @=</2, @>=/2, compare/3
Arithmeticis/2, =:=/2, =\=/2, </2, >/2, =</2, >=/2, succ/2, plus/3
Type checksatom/1, number/1, integer/1, float/1, atomic/1, compound/1, var/1, nonvar/1, is_list/1, ground/1, string/1, callable/1
Listsmember/2, append/3, length/2, reverse/2, nth0/3, nth1/3, last/2, sort/2, msort/2, sum_list/2, max_list/2, min_list/2
Terms & atomsfunctor/3, arg/3, =../2, copy_term/2, atom_length/2, atom_concat/3
Logictrue/0, fail/0, false/0

Arithmetic follows ISO semantics (-7 mod 3 =:= 2, -7 // 2 =:= -3, div, bitwise /\ \/ xor << >>, gcd, min, max, abs, trigonometry, pi, e, ...). Undefined results such as sqrt(-1) fail instead of binding NaN. Use getBuiltinList() / isControlConstruct() to inspect support at runtime.


Knowledge Graph Queries

SPARQL-like query language with natural language interface. Works with any GraphAdapter (in-memory, Postgres, Neo4j, or adapters from @cogitator-ai/memory).

Query Builder

import {
  GraphQueryBuilder,
  graphVariable as variable,
  executeQuery,
} from '@cogitator-ai/neuro-symbolic';

const query = GraphQueryBuilder.select()
  .where(variable('person'), 'works_at', variable('company'))
  .where(variable('company'), 'located_in', 'Berlin')
  .filter('person.name', 'startsWith', 'A')
  .orderBy('person.name', 'asc')
  .limit(10)
  .build();

const result = await executeQuery(query, {
  adapter: graphAdapter,
  agentId: 'agent-1',
  variables: new Map(),
});
  • Patterns join on shared variables; bidirectional edges match in both directions.
  • ?x a person / ?x type person matches node entity types.
  • describe queries match edges in either direction around the subject.
  • Filters can address nested properties: person.properties.profile.level.
  • count('*', 'total') counts all bindings.

Query Strings

import { parseQueryString } from '@cogitator-ai/neuro-symbolic';

const parsed = parseQueryString(`
  SELECT ?p WHERE { ?p works_at ?c . ?c located_in Berlin }
  FILTER(?p.confidence >= 0.5)
  ORDER BY DESC(?p.name)
  LIMIT 5
`);

Supported filter operators: = != > >= < <= contains startsWith endsWith regex in notIn.

Natural Language Queries

const answer = await ns.askGraph('Who works at "Acme"?');
console.log(answer.data?.naturalLanguageResponse);

NeuroSymbolic honours config.knowledgeGraph.enableNaturalLanguage and applies defaultQueryLimit to queries without an explicit limit.

Reasoning Engine

import { createReasoningEngine } from '@cogitator-ai/neuro-symbolic';

const engine = createReasoningEngine(graphAdapter, 'agent-1', { maxHops: 3, minConfidence: 0.5 });

const path = await engine.findPath(aliceId, companyId);
const hops = await engine.multiHopQuery(aliceId, ['works_at', 'located_in']);
const inferred = await engine.infer(); // transitive, inverse and composed relations, de-duplicated

Constraint Solving

SAT/SMT solving with a fluent DSL. Variable declarations return expressions; constraints are added to the builder.

Building Constraints

import { ConstraintBuilder, allDifferent, solve } from '@cogitator-ai/neuro-symbolic';

const builder = ConstraintBuilder.create('example');
const a = builder.bool('a');
const b = builder.bool('b');
const x = builder.int('x', 0, 100);
const y = builder.int('y', 0, 100);
const z = builder.real('z', 0, 1);

builder.assert(a.or(b));
builder.assert(x.add(y).lte(50));
builder.assert(z.mul(2).gt(0.5));
builder.assert(allDifferent(x, y));
builder.soft(x.eq(10), 2);
builder.maximize(x.add(y));

const result = await solve(builder.build());
if (result.status === 'sat') {
  console.log(result.model.assignments, result.model.objectiveValue);
}

Declaring the same variable twice or an empty domain (min > max) throws.

Solver Selection

solve(problem, { solver: 'z3' }) (the default) uses Z3 when z3-solver can be loaded and otherwise falls back to the built-in solver.

import { isZ3Available, solveWithZ3, solveSAT } from '@cogitator-ai/neuro-symbolic';

const result = (await isZ3Available()) ? await solveWithZ3(problem) : solveSAT(problem);
  • Z3: integers, reals, booleans and bit-vectors (unsigned semantics); mixed Int/Real expressions are coerced automatically; objectives and soft constraints use Z3's optimiser.
  • Built-in solver: exhaustive search when every variable has a finite domain (≤ 2^20 assignments) — exact sat/unsat, optimal objective, minimal soft-constraint violations; local search for real or unbounded variables (may return unknown).

Expression Types

x.add(y);
x.sub(5);
x.mul(2);
x.div(3);
x.mod(7);
x.pow(2);
x.abs();
x.min(y);
x.max(y);
a.and(b);
a.or(b);
a.not();
a.implies(b);
a.iff(b);
x.eq(10);
x.neq(y);
x.gt(0);
x.gte(0);
x.lt(100);
x.lte(100);

ite(a, x, y);
sum(x, y, z);
allDifferent(x, y, z);
atMost(2, a, b, c);
atLeast(1, a, b, c);
exactly(1, a, b, c);

Plan Verification

PDDL-like planning with verification and repair. Parameter references use the ?name syntax.

Action Schemas

import { ActionSchemaBuilder, ActionRegistry } from '@cogitator-ai/neuro-symbolic';

const move = ActionSchemaBuilder.create('move')
  .describe('Move robot from one location to another')
  .param('from', 'string')
  .param('to', 'string')
  .preSimple('robotAt', '?from')
  .preCompare('battery', 'gt', 10)
  .assign('robotAt', '?to')
  .decrement('battery', 5)
  .setCost(5)
  .build();

const registry = new ActionRegistry();
registry.register(move);

Precondition equality is structural (arrays and objects compare by value). Conditional effects evaluate their condition against the state before the action.

Plan Validation

import { createAction, validatePlan, formatValidationResult } from '@cogitator-ai/neuro-symbolic';

const plan = {
  id: 'plan-1',
  actions: [
    createAction('move', { from: 'A', to: 'B' }),
    createAction('move', { from: 'B', to: 'C' }),
  ],
  initialState: { id: 's0', variables: { robotAt: 'A', battery: 100 } },
  goalConditions: [{ type: 'simple' as const, variable: 'robotAt', value: 'C' }],
};

const result = validatePlan(plan, registry, { maxSteps: 50 });
console.log(formatValidationResult(result));

Validation reports precondition violations, missing/unknown parameters, unmet goals, redundant actions and ordering threats (an action deleting a variable a later action requires).

Invariant Checking

import { createInvariantChecker, formatInvariantResults } from '@cogitator-ai/neuro-symbolic';

const checker = createInvariantChecker(registry);
checker.addInvariant('battery-non-negative', {
  type: 'comparison',
  variable: 'battery',
  operator: 'gte',
  value: 0,
});
checker.addNever('danger', { type: 'simple', variable: 'robotAt', value: 'danger-zone' });
checker.addEventually('arrived', { type: 'simple', variable: 'robotAt', value: 'C' });

console.log(formatInvariantResults(checker.checkPlan(plan)));

The trajectory stops at the first action whose preconditions do not hold.

Plan Repair

import { createPlanRepairer, formatRepairResult } from '@cogitator-ai/neuro-symbolic';

const repairer = createPlanRepairer(registry, { maxInsertions: 3, maxRemovals: 2 });
const repair = repairer.repair(plan);

if (repair.success) {
  console.log('Repaired plan:', repair.repairedPlan);
} else {
  console.log(formatRepairResult(repair));
}

Insertion suggestions are verified by simulation (an action is only suggested if applying it establishes the failed condition); missing parameters are filled from defaults or the current state.


Main Orchestrator

The NeuroSymbolic class integrates all modules. Every method returns a NeuroSymbolicResult ({ success, data?, error?, duration }) instead of throwing.

import { createNeuroSymbolic } from '@cogitator-ai/neuro-symbolic';

const ns = createNeuroSymbolic({
  graphAdapter: myGraphAdapter,
  agentId: 'agent-1',
  config: {
    knowledgeGraph: { enableNaturalLanguage: true, defaultQueryLimit: 100 },
    logic: { maxDepth: 50, maxSolutions: 10, timeout: 5000 },
    constraints: { timeout: 10000, solver: 'z3' },
    planning: { maxPlanLength: 100, enableRepair: true, verifyInvariants: true },
  },
});

ns.loadLogicProgram('...');
ns.queryLogic('...');

await ns.solve(problem);

await ns.queryGraph(query);
await ns.askGraph('natural language question');
await ns.findPath(startNodeId, endNodeId);

ns.registerAction(actionSchema);
ns.validatePlan(plan);
ns.repairPlan(plan);
ns.checkInvariants(plan);
await ns.validateAndRepair(plan);
Methodsuccess means
queryLogicthe query has at least one solution
validatePlanvalidation ran (see data.valid)
repairPlanthe plan was repaired (suggestions are in data either way)
checkInvariantsall safety properties hold
validateAndRepairthe (repaired) plan is valid and all invariants hold on it

ns.getConfig() returns a ResolvedNeuroSymbolicConfig: every section (logic, constraints, planning, knowledgeGraph) is present with its defaults filled in, so no optional chaining is needed. ns.updateConfig(partial) merges changes into the running instance.

const { logic, constraints } = ns.getConfig();
console.log(logic.maxDepth, constraints.timeout);

ns.updateConfig({ logic: { maxSolutions: 5 } });

Agent Tools

Expose neuro-symbolic capabilities as tools for AI agents.

import { createNeuroSymbolicTools, MemoryGraphAdapter } from '@cogitator-ai/neuro-symbolic';
import { Agent, Cogitator } from '@cogitator-ai/core';

const nsTools = createNeuroSymbolicTools({ graphAdapter: new MemoryGraphAdapter() });

nsTools.instance.loadLogicProgram(`
  parent(tom, mary).
  parent(mary, ann).
  grandparent(X, Z) :- parent(X, Y), parent(Y, Z).
`);

const agent = new Agent({
  name: 'reasoning-agent',
  model: 'openai/gpt-6.1-sol',
  tools: nsTools.all,
  instructions:
    'Use query_logic for Prolog queries, solve_constraints for SAT/SMT problems and validate_plan to verify action sequences.',
});

const cogitator = new Cogitator({
  llm: { providers: { openai: { apiKey: process.env.OPENAI_API_KEY! } } },
});
const result = await cogitator.run(agent, { input: 'Who are the grandparents of ann?' });

Available Tools

PropertyTool nameDescription
queryLogicquery_logicRun a Prolog query against the knowledge base
assertFactassert_factAdd facts or rules
loadProgramload_logic_programLoad a Prolog program (optionally clearing)
solveConstraintssolve_constraintsSolve SAT/SMT problems with optional objective
validatePlanvalidate_planValidate a plan against action schemas
repairPlanrepair_planRepair an invalid plan
registerActionregister_actionRegister an action schema
findPath*find_graph_pathShortest path between graph nodes
queryGraph*query_graphQuery nodes (and optionally their edges)
addGraphNode*add_graph_nodeAdd a node
addGraphEdge*add_graph_edgeAdd an edge

*Graph tools are available when a graphAdapter is passed or the provided instance has one.

Factory Options

interface NeuroSymbolicToolsOptions {
  instance?: NeuroSymbolic;
  graphAdapter?: GraphAdapter;
  config?: Partial<NeuroSymbolicConfig>;
  agentId?: string;
}

When agentId is set, graph tools read and write that agent's graph; otherwise they use the calling agent's id from the tool context. createGraphTools(adapter, { agentId }) can be used on its own.

Graph Adapters

import {
  MemoryGraphAdapter,
  createPostgresGraphAdapter,
  createNeo4jGraphAdapter,
} from '@cogitator-ai/neuro-symbolic';

const memory = new MemoryGraphAdapter();
await memory.addNode({
  agentId: 'agent-1',
  name: 'Alice',
  type: 'person',
  aliases: [],
  properties: { age: 30 },
  confidence: 1,
  source: 'user',
});

const postgres = createPostgresGraphAdapter({ connectionString: process.env.DATABASE_URL! });
await postgres.connect();

const neo4j = createNeo4jGraphAdapter({
  uri: 'bolt://localhost:7687',
  username: 'neo4j',
  password: 'secret',
});
await neo4j.connect();

All adapters scope traversal and shortest-path search to the requesting agent, treat bidirectional edges as traversable in both directions and reject merges into a node listed among its own sources.

The Postgres adapter uses the pgvector extension for searchNodesSemantic(). It indexes node embeddings with HNSW, which needs no training data, so the index built on the empty table finds every node as the graph grows. Earlier versions built an ivfflat index there, which missed nodes once Postgres used it (a search for 60 nodes in a graph of 3000 returned 31). The first connect() after upgrading replaces that index with HNSW, which takes a while on a large graph. To avoid the wait, build the index ahead of the deploy with CREATE INDEX CONCURRENTLY idx_graph_nodes_embedding_new ON cogitator_graph.graph_nodes USING hnsw (embedding vector_cosine_ops), then drop the old index and rename the new one to idx_graph_nodes_embedding. An existing HNSW index is kept as it is. Each search raises hnsw.ef_search to the requested limit (up to 1000) and, on pgvector 0.8 or later, turns on iterative scans, so a large limit or an entityTypes filter still gets every matching node. Equally similar nodes are ordered by id.


Module Imports

Each module can be imported separately:

import {
  KnowledgeBase,
  SLDResolver,
  parseQuery,
  formatSolutions,
} from '@cogitator-ai/neuro-symbolic/logic';
import {
  GraphQueryBuilder,
  executeQuery,
  ReasoningEngine,
} from '@cogitator-ai/neuro-symbolic/knowledge-graph';
import { ConstraintBuilder, solve, Z3WASMSolver } from '@cogitator-ai/neuro-symbolic/constraints';
import {
  ActionSchemaBuilder,
  PlanValidator,
  InvariantChecker,
} from '@cogitator-ai/neuro-symbolic/planning';
import { createNeuroSymbolicTools } from '@cogitator-ai/neuro-symbolic/tools';

Type Reference

import type {
  Term,
  Clause,
  Substitution,
  ProofTree,
  LogicQueryResult,
  GraphQuery,
  GraphQueryResult,
  NaturalLanguageQueryResult,
  ConstraintProblem,
  ConstraintVariable,
  SolverResult,
  ActionSchema,
  Plan,
  PlanState,
  PlanValidationResult,
  SafetyProperty,
  InvariantCheckResult,
} from '@cogitator-ai/types';

License

MIT

版本与发布记录

@cogitator-ai/neuro-symbolic 共发布 110 个版本,首次发布于 2026/01/01;过去 12 个月发布了 110 个版本。

版本发布日期距今
17.1.40latest2026/10/2912 天前
17.1.392026/10/2912 天前
17.1.382026/10/2912 天前
17.1.372026/10/2912 天前
17.1.362026/10/2912 天前
17.1.352026/10/2812 天前

关于 @cogitator-ai/neuro-symbolic 的常见问题

@cogitator-ai/neuro-symbolic 是什么?

Neuro-symbolic AI for hybrid neural-symbolic reasoning

如何安装 @cogitator-ai/neuro-symbolic?

在项目目录运行 npm install @cogitator-ai/neuro-symbolic,或使用 pnpm add / yarn add / bun add。

@cogitator-ai/neuro-symbolic 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@cogitator-ai/neuro-symbolic 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@cogitator-ai/neuro-symbolic 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.12.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@cogitator-ai/neuro-symbolic 可以商用吗?

@cogitator-ai/neuro-symbolic 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@cogitator-ai/neuro-symbolic 的下载量有多少?

根据 npm 官方下载统计,@cogitator-ai/neuro-symbolic 在 2026/10/11 – 2026/11/09 这 30 天内被下载 11,583 次,日均约 386 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cogitator-ai/neuro-symbolic 还在维护吗?

最新版本 17.1.40 发布于 2026/10/29(12 天前);至今共发布 110 个版本,其中过去 12 个月发布了 110 个;首次发布于 2026/01/01。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。