Progressive scale by brackets
Intention
Section titled “Intention”I want to apply the higher rate only to the amount above the threshold.
The example pins 100 KZT at the threshold and 200 KZT on a 1500 base, not 300 KZT.
Incorrect form and why it stays silent
Section titled “Incorrect form and why it stays silent”decision Levy(x: Money) -> Money { table hit first { when x <= 1000 KZT => x * 10 percent; } }Without otherwise the table does not define an outcome outside the first row: a static rejection. Progression also needs the accumulated amount of the lower bracket; otherwise the higher rate is applied to the whole base.
Correct form
Section titled “Correct form”language "law.core" version "0.2";package recipes.l.r02 version "0.1.0";namespace "urn:recipe:l-calc:02";
decision Levy(x: Money) -> Money { table hit first { when x <= 1000 KZT => x * 10 percent; otherwise => 100 KZT + (x - 1000 KZT) * 20 percent; }}Frozen execution scene
Section titled “Frozen execution scene”| Facts and choice | Question | Answer |
|---|---|---|
| 1. base 0 KZT | Levy(0 KZT) | 0 KZT / COMPUTED |
| 2. base 999 KZT | Levy(999 KZT) | 99.9 KZT / COMPUTED |
| 3. base 1000 KZT | Levy(1000 KZT) | 100 KZT / COMPUTED |
| 4. base 1500 KZT | Levy(1500 KZT) | 200 KZT / COMPUTED |
zero base, zero levy
test "zero base, zero levy" { given { context { legal_time @2026-09-13; decision_time @2026-09-13T09:00:00+05:00; knowledge_time @2026-09-13T09:00:00+05:00; timezone "Asia/Almaty"; }
} evaluate Levy(0 KZT); expect value == 0 KZT; expect evaluation_status == COMPUTED;
}base below break
test "base below break" { given { context { legal_time @2026-09-13; decision_time @2026-09-13T09:00:00+05:00; knowledge_time @2026-09-13T09:00:00+05:00; timezone "Asia/Almaty"; }
} evaluate Levy(999 KZT); expect value == 99.9 KZT; expect evaluation_status == COMPUTED;
}base at break
test "base at break" { given { context { legal_time @2026-09-13; decision_time @2026-09-13T09:00:00+05:00; knowledge_time @2026-09-13T09:00:00+05:00; timezone "Asia/Almaty"; }
} evaluate Levy(1000 KZT); expect value == 100 KZT; expect evaluation_status == COMPUTED;
}base above break
test "base above break" { given { context { legal_time @2026-09-13; decision_time @2026-09-13T09:00:00+05:00; knowledge_time @2026-09-13T09:00:00+05:00; timezone "Asia/Almaty"; }
} evaluate Levy(1500 KZT); expect value == 200 KZT; expect evaluation_status == COMPUTED;
}Counterfactual
Section titled “Counterfactual”Mutation: otherwise => 100 KZT + (x - 1000 KZT) * 20 percent; → “; expected LDC-E8304. Additional counterfactuals are shown as separate table rows.
Boundary
Section titled “Boundary”A teaching non-negative base and conventional rates. Row order is semantic; a single rate on the whole base does not yield a progressive sum. A calculator shared by several rules lives in a separate recipe.
Pitfall
Section titled “Pitfall”Without the accumulated lower-bracket amount, the higher rate would apply to the whole base: 300 KZT instead of 200 KZT on a 1500 base.
Documentation for Arxo. Writings — blog.arxo.io.
Anonymous visit counts on stats.arxo.io, no cookies.