Skip to content

solvi.strategy

The code strategist ModelStrategist: dead ends dropped, the cheapest verified plan by declared costs (no model). The segment model behind ModelStrategist.load (solvi.segment_model, solvi.strategy_model up to 0.7) is experimental: no checkpoint is published.

Model strategist (experimental): the typed decomposer from research as a solvi strategist.

The deterministic strategist (solvi.strategist) walks back from each question's targets by exact names and, for a fact with alternative producers (provides=), needs the inputs of ALL of them (a fallback chain). This module plans differently:

  1. Points — code. A branch-and-bound search picks ONE producer per needed fact so that the plan is valid and cheapest (declared cost=; a part without a declared cost counts as unit). A producer whose inputs cannot be computed from the given facts (a dead end) is never chosen. Hard checks that govern a question (its then names the question, it has no then, or the question requires it) and that the deterministic flow over the usable producers contains are mandatory milestones: every plan must keep them.
  2. Segments — the model. Where the choice is not settled by declared costs (a fact with several usable producers, not all of them with a declared cost), the model gets a short task — "produce this fact from these available facts; these are the candidate parts (narrowed by code)" — and proposes 1–4 parts, in order. All segments of a plan go through the model in one batch.
  3. Verification — code. Each segment is checked (every part is a candidate, the last one provides the fact, every input is available or made earlier in the segment, types fit); an accepted segment fixes those choices and the search completes the rest; the whole plan is checked again (inputs bound, acyclic, types, every mandatory hard check kept). A rejected segment falls back to the code choice for that fact; a plan that fails the final check falls back to the code plan (on_failure="code"), to the deterministic strategist ("deterministic") or abstains ("abstain").

So a model error costs cost or coverage, never a silent wrong wiring: every candidate of a segment provides the same fact (that is what provides= declares) and runs its own validator at run time, names bind exactly, and only verified plans run. The plan is recorded in the trace as one hashed record (kind "plan"; provenance "proposed" when the model chose any part, with the model's fingerprint and, per segment, what was proposed and why it was accepted or rejected); trace.replay re-verifies it against the catalog.

from solvi.strategy import CostStrategist, ModelStrategist
system = System(cat, questions, strategist=CostStrategist())      # code only: cheapest verified plan, no model
system = System(cat, questions, strategist=ModelStrategist.load("path/to/strategist-checkpoint"))   # experimental

Experimental: no strategist checkpoint is published; see docs/strategist.md for its status and when the model helps at all.

Selection dataclass

Selection(choice: dict, needed: set, cost: float, proven: bool = True, feasible: bool = True, why: str = '')

One producer per needed fact (names), the facts the plan needs, its cost and whether the search proved it cheapest.

CostStrategist

CostStrategist(producers='declared', on_failure='code', costs=None, keep_alternatives=True, record=True)

The code strategist for System(..., strategist=...): dead ends dropped, the cheapest verified plan by declared (or measured) costs — no model. ModelStrategist is the same planner with a model that proposes segments.

how to treat the alternative producers of a fact (provides=):

"declared" (default) — as the deterministic strategist does: a fallback chain in declaration order (the first is the preferred one), except that producers whose inputs cannot be computed (dead ends) are dropped instead of making the whole fact unreachable. Answers are those of the deterministic strategist wherever it can answer; nothing is left to choose, so a model is never asked. "equivalent" — the producers of a fact are interchangeable (any accepted output is the same fact): one is chosen as the primary, the cheapest valid plan by declared cost= (unit when undeclared); where declared costs do not settle it, the model (if any) proposes the segment; the others stay as run-time fallbacks when their inputs are already computed (keep_alternatives=True).

on_failure: when the verified plan cannot be built — "code" (the code plan), "deterministic" (solvi.strategist.plan) or "abstain" (every question abstains). keep_alternatives: keep the other producers of a fact as run-time fallbacks. record: write the plan record into the trace. (0.7 names: fallback= for on_failure=, fallbacks= for keep_alternatives=; they still work with a SolviDeprecationWarning until 0.9.)

info

info()

{"type", "id", "fp"} of the model (as in trace records), or None.

plan

plan(catalog, questions, init_keys, heads=None, costs=None)

→ Flow. costs: {producer: cost} from the caller (System(cost_policy="measured") passes measured run times), under the strategist's own costs= (which wins where both name a producer).

ModelStrategist

ModelStrategist(model=None, producers='declared', on_failure='code', costs=None, keep_alternatives=True, record=True)

Bases: CostStrategist

CostStrategist with a model (experimental: no checkpoint is published) that proposes the producers where declared costs do not settle the choice; code verifies every proposal (see the module docs). ModelStrategist() without a model is CostStrategist() — that spelling of 0.7 still works, with a SolviDeprecationWarning.

load classmethod

load(path, backend='auto', producers='equivalent', threads=None, quantized=False, **kw)

A trained segment model (a directory or a Hugging Face id; docs/strategist.md) behind this strategist. The model chooses among interchangeable producers, so producers defaults to "equivalent" here.

Experimental: no checkpoint is published — it reads one you trained yourself (docs/strategist.md has the format).

alternatives

alternatives(p)

The producers of a part's fact: its alternatives, or the part itself.

reachable

reachable(catalog, init_keys)

Facts computable from init_keys when a fact needs only ONE of its producers (the deterministic strategist needs the inputs of every alternative).

search

search(catalog, questions, init_keys, costs=None, heads=None, fixed=None, extra=(), unit=UNIT, method='auto')

Cheapest valid selection for the questions' targets, their required parts and extra parts (e.g. mandatory checks). fixed: {fact: producer name} choices that must be kept (a model's accepted segments). method: "milp" (exact: a 0/1 program solved by scipy's HiGHS), "bnb" (branch and bound, capped at MAX_EXPAND nodes) or "auto" (milp when scipy has it). Ties go to the producer declared first. → Selection (feasible=False when a target cannot be computed; why says which).

mandatory_checks

mandatory_checks(catalog, questions, init_keys, heads=None)

Mandatory milestones: the hard checks that govern each question in the flow the deterministic strategist would build if every fact needed only its usable producers (dead ends dropped) — independent of which producer a plan chooses, so a shortcut that skips the fact such a check reads cannot drop the check. → {question: [check]}

view

view(catalog, choice, fallbacks=True, reach=None)

A shallow copy of the catalog in which every fact with alternative producers keeps only the chosen one (first) and, with fallbacks, the other producers whose inputs the plan already computes (after it, in declaration order) — unless such a producer reads, through any fact, the fact it would produce (then the plan could not run).

governing

governing(catalog, flow, questions)

Hard checks in a flow that govern each question (they decide its answer when false) → {question: [check]}.

validate

validate(catalog, flow, questions, init_keys, mandatory=None)

The plan checks → [problem]: every step's inputs are given or made by an earlier step (for a fact with alternative producers: every producer kept in the flow), the order is acyclic, producer and reader types fit, no question is left unresolved, and every mandatory hard check of a question is in its flow.

build

build(catalog, questions, init_keys, sel, heads=None, fallbacks=True, gov=None)

Selection → Flow (the deterministic strategist on the narrowed catalog, with mandatory checks as required parts).

segments

segments(catalog, questions, init_keys, sel, costs=None, depth=3, all_facts=False)

The facts whose producer the model should choose, each as a short task (narrowed by code): {"fact", "type", "question", "available": [(fact, type, how)], "candidates": [part info], "code": [code's parts]}. A fact is a segment when it has ≥ 2 usable producers and not all of them declare a cost (else code decides); all_facts=True: every fact with ≥ 2 producers (training / evaluation).

check_segment

check_segment(catalog, seg, nodes)

A proposed segment (part names, in order) → None if acceptable, else why not.

plan_record

plan_record(flow)

The hashed trace record of a planned flow (kind "plan"): the chosen producers, the mandatory checks and, per segment, what the model proposed and why it was accepted or rejected.

replay_plan

replay_plan(r, catalog, init_keys)

Re-verify a plan record against the catalog: every chosen producer exists and provides its fact, and its inputs are given or chosen facts → [(step, name, reason)].

narrowed

narrowed(group, tried)

A fact's producer group narrowed to the producers that ran (replay of a plan that dropped the others).