kernel-Nat.totient_mul_of_dvd
- Kind
- kernel-term
- Status
- checked
Supports: totient(m*e) = totient(m)*e under e | m, with the whole rendered type pinned.
test "$(cargo run -q -p axeyum-lean-kernel --example nat_theorem_inventory -- totient_mul_of_dvd 2>/dev/null | tr '\t' ' ' | grep -Fc 'Nat.totient_mul_of_dvd 3 ((x0 : AxNat) -> ((x1 : AxNat) -> ((x2 : AxNat.dvd x1 x0) -> Eq.{1} AxNat (AxNat.totient (AxNat.mul x0 x1)) (AxNat.mul (AxNat.totient x0) x1))))')" -ge 1 Evidence notes
The grep pins the WHOLE rendered type, not the name. The kernel re-derives the type from the proof term and so refuses a FALSE theorem, but it cannot notice a statement that is weaker or transposed, and this one has both kinds of neighbour. `nat_theorem_inventory` exits non-zero for a name that does not exist, and `grep -Fc` consumes the whole pipe with the count then tested, rather than `grep -q`, which would SIGPIPE the producer under pipefail. Measured 2026-08-30: `nat_theorem_inventory` consumes only ONE name argument -- given two names in either order it reports on the LAST one only -- so exactly one is passed here. Two neighbours matter specifically here. Transposing the right-hand side to `mul x1 (AxNat.totient x0)` or to `mul (AxNat.totient x1) x0` gives different theorems that agree at many numeral pairs; the factor order is quoted verbatim, and the Rust test asserts `!def_eq` against the transposed form at FREE variables, where the two genuinely separate. Weakening the hypothesis `AxNat.dvd x1 x0` to anything satisfied by more pairs would make the theorem unsound, and it too is quoted verbatim.