An essay · new in v1.3, still settling
Classic algorithms allocate comparisons. Semantic programs allocate model calls — which cost money, take seconds, and carry error rates. The old paradigms turn out to be budget strategies for exactly that resource, and Kimiya is the setting where the spending is priced: every strategy ends with a certificate that says what the answer is worth.
the enablers
Search needed two things the language did not have, so v1.3 added them — each with its own discipline:
commit and irreversible acts inside: a verdict must not rest on
unaccounted judgments.gen and judge. Identical input, identical reading — so
reuse is free, and a reading's θ factor enters the invoice once per run, no matter how often it
is consulted.§1 · greedy
Take the judged-best option at every step — it is what every agent loop already does. Kimiya adds one thing, and it is damning in a useful way:
-- k_rank: a declared purpose (tutorial §2) — “closer to the goal”, -- preserve [goal_progress], allow_loss [style, phrasing] pick := first(options) forall c in options: if judge<3,2/3> (c |= "closer to the goal than: " + pick) under k_rank panel [B, C]: pick := c
A chain of k judged choices enters the certificate at roughly βk. Twenty
choices at β≥0.97 → θ≈0.54: greedy's compounding fragility, which heuristics hide, becomes a
number on the invoice. The language does not make greedy better — it makes greedy
tell you what it cost. Wrap the loop in explore: and
re-judge only the winner outside, and the same search commits on one counted reading instead of
twenty.
§2 · reuse
Dynamic programming's whole trick is reusing subproblem answers. When the subproblem answer is an instrument reading, reuse has an epistemic meaning: one reading consulted many times is still one reading.
-- k_feas: a declared purpose — “feasible under the constraints” fn feasible(plan): -- same plan, same verdict — counted once, however often it recurs if memo judge<3,2/3> (plan |= "feasible under the constraints") under k_feas panel [B, C]: return 1 else: return 0
This inverts the usual trade-off. In classic computing, memoization buys time. Here it buys evidence: the memoized program ends with a stronger certificate than the naive one, because fewer independent readings back the verdict — while also costing fewer calls. We do not know another setting where adding a cache improves your epistemics. The honest caveat carries over from DP itself: judged comparisons are noisy, so the result is never "optimal" — it is "best found, at rate θ," and the certificate says so.
§3 · evolution
Evolutionary search — mutate, score, keep the best — is where the discipline pays out
completely, because of one fact about the invoice: gen contributes
no θ factor. A generator is a proposer, never a warrant. So if fitness is a
kernel function, the whole search costs the certificate nothing:
use python "score.py" -- provides fitness(): deterministic, certainty 1 best := "" best_s := 0 - 1 explore: forall g in range(8): c := gen<Text>("vary: " + best) by A -- mutation: fresh sampling, never memoized s := fitness(c) if check(s > best_s): best := c best_s := s check best_s > 0.9 -- the verdict is kernel commit(best) -- θ = 1.0
That architecture — an LLM as the mutation operator, a deterministic evaluator as the judge — is the one that has already made real mathematical discoveries in the wild. Here it is twenty lines, and the certificate carries certainty about the returned artifact's score, because the model only ever proposed. When no kernel fitness exists (taste, style), the judged version still runs — but the cross-provenance rule bites: a panel from the generator's own family is one voice grading its own work, and the run is stamped UNCERTIFIED — it completes, but its certificate refuses to count the self-judged factor — rather than allowed to lie.
where this goes
The pattern generalizes past toys. Consider a business that is underperforming: some factors
are immutable (market, season), some mutable (pricing, hours, channel mix), and there is a
current result and a wanted one. Finding which mutable factors to change is a search
over interventions with a semantic objective — exactly this shape. explore
the intervention space with judged plausibility screens; memo the
configurations that recur; commit only through live gates — kernel checks on the numbers,
a fresh cross-family panel on the final intervention set. The output is not just a
recommendation: it is a recommendation with an invoice — which claims are ironclad,
which are instrument readings, and at what rate.
That program is no longer hypothetical: it ships in the download as
examples/counterfactual.kim. Eight candidate interventions screened
(thirty-two with max_changes=2 — a declared param
feeding kernel enumeration), one θ factor on the certificate either way, and reruns reuse the
verdict reading for free. The invoice does not grow with the search space.
And its sibling, examples/counterfactual_evolve.kim, is the path this
page's §3 promised — for when the space is too big to enumerate, which is the enterprise case:
hundreds of levers, and the best intervention on nobody's menu. The model invents
interventions (gen inside explore, never
memoized — mutation needs diversity); a schema keeps free invention kernel-checkable, so
"touches only mutable levers" stays a certainty-1 fact; evolution starts from the enumerated
baseline and must beat it to replace it. Live against real models, the discipline showed its
teeth both ways: an invented proposal passed the kernel gate, a real cross-family screen pruned
it — and when the verdict panel voted 0/5 on the remaining claim, the run
abstained rather than issue a certificate it could not back.
Honest status
explore and memo shipped in v1.3 and are the
newest constructs in the language — implemented, tested in both runtimes, and likely to be
refined as they meet real problems. The reference
tracks what has settled.
Try it
Download the toolchain →
These programs run today — offline, with the mock oracle, in about a minute.