Rules as Facts

Alice never has a hardcoded counter-table — she has a small belief graph of (counter, counters, opponent) facts each with a valence in [0,1]. To decide what to play, she walks the graph, finds every triple whose object matches what Bob just did, and picks the highest-valence one. Edit the valences, watch Alice's choices flip. The decision is a graph query — nothing more.

What did Bob just do?

HP

alice
100
bob
100
close mid far
pick a move for Bob and hit Resolve

Alice's belief graph iter_spo_triples

pick: —
How it works. Alice's decision is pick_counter(beliefs, opponent_kind) — a single scan of iter_spo_triples filtering predicate == 'counters' AND object == opponent_kind, keeping the max-valence subject. No special case for any matchup; no hidden if/else. Edit a valence and the next pick changes the next instant.

Tie to Eddy. This is examples/cognition_dojo_f_v0.py verbatim — pick_counter over (counter, counters, opponent) triples in the fighter's belief graph. Decision IS a graph query: change the triples, change the policy. Lab 12 lets the outcomes edit those valences; lab 13 adds a model of what Bob will do next.