<!-- canonical: efficientnewlanguage.org/ai/examples/984-the-taller-tyres-made-every-kilometre-read-short | ai_layer_version: 0.1.0 | updated: 2026-09-23 -->

# Example 984 — The taller tyres made every kilometre read short

`the_taller_tyres_made_every_kilometre_read_short.eml` - A driver replaces 205/55 R16 tyres with taller 225/60 R16 ones on the same rims, keeps the needle at the 100 km/h limit on the motorway, and reasons that the speedometer shows the car's speed and reads a little high anyway. What the needle means on the new tyres is computed below.

## EML

```eml
# Self-authored for the EML case corpus (no external origin). A driver replaces
# 205/55 R16 tyres with taller 225/60 R16 ones on the same rims, keeps the
# needle at the 100 km/h limit on the motorway, and reasons that the
# speedometer shows the car's speed and reads a little high anyway. What the
# needle means on the new tyres is computed below.
#
# The reasoning is careful. The needle really does sit at 100; nothing in the
# car's electronics was changed; the speedometer really did read high before,
# 100 on the needle at a true 96; and the intent is exactly 'stay at the limit'.
#
# A speedometer does not see the road; it counts turns of the wheels and was
# calibrated for the old tyre's circumference. The taller tyre covers 10704 per
# ten thousand of the old distance in each turn, so the needle's 100 is now a
# true 102: the factory's four-kilometre margin has become two over. The
# odometer, accurate before, now shows 18684 of every 20000 km driven.

16 => rim_inches
254 => tenths_of_a_mm_per_inch
205 => old_tyre_width_mm
55 => old_sidewall_percent
225 => new_tyre_width_mm
60 => new_sidewall_percent
100 => indicated_kmh
96 => true_kmh_at_the_needle_100_on_the_old_tyres
20000 => km_driven_in_a_year

rim_inches * tenths_of_a_mm_per_inch => rim_tenths_of_a_mm
rim_tenths_of_a_mm + int(2 * old_tyre_width_mm * old_sidewall_percent * 10 / 100) => old_diameter_tenths_of_a_mm
rim_tenths_of_a_mm + int(2 * new_tyre_width_mm * new_sidewall_percent * 10 / 100) => new_diameter_tenths_of_a_mm
int(new_diameter_tenths_of_a_mm * 10000 / old_diameter_tenths_of_a_mm) => road_per_turn_vs_old_per_myriad
int(true_kmh_at_the_needle_100_on_the_old_tyres * new_diameter_tenths_of_a_mm / old_diameter_tenths_of_a_mm) => true_kmh_at_the_needle_100_now
indicated_kmh - true_kmh_at_the_needle_100_on_the_old_tyres => old_margin_kmh
true_kmh_at_the_needle_100_now - indicated_kmh => now_over_the_needle_kmh
int(km_driven_in_a_year * old_diameter_tenths_of_a_mm / new_diameter_tenths_of_a_mm) => odometer_shows_km
km_driven_in_a_year - odometer_shows_km => odometer_short_by_km

"rim                             : " + str(rim_inches) + " inches, " + str(rim_tenths_of_a_mm) + " tenths of a mm" ^0
"old tyre, 205/55                : " + str(old_diameter_tenths_of_a_mm) + " tenths of a mm across" ^0
"new tyre, 225/60                : " + str(new_diameter_tenths_of_a_mm) + " tenths of a mm across" ^0
"road per wheel turn vs old      : " + str(road_per_turn_vs_old_per_myriad) + " per ten thousand" ^0
"" ^0
"needle at " + str(indicated_kmh) + ", old tyres          : true " + str(true_kmh_at_the_needle_100_on_the_old_tyres) + " km/h, " + str(old_margin_kmh) + " under the needle" ^0
"needle at " + str(indicated_kmh) + ", new tyres          : true " + str(true_kmh_at_the_needle_100_now) + " km/h, " + str(now_over_the_needle_kmh) + " over the needle" ^0
"odometer after " + str(km_driven_in_a_year) + " km driven : " + str(odometer_shows_km) + " km, short by " + str(odometer_short_by_km) ^0
"" ^0

# ---- what the driver verified ----

"the needle-is-the-speed reasoning" ^0
"  needle : exactly at " + str(indicated_kmh) ^0
"  electronics : unchanged" ^0
"  known margin : the needle read " + str(old_margin_kmh) + " high on the old tyres" ^0
"  intent : stay at the limit" ^0
"  facts wrong : 0" ^0
"  verdict : AT 100 ON THE NEEDLE I AM AT OR UNDER THE LIMIT" ^0
"" ^0
"  holding the needle exactly at " + str(indicated_kmh) + " is the part done right here," ^0
"  and it is why the wheels turn at exactly the rate that" ^0
"  meant " + str(true_kmh_at_the_needle_100_on_the_old_tyres) + " km/h on the old tyres" ^0
"" ^0

# ---- what the needle counts ----

"a speedometer counts turns" ^0
"  what it measures : how fast the wheels turn" ^0
"  what it assumes : how much road one turn covers, the old" ^0
"    tyre's circumference" ^0
"  the new tyre : " + str(new_diameter_tenths_of_a_mm) + " tenths of a mm across instead of " + str(old_diameter_tenths_of_a_mm) + "," ^0
"    so each turn covers " + str(road_per_turn_vs_old_per_myriad) + " per ten thousand of the old distance" ^0
"  the same turning rate : now a true " + str(true_kmh_at_the_needle_100_now) + " km/h; the margin" ^0
"    of " + str(old_margin_kmh) + " under has become " + str(now_over_the_needle_kmh) + " over" ^0
"  the odometer : counts the same turns, and loses " + str(odometer_short_by_km) + " km a year" ^0
"" ^0

# ---- what the driver got ----

"the motorway" ^0
"  believed : at or under the limit, with room to spare" ^0
"  actual : " + str(true_kmh_at_the_needle_100_now) + " km/h at a needle of " + str(indicated_kmh) ^0
"  is the speedometer broken : no; it counts turns exactly as before" ^0
"  does the needle show the car's speed : only for the tyre it" ^0
"    was calibrated on" ^0
"" ^0

# ---- null control ----

# The same needle recalibrated for the new tyre's circumference instead of left
# on the old one.
102 => nc_true_kmh_at_the_needle_100_uncalibrated
96 => nc_true_kmh_at_the_needle_100_recalibrated
6 => nc_kmh_the_recalibration_returns

"null control - recalibrate for the new tyre" ^0
"  true speed at a needle of 100, uncalibrated : " + str(nc_true_kmh_at_the_needle_100_uncalibrated) + " km/h" ^0
"  true speed at a needle of 100, recalibrated : " + str(nc_true_kmh_at_the_needle_100_recalibrated) + " km/h" ^0
"  km/h the recalibration returns : " + str(nc_kmh_the_recalibration_returns) ^0
"  no tyre and no road changed; the instrument was told how much" ^0
"  road one turn now covers" ^0
"" ^0

# ---- the rule ----

"what an unchanged speedometer guarantees" ^0
"  it counts wheel turns exactly as before : exactly" ^0
"  its needle shows the car's speed : not addressed; a turn of the" ^0
"    taller tyre covers " + str(road_per_turn_vs_old_per_myriad) + " per ten thousand of the old distance," ^0
"    so the needle's " + str(indicated_kmh) + " is a true " + str(true_kmh_at_the_needle_100_now) + " and the year's " + str(km_driven_in_a_year) + " km" ^0
"    show as " + str(odometer_shows_km) ^0
"" ^0

"an instrument that counts something else and converts is only as right as" ^0
"its conversion; change what one count is worth and every reading drifts by" ^0
"the same share, silently" ^0
"" ^0

"The needle sits at " + str(indicated_kmh) + " and the electronics are untouched - both true. But the" ^0
"speedometer counts turns, and a turn of the taller tyre covers " + str(road_per_turn_vs_old_per_myriad) + " per ten" ^0
"thousand of the old one's road, so the needle's " + str(indicated_kmh) + " is a true " + str(true_kmh_at_the_needle_100_now) + " and " + str(km_driven_in_a_year) + " km" ^0
"read as " + str(odometer_shows_km) + ", until the speedometer is told what one turn is now worth." ^0
```

## Python (deterministic transpilation)

```python
rim_inches = 16
tenths_of_a_mm_per_inch = 254
old_tyre_width_mm = 205
old_sidewall_percent = 55
new_tyre_width_mm = 225
new_sidewall_percent = 60
indicated_kmh = 100
true_kmh_at_the_needle_100_on_the_old_tyres = 96
km_driven_in_a_year = 20000
rim_tenths_of_a_mm = rim_inches * tenths_of_a_mm_per_inch
old_diameter_tenths_of_a_mm = rim_tenths_of_a_mm + int(2 * old_tyre_width_mm * old_sidewall_percent * 10 / 100)
new_diameter_tenths_of_a_mm = rim_tenths_of_a_mm + int(2 * new_tyre_width_mm * new_sidewall_percent * 10 / 100)
road_per_turn_vs_old_per_myriad = int(new_diameter_tenths_of_a_mm * 10000 / old_diameter_tenths_of_a_mm)
true_kmh_at_the_needle_100_now = int(true_kmh_at_the_needle_100_on_the_old_tyres * new_diameter_tenths_of_a_mm / old_diameter_tenths_of_a_mm)
old_margin_kmh = indicated_kmh - true_kmh_at_the_needle_100_on_the_old_tyres
now_over_the_needle_kmh = true_kmh_at_the_needle_100_now - indicated_kmh
odometer_shows_km = int(km_driven_in_a_year * old_diameter_tenths_of_a_mm / new_diameter_tenths_of_a_mm)
odometer_short_by_km = km_driven_in_a_year - odometer_shows_km
print("rim                             : " + str(rim_inches) + " inches, " + str(rim_tenths_of_a_mm) + " tenths of a mm")
print("old tyre, 205/55                : " + str(old_diameter_tenths_of_a_mm) + " tenths of a mm across")
print("new tyre, 225/60                : " + str(new_diameter_tenths_of_a_mm) + " tenths of a mm across")
print("road per wheel turn vs old      : " + str(road_per_turn_vs_old_per_myriad) + " per ten thousand")
print("")
print("needle at " + str(indicated_kmh) + ", old tyres          : true " + str(true_kmh_at_the_needle_100_on_the_old_tyres) + " km/h, " + str(old_margin_kmh) + " under the needle")
print("needle at " + str(indicated_kmh) + ", new tyres          : true " + str(true_kmh_at_the_needle_100_now) + " km/h, " + str(now_over_the_needle_kmh) + " over the needle")
print("odometer after " + str(km_driven_in_a_year) + " km driven : " + str(odometer_shows_km) + " km, short by " + str(odometer_short_by_km))
print("")
print("the needle-is-the-speed reasoning")
print("  needle : exactly at " + str(indicated_kmh))
print("  electronics : unchanged")
print("  known margin : the needle read " + str(old_margin_kmh) + " high on the old tyres")
print("  intent : stay at the limit")
print("  facts wrong : 0")
print("  verdict : AT 100 ON THE NEEDLE I AM AT OR UNDER THE LIMIT")
print("")
print("  holding the needle exactly at " + str(indicated_kmh) + " is the part done right here,")
print("  and it is why the wheels turn at exactly the rate that")
print("  meant " + str(true_kmh_at_the_needle_100_on_the_old_tyres) + " km/h on the old tyres")
print("")
print("a speedometer counts turns")
print("  what it measures : how fast the wheels turn")
print("  what it assumes : how much road one turn covers, the old")
print("    tyre's circumference")
print("  the new tyre : " + str(new_diameter_tenths_of_a_mm) + " tenths of a mm across instead of " + str(old_diameter_tenths_of_a_mm) + ",")
print("    so each turn covers " + str(road_per_turn_vs_old_per_myriad) + " per ten thousand of the old distance")
print("  the same turning rate : now a true " + str(true_kmh_at_the_needle_100_now) + " km/h; the margin")
print("    of " + str(old_margin_kmh) + " under has become " + str(now_over_the_needle_kmh) + " over")
print("  the odometer : counts the same turns, and loses " + str(odometer_short_by_km) + " km a year")
print("")
print("the motorway")
print("  believed : at or under the limit, with room to spare")
print("  actual : " + str(true_kmh_at_the_needle_100_now) + " km/h at a needle of " + str(indicated_kmh))
print("  is the speedometer broken : no; it counts turns exactly as before")
print("  does the needle show the car's speed : only for the tyre it")
print("    was calibrated on")
print("")
nc_true_kmh_at_the_needle_100_uncalibrated = 102
nc_true_kmh_at_the_needle_100_recalibrated = 96
nc_kmh_the_recalibration_returns = 6
print("null control - recalibrate for the new tyre")
print("  true speed at a needle of 100, uncalibrated : " + str(nc_true_kmh_at_the_needle_100_uncalibrated) + " km/h")
print("  true speed at a needle of 100, recalibrated : " + str(nc_true_kmh_at_the_needle_100_recalibrated) + " km/h")
print("  km/h the recalibration returns : " + str(nc_kmh_the_recalibration_returns))
print("  no tyre and no road changed; the instrument was told how much")
print("  road one turn now covers")
print("")
print("what an unchanged speedometer guarantees")
print("  it counts wheel turns exactly as before : exactly")
print("  its needle shows the car's speed : not addressed; a turn of the")
print("    taller tyre covers " + str(road_per_turn_vs_old_per_myriad) + " per ten thousand of the old distance,")
print("    so the needle's " + str(indicated_kmh) + " is a true " + str(true_kmh_at_the_needle_100_now) + " and the year's " + str(km_driven_in_a_year) + " km")
print("    show as " + str(odometer_shows_km))
print("")
print("an instrument that counts something else and converts is only as right as")
print("its conversion; change what one count is worth and every reading drifts by")
print("the same share, silently")
print("")
print("The needle sits at " + str(indicated_kmh) + " and the electronics are untouched - both true. But the")
print("speedometer counts turns, and a turn of the taller tyre covers " + str(road_per_turn_vs_old_per_myriad) + " per ten")
print("thousand of the old one's road, so the needle's " + str(indicated_kmh) + " is a true " + str(true_kmh_at_the_needle_100_now) + " and " + str(km_driven_in_a_year) + " km")
print("read as " + str(odometer_shows_km) + ", until the speedometer is told what one turn is now worth.")
```

## stdout (executed)

```text
rim                             : 16 inches, 4064 tenths of a mm
old tyre, 205/55                : 6319 tenths of a mm across
new tyre, 225/60                : 6764 tenths of a mm across
road per wheel turn vs old      : 10704 per ten thousand

needle at 100, old tyres          : true 96 km/h, 4 under the needle
needle at 100, new tyres          : true 102 km/h, 2 over the needle
odometer after 20000 km driven : 18684 km, short by 1316

the needle-is-the-speed reasoning
  needle : exactly at 100
  electronics : unchanged
  known margin : the needle read 4 high on the old tyres
  intent : stay at the limit
  facts wrong : 0
  verdict : AT 100 ON THE NEEDLE I AM AT OR UNDER THE LIMIT

  holding the needle exactly at 100 is the part done right here,
  and it is why the wheels turn at exactly the rate that
  meant 96 km/h on the old tyres

a speedometer counts turns
  what it measures : how fast the wheels turn
  what it assumes : how much road one turn covers, the old
    tyre's circumference
  the new tyre : 6764 tenths of a mm across instead of 6319,
    so each turn covers 10704 per ten thousand of the old distance
  the same turning rate : now a true 102 km/h; the margin
    of 4 under has become 2 over
  the odometer : counts the same turns, and loses 1316 km a year

the motorway
  believed : at or under the limit, with room to spare
  actual : 102 km/h at a needle of 100
  is the speedometer broken : no; it counts turns exactly as before
  does the needle show the car's speed : only for the tyre it
    was calibrated on

null control - recalibrate for the new tyre
  true speed at a needle of 100, uncalibrated : 102 km/h
  true speed at a needle of 100, recalibrated : 96 km/h
  km/h the recalibration returns : 6
  no tyre and no road changed; the instrument was told how much
  road one turn now covers

what an unchanged speedometer guarantees
  it counts wheel turns exactly as before : exactly
  its needle shows the car's speed : not addressed; a turn of the
    taller tyre covers 10704 per ten thousand of the old distance,
    so the needle's 100 is a true 102 and the year's 20000 km
    show as 18684

an instrument that counts something else and converts is only as right as
its conversion; change what one count is worth and every reading drifts by
the same share, silently

The needle sits at 100 and the electronics are untouched - both true. But the
speedometer counts turns, and a turn of the taller tyre covers 10704 per ten
thousand of the old one's road, so the needle's 100 is a true 102 and 20000 km
read as 18684, until the speedometer is told what one turn is now worth.
```

## Round-trip

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

## Trace event types

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