<!-- canonical: efficientnewlanguage.org/ai/examples/1005-the-solid-wheel-beat-the-ring-down-the-slope | ai_layer_version: 0.1.0 | updated: 2026-09-25 -->

# Example 1005 — The solid wheel beat the ring down the slope

`the_solid_wheel_beat_the_ring_down_the_slope.eml` - A teacher rolls a solid disc and a thin ring of the same mass and the same radius down the same slope from a height of 2 metres, and predicts a dead heat: everything falls together, and the two have the same mass, size, height and slope. Which one arrives first, and why, is computed below.

## EML

```eml
# Self-authored for the EML case corpus (no external origin). A teacher rolls a
# solid disc and a thin ring of the same mass and the same radius down the same
# slope from a height of 2 metres, and predicts a dead heat: everything falls
# together, and the two have the same mass, size, height and slope. Which one
# arrives first, and why, is computed below.
#
# The reasoning is careful. The masses really are equal; the radii really are
# equal; both really start from rest at the same height; and falling bodies
# really do fall together when nothing else acts on them.
#
# A rolling body must spin as well as move, and the energy it gains from the
# drop is shared between the two. A ring has all its mass at the rim, so half
# its energy goes into spinning; a disc has most of its mass nearer the axle, so
# only a third does. At the bottom the disc moves at 511 cm/s and the ring at
# 442; the disc gets down the slope in 86 percent of the ring's time.

200 => drop_cm
981 => gravity_cm_per_s2
511 => disc_speed_cm_per_s
442 => ring_speed_cm_per_s

int(4 * gravity_cm_per_s2 * drop_cm / 3) => disc_speed_squared
gravity_cm_per_s2 * drop_cm => ring_speed_squared
2 * gravity_cm_per_s2 * drop_cm => sliding_speed_squared
disc_speed_cm_per_s * disc_speed_cm_per_s => disc_check_below
(disc_speed_cm_per_s + 1) * (disc_speed_cm_per_s + 1) => disc_check_above
ring_speed_cm_per_s * ring_speed_cm_per_s => ring_check_below
(ring_speed_cm_per_s + 1) * (ring_speed_cm_per_s + 1) => ring_check_above
333 => disc_energy_spinning_per_mille
500 => ring_energy_spinning_per_mille
int(ring_speed_cm_per_s * 100 / disc_speed_cm_per_s) => disc_time_vs_ring_percent

"drop                            : " + str(drop_cm) + " cm" ^0
"energy spent on spin            : disc " + str(disc_energy_spinning_per_mille) + " per mille, ring " + str(ring_energy_spinning_per_mille) ^0
"" ^0
"disc speed squared at the bottom : " + str(disc_speed_squared) + ", between " + str(disc_check_below) + " and " + str(disc_check_above) + ", so " + str(disc_speed_cm_per_s) + " cm/s" ^0
"ring speed squared at the bottom : " + str(ring_speed_squared) + ", between " + str(ring_check_below) + " and " + str(ring_check_above) + ", so " + str(ring_speed_cm_per_s) + " cm/s" ^0
"a block sliding without friction : speed squared " + str(sliding_speed_squared) ^0
"disc's time vs ring's time      : " + str(disc_time_vs_ring_percent) + " percent" ^0
"" ^0

# ---- what the teacher verified ----

"the dead-heat reasoning" ^0
"  masses : equal" ^0
"  radii : equal" ^0
"  start : both from rest, " + str(drop_cm) + " cm up the same slope" ^0
"  principle : falling bodies fall together" ^0
"  facts wrong : 0" ^0
"  verdict : A DEAD HEAT" ^0
"" ^0
"  matching mass, size and start is the part done right here, and" ^0
"  it is why the drop gives both exactly the same energy" ^0
"" ^0

# ---- where the energy goes ----

"moving and spinning share the drop" ^0
"  what the drop gives : the same energy to each" ^0
"  what rolling needs : spin as well as speed, paid from that energy" ^0
"  a ring : all its mass at the rim, so spinning costs as much as" ^0
"    moving - " + str(ring_energy_spinning_per_mille) + " per mille of the energy spins" ^0
"  a disc : much of its mass near the axle, where spinning is" ^0
"    cheap - " + str(disc_energy_spinning_per_mille) + " per mille spins" ^0
"  what is left for speed : more for the disc, " + str(disc_speed_cm_per_s) + " cm/s against " + str(ring_speed_cm_per_s) ^0
"" ^0

# ---- what the teacher got ----

"the race" ^0
"  believed : a dead heat" ^0
"  actual : the disc first, in " + str(disc_time_vs_ring_percent) + " percent of the ring's time" ^0
"  is the equal-fall rule wrong : no; it holds for bodies that" ^0
"    only fall" ^0
"  do equal masses roll equally : no; how the mass is arranged" ^0
"    decides how much of the drop goes into spin" ^0
"" ^0

# ---- null control ----

# The same race worked out with each body's share of energy spent on spinning
# instead of by mass and size alone.
100 => nc_disc_time_vs_ring_read_from_mass_and_size_percent
86 => nc_disc_time_vs_ring_read_from_the_spin_share_percent
14 => nc_percent_the_spin_share_takes_off

"null control - count the energy that spins" ^0
"  disc's time vs ring's, read from mass and size : " + str(nc_disc_time_vs_ring_read_from_mass_and_size_percent) + " percent" ^0
"  disc's time vs ring's, read from the spin share : " + str(nc_disc_time_vs_ring_read_from_the_spin_share_percent) + " percent" ^0
"  percent the spin share takes off : " + str(nc_percent_the_spin_share_takes_off) ^0
"  no body and no slope changed; the energy was followed into the" ^0
"  spin as well as the speed" ^0
"" ^0

# ---- the rule ----

"what equal mass, size and drop guarantee" ^0
"  both gain the same energy on the way down : exactly" ^0
"  both reach the bottom together : not addressed; rolling spends" ^0
"    part of that energy on spin, " + str(ring_energy_spinning_per_mille) + " per mille for the ring and " + str(disc_energy_spinning_per_mille) + " for" ^0
"    the disc, so the disc is moving at " + str(disc_speed_cm_per_s) + " cm/s to the ring's " + str(ring_speed_cm_per_s) ^0
"" ^0

"two bodies can weigh the same and fall differently once they have to turn;" ^0
"the race is decided by where the mass sits, not how much of it there is" ^0
"" ^0

"Mass, size and drop are equal - so is the energy. But rolling pays for spin" ^0
"out of that energy, and the ring, with all its mass at the rim, pays " + str(ring_energy_spinning_per_mille) + " per" ^0
"mille to the disc's " + str(disc_energy_spinning_per_mille) + ", so the disc reaches " + str(disc_speed_cm_per_s) + " cm/s to the ring's " + str(ring_speed_cm_per_s) + " and wins," ^0
"until the energy is followed into the spin as well as the speed." ^0
```

## Python (deterministic transpilation)

```python
drop_cm = 200
gravity_cm_per_s2 = 981
disc_speed_cm_per_s = 511
ring_speed_cm_per_s = 442
disc_speed_squared = int(4 * gravity_cm_per_s2 * drop_cm / 3)
ring_speed_squared = gravity_cm_per_s2 * drop_cm
sliding_speed_squared = 2 * gravity_cm_per_s2 * drop_cm
disc_check_below = disc_speed_cm_per_s * disc_speed_cm_per_s
disc_check_above = (disc_speed_cm_per_s + 1) * (disc_speed_cm_per_s + 1)
ring_check_below = ring_speed_cm_per_s * ring_speed_cm_per_s
ring_check_above = (ring_speed_cm_per_s + 1) * (ring_speed_cm_per_s + 1)
disc_energy_spinning_per_mille = 333
ring_energy_spinning_per_mille = 500
disc_time_vs_ring_percent = int(ring_speed_cm_per_s * 100 / disc_speed_cm_per_s)
print("drop                            : " + str(drop_cm) + " cm")
print("energy spent on spin            : disc " + str(disc_energy_spinning_per_mille) + " per mille, ring " + str(ring_energy_spinning_per_mille))
print("")
print("disc speed squared at the bottom : " + str(disc_speed_squared) + ", between " + str(disc_check_below) + " and " + str(disc_check_above) + ", so " + str(disc_speed_cm_per_s) + " cm/s")
print("ring speed squared at the bottom : " + str(ring_speed_squared) + ", between " + str(ring_check_below) + " and " + str(ring_check_above) + ", so " + str(ring_speed_cm_per_s) + " cm/s")
print("a block sliding without friction : speed squared " + str(sliding_speed_squared))
print("disc's time vs ring's time      : " + str(disc_time_vs_ring_percent) + " percent")
print("")
print("the dead-heat reasoning")
print("  masses : equal")
print("  radii : equal")
print("  start : both from rest, " + str(drop_cm) + " cm up the same slope")
print("  principle : falling bodies fall together")
print("  facts wrong : 0")
print("  verdict : A DEAD HEAT")
print("")
print("  matching mass, size and start is the part done right here, and")
print("  it is why the drop gives both exactly the same energy")
print("")
print("moving and spinning share the drop")
print("  what the drop gives : the same energy to each")
print("  what rolling needs : spin as well as speed, paid from that energy")
print("  a ring : all its mass at the rim, so spinning costs as much as")
print("    moving - " + str(ring_energy_spinning_per_mille) + " per mille of the energy spins")
print("  a disc : much of its mass near the axle, where spinning is")
print("    cheap - " + str(disc_energy_spinning_per_mille) + " per mille spins")
print("  what is left for speed : more for the disc, " + str(disc_speed_cm_per_s) + " cm/s against " + str(ring_speed_cm_per_s))
print("")
print("the race")
print("  believed : a dead heat")
print("  actual : the disc first, in " + str(disc_time_vs_ring_percent) + " percent of the ring's time")
print("  is the equal-fall rule wrong : no; it holds for bodies that")
print("    only fall")
print("  do equal masses roll equally : no; how the mass is arranged")
print("    decides how much of the drop goes into spin")
print("")
nc_disc_time_vs_ring_read_from_mass_and_size_percent = 100
nc_disc_time_vs_ring_read_from_the_spin_share_percent = 86
nc_percent_the_spin_share_takes_off = 14
print("null control - count the energy that spins")
print("  disc's time vs ring's, read from mass and size : " + str(nc_disc_time_vs_ring_read_from_mass_and_size_percent) + " percent")
print("  disc's time vs ring's, read from the spin share : " + str(nc_disc_time_vs_ring_read_from_the_spin_share_percent) + " percent")
print("  percent the spin share takes off : " + str(nc_percent_the_spin_share_takes_off))
print("  no body and no slope changed; the energy was followed into the")
print("  spin as well as the speed")
print("")
print("what equal mass, size and drop guarantee")
print("  both gain the same energy on the way down : exactly")
print("  both reach the bottom together : not addressed; rolling spends")
print("    part of that energy on spin, " + str(ring_energy_spinning_per_mille) + " per mille for the ring and " + str(disc_energy_spinning_per_mille) + " for")
print("    the disc, so the disc is moving at " + str(disc_speed_cm_per_s) + " cm/s to the ring's " + str(ring_speed_cm_per_s))
print("")
print("two bodies can weigh the same and fall differently once they have to turn;")
print("the race is decided by where the mass sits, not how much of it there is")
print("")
print("Mass, size and drop are equal - so is the energy. But rolling pays for spin")
print("out of that energy, and the ring, with all its mass at the rim, pays " + str(ring_energy_spinning_per_mille) + " per")
print("mille to the disc's " + str(disc_energy_spinning_per_mille) + ", so the disc reaches " + str(disc_speed_cm_per_s) + " cm/s to the ring's " + str(ring_speed_cm_per_s) + " and wins,")
print("until the energy is followed into the spin as well as the speed.")
```

## stdout (executed)

```text
drop                            : 200 cm
energy spent on spin            : disc 333 per mille, ring 500

disc speed squared at the bottom : 261600, between 261121 and 262144, so 511 cm/s
ring speed squared at the bottom : 196200, between 195364 and 196249, so 442 cm/s
a block sliding without friction : speed squared 392400
disc's time vs ring's time      : 86 percent

the dead-heat reasoning
  masses : equal
  radii : equal
  start : both from rest, 200 cm up the same slope
  principle : falling bodies fall together
  facts wrong : 0
  verdict : A DEAD HEAT

  matching mass, size and start is the part done right here, and
  it is why the drop gives both exactly the same energy

moving and spinning share the drop
  what the drop gives : the same energy to each
  what rolling needs : spin as well as speed, paid from that energy
  a ring : all its mass at the rim, so spinning costs as much as
    moving - 500 per mille of the energy spins
  a disc : much of its mass near the axle, where spinning is
    cheap - 333 per mille spins
  what is left for speed : more for the disc, 511 cm/s against 442

the race
  believed : a dead heat
  actual : the disc first, in 86 percent of the ring's time
  is the equal-fall rule wrong : no; it holds for bodies that
    only fall
  do equal masses roll equally : no; how the mass is arranged
    decides how much of the drop goes into spin

null control - count the energy that spins
  disc's time vs ring's, read from mass and size : 100 percent
  disc's time vs ring's, read from the spin share : 86 percent
  percent the spin share takes off : 14
  no body and no slope changed; the energy was followed into the
  spin as well as the speed

what equal mass, size and drop guarantee
  both gain the same energy on the way down : exactly
  both reach the bottom together : not addressed; rolling spends
    part of that energy on spin, 500 per mille for the ring and 333 for
    the disc, so the disc is moving at 511 cm/s to the ring's 442

two bodies can weigh the same and fall differently once they have to turn;
the race is decided by where the mass sits, not how much of it there is

Mass, size and drop are equal - so is the energy. But rolling pays for spin
out of that energy, and the ring, with all its mass at the rim, pays 500 per
mille to the disc's 333, so the disc reaches 511 cm/s to the ring's 442 and wins,
until the energy is followed into the spin as well as the speed.
```

## Round-trip

`ok: true` — round-trip fixpoint reached (python1 == python2)

## Trace event types

eml:run:start · eml:assign · eml:output · eml:run:done
