Infon HypergraphReasoner

Sheaf-aware typed R-GCN over the infon hypergraph that produces per-node Dempster–Shafer masses, then routes them through a tree of learned IKL operators (that, not, and, or, if, iff, forall, exists, ist) to answer compositional, IKL-style queries. Three optional question heads (next_anchor, anomaly, role_type) expose the same per-node features for retrieval / triage tasks.

The model is the symbolic-reasoning end-piece of the infon stack β€” upstream stages (extractor, coref, sheaf-GNN) build the hypergraph and hand it to this network as (nodeFeatures, edgeIndex, edgeTypes, edgeWeights, situationFeatures) tensors.

Quick start (JavaScript)

npm install @cp500/infon-reasoner onnxruntime-web
import { ReasonerModel } from '@cp500/infon-reasoner';

const model = await ReasonerModel.fromHub('cp500/infon-reasoner', {
  precision: 'fp16',   // half size, default in browsers
  device: 'auto',
});

// `graph` is the tensor triple produced by HypergraphBuilder upstream.
const query = {
  op: 'forall',
  args: [{
    op: 'and',
    args: [
      { op: 'that', args: [{ kind: 'triple', subject: 'x',
                              predicate: 'causes',  object: 'Y' }] },
      { op: 'not',  args: [{ op: 'that', args: [{ kind: 'triple',
                              subject: 'x', predicate: 'retracted',
                              object: 'Y' }] }] },
    ],
  }],
};

const r = await model.reason(graph, query);
console.log(r.verdict);                  // 'SUPPORTS' | 'REFUTES' | 'NEI'
console.log(r.mass);                     // DS mass over {S, R, NEI}
console.log(r.heads?.anomaly?.[0]);      // optional per-node anomaly

The JS client source is mirrored under js/ for self-contained installs (vendored alongside its sibling deps atom, ds, runtime).

Architecture

HyperGraph (nodeFeatures, edgeIndex, edgeTypes, edgeWeights,
            situationFeatures?)
   β”‚
   β–Ό
TypedRGCN backbone  (hidden_dim=64, n_edge_types=β€”)
   β€’ per-relation-type linear maps
   β€’ sheaf restriction stalks per edge
   β€’ N rounds of message passing + residual updates
   β”‚
   β–Ό
MassReadout per node          ──►  perNode: MassFunction[]
   {m(S), m(R), m(NEI), m(uncertain)}
   β”‚
   β–Ό  composer.ts walks the operator tree
IKLComposer (9 ONNX ops)      ──►  mass: MassFunction
   that β”‚ not β”‚ and β”‚ or β”‚ if β”‚ iff β”‚ forall β”‚ exists β”‚ ist
   β”‚
   β–Ό
Argmax over m(S)/m(R)/m(NEI)  ──►  verdict: SUPPORTS | REFUTES | NEI

   (parallel)
TypedRGCN backbone last layer
   β”œβ”€β–Ί next_anchor head      (anchor logits)
   β”œβ”€β–Ί anomaly head          (per-node score in [0,1])
   └─► role_type head        (per-node role logits)

The sheaf design types messages by edge type and situation vector, not by predicate slug β€” which is what makes the reasoner transfer across relation vocabularies. situation_dim=16.

IKL composition contract

Queries are JSON operator-trees. The leaf is that(atom) where atom = {kind: 'triple', subject, predicate, object}; every other node wraps one or two child queries. Variables in the subject/object slots (x, Y) are bound by forall / exists against the node ids present in the graph.

Full example β€” for every x, x causes Y holds and was not later retracted:

const query = {
  op: 'forall',
  args: [{
    op: 'and',
    args: [
      { op: 'that', args: [{ kind: 'triple', subject: 'x',
                              predicate: 'causes', object: 'Y' }] },
      { op: 'not',  args: [{ op: 'that', args: [{ kind: 'triple',
                              subject: 'x', predicate: 'retracted',
                              object: 'Y' }] }] },
    ],
  }],
};

The composer walks the tree post-order, dispatching each node to its ONNX session. Each operator consumes child masses + the relevant graph slice and emits a refined mass; the root's output is the final verdict.

Files

Backbone

File Size Purpose
onnx/backbone.onnx 407 KB Sheaf R-GCN backbone (FP32)
onnx/backbone.onnx.data β€” External weights for backbone FP32
onnx/backbone.fp16.onnx 223 KB Backbone (FP16, default for browser)
onnx/backbone.fp16.onnx.data β€” External weights for backbone FP16

IKL operators

File Size Purpose
onnx/ikl_that.onnx 37 KB IKL that operator (FP32)
onnx/ikl_that.fp16.onnx 19 KB IKL that operator (FP16)
onnx/ikl_not.onnx 37 KB IKL not operator (FP32)
onnx/ikl_not.fp16.onnx 19 KB IKL not operator (FP16)
onnx/ikl_and.onnx 38 KB IKL and operator (FP32)
onnx/ikl_and.fp16.onnx 21 KB IKL and operator (FP16)
onnx/ikl_or.onnx 38 KB IKL or operator (FP32)
onnx/ikl_or.fp16.onnx 21 KB IKL or operator (FP16)
onnx/ikl_if.onnx 72 KB IKL if operator (FP32)
onnx/ikl_if.fp16.onnx 38 KB IKL if operator (FP16)
onnx/ikl_iff.onnx 106 KB IKL iff operator (FP32)
onnx/ikl_iff.fp16.onnx 56 KB IKL iff operator (FP16)
onnx/ikl_forall.onnx 38 KB IKL forall operator (FP32)
onnx/ikl_forall.fp16.onnx 21 KB IKL forall operator (FP16)
onnx/ikl_exists.onnx 38 KB IKL exists operator (FP32)
onnx/ikl_exists.fp16.onnx 21 KB IKL exists operator (FP16)
onnx/ikl_ist.onnx 25 KB IKL ist operator (FP32)
onnx/ikl_ist.fp16.onnx 13 KB IKL ist operator (FP16)

Question heads

File Size Purpose
onnx/head_next_anchor.onnx 1 KB next_anchor head (FP32)
onnx/head_next_anchor.fp16.onnx 1 KB next_anchor head (FP16)
onnx/head_anomaly.onnx 9 KB anomaly head (FP32)
onnx/head_anomaly.fp16.onnx 6 KB anomaly head (FP16)
onnx/head_role_type.onnx 35 KB role_type head (FP32)
onnx/head_role_type.fp16.onnx 18 KB role_type head (FP16)

The meta.json next to the ONNX files keys logical names (backbone_fp16, ikl_and_fp32, head_anomaly_fp16, …) to file paths, so the JS client doesn't hard-code any layout. Re-training keeps the .pt snapshots under pytorch/.

Evaluation

Validation metrics from the default Tier 6 wave 1 training run on the synthetic hypergraph corpus.

IKL operators (val MSE on per-node DS mass)

IKL op Val MSE
that β€”
not β€”
and β€”
or β€”
if β€”
iff β€”
forall β€”
exists β€”
ist β€”

Question heads (val accuracy)

Head Val acc
next_anchor β€”
anomaly β€”
role_type β€”

Limitations

  • Synthetic data only. All training uses the procedurally generated hypergraph corpus from synthgen_hypergraph.py. Real-world graphs with adversarial / noisy structure are not yet validated; expect domain shift on free-text-derived graphs.
  • MVP head set. Only three question heads ship in this release (next_anchor, anomaly, role_type). The architecture admits more, but they are not yet trained. Untrained heads should be treated as unavailable.
  • Operator coverage = the 9 IKL connectives above. Anything outside that set must be expressed by composition; the composer raises a programmer-error if it encounters an unknown op tag.
  • No long-range backtracking. The reasoner is a forward-pass composer, not a search procedure. Pair it with @cp500/infon's GraphMCTS (./mcts) for tasks that need multi-step abductive search.
  • forall / exists resolve over node ids. If the upstream graph drops a candidate (e.g. coref merged it into another mention) the quantifier sees fewer bindings than a human reader would.

License

Apache 2.0 for both weights and JS client code.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support