Engine · 4

Evaluation

Evaluation forward-chains the corpus's rules over a story's facts to a fixpoint: a matching rule fires, its then: writes new facts, and those can trigger further rules, until nothing new is produced. The result is every trope that fires and every fact the rules derive.

The fixpoint

Eval reads the story's asserted facts as the initial state and applies the rules in ledger order, repeating until stable. Here the Betrayal rule matches the betrayal event and derives a new state on the traitor:

verb Betrays(agent: char, target: char)
prop Traitor

rule Betrayal {
  when: evt $e [&Betrays(agent=$t, target=$v)]
  then: $t [+Traitor]
}

char vale
char renn
scene s { beat 1 { evt e [&Betrays(agent=vale, target=renn)] } }
$ tropelang eval story.trl
firings:  Betrayal($e=e, $t=vale, $v=renn)
derived:  vale [+Traitor]

Eval fires the corpus's rules over the story (recognition additionally scores buffer-local rules). Processing is deterministic — ledger order, a capped cascade — and never mutates the source: initial / final / firings / derived are a report, not an edit.

Derivation

A producer rule writes an intermediate anchor that other rules read. It lets eval chain more than one hop, and it is the structure the planning verbs traverse: a fact no rule produces is an observable leaf; anything producible is derived and chains.

// a producer rule — its then: writes an INTERMEDIATE anchor other rules read
rule lower_uti {
  when: $p [+Dysuria] $p [+Frequency]
  then: $p [+LowerUrinaryTract]
}

With this producer in the corpus, a chart carrying Dysuria and Frequency derives LowerUrinaryTract — which a downstream trope can then require without the chart ever stating it directly. Frontier recurses through exactly this derived anchor to reach the real observable leaves.

Related: derive computes a header field from a formula (e.g. a prevalence tier) — a read-only value on the file, distinct from a rule that derives a fact on an entity. See the grammar.

State at a point

Facts have a temporal interval, so the tags in force on an entity can be read at a given point in the timeline — epistemic tier and all. The editor's hover card uses this to show "state here."

Interfaces

CLI
tropelang eval <file> — the firings, derived facts, and the initial → final state.
WASM
eval_buffer(src){ firings, derived, initial, final, why }; state_at(src, name, offset) — the tags on an entity at a point.