The comparison-function library, formalized — TARGET 12 of the LeanPunov stream

Seal

Rung class-k · Status sealed · #print axioms for every public declaration reports exactly [propext, Classical.choice, Quot.sound] — no sorryAx (recorded in Verification; stream note: sealed 2026-07-06 ~06:05, build green 2648 jobs). No interface hypotheses. Public structures: IsClassK, IsClassKInfinity, IsClassKL; definition classKInv. Confirmed absent from Mathlib v4.31.0 — upstream candidate.
Links: module index · interface ledger · related lyapunov_comparison, time_varying_comparison · sources panteley1998global, panteley2001growth, khalil1996nonlinear (no wiki page yet)

Sealed theorems

IsClassK.monotoneOn

Strict monotonicity weakened to monotone on the ray.

IsClassK.le_of_le

gives — the sandwich-to-bound step.

IsClassK.lt_of_lt

Strict version.

IsClassK.nonneg

Nonnegativity on the ray is a theorem, not a definition clause.

IsClassK.pos_of_pos

gives .

IsClassK.mapsTo

The ray maps into the ray.

IsClassK.eq_zero_iff

on the ray.

isClassK_id

The identity is class .

IsClassK.const_mul

Positive scalar multiples stay class .

IsClassK.comp

Composition stays class .

IsClassK.add

Sums stay class .

IsClassK.min

Pointwise min stays class .

IsClassK.max

Pointwise max stays class .

isClassKInfinity_id

The identity is class .

IsClassKInfinity.const_mul

Positive scalar multiples stay class .

IsClassKInfinity.comp

Composition stays class .

IsClassKInfinity.surjOn

A class- function covers the whole ray (intermediate value theorem).

IsClassKInfinity.bijOn

A genuine bijection of onto itself.

IsClassKInfinity.classKInv_leftInvOn

on the ray.

IsClassKInfinity.classKInv_rightInvOn

on the ray.

IsClassKInfinity.classKInv_isClassKInfinity

The flagship — the inverse of a class- function is class , continuity via StrictMono.orderIsoOfSurjective.

IsClassKL.nonneg

on the ray.

Why this module, and why now

Every other stone in this stream has been a theorem — a differential inequality, an invariance principle, a passivity identity. This one is different in kind: it is the vocabulary the later stones are written in. The class-, and comparison functions are the alphabet of nonlinear stability. A Lyapunov function is “positive definite and radially unbounded” precisely when it is sandwiched by two class- functions; a system is input-to-state stable (ISS) precisely when its trajectory obeys with of class and of class . The Panteley–Loría cascade theorems that this stream is climbing toward (panteley1998global Assumptions A1–A4, panteley2001growth Assumptions A1.2–A4) state their hypotheses entirely in this language. We cannot formalize those theorems until the alphabet exists.

It does not exist in Mathlib. A search of Mathlib v4.31.0 for any class- / comparison-function development returns nothing — the concept is absent. So this module is, like the house LaSalle layer ((~/Code/vault/lean/lasalle_invariance.md)), a candidate for upstream contribution: a self-contained, axiom-clean development of the comparison-function classes on the reals. The scope here is deliberately broad, not deep — definitions plus a wide base of small structural lemmas — because the substrate’s job is to be reused, not to prove a headline result of its own.

Sources and provenance

The definitions are read verbatim off the rendered sources on disk, not reconstructed from memory.

  • panteley1998global (Panteley & Loría, Syst. Control Lett. 33, 1998), Notation paragraph (p.1): “A continuous function is said to be of class if is strictly increasing and ; if in addition as . A continuous function is of class if for each fixed and as for each .” Note the argument order is with in the second slot.

  • panteley2001growth (Panteley & Loría, Automatica 37, 2001), Notation paragraph (p.3): the identical , ; adds class “continuous, strictly decreasing, — and states in the Khalil argument order : for each fixed and for each .” This is the ordering we formalize, because it is the one the ISS bound uses.

  • Khalil, Nonlinear Systems 3rd ed., §4.4 Definitions 4.2–4.3 — the canonical textbook statement of these classes. Cited by name; the precise section is to be verified when the Khalil OCR lands (the ingest workstation is currently down). Flagged, not fabricated: the two Panteley sources above already pin every clause we formalize, so the definitions stand on rendered provenance regardless.

The two Panteley statements agree on and to the letter and differ only in the cosmetic argument order of . We take the 2001 (Khalil) ordering.

The carrier: ℝ → ℝ with properties on [0,∞)

The paper’s functions live on . There are two honest ways to render "" in Lean: the subtype NNReal, or plain ℝ → ℝ with the defining properties asserted only on the ray Set.Ici 0. We take the second, for three reasons.

  1. It composes with the consumers without friction. The quantities the cascade/ISS rungs feed to a comparison function are and a Lyapunov value — both plain reals. With the ℝ → ℝ carrier, is a bare application; with NNReal it would need a coercion at every use site.
  2. It matches the house idiom. TimeVaryingComparison.lean ((~/Code/vault/lean/time_varying_comparison.md)) already carries its hypotheses as ContinuousOn v (Ici 0). Reusing Ici 0 keeps the stream’s modules speaking one dialect.
  3. Nonnegativity becomes a theorem, not a hypothesis. The paper writes the codomain as , but for a class- function that is derived: and strict monotonicity give for . We prove this as IsClassK.nonneg rather than bolting it onto the definition — one fewer thing to check when building a class- function, and a faithful statement of what the class actually constrains.

Concretely:

structure IsClassK (f : ℝ → ℝ) : Prop where
  continuousOn : ContinuousOn f (Ici 0)
  strictMonoOn : StrictMonoOn f (Ici 0)
  map_zero     : f 0 = 0

structure IsClassKInfinity (f : ℝ → ℝ) : Prop extends IsClassK f where
  tendsto_atTop : Tendsto f atTop atTop

extends , so every lemma applies to a function through the toIsClassK projection, and unboundedness is the single added field. Encoding ” as ” as Tendsto f atTop atTop is exact: the filter atTop on concerns , all of which lie in the ray, so no domain bookkeeping is needed.

The 𝒦ℒ encoding and the r > 0 subtlety

structure IsClassKL (β : ℝ → ℝ → ℝ) : Prop where
  isClassK_fst     : ∀ s, 0 ≤ s → IsClassK (fun r => β r s)
  strictAntiOn_snd : ∀ r, 0 < r → StrictAntiOn (fun s => β r s) (Ici 0)
  tendsto_snd      : ∀ r, 0 < r → Tendsto (fun s => β r s) atTop (𝓝 0)

is class in its first argument (for each fixed ) and class in its second argument (strictly decreasing, tending to ). Class is unbundled into its two defining clauses strictAntiOn_snd and tendsto_snd rather than given its own structure — it never appears on its own in the cascade hypotheses, so a named IsClassL would be an abstraction with one use site.

The one place we depart from the literal text of panteley2001growth is deliberate and is the sort of thing a reviewer must see. The paper writes ” for each ”. But class in the first argument forces for all (that is exactly map_zero of fun r => β r s). So the slice is identically zero — and the zero function is not strictly decreasing. The literal “for each ” is thus vacuously inconsistent at the single point ; the literature glosses this degenerate slice. We pin it honestly by asserting the decreasing clauses for only. This loses nothing a consumer needs — a bound with means the trajectory started at the origin, where the bound is already trivial — and it is the same restriction Khalil’s “for each fixed , is decreasing” is read with in practice.

The lemma base

Twenty small results, each one a manipulation the cascade/ISS proofs will reach for.

Sign and monotonicity of . monotoneOn, le_of_le (), lt_of_lt, nonneg, pos_of_pos, mapsTo (the ray into the ray), eq_zero_iff ( on the ray). The le_of_le shape is exactly the step that turns the sandwich into a bound on once composed with the inverse.

Constructions of . The identity isClassK_id; positive scalar multiples const_mul; composition comp (the MapsTo-guarded StrictMonoOn.comp and ContinuousOn.comp); sums add; and pointwise min / max. Closure under min and max is what lets a proof replace two comparison functions by a single dominating (or dominated) one — the standard “take ” move.

Constructions of . isClassKInfinity_id, const_mul, comp (unboundedness composes via Tendsto.comp).

Bijectivity of the carrier. surjOn shows a function covers the whole ray: continuity plus plus hand the intermediate value theorem (intermediate_value_Ici) every value in . bijOn packages this with injectivity (from StrictMonoOn.injOn) and mapsTo into a genuine bijection of onto itself. This is the ” is invertible” fact in its cleanest form.

Sign of . IsClassKL.nonneg on the ray, immediate from the -slice.

The inverse is class

The flagship. For the inverse is again class — this is what makes the ISS manipulation legitimate. We realize the inverse as classKInv f := Function.invFunOn f (Ici 0), the canonical partial inverse restricted to the ray, and prove:

  • classKInv_leftInvOn / classKInv_rightInvOn — the genuine two-sided inverse relations and on the ray, straight from BijOn.invOn_invFunOn.
  • classKInv_isClassKInfinity — the inverse is class .

The four pieces of the last result:

  • : apply the left-inverse at .
  • strictly increasing: order-reverse. If then applying the monotone and the right-inverse gives , contradicting .
  • unbounded: as soon as , since is monotone and .
  • continuity — the one genuinely analytic step. Rather than fight a hand-rolled inverse-continuity argument, we borrow Mathlib’s order machinery. The restriction of to the subtype is a strictly monotone surjection of onto itself, hence an OrderIso (StrictMono.orderIsoOfSurjective). The subtype is order-connected, so it carries the order topology (orderTopology_of_ordConnected), and an order isomorphism between order-topology spaces is a homeomorphism — its inverse is continuous for free (OrderIso.continuous). A short bridge identifies invFunOn f (Ici 0) on the ray with the underlying map of that homeomorphism’s inverse (both are the -preimage, equal by injectivity of ), and continuousOn_iff_continuous_restrict transports subtype-continuity back to ContinuousOn _ (Ici 0).

That the continuity of the inverse falls out of a Mathlib homeomorphism, with no bespoke analysis, is the payoff of choosing the order-connected ray as the carrier.

What was deliberately left out

  • No stability theorems. This module is pure definitional substrate, by scope. The Lyapunov sandwich, ISS estimate, and the Panteley cascade lemmas that consume these classes are separate targets.
  • No standalone IsClassL structure — unbundled into the two clauses, as it has no independent consumer.
  • No construction lemmas (e.g. the canonical ). is carried as a definition with only the nonneg sanity lemma; its builders can be added the turn an ISS proof first needs one, rather than speculatively now.
  • No abstract-order generalization. Everything is stated on . A general-ordered-field version would be the shape of an actual Mathlib PR; for the stream, is the only carrier the dynamics use.

What the later rungs will consume

  • The Lyapunov sandwich rung will use le_of_le / lt_of_lt and IsClassKInfinity.bijOn + classKInv_rightInvOn to move between and .
  • The ISS rung will use IsClassKL for the transient term and IsClassK.comp / add / max to assemble the gain composition and the of a state and an input gain.
  • The Panteley cascade rung will use IsClassKInfinity for the assumption- bounds (panteley2001growth A1.2) and IsClassK for the interconnection coefficient .

Mathlib substrate used

ContinuousOn.comp, StrictMonoOn.comp (both MapsTo-guarded), StrictMonoOn.monotoneOn, StrictMonoOn.injOn; continuous_min / continuous_max with Continuous.comp_continuousOn and ContinuousOn.prodMk; isPreconnected_Ici with IsPreconnected.intermediate_value_Ici and Ici_mem_atTop for surjectivity; Function.invFunOn with Set.BijOn.invOn_invFunOn and Set.SurjOn.mapsTo_invFunOn; StrictMono.orderIsoOfSurjective with OrderIso.continuous, orderTopology_of_ordConnected, and continuousOn_iff_continuous_restrict for the inverse’s continuity; Filter.Tendsto.const_mul_atTop and tendsto_atTop_atTop.

Verification

Full lake build green. #print axioms for every one of the module’s public declarations (7 lemmas, 6 constructions, 5 results, the classKInv definition, 3 inverse results, IsClassKL.nonneg) reports exactly [propext, Classical.choice, Quot.sound] — no sorryAx, no extra axioms. The Classical.choice dependence enters honestly through invFunOn (a choice-based partial inverse) and the order-topology instances; it is the same trio the rest of the stream stands on.

Lean source beside this document: (~/Code/vault/lean/ComparisonFunctions.lean).