Skip to content

Multi-place combo steps

A step is normally atomic — it touches exactly one decimal place, like +7 or -30. A recipe can also produce composite steps that touch several places at once, like +47 or -89.

This is how you build training material for whole two- and three-digit numbers: "children work with numbers 10–99, where the tens and ones digits each independently follow the techniques they already know."

Channels

An attachment of a rule to a recipe carries a place:

PlaceMeaning
0Ordinary, global attachment. The rule is eligible at every place. This is the default.
1, 10, 100, 1000The attachment is scoped to that one decimal place — a channel.

A composite candidate is assembled by taking one digit per configured channel and combining them, with a single shared sign for the whole step. Each channel's digit is then classified independently, as if it were its own atomic step at that place. Every channel must find a matching rule, or the whole candidate is rejected.

There is no cross-channel logic. No rule ever sees "the tens digit and the ones digit together" — each place is curated on its own terms. That is what makes the feature composable: you reuse the rules you already have, at the place you want them.

Place is per-attachment, not per-rule

The same rule can be attached to one recipe more than once, at different places — for example a "Plain (1)" rule attached at both 10 and 1. Each attachment is independent and carries its own usage and quotas.

Which places are available

A channel above the recipe's own sumMax could never fire, so only places the sum ceiling can actually reach are offered:

sumMaxPlaces available
191, 10
991, 10
9991, 10, 100
19991, 10, 100, 1000

If you expected a hundreds channel and it is not offered, raise sumMax first.

Eligibility: global rules still apply

For any candidate landing on place p — whether it is an atomic step or one channel of a composite — the eligible rules are:

everything attached at place: 0 plus everything attached at place: p

Two consequences:

A channel-tagged rule also admits ordinary atomic steps at that place. A rule attached at place: 10 is not composite-only; it will happily match a plain -10 step too. You do not need a second, global copy of it.

A global rule participates in every channel. A rule attached at place: 0 is eligible on the tens channel and the ones channel alike.

Because every attachment defaults to place: 0, a recipe that uses no channels behaves exactly as it always did — this eligibility rule collapses to "check every attached rule".

Two worked configurations

Tens fixed at one bead, ones unrestricted

Numbers 10–19, where the tens digit only ever moves by a single bead and the ones digit follows the full set of techniques.

Recipe: sumMax: 19, minStepsCount: 7.

RuleUsagePlace
Plain (1) – Additionfiller10
Plain (1) – Subtractionfiller10
Plain (9) – Addition / Subtractiontarget1
Plain (7), (8) – Addition / Subtractionreview1
the remaining Plain rulesfiller1
No negative sumconstraint0

The tens channel gets only the two "1 bead" rules, so the tens digit can only ever step by one. The ones channel gets the whole family. Note that the Plain (1) rules appear twice — once in the tens channel, once as part of the ones channel's full family. That is intended, not a mistake.

Generated steps look like +11, +16, -19 — and also plain -10, which is an ordinary atomic step where the ones channel simply contributed nothing. Composite and atomic steps coexist freely; nothing forces every step to be composite.

Both digits unrestricted

Numbers 10–99, where tens and ones each independently follow the same technique set.

Recipe: sumMax: 99, minStepsCount: 6.

RuleUsagePlace
Plain (any)target1
Plain (any)target10
No negative sumconstraint0

Two pattern attachments in total. Plain (any) is a consolidated rule matching the whole family in one expression — see the rule catalog.

Generated steps look like +25, -15, +37, -89.

Cost and limits

Candidate growth

Composite candidates grow as 2 × 9ⁿ where n is the number of channels:

ChannelsCandidates
2162
31,458
413,122

Channel count is not capped, but expect generation to get measurably slower past two or three channels.

The 31-rule ceiling

A recipe may attach at most 31 pattern-role rules. Channels multiply against that ceiling: N rules across C channels costs N × C slots, not N.

Attaching a full 18-rule family to two channels is 36 slots and simply will not compile. This is the trade-off the two configurations above illustrate:

ApproachSlotsYou getYou give up
Full family on one channel, minimal set on the other20Per-digit target / review / filler quotasVariety on the restricted channel
A consolidated "(any)" rule per channel2Full variety on every channelPer-digit quotas

The consolidated "(any)" rules exist precisely as the escape hatch when you hit the ceiling and do not need per-digit quotas.

Two things that will surprise you

A place = X constraint silently rejects every composite step

place is null on a composite step, so a constraint like place = 10 or place IN (1, 10) evaluates to false for every composite candidate — regardless of which digits it actually contains. The recipe then produces only atomic steps, or reports as infeasible, with no error explaining why.

To restrict which places a composite step may touch, use digitAt(current_value, p) instead of place. See the null trap.

A place-scoped rule may not reference current_sum

Inside one channel, "the sum after this step" would mean the running total plus that single channel's digit — an intermediate state the exercise never actually passes through, since a composite step commits all of its digits together. Referencing current_sum in a place-scoped rule is rejected when the recipe is compiled.

Whole-step sum conditions belong in an ordinary constraint rule at place: 0, where they are evaluated once against the real, complete step value. A "no negative sum" constraint works unchanged on composite recipes.

How a composite step is reported

A generated composite step reports place, formula, and digitBefore as null, and instead carries a per-channel breakdown: for each place it touched, the digit and the specific attachment that matched there. An atomic step is the reverse — the three fields are set and the breakdown is absent. A step is always exactly one of the two.

See also

Reference and cookbook for mental-math rule and recipe authoring.