Project P151

Tax brackets

Income bands written from a sentence and read four ways - closed, half-open, open, left-open - the incomes on a band's end, the slab tax the reading decides and the marginal tax it cannot change.

2 modules · 2 recorded sessionstext-menu UI in the terminalupdated 2026-10-18

Every screen below was recorded under CPython. When this page was built, the EML interpreter replayed each session from the same input and printed the same bytes.

About

Income bands written from a sentence - 0-10000, 10000-40000, 40000-100000, 100000 and above - read four ways, and the incomes that sit on a band's end.

  • main.eml - the menu, the bands under each reading, one income under each, the partition check over the incomes on file, and adding one
  • bands.eml - the bands, the readings, the incomes on file, whether a band takes an income, the bands that take it, the slab tax and the marginal tax

How each part works:

  • As in the corpus case boundary-inclusive-or-not, "between" is four questions - closed, half-open, open, left-open - and they part only at the ends: 0, 10000, 40000 and 100000. Every income in the middle lands in the same band under all four, which is why the difference survives every test there.
  • Consecutive bands read closed take the three inner ends twice; read open they take the four ends not at all; left-open misses only 0. Half-open alone puts every income in exactly one band: the bands are a partition.
  • The slab tax charges the whole income at its band's rate, so the reading decides it at an end: 10000 pays 0.00, 1000.00 or 3000.00 - read open no band takes it, and the else branch charges the top rate.
  • The marginal tax charges each slice at its own band's rate. It is the same under every reading, a slice's width not depending on which band owns its end, and it does not jump.

What is checked: menu choices 1 to 5; an income from 0 to 9999999. An empty answer cancels.

Sessions: sessions/basic.in gives: - the bands; incomes 10000, 25000, 100000 and 0; - the incomes on file; 40000 added, and the incomes on file again.

sessions/bad-input.in gives: - menu choices 0 and x; - incomes: a cancel, 12345678, 1e5 and -5; - adding: a cancel and x, then 99999; the incomes on file.

Built on the verified corpus case boundary-inclusive-or-not (four readings of a range, consecutive buckets that double-count or drop a boundary, and a partition check by counting).

Recorded sessions

What the screen shows while someone uses the program. Each typed line appears after its prompt, the way a terminal shows it.

bad-input

interpreter: byte-equal
== Tax brackets ==
Bands written from a sentence, read four ways, and the incomes that sit on their ends.

1) bands  2) one income  3) the incomes on file  4) add an income  5) quit
choice> 0
Pick a number from 1 to 5.

1) bands  2) one income  3) the incomes on file  4) add an income  5) quit
choice> x
Pick a number from 1 to 5.

1) bands  2) one income  3) the incomes on file  4) add an income  5) quit
choice> 2
income (0 to 9999999)> 
Cancelled.

1) bands  2) one income  3) the incomes on file  4) add an income  5) quit
choice> 2
income (0 to 9999999)> 12345678
Type a whole number from 0 to 9999999.

1) bands  2) one income  3) the incomes on file  4) add an income  5) quit
choice> 2
income (0 to 9999999)> 1e5
Type a whole number from 0 to 9999999.

1) bands  2) one income  3) the incomes on file  4) add an income  5) quit
choice> 2
income (0 to 9999999)> -5
Type a whole number from 0 to 9999999.

1) bands  2) one income  3) the incomes on file  4) add an income  5) quit
choice> 4
income (0 to 9999999)> 
Cancelled.

1) bands  2) one income  3) the incomes on file  4) add an income  5) quit
choice> 4
income (0 to 9999999)> x
Type a whole number from 0 to 9999999.

1) bands  2) one income  3) the incomes on file  4) add an income  5) quit
choice> 4
income (0 to 9999999)> 99999
Income 99999 added; 10 on file.

1) bands  2) one income  3) the incomes on file  4) add an income  5) quit
choice> 3
Over the 10 incomes on file:
  reading    in no band  in one  in two   slab tax in all
  closed              0       7       3         113900.00
  half-open           0      10       0         128900.00
  open                4       6       0         134900.00
  left-open           1       9       0         113900.00
The readings part only at 0, 10000, 40000, 100000: incomes on a band's end.
Every income in exactly one band: half-open.
Marginal tax in all: 76900.00, the same under every reading.

1) bands  2) one income  3) the incomes on file  4) add an income  5) quit
choice> 5
Bye.
What was typed (18 lines)
0
x
2

2
12345678
2
1e5
2
-5
4

4
x
4
99999
3
5

basic

interpreter: byte-equal
== Tax brackets ==
Bands written from a sentence, read four ways, and the incomes that sit on their ends.

1) bands  2) one income  3) the incomes on file  4) add an income  5) quit
choice> 1
The sentence: 0-10000 at 0%, 10000-40000 at 10%, 40000-100000 at 20%, 100000 and above at 30%.
  band  closed            half-open         open              left-open
  1 0%  [0, 10000]        [0, 10000)        (0, 10000)        (0, 10000]
  2 10% [10000, 40000]    [10000, 40000)    (10000, 40000)    (10000, 40000]
  3 20% [40000, 100000]   [40000, 100000)   (40000, 100000)   (40000, 100000]
  4 30% [100000, and up)  [100000, and up)  (100000, and up)  (100000, and up)

1) bands  2) one income  3) the incomes on file  4) add an income  5) quit
choice> 2
income (0 to 9999999)> 10000
Income 10000:
  reading    bands that take it  slab tax: the whole income at the band's rate
  closed     1 and 2             0.00 - band 1, the first that takes it
  half-open  2                   1000.00
  open       none                3000.00 - no band takes it, and the else branch charges the top rate
  left-open  1                   0.00
Marginal tax, each slice at its own band's rate: 0.00 under every reading: a slice's width does not depend on which band owns its end.

1) bands  2) one income  3) the incomes on file  4) add an income  5) quit
choice> 2
income (0 to 9999999)> 25000
Income 25000:
  reading    bands that take it  slab tax: the whole income at the band's rate
  closed     2                   2500.00
  half-open  2                   2500.00
  open       2                   2500.00
  left-open  2                   2500.00
Marginal tax, each slice at its own band's rate: 1500.00 under every reading: a slice's width does not depend on which band owns its end.

1) bands  2) one income  3) the incomes on file  4) add an income  5) quit
choice> 2
income (0 to 9999999)> 100000
Income 100000:
  reading    bands that take it  slab tax: the whole income at the band's rate
  closed     3 and 4             20000.00 - band 3, the first that takes it
  half-open  4                   30000.00
  open       none                30000.00 - no band takes it, and the else branch charges the top rate
  left-open  3                   20000.00
Marginal tax, each slice at its own band's rate: 15000.00 under every reading: a slice's width does not depend on which band owns its end.

1) bands  2) one income  3) the incomes on file  4) add an income  5) quit
choice> 2
income (0 to 9999999)> 0
Income 0:
  reading    bands that take it  slab tax: the whole income at the band's rate
  closed     1                   0.00
  half-open  1                   0.00
  open       none                0.00 - no band takes it, and the else branch charges the top rate
  left-open  none                0.00 - no band takes it, and the else branch charges the top rate
Marginal tax, each slice at its own band's rate: 0.00 under every reading: a slice's width does not depend on which band owns its end.

1) bands  2) one income  3) the incomes on file  4) add an income  5) quit
choice> 3
Over the 9 incomes on file:
  reading    in no band  in one  in two   slab tax in all
  closed              0       6       3          93900.20
  half-open           0       9       0         108900.20
  open                4       5       0         114900.20
  left-open           1       8       0          93900.20
The readings part only at 0, 10000, 40000, 100000: incomes on a band's end.
Every income in exactly one band: half-open.
Marginal tax in all: 61900.20, the same under every reading.

1) bands  2) one income  3) the incomes on file  4) add an income  5) quit
choice> 4
income (0 to 9999999)> 40000
Income 40000 added; 10 on file.

1) bands  2) one income  3) the incomes on file  4) add an income  5) quit
choice> 3
Over the 10 incomes on file:
  reading    in no band  in one  in two   slab tax in all
  closed              0       6       4          97900.20
  half-open           0      10       0         116900.20
  open                5       5       0         126900.20
  left-open           1       9       0          97900.20
The readings part only at 0, 10000, 40000, 100000: incomes on a band's end.
Every income in exactly one band: half-open.
Marginal tax in all: 64900.20, the same under every reading.

1) bands  2) one income  3) the incomes on file  4) add an income  5) quit
choice> 5
Bye.
What was typed (14 lines)
1
2
10000
2
25000
2
100000
2
0
3
4
40000
3
5

Modules

The program as written, entry module first. Each module transpiles to its own Python file, which is what eml project run executes.

main.eml(entry)

eml
# P151 tax brackets: the bands and their four readings, one income under
# each, the partition check over the incomes on file, and adding one.
import bands

def plain(s):
    0 => i
    len(s) => j
    while i < j and s[i] == " ":
        i + 1 => i
    while j > i and s[j - 1] == " ":
        j - 1 => j
    return s[i:j]

def pad(s, n):
    s => out
    while len(out) < n:
        out + " " => out
    return out

def lpad(s, n):
    s => out
    while len(out) < n:
        " " + out => out
    return out

def money(c):
    c % 100 => p
    if p < 10:
        return str(int((c - p) / 100)) + ".0" + str(p)
    return str(int((c - p) / 100)) + "." + str(p)

def interval(reading, b):
    if reading == "closed" or reading == "half-open":
        "[" => left
    else:
        "(" => left
    if b[1] < 0:
        return left + str(b[0]) + ", and up)"
    if reading == "closed" or reading == "left-open":
        "]" => right
    else:
        ")" => right
    return left + str(b[0]) + ", " + str(b[1]) + right

def show_bands():
    "The sentence: 0-10000 at 0%, 10000-40000 at 10%, 40000-100000 at 20%, 100000 and above at 30%." ^0
    ("  " + pad("band", 6) + pad("closed", 18) + pad("half-open", 18) + pad("open", 18) + "left-open") ^0
    1 => k
    for b in bands.bands():
        ("  " + pad(str(k) + " " + str(b[2]) + "%", 6) + pad(interval("closed", b), 18) + pad(interval("half-open", b), 18) + pad(interval("open", b), 18) + interval("left-open", b)) ^0
        k + 1 => k

def names(ks):
    if len(ks) == 0:
        return "none"
    "" => out
    for k in ks:
        if out == "":
            str(k) => out
        else:
            out + " and " + str(k) => out
    return out

def one_income():
    plain(input("income (0 to 9999999)> ")) => t
    if t == "":
        "Cancelled." ^0
        return
    if len(t) > 7:
        "Type a whole number from 0 to 9999999." ^0
        return
    for c in t:
        if c < "0" or c > "9":
            "Type a whole number from 0 to 9999999." ^0
            return
    int(t) => x
    show_income(x)

def show_income(x):
    ("Income " + str(x) + ":") ^0
    ("  " + pad("reading", 11) + pad("bands that take it", 20) + "slab tax: the whole income at the band's rate") ^0
    for r in bands.readings():
        bands.taking(r, x) => ks
        money(bands.slab(r, x)) => s
        if len(ks) == 0:
            s + " - no band takes it, and the else branch charges the top rate" => s
        elif len(ks) > 1:
            s + " - band " + str(ks[0]) + ", the first that takes it" => s
        ("  " + pad(r, 11) + pad(names(ks), 20) + s) ^0
    ("Marginal tax, each slice at its own band's rate: " + money(bands.marginal(x)) + " under every reading: a slice's width does not depend on which band owns its end.") ^0

def partition(xs):
    ("Over the " + str(len(xs)) + " incomes on file:") ^0
    ("  " + pad("reading", 11) + "in no band  in one  in two   slab tax in all") ^0
    "" => exact
    for r in bands.readings():
        0 => none
        0 => one
        0 => two
        0 => total
        for x in xs:
            len(bands.taking(r, x)) => n
            if n == 0:
                none + 1 => none
            elif n == 1:
                one + 1 => one
            else:
                two + 1 => two
            total + bands.slab(r, x) => total
        ("  " + pad(r, 11) + lpad(str(none), 10) + lpad(str(one), 8) + lpad(str(two), 8) + lpad(money(total), 18)) ^0
        if one == len(xs):
            if exact == "":
                r => exact
            else:
                exact + " and " + r => exact
    "" => edge
    [] => seen
    for x in xs:
        bands.taking("closed", x) => a
        bands.taking("open", x) => b
        False => dup
        for y in seen:
            if y == x:
                True => dup
        if (len(a) != 1 or len(b) != 1) and not dup:
            seen + [x] => seen
            if edge == "":
                str(x) => edge
            else:
                edge + ", " + str(x) => edge
    if edge != "":
        ("The readings part only at " + edge + ": incomes on a band's end.") ^0
    ("Every income in exactly one band: " + exact + ".") ^0
    0 => m
    for x in xs:
        m + bands.marginal(x) => m
    ("Marginal tax in all: " + money(m) + ", the same under every reading.") ^0

def add(xs):
    plain(input("income (0 to 9999999)> ")) => t
    if t == "":
        "Cancelled." ^0
        return xs
    if len(t) > 7:
        "Type a whole number from 0 to 9999999." ^0
        return xs
    for c in t:
        if c < "0" or c > "9":
            "Type a whole number from 0 to 9999999." ^0
            return xs
    int(t) => x
    ("Income " + str(x) + " added; " + str(len(xs) + 1) + " on file.") ^0
    return xs + [x]

bands.incomes() => xs

"== Tax brackets ==" ^0
"Bands written from a sentence, read four ways, and the incomes that sit on their ends." ^0
True => running
while running:
    "" ^0
    "1) bands  2) one income  3) the incomes on file  4) add an income  5) quit" ^0
    plain(input("choice> ")) => choice
    if choice == "1":
        show_bands()
    elif choice == "2":
        one_income()
    elif choice == "3":
        partition(xs)
    elif choice == "4":
        add(xs) => xs
    elif choice == "5":
        False => running
    else:
        "Pick a number from 1 to 5." ^0
"Bye." ^0
Python projection (main.py)
import bands

def plain(s):
    i = 0
    j = len(s)
    while i < j and s[i] == " ":
        i = i + 1
    while j > i and s[j - 1] == " ":
        j = j - 1
    return s[i:j]

def pad(s, n):
    out = s
    while len(out) < n:
        out = out + " "
    return out

def lpad(s, n):
    out = s
    while len(out) < n:
        out = " " + out
    return out

def money(c):
    p = c % 100
    if p < 10:
        return str(int((c - p) / 100)) + ".0" + str(p)
    return str(int((c - p) / 100)) + "." + str(p)

def interval(reading, b):
    if reading == "closed" or reading == "half-open":
        left = "["
    else:
        left = "("
    if b[1] < 0:
        return left + str(b[0]) + ", and up)"
    if reading == "closed" or reading == "left-open":
        right = "]"
    else:
        right = ")"
    return left + str(b[0]) + ", " + str(b[1]) + right

def show_bands():
    print("The sentence: 0-10000 at 0%, 10000-40000 at 10%, 40000-100000 at 20%, 100000 and above at 30%.")
    print("  " + pad("band", 6) + pad("closed", 18) + pad("half-open", 18) + pad("open", 18) + "left-open")
    k = 1
    for b in bands.bands():
        print("  " + pad(str(k) + " " + str(b[2]) + "%", 6) + pad(interval("closed", b), 18) + pad(interval("half-open", b), 18) + pad(interval("open", b), 18) + interval("left-open", b))
        k = k + 1

def names(ks):
    if len(ks) == 0:
        return "none"
    out = ""
    for k in ks:
        if out == "":
            out = str(k)
        else:
            out = out + " and " + str(k)
    return out

def one_income():
    t = plain(input("income (0 to 9999999)> "))
    if t == "":
        print("Cancelled.")
        return
    if len(t) > 7:
        print("Type a whole number from 0 to 9999999.")
        return
    for c in t:
        if c < "0" or c > "9":
            print("Type a whole number from 0 to 9999999.")
            return
    x = int(t)
    show_income(x)

def show_income(x):
    print("Income " + str(x) + ":")
    print("  " + pad("reading", 11) + pad("bands that take it", 20) + "slab tax: the whole income at the band's rate")
    for r in bands.readings():
        ks = bands.taking(r, x)
        s = money(bands.slab(r, x))
        if len(ks) == 0:
            s = s + " - no band takes it, and the else branch charges the top rate"
        elif len(ks) > 1:
            s = s + " - band " + str(ks[0]) + ", the first that takes it"
        print("  " + pad(r, 11) + pad(names(ks), 20) + s)
    print("Marginal tax, each slice at its own band's rate: " + money(bands.marginal(x)) + " under every reading: a slice's width does not depend on which band owns its end.")

def partition(xs):
    print("Over the " + str(len(xs)) + " incomes on file:")
    print("  " + pad("reading", 11) + "in no band  in one  in two   slab tax in all")
    exact = ""
    for r in bands.readings():
        none = 0
        one = 0
        two = 0
        total = 0
        for x in xs:
            n = len(bands.taking(r, x))
            if n == 0:
                none = none + 1
            elif n == 1:
                one = one + 1
            else:
                two = two + 1
            total = total + bands.slab(r, x)
        print("  " + pad(r, 11) + lpad(str(none), 10) + lpad(str(one), 8) + lpad(str(two), 8) + lpad(money(total), 18))
        if one == len(xs):
            if exact == "":
                exact = r
            else:
                exact = exact + " and " + r
    edge = ""
    seen = []
    for x in xs:
        a = bands.taking("closed", x)
        b = bands.taking("open", x)
        dup = False
        for y in seen:
            if y == x:
                dup = True
        if (len(a) != 1 or len(b) != 1) and not dup:
            seen = seen + [x]
            if edge == "":
                edge = str(x)
            else:
                edge = edge + ", " + str(x)
    if edge != "":
        print("The readings part only at " + edge + ": incomes on a band's end.")
    print("Every income in exactly one band: " + exact + ".")
    m = 0
    for x in xs:
        m = m + bands.marginal(x)
    print("Marginal tax in all: " + money(m) + ", the same under every reading.")

def add(xs):
    t = plain(input("income (0 to 9999999)> "))
    if t == "":
        print("Cancelled.")
        return xs
    if len(t) > 7:
        print("Type a whole number from 0 to 9999999.")
        return xs
    for c in t:
        if c < "0" or c > "9":
            print("Type a whole number from 0 to 9999999.")
            return xs
    x = int(t)
    print("Income " + str(x) + " added; " + str(len(xs) + 1) + " on file.")
    return xs + [x]

xs = bands.incomes()
print("== Tax brackets ==")
print("Bands written from a sentence, read four ways, and the incomes that sit on their ends.")
running = True
while running:
    print("")
    print("1) bands  2) one income  3) the incomes on file  4) add an income  5) quit")
    choice = plain(input("choice> "))
    if choice == "1":
        show_bands()
    elif choice == "2":
        one_income()
    elif choice == "3":
        partition(xs)
    elif choice == "4":
        xs = add(xs)
    elif choice == "5":
        running = False
    else:
        print("Pick a number from 1 to 5.")
print("Bye.")

bands.eml

eml
# P151 tax brackets - income bands written from a sentence, "0-10000,
# 10000-40000, 40000-100000, 100000 and above", read four ways. As in the
# corpus case boundary-inclusive-or-not, "between" is four questions -
# closed, half-open, open, left-open - and they differ only at the end
# points, which is why the difference survives every test in the middle.
# Consecutive bands read closed take a boundary twice and read open take it
# not at all; only half-open makes the bands a partition. A band is [low,
# high, rate in percent]; the last has no high.

def bands():
    return [[0, 10000, 0], [10000, 40000, 10], [40000, 100000, 20], [100000, 0 - 1, 30]]

def readings():
    return ["closed", "half-open", "open", "left-open"]

def incomes():
    return [0, 8500, 10000, 25000, 40000, 40001, 72000, 100000, 150000]

def takes(reading, b, x):
    # does band b take income x under the reading
    if reading == "closed" or reading == "half-open":
        x >= b[0] => low_ok
    else:
        x > b[0] => low_ok
    if b[1] < 0:
        return low_ok
    if reading == "closed" or reading == "left-open":
        x <= b[1] => high_ok
    else:
        x < b[1] => high_ok
    return low_ok and high_ok

def taking(reading, x):
    # the numbers of the bands that take x, from 1
    [] => out
    1 => k
    for b in bands():
        if takes(reading, b, x):
            out + [k] => out
        k + 1 => k
    return out

def slab(reading, x):
    # the whole income at the rate of the first band that takes it, in
    # cents; with no band the else branch charges the top rate
    for b in bands():
        if takes(reading, b, x):
            return x * b[2]
    return x * bands()[len(bands()) - 1][2]

def marginal(x):
    # each slice of the income at its own band's rate, in cents
    0 => t
    for b in bands():
        x => top
        if b[1] >= 0 and b[1] < top:
            b[1] => top
        if top > b[0]:
            t + (top - b[0]) * b[2] => t
    return t
Python projection (bands.py)
def bands():
    return [[0, 10000, 0], [10000, 40000, 10], [40000, 100000, 20], [100000, 0 - 1, 30]]

def readings():
    return ["closed", "half-open", "open", "left-open"]

def incomes():
    return [0, 8500, 10000, 25000, 40000, 40001, 72000, 100000, 150000]

def takes(reading, b, x):
    if reading == "closed" or reading == "half-open":
        low_ok = x >= b[0]
    else:
        low_ok = x > b[0]
    if b[1] < 0:
        return low_ok
    if reading == "closed" or reading == "left-open":
        high_ok = x <= b[1]
    else:
        high_ok = x < b[1]
    return low_ok and high_ok

def taking(reading, x):
    out = []
    k = 1
    for b in bands():
        if takes(reading, b, x):
            out = out + [k]
        k = k + 1
    return out

def slab(reading, x):
    for b in bands():
        if takes(reading, b, x):
            return x * b[2]
    return x * bands()[len(bands()) - 1][2]

def marginal(x):
    t = 0
    for b in bands():
        top = x
        if b[1] >= 0 and b[1] < top:
            top = b[1]
        if top > b[0]:
            t = t + (top - b[0]) * b[2]
    return t

Built on these corpus cases

ΣEML 2026

Efficient New Language — a high-density semantic overlay for humans and AI agents.

This site’s demos run on the real EML toolchain, in your browser.

© 2026 EveMissLab (一言諾科技有限公司) / Neo.K. All rights reserved.