Skip to content

Interactive graphical models: model() worlds with live, editable beliefs#20

Open
koaning wants to merge 8 commits into
mainfrom
koaning/dag-redesign-v1
Open

Interactive graphical models: model() worlds with live, editable beliefs#20
koaning wants to merge 8 commits into
mainfrom
koaning/dag-redesign-v1

Conversation

@koaning

@koaning koaning commented Jul 22, 2026

Copy link
Copy Markdown
Owner

Adds a probabilistic-graphical-model layer to dicekit: inside with model() as m: a bare Dice is a root variable, Dice.from_function(fn, parents=[...]) adds a conditional dependent, and operator expressions become derived variables over one exact joint, queryable via p()/m.query() with hard (given=) and soft (Jeffrey) evidence. Beliefs are now stateful and update in place: dice.believe()/forget() condition every subsequent query, multiple beliefs are satisfied jointly via iterative proportional fitting (order-independent), and lazy marginal caches invalidate automatically. m.show() renders the model as a DAG of live charts where every node has an in-widget edit toggle — drag bars to assert a belief and all other nodes repaint through kernel-side widget wiring (no notebook re-runs, no editor-cell boilerplate); displaying a bare variable or world gives the same live view. Also fixes a KeyError for derived parents in from_function, and the learn notebook gains a DAG prototype plus a live factor-graph and joint-atoms visualization. Includes 30+ new tests (67 passing) and notebook-driven builds via make build.

🤖 Generated with Claude Code

koaning and others added 8 commits July 21, 2026 23:24
…h demo

Bars signal mode (black static, blue editing); reset is the single way out
of edit mode. Model variables display as live wired charts (marimo prefers
_display_), a bare World renders its graph, and learn.py gains a live
factor-graph + joint-atoms prototype.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Observable Plot sorts ordinal domains alphabetically by default, so the CPT
heatmaps and belief slots disagreed with the variable charts' outcome order.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…uery

The joint is now a product of factors (priors + families); queries run
min-fill variable elimination, beliefs fit via IPF over adjustment factors,
and whole-graph repaints use one two-pass sum-product calibration on forest
factor graphs (VE fallback when loopy). Cost follows treewidth, not variable
count: a 200-test star repaint drops 12.3s -> 0.025s, and models the old
enumerator could not represent (2^201 rows) answer instantly and exactly.
Edge messages are stored for the upcoming message-passing visualization.
The enumerator survives as joint(), cross-checked by randomized oracle tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The factor view renders the real engine factors (prior + CPT heatmaps)
between the variables they touch, with a dashed belief slot per variable
that lights up when a belief is asserted. messages=True adds a two-row
strip per edge showing the calibration's actual sum-product messages,
repainted on every belief change. Replaces the hand-built learn.py
prototype with the one-liner.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Each verified three ways: an independent in-test brute-force enumeration
sharing the model's CPT constants, published literature values (Wikipedia
sprinkler 0.3577/0.6467, R&N alarm 0.284, Monty (n-1)/(n(n-2)) for 3-5
doors), and cross-engine paths (hard given vs point-mass believe, Jeffrey
mixture identity for soft beliefs, exact Fraction arithmetic end to end).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant