kernel-Int.dvd_mul_split
- Kind
- kernel-term
- Status
- checked
Supports: ∀ {a b c : ℤ}, c ∣ a * b ↔ ∃ c₁ c₂, c₁ ∣ a ∧ c₂ ∣ b ∧ c₁ * c₂ = c
test "$(cargo run -q --release -p axeyum-lean-kernel --example int_theorem_inventory -- dvd_mul_split 2>/dev/null | /usr/bin/grep -cE '^theorem[[:space:]]+Int\.dvd_mul_split[[:space:]]')" -ge 1 Evidence notes
`build_int_prelude` admits `Int.dvd_mul_split` through the trusted `Kernel::add_declaration` gate, which re-checks the proof term against the stated type. New proof, lane int-dvd-mul-split: `int_prelude/dvd_mul_split.rs`, wired in via one `declare_dvd_mul_split` call after `gcd_scaled_mirrors::declare_all` (last in the build, since it needs `gcd.rs`, `ring.rs`'s `Int.mul_eq_zero`, and the whole Nat prelude). NOT named `Int.dvd_mul` for the same reason the Nat mirror isn't (Mathlib's literal name space collision class). None of the three blockers the prior lane's handoff (docs/plan/status/343-dvd-mul-split.md) identified turned out to be needed: no general `Int.gcd_mul_right` was built (the real content routes entirely through `natAbs c`/`natAbs a`/`natAbs b` and the already-proved `Nat.gcd_mul_right`, so the sign of `b` never has to be split on or reconstructed), no new Int-level cancellation lemma was built (the one cancellation is at the Nat level, via `Nat.mul_left_cancel_of_pos`), and `g1 != 0` from `c != 0` needed only `Nat.eq_zero_of_gcd_eq_zero_left` plus a local copy of `ring.rs`'s private `nat_abs_zero_implies_int_zero`. Witnesses `c1 := ofNat(Nat.gcd(natAbs c, natAbs a))`, `c2 := w` (from Int-level `dvd_elim` on `gcd_dvd_left`, so genuinely Int-signed, never reconstructed from a Nat witness after the fact -- the sign-ambiguous route the handoff correctly warned off). The `c=0` case is handled by a direct case split on `a=0 ∨ b=0` (`Int.mul_eq_zero`), matching the Nat proof's own corner. Reverse direction is the same uniform four-factor regrouping the Nat proof uses, built from `Int.mul_assoc`/`Int.mul_comm` since no `Int.mul_left_comm` field exists. `int_theorem_inventory`'s rendered type is `(x0:Int)->(x1:Int)->(x2:Int)->Iff (Int.dvd x0 (Int.mul x1 x2)) (Exists x3, Exists x4, And (Int.dvd x3 x1) (And (Int.dvd x4 x2) (Eq (Int.mul x3 x4) x0)))`, matching this fact's `formal.statement` exactly (x0/x1/x2/x3/x4 = c/a/b/c1/c2). `int_theorem_inventory` exits non-zero for a name that does not exist (verified: `dvd_mul_split_bogus_xyz` -> exit 1, `error: no Int declaration matches ...`), and the anchored `grep -cE` (tested `-ge 1` directly, not piped through `grep -q`) requires the exact name preceded by `theorem` and followed by whitespace -- verified both directions with `/usr/bin/grep` explicitly (positive count 1, bogus-name count 0).