Logical layer¶
OddsFox Graph attaches formal truth conditions to covered OUTCOME nodes,
emits structural logical edges at compile time, then optionally applies a
small deterministic rule registry. Transitive IMPLIES closure is on-demand.
What compiles¶
The proposition compiler (oddsgraph/propositions.py) covers these market
categories:
| Category | Predicates | Typical Polymarket pattern |
|---|---|---|
| Match moneyline / draw / advance | wins_match, draws_match, advances_match |
Team vs. Team, draw markets, team-to-advance |
| Group winner | wins_group |
Group X Winner |
| Stage of elimination | eliminated_at_stage |
Stage of Elimination: Team |
| World Cup winner | wins_competition |
tournament winner markets |
| Reaches stage | reaches_stage |
Nation to Reach Final/Semifinals/…, knockout-advance |
Covered outcomes get a Proposition payload in proposition_json, for
example:
{
"predicate": "reaches_stage",
"arguments": {
"team": "team:canada",
"competition": "competition:world-cup-2026",
"stage": "stage:world-cup-2026:final"
},
"polarity": true
}
Residual / unrecognized market types still produce EVENT / MARKET /
OUTCOME structure without propositions — those outcomes stay
disconnected from topology. See Known limitations.
Compile-time structural edges¶
Compiled outcomes get structural edges as follows (not every edge for every outcome):
| Edge | When |
|---|---|
REFERS_TO |
Outcome → each topology entity named in proposition arguments |
PRICES |
Market → priced outcome / entity |
COMPLEMENT |
Binary YES/NO outcome pairs |
EXACTLY_ONE |
Constraint → member outcomes of an exclusive partition |
Match-result EXACTLY_ONE (win A / win B / draw) requires the draw market
in addition to the two team moneylines — without it the partition is incomplete
because a soccer match can still draw
(oddsgraph/propositions.py:_build_match_propositions). Separate
EXACTLY_ONE partitions still emit for team-to-advance markets (when both
advance outcomes are present) and for other exclusive templates such as group
winner / stage elimination / WC winner.
Proposition-compiler edges carry derivation_type=compiler on export;
residual LLM / template topology edges use extraction.
Rule registry¶
When reasoning is enabled, oddsgraph/rules.py pairs propositions and emits
direct logical edges. Registered rules:
rule_id |
Edge type | Semantics |
|---|---|---|
wc.stage_monotonicity |
IMPLIES |
Reaching a later stage implies reaching every earlier marketed stage (unknown ranks skipped) |
wc.champion_reaches_final |
IMPLIES |
Winning the competition implies reaching the Final |
wc.elimination_implies_reaches |
IMPLIES |
Being eliminated at a knockout+ stage implies reaching that stage |
wc.champion_equals_elim_at_champion |
EQUIVALENT (bidirectional) |
Winning the competition is equivalent to elimination-at-Champion |
wc.single_match_winner_mutex |
MUTEX (bidirectional) |
Distinct team moneylines for the same match cannot both be true |
Rule-derived edges land in edges.parquet with:
derivation_type=rulerule_id/rule_versionidentifying the registry entrypremisesholding the proposition keys that fired the rule
The registry is intentionally small and WC2026-specific — not LLM judgment.
Build flags¶
| Flag | Default | Effect |
|---|---|---|
--propositions / --no-propositions |
on | Compile propositions and structural logical edges |
--reasoning / --no-reasoning |
on | Apply the rule registry over compiled propositions |
Rules only ever run over compiled propositions (pipeline.py skips the rule
engine when no propositions were compiled). Disabling propositions therefore
leaves reasoning with nothing to pair. Disabling reasoning alone still keeps
REFERS_TO / PRICES / COMPLEMENT / EXACTLY_ONE.
On-demand closure¶
oddsgraph closure reads exported IMPLIES edges and writes transitive
edges to build/implies_closure.parquet:
- Same columns as
edges.parquet derivation_type=transitivepremisesholds the shortest path of node ids (source…target)
Closure is not materialized into edges.parquet by default. Prefer this
command over inventing transitive joins downstream — see
Integrators.