Factoidal — RIF Core forward-chaining demo

A small Horn-clause rule engine, F*-verified. The page runs the smoke-test program from RIF.Core.Eval.fst and shows the saturated graph.
Phase 2 milestone — see the RIF investigation note and PR #220 (fuel-bounded fixpoint). Phase 3 (RIF/XML parser) is pending — you cannot yet paste an arbitrary .rif document. Until a JS bridge for RIF_Core_Eval.fixpoint lands, this page renders the saturated graph computed at bundle init from the in-source smoke program.

RIF Core (Rule Interchange Format Core dialect) is a Horn-clause sublanguage standardised by the W3C. The Factoidal implementation covers the operational fragment relevant to RDF: triples, frames, membership (#), and subclass (##) atoms; rules are Forall vars (head :- body) with conjunctive bodies. Equality, built-ins, and the import / dialect-mixing machinery are out of scope.

The engine in RIF.Core.Eval.fst performs naive forward chaining with set semantics. One round = fire every rule once against the current graph; a fuel parameter caps the number of rounds. The saturation lemma (lemma_fixpoint_extends) is proved: forward chaining never removes a triple. Termination on this demo is by exhaustion of new productions (4 rounds for the smoke program below) rather than fuel cutoff.

What the engine is not: full RIF (no Core-Plus dialects, no BLD / PRD, no built-ins beyond term equality, no skolemisation). The body translator delegates to SPARQL11.Algebra.eval_bgp, so rule bodies are evaluated as basic graph patterns; this matches the standard operational reading of RIF Core under simple entailment.

Input graph

@prefix ex:   <ex:> .
@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

ex:alice   rdf:type        ex:Student .
ex:Student rdfs:subClassOf ex:Person  .
ex:Person  rdfs:subClassOf ex:Agent   .

RIF Core program

// Rule 1: subClassOf transitivity
Forall ?x ?y ?z (
  ?x rdfs:subClassOf ?z :-
    And ( ?x rdfs:subClassOf ?y
          ?y rdfs:subClassOf ?z )
)

// Rule 2: rdf:type propagation up the class hierarchy
Forall ?o ?c ?d (
  ?o # ?d :-
    And ( ?o # ?c
          ?c rdfs:subClassOf ?d )
)
Ready (static smoke output).

Saturated graph

Click Run inference to render the saturated graph.

What's actually running

Caveat

Parser and algebra spec verified in F*; on-disk backend has unverified OCaml-side optimization layers being migrated back to F* (see fstar-purity-unwind.md). The RIF Core engine itself is pure F* with no assume val holes.