eml-stdlib 0.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. eml_stdlib/__init__.py +81 -0
  2. eml_stdlib/ballistics/air_density.eml +73 -0
  3. eml_stdlib/ballistics/ballistic_solver.eml +102 -0
  4. eml_stdlib/ballistics/coriolis.eml +60 -0
  5. eml_stdlib/ballistics/drag.eml +44 -0
  6. eml_stdlib/ballistics/gravity.eml +52 -0
  7. eml_stdlib/ballistics/muzzle_velocity.eml +42 -0
  8. eml_stdlib/ballistics/spin_drift.eml +60 -0
  9. eml_stdlib/ballistics/time_of_flight.eml +79 -0
  10. eml_stdlib/ballistics/wind.eml +58 -0
  11. eml_stdlib/biology/abilities/ballistic_armor.eml +61 -0
  12. eml_stdlib/biology/abilities/bite_force.eml +48 -0
  13. eml_stdlib/biology/abilities/chromatophore.eml +50 -0
  14. eml_stdlib/biology/abilities/discharge.eml +45 -0
  15. eml_stdlib/biology/abilities/elastic_energy.eml +42 -0
  16. eml_stdlib/biology/abilities/locomotion.eml +50 -0
  17. eml_stdlib/biology/abilities/muscle_power.eml +47 -0
  18. eml_stdlib/biology/abilities/sprint.eml +36 -0
  19. eml_stdlib/biology/abilities/texture_match.eml +49 -0
  20. eml_stdlib/biology/abilities/toxin.eml +44 -0
  21. eml_stdlib/biology/cone_l.eml +36 -0
  22. eml_stdlib/biology/cone_s.eml +32 -0
  23. eml_stdlib/biology/cryptochrome.eml +44 -0
  24. eml_stdlib/biology/geomagnetic_field.eml +32 -0
  25. eml_stdlib/biology/goldman_equation.eml +41 -0
  26. eml_stdlib/biology/hill_equation.eml +65 -0
  27. eml_stdlib/biology/hodgkin_huxley.eml +108 -0
  28. eml_stdlib/biology/michaelis_menten.eml +65 -0
  29. eml_stdlib/biology/plume_diffusion.eml +47 -0
  30. eml_stdlib/biology/receptor_binding.eml +35 -0
  31. eml_stdlib/biology/rod_sensitivity.eml +38 -0
  32. eml_stdlib/biology/tapetum.eml +70 -0
  33. eml_stdlib/carriers/acoustic_cloak.eml +56 -0
  34. eml_stdlib/carriers/ferron_emission.eml +55 -0
  35. eml_stdlib/carriers/ferron_logic.eml +45 -0
  36. eml_stdlib/carriers/ferron_propagation.eml +69 -0
  37. eml_stdlib/carriers/mach_zehnder.eml +52 -0
  38. eml_stdlib/carriers/magnon_dispersion.eml +57 -0
  39. eml_stdlib/carriers/magnon_logic.eml +45 -0
  40. eml_stdlib/carriers/optical_neuron.eml +55 -0
  41. eml_stdlib/carriers/phonon_bandgap.eml +54 -0
  42. eml_stdlib/carriers/ring_resonator.eml +48 -0
  43. eml_stdlib/carriers/spin_torque.eml +61 -0
  44. eml_stdlib/carriers/thermal_rectifier.eml +63 -0
  45. eml_stdlib/catalog.json +4209 -0
  46. eml_stdlib/circuits/buck_converter.eml +74 -0
  47. eml_stdlib/circuits/cmos_inverter.eml +75 -0
  48. eml_stdlib/circuits/h_bridge.eml +69 -0
  49. eml_stdlib/circuits/ldo.eml +66 -0
  50. eml_stdlib/circuits/mosfet_iv.eml +59 -0
  51. eml_stdlib/circuits/pll_loop.eml +63 -0
  52. eml_stdlib/circuits/rc_filter.eml +98 -0
  53. eml_stdlib/circuits/voltage_divider.eml +68 -0
  54. eml_stdlib/control/bangbang.eml +34 -0
  55. eml_stdlib/control/deadband.eml +28 -0
  56. eml_stdlib/control/hysteresis.eml +28 -0
  57. eml_stdlib/control/kalman_1d.eml +53 -0
  58. eml_stdlib/control/lqr_1d.eml +47 -0
  59. eml_stdlib/control/pid.eml +38 -0
  60. eml_stdlib/gaming/animation/bounce.eml +39 -0
  61. eml_stdlib/gaming/animation/ease_in.eml +27 -0
  62. eml_stdlib/gaming/animation/ease_in_out.eml +29 -0
  63. eml_stdlib/gaming/animation/ease_out.eml +27 -0
  64. eml_stdlib/gaming/animation/ik_2bone.eml +57 -0
  65. eml_stdlib/gaming/animation/spring.eml +39 -0
  66. eml_stdlib/gaming/audio/distance_attenuation.eml +50 -0
  67. eml_stdlib/gaming/audio/doppler.eml +39 -0
  68. eml_stdlib/gaming/audio/lowpass_audio.eml +32 -0
  69. eml_stdlib/gaming/audio/reverb_delay.eml +41 -0
  70. eml_stdlib/gaming/camera/dof_blur.eml +30 -0
  71. eml_stdlib/gaming/camera/fov_projection.eml +47 -0
  72. eml_stdlib/gaming/camera/orbit.eml +48 -0
  73. eml_stdlib/gaming/camera/shake.eml +20 -0
  74. eml_stdlib/gaming/lighting/ambient_occlusion.eml +40 -0
  75. eml_stdlib/gaming/lighting/area_light.eml +50 -0
  76. eml_stdlib/gaming/lighting/fog_exp.eml +28 -0
  77. eml_stdlib/gaming/lighting/fog_exp2.eml +30 -0
  78. eml_stdlib/gaming/lighting/point_light.eml +33 -0
  79. eml_stdlib/gaming/lighting/spot_light.eml +43 -0
  80. eml_stdlib/gaming/noise/fbm.eml +65 -0
  81. eml_stdlib/gaming/noise/perlin_2d.eml +65 -0
  82. eml_stdlib/gaming/noise/perlin_3d.eml +63 -0
  83. eml_stdlib/gaming/noise/simplex_2d.eml +67 -0
  84. eml_stdlib/gaming/noise/turbulence.eml +46 -0
  85. eml_stdlib/gaming/noise/value_noise.eml +45 -0
  86. eml_stdlib/gaming/noise/voronoi_2d.eml +83 -0
  87. eml_stdlib/gaming/noise/white_noise.eml +47 -0
  88. eml_stdlib/gaming/noise/worley.eml +79 -0
  89. eml_stdlib/gaming/particles/drag.eml +30 -0
  90. eml_stdlib/gaming/particles/emitter_radial.eml +35 -0
  91. eml_stdlib/gaming/particles/fade.eml +36 -0
  92. eml_stdlib/gaming/particles/gravity_particle.eml +32 -0
  93. eml_stdlib/gaming/particles/size_over_life.eml +28 -0
  94. eml_stdlib/gaming/physics/aabb_overlap.eml +38 -0
  95. eml_stdlib/gaming/physics/buoyancy.eml +43 -0
  96. eml_stdlib/gaming/physics/circle_collision.eml +46 -0
  97. eml_stdlib/gaming/physics/impulse_resolve.eml +39 -0
  98. eml_stdlib/gaming/physics/rigid_body_2d.eml +61 -0
  99. eml_stdlib/gaming/physics/spring_damper.eml +30 -0
  100. eml_stdlib/gaming/physics/verlet.eml +29 -0
  101. eml_stdlib/gaming/shading/fresnel.eml +57 -0
  102. eml_stdlib/gaming/shading/matcap.eml +34 -0
  103. eml_stdlib/gaming/shading/pbr_diffuse.eml +41 -0
  104. eml_stdlib/gaming/shading/pbr_specular.eml +75 -0
  105. eml_stdlib/gaming/shading/subsurface.eml +52 -0
  106. eml_stdlib/gaming/shading/toon.eml +30 -0
  107. eml_stdlib/gaming/terrain/biome_select.eml +41 -0
  108. eml_stdlib/gaming/terrain/cliff_detect.eml +35 -0
  109. eml_stdlib/gaming/terrain/erosion_hydraulic.eml +57 -0
  110. eml_stdlib/gaming/terrain/erosion_thermal.eml +44 -0
  111. eml_stdlib/gaming/terrain/heightmap.eml +33 -0
  112. eml_stdlib/gaming/textures/brick.eml +27 -0
  113. eml_stdlib/gaming/textures/caustics.eml +25 -0
  114. eml_stdlib/gaming/textures/checkerboard.eml +27 -0
  115. eml_stdlib/gaming/textures/fire.eml +26 -0
  116. eml_stdlib/gaming/textures/marble.eml +24 -0
  117. eml_stdlib/gaming/textures/rust.eml +23 -0
  118. eml_stdlib/gaming/textures/water_surface.eml +49 -0
  119. eml_stdlib/gaming/textures/wood.eml +41 -0
  120. eml_stdlib/math/abs.eml +45 -0
  121. eml_stdlib/math/atan.eml +32 -0
  122. eml_stdlib/math/atan2.eml +61 -0
  123. eml_stdlib/math/bessel_j0.eml +65 -0
  124. eml_stdlib/math/cos.eml +42 -0
  125. eml_stdlib/math/cosh.eml +24 -0
  126. eml_stdlib/math/erf.eml +66 -0
  127. eml_stdlib/math/exp.eml +49 -0
  128. eml_stdlib/math/gamma.eml +55 -0
  129. eml_stdlib/math/gaussian.eml +18 -0
  130. eml_stdlib/math/log.eml +59 -0
  131. eml_stdlib/math/pow.eml +51 -0
  132. eml_stdlib/math/relu.eml +63 -0
  133. eml_stdlib/math/sigmoid.eml +21 -0
  134. eml_stdlib/math/sin.eml +37 -0
  135. eml_stdlib/math/sinh.eml +24 -0
  136. eml_stdlib/math/softmax.eml +87 -0
  137. eml_stdlib/math/sqrt.eml +46 -0
  138. eml_stdlib/math/tan.eml +36 -0
  139. eml_stdlib/math/tanh.eml +54 -0
  140. eml_stdlib/ml/attention.eml +70 -0
  141. eml_stdlib/ml/cross_entropy.eml +85 -0
  142. eml_stdlib/ml/gelu.eml +51 -0
  143. eml_stdlib/ml/layernorm.eml +49 -0
  144. eml_stdlib/ml/leaky_relu.eml +51 -0
  145. eml_stdlib/ml/relu.eml +63 -0
  146. eml_stdlib/ml/rotary_embed.eml +64 -0
  147. eml_stdlib/ml/silu.eml +40 -0
  148. eml_stdlib/ml/softmax.eml +87 -0
  149. eml_stdlib/physics/coulomb.eml +48 -0
  150. eml_stdlib/physics/damped_oscillator.eml +20 -0
  151. eml_stdlib/physics/diffusion.eml +45 -0
  152. eml_stdlib/physics/gravity.eml +60 -0
  153. eml_stdlib/physics/hooke.eml +56 -0
  154. eml_stdlib/physics/navier_stokes_1d.eml +57 -0
  155. eml_stdlib/physics/planck_radiation.eml +77 -0
  156. eml_stdlib/physics/stefan_boltzmann.eml +75 -0
  157. eml_stdlib/physics/wave_propagation.eml +52 -0
  158. eml_stdlib/quantum/cnot.eml +72 -0
  159. eml_stdlib/quantum/grover_oracle.eml +69 -0
  160. eml_stdlib/quantum/hadamard.eml +73 -0
  161. eml_stdlib/quantum/pauli_x.eml +29 -0
  162. eml_stdlib/quantum/pauli_z.eml +29 -0
  163. eml_stdlib/quantum/phase_gate.eml +76 -0
  164. eml_stdlib/quantum/rotation_rz.eml +92 -0
  165. eml_stdlib/sensors/accelerometer.eml +59 -0
  166. eml_stdlib/sensors/hall_effect.eml +42 -0
  167. eml_stdlib/sensors/photodetector.eml +58 -0
  168. eml_stdlib/sensors/rtd.eml +57 -0
  169. eml_stdlib/sensors/strain_gauge.eml +63 -0
  170. eml_stdlib/sensors/thermistor.eml +71 -0
  171. eml_stdlib/signal/bandpass.eml +39 -0
  172. eml_stdlib/signal/chirp.eml +42 -0
  173. eml_stdlib/signal/dft_single.eml +30 -0
  174. eml_stdlib/signal/fft_butterfly.eml +36 -0
  175. eml_stdlib/signal/highpass.eml +45 -0
  176. eml_stdlib/signal/lowpass.eml +49 -0
  177. eml_stdlib/signal/matched_filter.eml +48 -0
  178. eml_stdlib/signal/notch_filter.eml +47 -0
  179. eml_stdlib/signal/window_hamming.eml +47 -0
  180. eml_stdlib/signal/window_hann.eml +50 -0
  181. eml_stdlib-0.4.0.dist-info/METADATA +453 -0
  182. eml_stdlib-0.4.0.dist-info/RECORD +185 -0
  183. eml_stdlib-0.4.0.dist-info/WHEEL +5 -0
  184. eml_stdlib-0.4.0.dist-info/licenses/LICENSE +21 -0
  185. eml_stdlib-0.4.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,61 @@
1
+ // ballistic_armor.eml -- armadillo plate / ballistic vest absorption.
2
+ //
3
+ // Kinetic energy delivered by a bullet:
4
+ // E_k = ½ * m * v²
5
+ //
6
+ // Armour absorbs a fraction of that energy; remaining energy
7
+ // causes wound damage. Chain order 0.
8
+
9
+ module ballistic_armor;
10
+
11
+ @verify(lean, theorem = "kinetic_energy_nonneg")
12
+ fn kinetic_energy(mass_kg: Real, velocity_mps: Real) -> Real
13
+ where chain_order <= 0,
14
+ domain: mass_kg >= 0.0
15
+ ensures (result >= 0.0)
16
+ {
17
+ 0.5 * mass_kg * velocity_mps * velocity_mps
18
+ }
19
+
20
+ // Energy absorbed by armor with given absorption coefficient
21
+ // (dimensionless, [0,1]).
22
+ @verify(lean, theorem = "armor_absorbed_in_band")
23
+ fn energy_absorbed(mass_kg: Real, velocity_mps: Real,
24
+ absorption_coeff: Real) -> Real
25
+ where chain_order <= 0,
26
+ domain: mass_kg >= 0.0
27
+ requires (absorption_coeff >= 0.0)
28
+ requires (absorption_coeff <= 1.0)
29
+ ensures (result >= 0.0)
30
+ {
31
+ let e_k: Real = 0.5 * mass_kg * velocity_mps * velocity_mps;
32
+ e_k * absorption_coeff
33
+ }
34
+
35
+ // Energy that penetrates (delivered to flesh).
36
+ @verify(lean, theorem = "armor_penetrating_energy_nonneg")
37
+ fn energy_penetrating(mass_kg: Real, velocity_mps: Real,
38
+ absorption_coeff: Real) -> Real
39
+ where chain_order <= 0,
40
+ domain: mass_kg >= 0.0
41
+ requires (absorption_coeff >= 0.0)
42
+ requires (absorption_coeff <= 1.0)
43
+ ensures (result >= 0.0)
44
+ {
45
+ let e_k: Real = 0.5 * mass_kg * velocity_mps * velocity_mps;
46
+ e_k * (1.0 - absorption_coeff)
47
+ }
48
+
49
+ // Ricochet probability rises sharply for shallow impact angles.
50
+ // θ_impact = angle between bullet velocity and surface normal.
51
+ // p_ricochet = 1 - cos(θ_impact)^2 for θ in (0, π/2)
52
+ @verify(lean, theorem = "ricochet_probability_in_unit_interval")
53
+ fn ricochet_probability(angle_rad: Real) -> Real
54
+ where chain_order <= 1,
55
+ domain: angle_rad >= 0.0
56
+ ensures (result >= 0.0)
57
+ ensures (result <= 1.0)
58
+ {
59
+ let c: Real = clamp(cos(angle_rad), 0.0, 1.0);
60
+ 1.0 - c * c
61
+ }
@@ -0,0 +1,48 @@
1
+ // bite_force.eml -- jaw-power scaling for the beast's stage attacks.
2
+ //
3
+ // Bite force at the canines:
4
+ //
5
+ // F_bite = k * BSL² * cos(θ_jaw)
6
+ //
7
+ // where BSL is the body's bite-strength linear factor (proxy for
8
+ // mass-and-jaw-leverage compound) and θ_jaw the jaw opening angle.
9
+ // Chain order 1 (cos). Used to compute how many points of damage
10
+ // the beast deals per stage.
11
+
12
+ module bite_force;
13
+
14
+ @verify(lean, theorem = "bite_force_nonneg")
15
+ fn bite_force_n(k: Real, bsl: Real, jaw_angle_rad: Real) -> Real
16
+ where chain_order <= 1,
17
+ domain: k >= 0.0 && bsl >= 0.0
18
+ ensures (result >= 0.0)
19
+ {
20
+ let c: Real = clamp(cos(jaw_angle_rad), 0.0, 1.0);
21
+ k * bsl * bsl * c
22
+ }
23
+
24
+ // Damage delivered per bite, scaling with bite force and a wound
25
+ // constant (HP per Newton, calibrated to game balance).
26
+ @verify(lean, theorem = "bite_damage_nonneg")
27
+ fn damage_per_bite(bite_force_n_in: Real, wound_constant: Real) -> Real
28
+ where chain_order <= 0,
29
+ domain: bite_force_n_in >= 0.0 && wound_constant >= 0.0
30
+ ensures (result >= 0.0)
31
+ {
32
+ bite_force_n_in * wound_constant
33
+ }
34
+
35
+ // Stage-multiplier for the beast's bite, callable from beast_combat.
36
+ // stage 0 (hands): 0.10
37
+ // stage 1 (claws): 0.30
38
+ // stage 2 (bite): 0.60
39
+ // stage 3 (lunge): 0.80
40
+ @verify(lean, theorem = "bite_stage_multiplier_nondecreasing")
41
+ fn stage_multiplier(stage: Real) -> Real
42
+ where chain_order <= 0,
43
+ domain: stage >= 0.0
44
+ ensures (result >= 0.0)
45
+ {
46
+ let s_clamped: Real = clamp(stage, 0.0, 3.0);
47
+ 0.10 + 0.235 * s_clamped + 0.0166 * s_clamped * s_clamped
48
+ }
@@ -0,0 +1,50 @@
1
+ // chromatophore.eml -- gecko / cephalopod camouflage via Bragg reflection.
2
+ //
3
+ // Iridophore stacks reflect a band of wavelengths centred on:
4
+ //
5
+ // λ = 2 * n * d * cos(θ)
6
+ //
7
+ // where n is refractive index, d the lamellar spacing, θ the
8
+ // viewing angle. The chromatophore can dilate/contract d so the
9
+ // reflected band shifts. Chain order 1 (cos).
10
+
11
+ module chromatophore;
12
+
13
+ @verify(lean, theorem = "bragg_wavelength_nonneg")
14
+ fn bragg_wavelength(refractive_index: Real, spacing_nm: Real,
15
+ angle_rad: Real) -> Real
16
+ where chain_order <= 1,
17
+ domain: refractive_index > 0.0 && spacing_nm > 0.0
18
+ ensures (result >= 0.0)
19
+ {
20
+ let cos_t: Real = clamp(cos(angle_rad), 0.0, 1.0);
21
+ 2.0 * refractive_index * spacing_nm * cos_t
22
+ }
23
+
24
+ // Camouflage transparency [0, 1] as a function of motion.
25
+ // Stationary subject: full Bragg-tuned camouflage.
26
+ // Moving subject: temporal mismatch leaks the silhouette.
27
+ // transparency = max_t * exp(-velocity / tau)
28
+ @verify(lean, theorem = "camo_transparency_in_unit_interval")
29
+ fn transparency(max_t: Real, velocity_mps: Real, tau_mps: Real) -> Real
30
+ where chain_order <= 1,
31
+ domain: max_t >= 0.0 && max_t <= 1.0 && tau_mps > 0.0
32
+ requires (velocity_mps >= 0.0)
33
+ ensures (result >= 0.0)
34
+ ensures (result <= 1.0)
35
+ {
36
+ max_t * exp(-velocity_mps / tau_mps)
37
+ }
38
+
39
+ // Detection contrast against the background at distance r.
40
+ // contrast(r, transparency) = (1 - transparency) * base_contrast / r²
41
+ @verify(lean, theorem = "camo_contrast_drops_with_distance")
42
+ fn detection_contrast(transparency: Real, base_contrast: Real, r_m: Real) -> Real
43
+ where chain_order <= 0,
44
+ domain: r_m > 0.0 && base_contrast >= 0.0
45
+ requires (transparency >= 0.0)
46
+ requires (transparency <= 1.0)
47
+ ensures (result >= 0.0)
48
+ {
49
+ (1.0 - transparency) * base_contrast / (r_m * r_m)
50
+ }
@@ -0,0 +1,45 @@
1
+ // discharge.eml -- electric eel discharge waveform.
2
+ //
3
+ // Eel pulse voltage:
4
+ //
5
+ // V(t) = V_peak * exp(-t / τ)
6
+ //
7
+ // where V_peak ≈ 860 V and τ ≈ 2 ms. Chain order 1.
8
+ //
9
+ // Used by the eel ability to compute EMP duration on hunter
10
+ // instruments and stun damage on the beast.
11
+
12
+ module discharge;
13
+
14
+ const V_PEAK_DEFAULT: Real = 860.0 // Volts
15
+ const TAU_DEFAULT: Real = 0.002 // seconds
16
+
17
+ @verify(lean, theorem = "discharge_voltage_nonneg")
18
+ fn voltage(v_peak: Real, tau_s: Real, t_s: Real) -> Real
19
+ where chain_order <= 1,
20
+ domain: v_peak >= 0.0 && tau_s > 0.0 && t_s >= 0.0
21
+ ensures (result >= 0.0)
22
+ {
23
+ v_peak * exp(-t_s / tau_s)
24
+ }
25
+
26
+ // Default-parameters convenience.
27
+ @verify(lean, theorem = "discharge_default_voltage_nonneg")
28
+ fn voltage_default(t_s: Real) -> Real
29
+ where chain_order <= 1,
30
+ domain: t_s >= 0.0
31
+ ensures (result >= 0.0)
32
+ {
33
+ V_PEAK_DEFAULT * exp(-t_s / TAU_DEFAULT)
34
+ }
35
+
36
+ // Energy delivered per pulse (J), assuming constant body resistance.
37
+ // E = V_peak² * τ / (2 * R)
38
+ @verify(lean, theorem = "discharge_energy_nonneg")
39
+ fn pulse_energy(v_peak: Real, tau_s: Real, body_ohm: Real) -> Real
40
+ where chain_order <= 0,
41
+ domain: v_peak >= 0.0 && tau_s >= 0.0 && body_ohm > 0.0
42
+ ensures (result >= 0.0)
43
+ {
44
+ v_peak * v_peak * tau_s / (2.0 * body_ohm)
45
+ }
@@ -0,0 +1,42 @@
1
+ // elastic_energy.eml -- flea-style elastic-jump physics.
2
+ //
3
+ // A flea stores energy in its resilin pad, then releases it
4
+ // instantaneously. Take-off velocity is governed by:
5
+ //
6
+ // v = sqrt(2 * E / m)
7
+ //
8
+ // where E is stored elastic energy (J) and m the body mass (kg).
9
+ // Chain order 1 (sqrt). Used by the beast jump ability.
10
+
11
+ module elastic_energy;
12
+
13
+ @verify(lean, theorem = "elastic_takeoff_velocity_nonneg")
14
+ fn takeoff_velocity(elastic_energy_j: Real, mass_kg: Real) -> Real
15
+ where chain_order <= 1,
16
+ domain: elastic_energy_j >= 0.0 && mass_kg > 0.0
17
+ ensures (result >= 0.0)
18
+ {
19
+ sqrt(2.0 * elastic_energy_j / mass_kg)
20
+ }
21
+
22
+ // Maximum jump height assuming straight-up release, no drag.
23
+ // h = v² / (2g)
24
+ @verify(lean, theorem = "elastic_jump_height_nonneg")
25
+ fn jump_height(elastic_energy_j: Real, mass_kg: Real, g: Real) -> Real
26
+ where chain_order <= 0,
27
+ domain: elastic_energy_j >= 0.0 && mass_kg > 0.0 && g > 0.0
28
+ ensures (result >= 0.0)
29
+ {
30
+ elastic_energy_j / (mass_kg * g)
31
+ }
32
+
33
+ // Range of a 45° elastic launch (no drag, level ground).
34
+ // R = v² / g
35
+ @verify(lean, theorem = "elastic_jump_range_nonneg")
36
+ fn jump_range(elastic_energy_j: Real, mass_kg: Real, g: Real) -> Real
37
+ where chain_order <= 0,
38
+ domain: elastic_energy_j >= 0.0 && mass_kg > 0.0 && g > 0.0
39
+ ensures (result >= 0.0)
40
+ {
41
+ 2.0 * elastic_energy_j / (mass_kg * g)
42
+ }
@@ -0,0 +1,50 @@
1
+ // locomotion.eml -- many-legged speed bonus model (centipede).
2
+ //
3
+ // Stride frequency f * stride length L = ground-speed v.
4
+ // More legs in phase → higher achievable f at the same metabolic
5
+ // cost. Linear surrogate:
6
+ //
7
+ // v(n_legs) = v_base * (1 + α * (n_legs - 2))
8
+ //
9
+ // with α = 0.10 per pair beyond the bipedal baseline; chain 0.
10
+
11
+ module locomotion;
12
+
13
+ const ALPHA_PER_LEG_PAIR: Real = 0.10
14
+ const N_LEGS_BASELINE: Real = 2.0 // bipedal human reference
15
+
16
+ @verify(lean, theorem = "locomotion_speed_grows_with_legs")
17
+ fn ground_speed(v_base: Real, n_legs: Real) -> Real
18
+ where chain_order <= 0,
19
+ domain: v_base >= 0.0 && n_legs >= 0.0
20
+ ensures (result >= 0.0)
21
+ {
22
+ let extra_pairs: Real = clamp((n_legs - N_LEGS_BASELINE) * 0.5, 0.0, 100.0);
23
+ v_base * (1.0 + ALPHA_PER_LEG_PAIR * extra_pairs)
24
+ }
25
+
26
+ // Same expressed as a multiplier on the base speed.
27
+ @verify(lean, theorem = "locomotion_multiplier_geq_one")
28
+ fn speed_multiplier(n_legs: Real) -> Real
29
+ where chain_order <= 0,
30
+ domain: n_legs >= 0.0
31
+ ensures (result >= 1.0)
32
+ {
33
+ let extra_pairs: Real = clamp((n_legs - N_LEGS_BASELINE) * 0.5, 0.0, 100.0);
34
+ 1.0 + ALPHA_PER_LEG_PAIR * extra_pairs
35
+ }
36
+
37
+ // Wall-climbing toggle threshold: enough legs and enough adhesion to
38
+ // support body weight against gravity. Returns 1.0 if climbing is
39
+ // possible, 0.0 otherwise (for clamp-style boolean dispatch).
40
+ @verify(lean, theorem = "wall_climb_threshold_in_zero_one")
41
+ fn wall_climb_capable(n_legs: Real, adhesion_n_per_leg: Real,
42
+ body_weight_n: Real) -> Real
43
+ where chain_order <= 0,
44
+ domain: n_legs >= 0.0 && adhesion_n_per_leg >= 0.0
45
+ ensures (result >= 0.0)
46
+ ensures (result <= 1.0)
47
+ {
48
+ let total_grip: Real = n_legs * adhesion_n_per_leg;
49
+ clamp((total_grip - body_weight_n) * 1.0e6, 0.0, 1.0)
50
+ }
@@ -0,0 +1,47 @@
1
+ // muscle_power.eml -- striated-muscle power-to-mass scaling.
2
+ //
3
+ // Peak power per kg of muscle ~ 250 W/kg in mammals. Power-to-weight
4
+ // scales linearly with mass-fraction of muscle:
5
+ //
6
+ // P_total = P_per_kg * mass_kg * muscle_fraction
7
+ //
8
+ // Chain order 0. Used by beast stage thresholds (each consumed
9
+ // animal adds a small muscle-mass contribution).
10
+
11
+ module muscle_power;
12
+
13
+ const P_PER_KG: Real = 250.0 // W/kg, peak skeletal muscle
14
+
15
+ @verify(lean, theorem = "muscle_power_nonneg")
16
+ fn total_power(mass_kg: Real, muscle_fraction: Real) -> Real
17
+ where chain_order <= 0,
18
+ domain: mass_kg >= 0.0
19
+ requires (muscle_fraction >= 0.0)
20
+ requires (muscle_fraction <= 1.0)
21
+ ensures (result >= 0.0)
22
+ {
23
+ P_PER_KG * mass_kg * muscle_fraction
24
+ }
25
+
26
+ // Power-to-weight ratio (W/kg total body).
27
+ @verify(lean, theorem = "muscle_power_to_weight_nonneg")
28
+ fn power_to_weight(muscle_fraction: Real) -> Real
29
+ where chain_order <= 0
30
+ requires (muscle_fraction >= 0.0)
31
+ requires (muscle_fraction <= 1.0)
32
+ ensures (result >= 0.0)
33
+ {
34
+ P_PER_KG * muscle_fraction
35
+ }
36
+
37
+ // Top-speed proxy: P-to-W against drag = constant gives v ∝ ∛P.
38
+ @verify(lean, theorem = "muscle_topspeed_proxy_nonneg")
39
+ fn top_speed_proxy(muscle_fraction: Real, k_drag_inv_cube: Real) -> Real
40
+ where chain_order <= 1,
41
+ domain: k_drag_inv_cube >= 0.0
42
+ requires (muscle_fraction >= 0.0)
43
+ requires (muscle_fraction <= 1.0)
44
+ ensures (result >= 0.0)
45
+ {
46
+ pow(P_PER_KG * muscle_fraction * k_drag_inv_cube, 0.333333)
47
+ }
@@ -0,0 +1,36 @@
1
+ // sprint.eml -- cheetah-style burst-acceleration model.
2
+ //
3
+ // v(t) = v_max * (1 - exp(-t / τ))
4
+ //
5
+ // Asymptotic approach to peak speed; cheetahs hit ~95% of peak in
6
+ // ~3 s. Chain order 1.
7
+
8
+ module sprint;
9
+
10
+ const V_MAX_CHEETAH: Real = 33.3 // m/s (~120 km/h)
11
+ const TAU_CHEETAH: Real = 1.2 // seconds, time constant
12
+
13
+ @verify(lean, theorem = "sprint_velocity_in_band")
14
+ fn velocity(v_max: Real, tau_s: Real, t_s: Real) -> Real
15
+ where chain_order <= 1,
16
+ domain: v_max >= 0.0 && tau_s > 0.0 && t_s >= 0.0
17
+ ensures (result >= 0.0)
18
+ ensures (result <= v_max)
19
+ {
20
+ v_max * (1.0 - exp(-t_s / tau_s))
21
+ }
22
+
23
+ // Distance covered from cold start at time t.
24
+ // x(t) = v_max * (t - τ * (1 - exp(-t/τ)))
25
+ @verify(lean, theorem = "sprint_distance_nonneg")
26
+ fn distance_covered(v_max: Real, tau_s: Real, t_s: Real) -> Real
27
+ where chain_order <= 1,
28
+ domain: v_max >= 0.0 && tau_s > 0.0 && t_s >= 0.0
29
+ ensures (result >= 0.0)
30
+ {
31
+ v_max * (t_s - tau_s * (1.0 - exp(-t_s / tau_s)))
32
+ }
33
+
34
+ // Burst duration before fatigue kicks in (cheetah ≈ 30 s).
35
+ const BURST_LIMIT_S: Real = 30.0
36
+ const COOLDOWN_S: Real = 30.0
@@ -0,0 +1,49 @@
1
+ // texture_match.eml -- octopus chromatic + textural skin matching.
2
+ //
3
+ // Per-pixel match score between the cephalopod's skin
4
+ // and the surrounding background, integrated over a small patch:
5
+ //
6
+ // match(p) = 1 - sqrt( ( ΔL² + Δa² + Δb² ) / S_max² )
7
+ //
8
+ // where (L, a, b) are perceptual colour coordinates and S_max
9
+ // the worst-case distance. Output ∈ [0, 1].
10
+
11
+ module texture_match;
12
+
13
+ const S_MAX: Real = 256.0 // perceptual distance for 8-bit Lab range
14
+
15
+ @verify(lean, theorem = "texture_match_in_unit_interval")
16
+ fn match_score(d_l: Real, d_a: Real, d_b: Real) -> Real
17
+ where chain_order <= 1
18
+ ensures (result >= 0.0)
19
+ ensures (result <= 1.0)
20
+ {
21
+ let dist: Real = sqrt(d_l * d_l + d_a * d_a + d_b * d_b);
22
+ clamp(1.0 - dist / S_MAX, 0.0, 1.0)
23
+ }
24
+
25
+ // Detection probability at distance r given a match score.
26
+ // p_detect = (1 - match) * (1 / r²) * detector_sensitivity
27
+ @verify(lean, theorem = "texture_detect_in_unit_interval")
28
+ fn detection_probability(match_score: Real, r_m: Real,
29
+ detector_sensitivity: Real) -> Real
30
+ where chain_order <= 0,
31
+ domain: r_m > 0.0 && detector_sensitivity >= 0.0
32
+ requires (match_score >= 0.0)
33
+ requires (match_score <= 1.0)
34
+ ensures (result >= 0.0)
35
+ {
36
+ (1.0 - match_score) * detector_sensitivity / (r_m * r_m)
37
+ }
38
+
39
+ // Ink-cloud blinding decay: visibility recovers exponentially.
40
+ // visibility(t) = 1 - exp(-t / τ)
41
+ @verify(lean, theorem = "ink_recovery_in_unit_interval")
42
+ fn ink_visibility(t_s: Real, tau_s: Real) -> Real
43
+ where chain_order <= 1,
44
+ domain: t_s >= 0.0 && tau_s > 0.0
45
+ ensures (result >= 0.0)
46
+ ensures (result <= 1.0)
47
+ {
48
+ 1.0 - exp(-t_s / tau_s)
49
+ }
@@ -0,0 +1,44 @@
1
+ // toxin.eml -- viper-bite damage-over-time model.
2
+ //
3
+ // Toxin concentration in the bloodstream follows first-order
4
+ // exponential clearance:
5
+ //
6
+ // C(t) = C_0 * exp(-k * t)
7
+ //
8
+ // Damage rate is proportional to concentration above the LD50
9
+ // threshold; integral over the wound's active window yields total
10
+ // damage. Chain order 1.
11
+
12
+ module toxin;
13
+
14
+ @verify(lean, theorem = "toxin_concentration_nonneg")
15
+ fn concentration(dose: Real, k_clearance: Real, t_seconds: Real) -> Real
16
+ where chain_order <= 1,
17
+ domain: dose >= 0.0 && k_clearance >= 0.0 && t_seconds >= 0.0
18
+ ensures (result >= 0.0)
19
+ {
20
+ dose * exp(-k_clearance * t_seconds)
21
+ }
22
+
23
+ // Instantaneous damage rate (HP per second).
24
+ @verify(lean, theorem = "toxin_damage_rate_nonneg")
25
+ fn damage_rate(dose: Real, k_clearance: Real, t_seconds: Real,
26
+ toxicity: Real) -> Real
27
+ where chain_order <= 1,
28
+ domain: dose >= 0.0 && k_clearance >= 0.0 && t_seconds >= 0.0 && toxicity >= 0.0
29
+ ensures (result >= 0.0)
30
+ {
31
+ toxicity * dose * exp(-k_clearance * t_seconds)
32
+ }
33
+
34
+ // Total damage integrated from t=0 to t=T.
35
+ // D = (toxicity * dose / k) * (1 - exp(-k*T))
36
+ @verify(lean, theorem = "toxin_total_damage_nonneg")
37
+ fn total_damage(dose: Real, k_clearance: Real, duration_s: Real,
38
+ toxicity: Real) -> Real
39
+ where chain_order <= 1,
40
+ domain: dose >= 0.0 && k_clearance > 0.0 && duration_s >= 0.0 && toxicity >= 0.0
41
+ ensures (result >= 0.0)
42
+ {
43
+ (toxicity * dose / k_clearance) * (1.0 - exp(-k_clearance * duration_s))
44
+ }
@@ -0,0 +1,36 @@
1
+ // cone_l.eml
2
+ //
3
+ // Feline long-wavelength (L, "green-yellow") cone spectral
4
+ // sensitivity. This is the cone that *almost* sees red — its
5
+ // peak at 554 nm is shifted ~10 nm shorter than the human L
6
+ // cone's 564 nm peak, which is why a red ball looks olive-yellow
7
+ // to a cat: the response in the deep-red region (>600 nm) tails
8
+ // off much faster.
9
+ //
10
+ // Source: Loop et al. (1987) and the Govardovskii et al. (2000)
11
+ // visual-pigment template. λ_peak = 554 nm. σ ≈ 50 nm (FWHM
12
+ // ≈ 118 nm), reflecting the wider long-wavelength tail of L
13
+ // cones — without this the model would render deep red as
14
+ // absolute black instead of the dark olive cats actually see.
15
+ //
16
+ // L(λ) = exp(-((λ - 554)² / (2 · 50²)))
17
+ //
18
+ // This file does NOT define a "red" / M-wavelength cone — cats
19
+ // don't have one, and adding a third cone here would silently
20
+ // turn the model into a trichromat. Postcondition keeps the
21
+ // output bounded.
22
+
23
+ module cone_l;
24
+
25
+ const CONE_L_PEAK_NM: Real = 554.0
26
+ const CONE_L_SIGMA_NM: Real = 50.0
27
+
28
+ @verify(lean, theorem = "cone_l_sensitivity_bounded_unit")
29
+ fn cone_l_sensitivity(wavelength_nm: Real) -> Real
30
+ where chain_order <= 1
31
+ ensures (result >= 0.0)
32
+ ensures (result <= 1.0)
33
+ {
34
+ exp(-((wavelength_nm - CONE_L_PEAK_NM) * (wavelength_nm - CONE_L_PEAK_NM))
35
+ / (2.0 * CONE_L_SIGMA_NM * CONE_L_SIGMA_NM))
36
+ }
@@ -0,0 +1,32 @@
1
+ // cone_s.eml
2
+ //
3
+ // Feline short-wavelength (S, "blue") cone spectral sensitivity.
4
+ // Cats are dichromats — only S and L cones, no medium-wavelength
5
+ // "red" cone. The S cone is the cleaner of the two; its peak at
6
+ // 450 nm is well-isolated from the L cone at 554 nm.
7
+ //
8
+ // Source: Loop et al. (1987), "Cone receptor population in the
9
+ // adult cat retina." Peak λ ≈ 450 nm, FWHM ≈ 70 nm → σ ≈ 30 nm
10
+ // (the cone curve is narrower than the rod's because cone opsins
11
+ // have tighter absorption profiles).
12
+ //
13
+ // S(λ) = exp(-((λ - 450)² / (2 · 30²)))
14
+ //
15
+ // Postcondition pins the sensitivity to [0, 1]; values outside
16
+ // would corrupt every downstream channel of the cat-vision
17
+ // transform.
18
+
19
+ module cone_s;
20
+
21
+ const CONE_S_PEAK_NM: Real = 450.0
22
+ const CONE_S_SIGMA_NM: Real = 30.0
23
+
24
+ @verify(lean, theorem = "cone_s_sensitivity_bounded_unit")
25
+ fn cone_s_sensitivity(wavelength_nm: Real) -> Real
26
+ where chain_order <= 1
27
+ ensures (result >= 0.0)
28
+ ensures (result <= 1.0)
29
+ {
30
+ exp(-((wavelength_nm - CONE_S_PEAK_NM) * (wavelength_nm - CONE_S_PEAK_NM))
31
+ / (2.0 * CONE_S_SIGMA_NM * CONE_S_SIGMA_NM))
32
+ }
@@ -0,0 +1,44 @@
1
+ // cryptochrome.eml
2
+ //
3
+ // Cryptochrome radical-pair magnetoreception. Cryptochrome (CRY)
4
+ // is a flavoprotein in the bird retina; absorbing a blue-light
5
+ // photon excites a flavin/tryptophan radical pair whose singlet
6
+ // vs. triplet recombination yield depends on the orientation of
7
+ // the geomagnetic field relative to the molecular axis:
8
+ //
9
+ // Φ(B, θ) = 1/3 + (2/15) · (γ · B · τ)² · (3·cos²(θ) - 1)
10
+ //
11
+ // θ is the angle between the field vector and the radical-pair
12
+ // axis; γ is the gyromagnetic ratio (~28 GHz/T); τ is the
13
+ // recombination lifetime (~µs). The term `3·cos²(θ) - 1` is the
14
+ // signature P₂ Legendre polynomial — the same anisotropy
15
+ // signature seen in NMR and EPR spectra. This is "quantum
16
+ // biology" in the strict sense: the spin-coherence of the
17
+ // radical pair has to outlast environmental decoherence to
18
+ // transmit a usable signal (Hore & Mouritsen 2016).
19
+ //
20
+ // Postcondition: Φ ∈ [0, 1] — it's a quantum yield, a probability.
21
+
22
+ module cryptochrome;
23
+
24
+ const ONE_THIRD: Real = 0.3333333333333333
25
+
26
+ @verify(lean, theorem = "cryptochrome_yield_in_unit_interval")
27
+ fn cryptochrome_yield(
28
+ field_strength_T: Real{b | b >= 0.0},
29
+ angle_rad: Real,
30
+ coupling: Real{c | c >= 0.0},
31
+ ) -> Real{r | 0.0 <= r && r <= 1.0}
32
+ where chain_order <= 1
33
+ {
34
+ // (γ·B·τ)² is bundled into `coupling` for clean units; the
35
+ // model is qualitative, not quantitative, in this file (the
36
+ // exact pre-factor is a tuning parameter for a given CRY
37
+ // isoform). The clamp pins the postcondition.
38
+ clamp(
39
+ ONE_THIRD + (2.0 / 15.0) * coupling
40
+ * (3.0 * cos(angle_rad) * cos(angle_rad) - 1.0),
41
+ 0.0,
42
+ 1.0
43
+ )
44
+ }
@@ -0,0 +1,32 @@
1
+ // geomagnetic_field.eml
2
+ //
3
+ // Earth's magnetic field magnitude as a function of geomagnetic
4
+ // latitude. Modeled as a centered axial dipole — the leading-order
5
+ // approximation that captures ~95 % of the surface field:
6
+ //
7
+ // B(λ) = B_eq · √(1 + 3 · sin²(λ))
8
+ //
9
+ // B_eq ≈ 30 µT at the equator; the field is twice as strong
10
+ // (~60 µT) at the poles where field lines converge. Pigeons
11
+ // navigate using the *magnitude* component of this map for the
12
+ // "map" sense and the inclination angle (separate file) for
13
+ // "compass" — the famous Wiltschko (1972) bicomponent model.
14
+ //
15
+ // Postcondition: B > 0 everywhere on Earth's surface (the dipole
16
+ // has no zeros). The Cryptochrome model downstream takes B as
17
+ // an input and would divide-by-zero on a vanishing field.
18
+
19
+ module geomagnetic_field;
20
+
21
+ const B_EQUATORIAL_T: Real = 3.0e-5 // 30 µT — IGRF equatorial baseline
22
+
23
+ @verify(lean, theorem = "geomagnetic_field_strictly_positive")
24
+ fn geomagnetic_field(latitude_rad: Real)
25
+ -> Real{r | r >= B_EQUATORIAL_T}
26
+ where chain_order <= 1
27
+ {
28
+ // sqrt(1 + 3·sin²) ≥ 1 ⇒ result ≥ B_eq. We use max() as the
29
+ // outer guard so the postcondition is one-line provable.
30
+ max(B_EQUATORIAL_T,
31
+ B_EQUATORIAL_T * sqrt(1.0 + 3.0 * sin(latitude_rad) * sin(latitude_rad)))
32
+ }
@@ -0,0 +1,41 @@
1
+ // goldman_equation.eml -- Goldman-Hodgkin-Katz voltage equation.
2
+ //
3
+ // Resting membrane potential when multiple ions cross a permeable
4
+ // membrane:
5
+ //
6
+ // V_m = (RT / F) * ln( (P_K[K+]_o + P_Na[Na+]_o + P_Cl[Cl-]_i)
7
+ // / (P_K[K+]_i + P_Na[Na+]_i + P_Cl[Cl-]_o) )
8
+ //
9
+ // The single-ion limit collapses to the Nernst equation. Chain
10
+ // order 1.
11
+
12
+ module goldman_equation;
13
+
14
+ const R_GAS: Real = 8.314462618 // J / (mol K)
15
+ const F_FAR: Real = 96485.33212 // C / mol
16
+
17
+ // Three-ion form (K+, Na+, Cl-) at body temperature.
18
+ @verify(lean, theorem = "goldman_voltage_sign_matches_log_argument")
19
+ fn membrane_potential(t_kelvin: Real,
20
+ p_k: Real, k_out: Real, k_in: Real,
21
+ p_na: Real, na_out: Real, na_in: Real,
22
+ p_cl: Real, cl_out: Real, cl_in: Real) -> Real
23
+ where chain_order <= 1,
24
+ domain: t_kelvin > 0.0
25
+ {
26
+ let num = p_k * k_out + p_na * na_out + p_cl * cl_in;
27
+ let den = p_k * k_in + p_na * na_in + p_cl * cl_out;
28
+ (R_GAS * t_kelvin / F_FAR) * ln(num / den)
29
+ }
30
+
31
+ // Nernst equation: single-ion limit.
32
+ @verify(lean, theorem = "nernst_voltage_sign_matches_concentration_ratio")
33
+ fn nernst(t_kelvin: Real, valence: Real, c_out: Real, c_in: Real) -> Real
34
+ where chain_order <= 1,
35
+ domain: t_kelvin > 0.0 && valence != 0.0 && c_in > 0.0
36
+ {
37
+ (R_GAS * t_kelvin / (valence * F_FAR)) * ln(c_out / c_in)
38
+ }
39
+
40
+ // Body-temperature pre-factor RT/F at 37 deg C, in mV.
41
+ const RT_OVER_F_BODY_MV: Real = 26.7148