Trichromat with UV — pollinator vision

What does a bee see on a sunflower?

A UV cone at 350 nm, a blue cone at 440, a green cone at 540 — the bee's RGB is shifted into the ultraviolet. Flowers paint UV nectar guides we can't see; for the bee, every sunflower has a runway.

Sunflower — what we see
Sunflower — what the bee sees (UV mapped to violet)
UV nectar guide
The flower’s centre disc and petal stripes reflect UV strongly — that’s the runway. The bee sees a bullseye where we see uniform yellow.

Three cones — UV at 350 nm, blue at 440, green at 540 — replace our RGB. The kernels above paint the same flower in both opponent spaces; the bee’s UV channel is mapped to violet on screen because there’s no honest way to display real UV on a human monitor.

The math behind it

Each function carries a @verify contract that compiles to a Lean theorem about its bounds. The same source compiles to C, Verilog, HLSL, and 28 more targets. View the experiment on GitHub →

bee_cones.emlchain 1
module bee_cones;

// Three Gaussian cone sensitivities for Apis mellifera.
// Wavelengths in nanometres; sigma is FWHM/2.355 of the
// reported peak.
const LAMBDA_UV_NM:   Real = 350.0
const LAMBDA_BLUE_NM: Real = 440.0
const LAMBDA_GREEN_NM:Real = 540.0
const SIGMA_NM:       Real =  35.0

@verify(lean, theorem = "cone_response_in_unit_interval")
fn cone_response(lambda_nm: Real, lambda_peak_nm: Real) -> Real
    requires (lambda_nm > 0.0)
    ensures  (0.0 <= result and result <= 1.0)
{
    exp(-((lambda_nm - lambda_peak_nm) * (lambda_nm - lambda_peak_nm))
        / (2.0 * SIGMA_NM * SIGMA_NM))
}
uv_excitation.emlchain 1
module uv_excitation;

// "Nectar guide" excitation in the UV channel — the headline
// signature of bee vision. A typical sunflower has an outer-
// petal reflectance ≈ 0.05 in UV (low) and a centre-disc
// reflectance ≈ 0.30 (high), even though both look uniform
// yellow to us. The ratio is what the bee chases.
const SUNFLOWER_OUTER_UV_REFL:  Real = 0.05
const SUNFLOWER_CENTRE_UV_REFL: Real = 0.30
const SUNFLOWER_OUTER_VIS_REFL: Real = 0.62  // human-yellow
const SUNFLOWER_CENTRE_VIS_REFL:Real = 0.62  // ~same in visible

@verify(lean, theorem = "uv_contrast_exceeds_visible_for_sunflower")
fn uv_to_visible_contrast_ratio() -> Real
    ensures (result > 1.0)
{
    ((SUNFLOWER_CENTRE_UV_REFL - SUNFLOWER_OUTER_UV_REFL) /
     (SUNFLOWER_OUTER_UV_REFL + 0.001))
    /
    ((SUNFLOWER_CENTRE_VIS_REFL - SUNFLOWER_OUTER_VIS_REFL + 0.001) /
     (SUNFLOWER_OUTER_VIS_REFL + 0.001))
}
opponent_color.emlchain 1
module opponent_color;

// Bee colour vision is opponent — a UV-vs-Blue+Green axis and a
// Blue-vs-Green axis come out of three cone responses, just as
// human L-M and S-(L+M) do for our three cones. The math is
// identical; only the cone peaks change.
@verify(lean, theorem = "opponent_uv_bg_in_signed_unit_interval")
fn opponent_uv_bg(uv: Real, blue: Real, green: Real) -> Real
    requires (0.0 <= uv and uv <= 1.0 and
              0.0 <= blue and blue <= 1.0 and
              0.0 <= green and green <= 1.0)
    ensures  (-1.0 <= result and result <= 1.0)
{
    clamp(uv - 0.5 * (blue + green), -1.0, 1.0)
}

@verify(lean, theorem = "opponent_b_g_in_signed_unit_interval")
fn opponent_b_g(blue: Real, green: Real) -> Real
    requires (0.0 <= blue and blue <= 1.0 and
              0.0 <= green and green <= 1.0)
    ensures  (-1.0 <= result and result <= 1.0)
{
    clamp(blue - green, -1.0, 1.0)
}
bee_color_chromaticity.emlchain 1
module bee_color_chromaticity;

// Position on the bee's chromaticity diagram. A flower's (x, y)
// is its (opponent_uv_bg, opponent_b_g) coordinate; nearby
// points = colours the bee struggles to distinguish. The
// "perceptual distance" between two flowers is just Euclidean
// in this space.
@verify(lean, theorem = "perceptual_distance_nonneg")
fn perceptual_distance(x1: Real, y1: Real, x2: Real, y2: Real) -> Real
    ensures (result >= 0.0)
{
    sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))
}

Same EML pipeline. Different sense.

Eight more cross-species sensor models live alongside this one — bat sonar, owl 3D hearing, pit-viper infrared, dog olfaction, pigeon magnetoreception, shark electric sense, mantis shrimp 16-channel hyperspectral, spider web vibration.

See all nine senses →