Tiramemsu

Reasoning with N3 · Chapter 1 of 10

Chapter 1

Why rules in agent memory

A memory that only stores what it was told cannot say what follows from it. Rules can. In tiramemsu, what a rule concludes keeps its reasons, respects both clocks, and falls when its reasons go.

What follows from memory

An agent has written two facts: Alice works at Acme, and Acme is in Berlin. A user asks where Alice works. No statement says Alice works in Berlin. The answer follows from two that do.

There are three usual ways out, and each has a cost:

A rule states the inference once, in a form a machine can run and a person can read:

where-people-work.n3

@prefix v: <urn:tiramemsu:v:>.

{ ?p v:worksAt ?c. ?c v:locatedIn ?l } => { ?p v:worksIn ?l }.

Read it as: for any ?p, ?c and ?l, if ?p works at ?c and ?c is located in ?l, then ?p works in ?l. This is Notation3, or N3, the rule language of the RDF world. Chapter 2 teaches enough of it to read every example in this book.

What a plain reasoner gets wrong

Run that rule with any N3 reasoner over an export of the memory and you get an answer. In a memory with two clocks, it is often the wrong one.

Grounded conclusions

Tiramemsu already keeps one promise about grounding: a layer never outlives the fact it is about. Retract a fact and its confidence, its source and the beliefs that cite it are retracted in the same transaction. The companion article Memory that stays grounded explains why that cascade takes exactly what it must.

Reasoning extends the promise to conclusions. When tiramemsu writes what a rule concludes, it writes a derived belief: a statement with one support link to every premise it used and one to the stored rule set. A conclusion is grounded when all of its supports are live. The cascade follows support links, so:

No background job and no reconciliation pass are involved. It is the same cascade that retracts layers, with one more kind of edge to follow.

Never forget, still

Tiramemsu never deletes. A reasoner that writes must keep that rule too. It does:

Three verbs

The whole feature is three operations:

VerbWrites?What it does
View::reason(rules, &ReasonOptions)NoRuns N3 rules over a view and returns the conclusions, each with a proof made of statement ids. Accepts every builtin, including negation and the clock.
Tx::store_rules(rule_set, n3)YesKeeps a rule set as one statement, so rules have history and can be corrected.
Db::materialize(rule_set, &MaterializeOptions)YesReasons with a stored rule set and writes the conclusions as derived beliefs. Monotonic rules only.

A first taste, in Rust. The rule finds who is mortal. Nothing is written.

use tiramemsu::{ReasonOptions, Rules};

let rules = r#"@prefix v: <urn:tiramemsu:v:>.
{ ?x a v:Human } => { ?x a v:Mortal }."#;

let result = db.now().reason(Rules::Text(rules.into()), &ReasonOptions::default())?;
for c in &result.conclusions {
    // (v:socrates rdf:type v:Mortal), proof { rule: 0, premises: [e1] }
    println!("{} {} {}  rule {}  premises {:?}", c.s, c.p, c.o, c.proof.rule, c.proof.premises);
}

The premises are statement ids, not copies of triples. Each one points at the exact statement the conclusion rests on, with its layers, its clocks and its history.

Before you start

Status. Reasoning ships behind the opt-in Cargo feature n3, off by default (OpenSpec change add-n3-reasoning, built on add-derived-beliefs). The reasoner is eyeron by Jos De Roo (MIT). Until eyeron is on crates.io the feature is available only when building from the repository.

You need to know tiramemsu’s two clocks and what a layer is. If either is new, read Time travel and bitemporality, explained and Layered graphs, explained first. You do not need to know N3. The next chapter teaches it.