fact: Fixpoint Smith {m n} : 'M[R]_(m,n) -> 'M[R]_(m) * seq R * 'M[R]_(n) := match m, n return 'M[R]_(m, n) -> 'M[R]_(m) * seq R * 'M[R]_(n) with | _.+1, _.+1 => fun M : 'M[R]_(1 + _, 1 + _) => if find_pivot M is Some (i, j) then let a := fun_of_matrix M i j in let A := xrow i 0 (xcol j 0 M) in let: (P,A,Q) := improve_pivot A in let a := fun_of_matrix A 0 0 in let u := dlsubmx A in let v := ursubmx A in let v' := map_mx (fun x => odflt 0 (x %/? a)) v in let A := ((drsubmx A) - (const_mx 1 *m v)) in let: (P', d, Q') := Smith (map_mx (fun x => odflt 0 (x %/? a)) A) in ((lift0_mx P' *m block_mx 1%:M 0 (- const_mx 1) 1%:M *m (xcol i 0 P)), a :: [seq x * a | x <- d], (xrow j 0 Q *m block_mx 1 (- v') 0 1%:M *m lift0_mx Q')) else (1, [::], 1) | _, _ => fun M => (1%:M, [::], 1%:M) end.
imports: HB(structures) mathcomp(ssreflect ssrfun ssrbool eqtype ssrnat div seq path) mathcomp(ssralg ssrint ssrnum fintype choice) mathcomp(matrix mxalgebra bigop zmodp perm) dvdring mxstructure stronglydiscrete coherent edr