4 val make
: int * int * (int * int -> 'entry
) -> 'entry matrix
5 val height
: 'entry matrix
-> int
6 val width
: 'entry matrix
-> int
7 val fetch
: 'entry matrix
* int * int -> 'entry
8 val fetchRow
: 'entry matrix
* int -> int -> 'entry
9 val fetchCol
: 'entry matrix
* int -> int -> 'entry
10 val store
: 'entry matrix
* int * int * 'entry
-> unit
11 val storeRow
: 'entry matrix
* int -> int * 'entry
-> unit
12 val storeCol
: 'entry matrix
* int -> int * 'entry
-> unit
13 val rowSwap
: 'entry matrix
* int * int -> unit
14 val colSwap
: 'entry matrix
* int * int -> unit
15 val rowOp
: 'entry matrix
* int * int * ('entry
* 'entry
-> 'entry
) -> unit
16 val colOp
: 'entry matrix
* int * int * ('entry
* 'entry
-> 'entry
) -> unit
17 val copy
: 'entry matrix
-> 'entry matrix
18 val map
: 'entry1 matrix
* ('entry1
-> 'entry2
) -> 'entry2 matrix
19 val toString
: 'entry matrix
* ('entry
-> string) -> string
22 structure Matrix
:> MATRIX
=
24 type 'entry matrix
= int * int * 'entry array
32 fun make (height
: int, width
: int, generator
: int * int -> 'entry
)
34 if height
< 0 orelse width
< 0
38 Array
.tabulate (height
*width
,
39 fn z
=> generator (z
div width
,
42 fun height (height
, _
, _
) = height
44 fun width (width
, _
, _
) = width
46 fun fetch ((height
, width
, mat
), row
, col
) =
51 then Array
.sub (mat
, col
+ width
*row
)
54 fun fetchRow ((height
, width
, mat
), row
) =
55 if 0 <= row
andalso row
< height
56 then let val offset
= width
* row
58 if 0 <= col
andalso col
< width
59 then Array
.sub (mat
, col
+ offset
)
64 fun fetchCol ((height
, width
, mat
), col
) =
65 if 0 <= col
andalso col
< width
67 if 0 <= row
andalso row
< height
68 then Array
.sub (mat
, col
+ width
*row
)
72 fun store ((height
, width
, mat
), row
, col
, entry
) =
77 then Array
.update (mat
, col
+ width
*row
, entry
)
80 fun storeRow ((height
, width
, mat
), row
) =
81 if 0 <= row
andalso row
< height
82 then let val offset
= width
* row
84 if 0 <= col
andalso col
< width
85 then Array
.update (mat
, col
+ offset
, entry
)
90 fun storeCol ((height
, width
, mat
), col
) =
91 if 0 <= col
andalso col
< width
92 then fn (row
, entry
) =>
93 if 0 <= row
andalso row
< height
94 then Array
.update (mat
, col
+ width
*row
, entry
)
98 fun swapLoop (from1
: int -> 'entry
,
99 to1
: int * 'entry
-> unit
,
100 from2
: int -> 'entry
,
101 to2
: int * 'entry
-> unit
,
103 let fun loop (i
: int): unit
=
106 else let val tmp
= from1 i
114 fun rowSwap (mat
as (height
, width
, _
), row1
, row2
): unit
=
115 if 0 <= row1
andalso row1
< height
116 andalso 0 <= row2
andalso row2
< height
119 else swapLoop (fetchRow (mat
, row1
),
120 storeRow (mat
, row1
),
121 fetchRow (mat
, row2
),
122 storeRow (mat
, row2
),
126 fun colSwap (mat
as (height
, width
, _
), col1
, col2
): unit
=
127 if 0 <= col1
andalso col1
< width
128 andalso 0 <= col2
andalso col2
< width
131 else swapLoop (fetchCol (mat
, col1
),
132 storeCol (mat
, col1
),
133 fetchCol (mat
, col2
),
134 storeCol (mat
, col2
),
138 fun opLoop (from1
: int -> 'entry
,
139 from2
: int -> 'entry
,
140 to2
: int * 'entry
-> unit
,
142 f
: 'entry
* 'entry
-> 'entry
): unit
=
143 let fun loop (i
: int): unit
=
148 f (from1 i
, from2 i
));
153 fun rowOp (mat
as (height
, width
, _
),
156 f
: 'entry
* 'entry
-> 'entry
): unit
=
157 if 0 <= row1
andalso row1
< height
158 andalso 0 <= row2
andalso row2
< height
160 then opLoop (fetchRow (mat
, row1
),
161 fetchRow (mat
, row2
),
162 storeRow (mat
, row2
),
167 fun colOp (mat
as (height
, width
, _
),
170 f
: 'entry
* 'entry
-> 'entry
): unit
=
171 if 0 <= col1
andalso col1
< width
172 andalso 0 <= col2
andalso col2
< width
174 then opLoop (fetchCol (mat
, col1
),
175 fetchCol (mat
, col2
),
176 storeCol (mat
, col2
),
181 fun copy ((height
, width
, mat
)) =
184 Array
.tabulate (Array
.length mat
,
185 fn i
=> Array
.sub (mat
, i
)))
187 fun map ((height
, width
, mat
: 'entry1 Array
.array
),
188 f
: 'entry1
-> 'entry2
)
192 Array
.tabulate (Array
.length mat
,
193 fn i
=> f (Array
.sub (mat
, i
))))
195 (* Natural fold a range
of integers
in reverse
. *)
196 fun naturalFold (limit
: int,
198 folder
: int * 'state
-> 'state
): 'state
=
199 let fun loop (i
: int, state
: 'state
) =
202 else loop (i
- 1, folder (i
- 1, state
))
205 else loop (limit
, state
)
209 local val blank8
= Byte
.charToByte #
" "
211 fun makeBlanks size
=
212 let val blanks
= Word8Vector
.tabulate (size
,
214 in Byte
.bytesToString blanks
217 in fun toString (mat
: 'entry matrix
, f
: 'entry
-> string): string =
218 let val mat
as (height
, width
, _
) = map (mat
, f
)
219 fun maxSize
from (i
, width
) = Int.max (String.size (from i
),
221 fun colWidth col
= naturalFold (height
,
223 maxSize (fetchCol (mat
,
225 val widths
= Vector.tabulate (width
, colWidth
)
226 fun doRow (row
: int, ac
: string list
): string list
=
227 let val from
= fetchRow (mat
, row
)
228 fun loop (col
: int, ac
: string list
) =
229 let val next
= from col
231 val s
= String.size next
232 val pad
= Vector.sub (widths
, col
) - s
235 else (makeBlanks pad
)::ac
244 else loop (width
- 1, ac
)
246 val pieces
= naturalFold (height
,
249 in String.concat pieces
254 val zero
= IntInf
.fromInt
0
256 fun smaller (a
: IntInf
.int, b
: IntInf
.int): bool =
258 andalso (b
= zero
orelse IntInf
.< (IntInf
.abs a
, IntInf
.abs b
))
260 fun smithNormalForm (mat
: IntInf
.int Matrix
.matrix
): IntInf
.int Matrix
.matrix
=
261 let val height
= Matrix
.height mat
262 val width
= Matrix
.width mat
263 val mat
= Matrix
.copy mat
264 val range
= Int.min (width
, height
)
266 let val matCol
= Matrix
.fetchCol (mat
, pos
)
267 val matRow
= Matrix
.fetchRow (mat
, pos
)
268 val _
= print ("dd: pos = " ^
(Int.toString pos
) ^
"\n")
269 fun swapRowLoop (best
, bestRow
, bestCol
, row
) =
271 then (Matrix
.rowSwap (mat
, pos
, bestRow
);
272 Matrix
.colSwap (mat
, pos
, bestCol
))
273 else let val matRow
= Matrix
.fetchRow (mat
, row
)
274 fun swapColLoop (best
, bestRow
, bestCol
, col
) =
276 then swapRowLoop (best
, bestRow
, bestCol
, row
+ 1)
277 else let val next
= matRow col
278 in if smaller (next
, best
)
279 then swapColLoop (next
, row
, col
, col
+ 1)
280 else swapColLoop (best
, bestRow
, bestCol
, col
+ 1)
282 in swapColLoop (best
, bestRow
, bestCol
, pos
)
286 then if (matCol row
) = zero
287 then rowLoop (row
+ 1)
288 else (Matrix
.rowOp (mat
,
291 let val x
= IntInf
.~
(IntInf
.quot(matCol row
, matCol pos
))
292 in fn (lhs
, rhs
) => IntInf
.+ (IntInf
.* (lhs
, x
), rhs
)
294 if (matCol row
) = zero
295 then rowLoop (row
+ 1)
297 else let fun colLoop col
=
299 then if (matRow col
) = zero
300 then colLoop (col
+ 1)
301 else (Matrix
.colOp (mat
,
304 let val x
= IntInf
.~
(IntInf
.quot (matRow col
, matRow pos
))
305 in fn (lhs
, rhs
) => IntInf
.+ (IntInf
.* (lhs
, x
), rhs
)
307 if (matRow col
) = zero
308 then colLoop (col
+ 1)
313 and hitPosAgain () = (swapRowLoop (zero
, pos
, pos
, pos
);
325 val table
= [[ 8, ~
3, 1, 3, 6, 9, ~
2, 4, ~
9, ~
9, 2, 3, 8, ~
1, 3, ~
5, 4, ~
3, ~
5, ~
6, 8, 1, 4, ~
5, 7, ~
4, ~
4, ~
7, 7, 1, 4, ~
3, 8, 4, ~
4, ~
8, 5, ~
9, 3, ~
4, 1, 9, ~
8, ~
6, ~
2, 8, ~
9, ~
5, ~
3, ~
3],
326 [ 0, 8, ~
6, ~
2, ~
3, 4, 5, ~
2, 7, ~
7, ~
6, ~
7, ~
3, ~
4, 9, 7, ~
3, 3, 0, 3, 3, ~
8, ~
8, 2, 3, 8, 3, ~
2, ~
4, 3, ~
6, ~
6, ~
2, 6, 5, ~
1, ~
3, 1, 8, ~
8, 2, 1, ~
7, ~
7, ~
7, ~
3, ~
6, 6, ~
4, ~
9],
327 [ 0, ~
5, 8, ~
9, 2, 4, 2, 7, ~
4, 9, ~
3, 6, ~
2, 3, ~
3, 0, ~
9, 5, 8, ~
1, 2, ~
8, 3, 4, ~
6, 5, ~
6, ~
5, ~
8, 0, ~
5, 3, ~
2, ~
5, 8, 7, ~
1, 1, ~
1, 7, 6, 3, 6, 5, 6, 8, 7, 9, 7, ~
3],
328 [ 5, 4, 7, 2, 3, ~
9, 7, ~
7, 3, ~
8, 7, 5, 5, ~
2, ~
6, ~
3, 6, 5, 3, ~
1, ~
1, 4, 5, ~
5, 5, 9, 9, 3, 8, ~
3, ~
1, 9, ~
9, 6, ~
7, 7, 4, 6, ~
8, ~
9, 0, ~
3, ~
2, ~
7, 1, ~
2, ~
6, 7, 7, 7],
329 [ 2, 9, 9, 3, ~
4, 0, 9, 2, 5, 3, ~
5, ~
3, ~
1, 1, 8, ~
6, 2, ~
4, ~
8, ~
7, ~
8, 4, 5, 8, ~
1, ~
1, 7, 2, 5, 5, ~
4, ~
7, ~
3, ~
7, 6, ~
4, ~
5, ~
8, ~
5, ~
9, ~
8, 5, ~
5, ~
5, 0, 8, 8, 6, 4, ~
1],
330 [ 5, 5, 1, ~
7, 3, ~
5, 4, 9, 3, 4, 4, ~
5, 7, ~
1, 7, 4, ~
7, 7, ~
7, ~
2, 9, ~
9, 0, ~
4, ~
4, 0, 2, 6, 3, ~
1, 6, 6, 8, ~
6, ~
4, ~
9, 3, ~
2, ~
5, 5, ~
3, 2, ~
1, ~
6, 9, 3, ~
3, ~
8, ~
9, 7],
331 [ 7, 1, 2, 7, 6, 5, ~
6, ~
3, ~
4, ~
8, 0, 9, 6, 1, 2, ~
5, 4, 4, 4, ~
6, ~
7, ~
9, ~
6, 2, ~
4, 5, ~
2, 1, 0, 1, ~
8, 7, ~
7, ~
5, 4, 1, ~
5, 4, ~
4, ~
2, ~
3, 1, 1, 3, 4, ~
4, ~
5, 9, 8, ~
2],
332 [ 6, 2, ~
1, ~
8, 4, ~
7, 7, ~
3, ~
2, ~
5, 3, 0, 3, ~
9, 3, 3, 9, ~
1, 4, 8, ~
9, 6, ~
5, 9, 5, ~
1, ~
1, ~
9, 7, ~
2, 3, 9, 8, 9, 2, 7, 7, 6, ~
1, ~
1, ~
2, ~
2, ~
7, 3, ~
6, 0, ~
9, 4, 3, 7],
333 [ 0, ~
6, ~
3, ~
7, ~
1, 5, ~
2, 8, ~
5, ~
3, ~
8, 7, ~
2, ~
2, 0, ~
8, 4, 8, 9, ~
5, ~
4, ~
8, ~
1, 7, 1, 1, 6, ~
9, ~
4, 0, 8, 4, 3, ~
7, 6, 0, 1, 8, 6, ~
1, ~
1, ~
7, 9, ~
9, ~
5, ~
2, ~
2, ~
1, 1, 0],
334 [~
4, 9, 6, ~
3, ~
2, ~
6, ~
3, 4, 8, ~
8, 1, ~
5, 9, 7, 9, 7, ~
9, ~
6, 6, 1, ~
3, 3, ~
3, ~
7, 1, 7, ~
7, 0, ~
2, 7, ~
4, ~
6, 0, 1, ~
3, ~
5, ~
9, ~
7, 8, 4, 9, ~
8, ~
8, ~
7, ~
6, 7, 6, ~
3, ~
8, 5],
335 [ 6, 7, ~
5, ~
9, 6, 1, 8, 4, ~
2, 7, ~
7, ~
1, ~
9, 1, ~
6, ~
5, 4, 9, 6, 0, ~
8, ~
3, 1, ~
3, 8, ~
3, 2, 9, ~
3, ~
9, ~
1, ~
3, 4, 3, 2, ~
9, ~
5, ~
3, 8, ~
4, 8, 5, ~
4, 7, 6, ~
8, 7, 6, ~
5, 5],
336 [ 1, 7, ~
8, ~
9, ~
7, ~
3, 8, 9, ~
7, ~
1, ~
7, 4, 0, 0, 1, ~
5, 9, ~
8, ~
1, ~
2, 3, 5, 9, ~
9, 5, 4, ~
9, 1, ~
4, ~
2, 3, ~
4, 8, ~
6, ~
4, ~
8, ~
5, ~
5, 4, ~
2, ~
4, ~
1, ~
9, ~
5, 2, ~
9, 2, ~
9, ~
2, ~
3],
337 [~
5, ~
4, ~
4, 9, 2, 7, ~
2, 6, 7, 2, ~
9, 4, 2, 7, 8, ~
9, 2, 5, 3, 9, 6, 3, 0, ~
7, ~
6, ~
7, 6, ~
2, 9, ~
3, ~
6, 9, ~
9, 2, 2, ~
6, ~
1, 4, ~
3, 3, 0, 6, ~
3, 4, 9, 9, ~
6, 5, 5, ~
5],
338 [ 5, ~
7, 8, ~
4, 8, 8, ~
4, ~
9, 6, 0, ~
3, 6, 0, 8, 8, ~
6, ~
2, 5, 4, ~
1, ~
8, 1, ~
3, ~
1, 2, 3, ~
9, ~
9, ~
5, 1, 8, ~
5, ~
3, 0, ~
4, ~
9, 0, ~
6, 3, ~
1, ~
7, 0, 8, 9, ~
6, ~
1, ~
9, 1, ~
6, 2],
339 [ 7, ~
5, ~
1, 5, ~
2, 7, 0, ~
7, ~
1, 8, 8, ~
3, 9, ~
5, 7, ~
8, ~
8, ~
4, 3, 2, ~
1, 8, ~
2, 1, 2, 5, 0, ~
6, 7, 3, 3, 7, ~
5, 5, ~
1, 1, 0, ~
8, 1, 0, 0, ~
4, 6, 9, ~
5, ~
6, 3, ~
5, 8, 5],
340 [~
4, ~
2, 3, ~
3, ~
1, 2, ~
2, ~
1, ~
9, ~
5, 1, 0, 0, 2, 9, ~
3, ~
9, 2, 9, 3, 8, ~
3, 4, 8, 8, 3, ~
3, ~
1, ~
4, 4, ~
6, ~
9, 5, ~
2, 1, 3, ~
7, ~
5, ~
6, ~
5, ~
8, 4, ~
8, ~
3, 5, 0, 7, ~
9, 6, 2],
341 [ 5, 1, 4, ~
3, ~
1, ~
9, 5, ~
8, ~
8, 6, 1, 1, ~
2, 7, 5, 6, ~
4, 2, ~
7, 0, ~
7, ~
3, ~
5, 9, 3, 4, ~
6, 8, ~
4, 3, 6, 0, 2, 3, ~
6, 3, 9, 4, 1, ~
4, 6, ~
5, ~
7, 0, ~
1, ~
8, ~
3, ~
9, 9, 7],
342 [ 2, ~
6, ~
1, 8, 4, ~
3, ~
1, ~
6, ~
2, ~
8, ~
2, ~
1, ~
1, ~
5, ~
9, ~
8, 9, ~
9, 5, 1, 9, ~
1, ~
6, 9, ~
7, 2, 8, ~
7, 4, ~
9, 7, 6, ~
2, 1, ~
2, ~
7, 8, 0, 5, 0, ~
5, ~
7, ~
6, 0, 4, 0, 3, ~
8, 5, 4],
343 [~
2, 9, ~
9, ~
6, 1, ~
8, 8, 4, ~
6, 8, 1, ~
3, ~
7, 8, ~
5, 2, ~
8, 1, 3, ~
2, 6, 6, 6, 1, 0, 0, ~
7, 7, ~
3, ~
3, 0, ~
4, 3, ~
7, ~
6, 7, 5, 9, ~
5, 7, ~
8, 2, 3, ~
8, ~
7, 6, ~
5, ~
5, ~
8, ~
9],
344 [~
7, ~
4, 4, 1, ~
1, ~
3, ~
8, 3, 7, 9, 8, 3, 0, 4, 4, ~
1, ~
5, 4, 2, 2, 0, 6, ~
6, 2, ~
9, 8, ~
9, 3, ~
2, 2, 6, 6, 1, 7, 1, 0, ~
8, 2, 3, ~
3, 8, 9, 5, 5, ~
6, 4, ~
7, ~
4, ~
2, ~
3],
345 [~
5, 8, 6, 1, ~
6, ~
6, 6, 1, 1, ~
3, ~
9, ~
6, 2, ~
7, 2, ~
1, 6, ~
6, 0, 2, ~
7, 8, ~
8, 4, 9, ~
3, 9, ~
7, ~
9, ~
6, ~
4, ~
4, ~
5, 8, 2, ~
5, ~
4, ~
3, 5, 2, 1, ~
3, ~
3, ~
7, ~
9, 3, 7, ~
7, 3, ~
8],
346 [~
4, ~
7, ~
2, 2, ~
4, ~
2, 6, ~
3, ~
1, ~
4, 0, ~
5, 9, 7, ~
6, ~
9, 7, ~
9, ~
6, 2, ~
3, 1, 5, ~
9, 4, ~
5, 4, ~
9, 1, ~
2, ~
2, 4, 0, 4, ~
8, ~
8, 3, ~
1, ~
5, ~
4, ~
9, ~
7, 7, 6, 3, ~
9, 6, 4, ~
4, ~
7],
347 [~
9, 6, 6, ~
5, ~
1, ~
7, 4, ~
9, 4, ~
1, 6, ~
4, 7, 2, 8, 7, 3, 1, ~
7, 7, 7, 9, 8, ~
9, 7, 2, 1, 2, ~
8, 4, 5, 6, 7, 2, ~
7, 6, 8, 4, ~
9, 7, ~
5, 6, 9, ~
1, 9, 2, 0, 9, 3, 6],
348 [ 4, ~
3, 8, 0, ~
2, ~
2, 2, ~
3, 8, 3, 1, ~
8, ~
5, ~
2, 5, 6, 8, 0, ~
3, 4, ~
2, 4, ~
9, ~
5, 7, 6, ~
4, ~
7, 2, 4, ~
3, ~
8, ~
9, 9, 8, ~
9, 3, ~
7, 4, ~
7, ~
5, 4, 9, 3, ~
6, ~
3, ~
7, 4, 2, ~
2],
349 [~
8, ~
8, 6, ~
2, ~
6, 8, ~
3, 3, ~
1, ~
7, 1, 9, 1, 7, ~
6, 8, ~
2, ~
9, ~
1, 3, ~
4, 7, 8, ~
1, 9, ~
9, 6, ~
3, 5, 0, 2, 5, ~
1, ~
6, ~
6, 1, 8, 6, ~
3, ~
9, ~
1, 9, ~
2, 9, ~
8, ~
7, ~
3, 6, ~
3, ~
3],
350 [ 5, ~
2, 3, 0, ~
9, ~
8, ~
6, 1, 8, 0, 1, 2, ~
8, ~
2, 0, ~
9, ~
8, 0, 5, ~
3, ~
4, 5, 6, ~
2, ~
5, 0, ~
9, 9, ~
9, ~
5, 9, 9, ~
5, ~
2, 4, 3, 8, ~
8, ~
7, 5, ~
3, ~
2, 2, 3, 9, 7, ~
1, 0, 4, ~
1],
351 [~
4, 5, ~
5, 7, 8, 9, 7, ~
3, 1, 9, ~
7, ~
1, 8, ~
5, ~
1, 2, ~
8, 1, 0, 9, ~
8, ~
1, 6, ~
1, 9, ~
8, 7, 4, ~
8, 7, 0, ~
6, 2, 3, 7, 4, ~
3, ~
5, 9, ~
3, 0, 6, ~
9, 2, 4, ~
8, 6, ~
7, 9, 1],
352 [ 7, 0, ~
9, 6, 8, 2, 2, 5, ~
6, ~
6, 9, ~
5, 9, 2, 2, ~
8, 0, ~
6, ~
9, ~
6, ~
4, ~
9, 8, ~
2, 9, 7, ~
5, ~
1, 7, 2, ~
7, 7, ~
1, ~
3, 6, 6, 1, ~
4, 0, ~
1, ~
6, ~
5, 6, ~
7, ~
3, ~
2, 8, 2, ~
9, 8],
353 [ 8, ~
7, ~
9, ~
6, 9, ~
7, ~
7, 6, ~
8, 9, 5, ~
4, 1, ~
7, ~
8, ~
6, ~
3, 8, ~
8, 1, ~
8, 6, 9, ~
3, ~
7, 7, 1, 6, 1, 0, 8, ~
5, ~
8, 8, ~
9, 0, 4, 4, 3, ~
4, 6, ~
3, ~
9, 0, 4, ~
4, ~
5, ~
9, ~
5, ~
8],
354 [~
3, ~
2, 8, 1, ~
1, ~
1, ~
4, 3, 7, ~
2, ~
9, 9, ~
8, ~
9, 6, ~
4, 7, ~
1, ~
5, ~
3, ~
9, 0, ~
3, 0, 7, 9, 1, ~
2, 7, ~
9, ~
6, 3, 3, ~
4, ~
7, ~
3, ~
4, ~
8, ~
2, ~
3, ~
9, ~
2, ~
6, 3, ~
6, ~
4, 7, ~
5, ~
8, ~
1],
355 [~
9, ~
9, ~
2, ~
9, ~
9, 9, 6, 6, 7, 5, ~
1, ~
2, 1, 5, 2, ~
3, ~
4, 1, ~
6, 0, ~
3, ~
9, ~
1, 7, 0, ~
9, 5, ~
2, ~
2, 5, 3, 4, ~
1, 6, ~
6, 3, ~
6, 7, ~
1, 5, ~
8, ~
4, ~
2, ~
2, ~
6, ~
5, ~
6, 3, ~
1, 4],
356 [ 7, 7, 8, 7, 6, 1, ~
2, 5, ~
6, 9, 4, 8, 5, 0, ~
4, ~
2, ~
2, ~
5, ~
2, ~
6, 9, ~
8, ~
2, ~
5, ~
9, 3, ~
6, ~
3, ~
4, ~
5, ~
2, 6, 1, 6, ~
5, 0, ~
3, ~
2, 4, ~
6, 1, 6, ~
1, 3, ~
9, 2, ~
3, 1, 5, ~
6],
357 [ 6, 4, ~
7, 3, ~
7, 9, 1, ~
7, ~
8, 0, ~
6, 8, 4, 1, 9, 6, 8, 3, 0, 9, 0, 4, 9, ~
7, ~
7, 1, 5, 1, ~
5, 6, 9, 2, 4, 1, ~
9, 8, 4, 5, 8, 3, 2, ~
9, ~
6, ~
9, 9, ~
9, 7, ~
6, ~
4, 3],
358 [~
3, ~
9, ~
4, 2, 3, 9, ~
9, 8, ~
9, 9, ~
4, ~
9, ~
5, 5, 0, 7, 3, ~
5, ~
8, 2, ~
3, 0, ~
9, ~
3, 1, 9, 4, 5, ~
1, 8, 0, ~
4, ~
2, 9, ~
4, ~
1, 3, 5, 9, ~
1, 1, 4, ~
8, ~
2, ~
3, 5, 1, 5, ~
6, 7],
359 [ 9, ~
3, 2, ~
9, 3, 4, 0, 7, ~
5, 9, 0, ~
6, 7, ~
2, 3, ~
7, 2, ~
5, ~
2, 6, 3, ~
9, ~
5, ~
9, 5, 2, ~
5, ~
3, 8, ~
5, 6, 2, 9, ~
7, ~
7, ~
7, ~
6, 9, ~
3, 6, 0, 6, ~
6, ~
9, 4, ~
3, ~
9, 0, ~
4, ~
9],
360 [~
4, ~
8, 8, ~
7, 7, 0, ~
6, ~
6, 8, ~
9, ~
4, 5, ~
3, ~
1, 7, ~
5, ~
6, ~
1, 8, 6, ~
2, 1, ~
1, 5, ~
9, 1, ~
1, ~
7, ~
6, ~
6, ~
6, ~
4, 6, 3, ~
5, ~
5, ~
6, 2, 3, ~
6, ~
8, ~
3, 8, ~
2, ~
5, ~
4, ~
3, 1, 4, ~
4],
361 [ 4, ~
6, 2, 6, 2, ~
8, 8, 5, 8, ~
2, 0, ~
6, ~
1, ~
6, ~
2, 2, 6, ~
9, ~
7, ~
6, ~
4, ~
4, ~
7, ~
2, 8, 6, 3, ~
7, ~
6, 8, 2, 3, 4, 5, 3, 4, ~
6, 8, 8, ~
1, 4, ~
5, 6, 2, 8, ~
3, ~
9, ~
2, 6, 7],
362 [ 3, ~
4, 0, ~
3, ~
5, 0, ~
2, ~
6, ~
2, 8, 5, ~
9, ~
4, ~
8, ~
6, 0, 8, 9, 1, ~
2, 8, 2, ~
2, 8, 9, 3, 3, 5, ~
9, ~
3, ~
2, 7, 2, 9, 0, 4, 8, ~
9, 0, ~
6, 9, ~
9, 9, ~
4, 8, ~
8, ~
8, 2, ~
3, 2],
363 [~
1, 3, ~
9, ~
8, ~
7, 6, ~
6, 3, 0, 5, ~
5, 1, 2, ~
2, ~
3, 7, 7, 3, ~
4, ~
2, ~
9, ~
5, ~
1, 9, 6, 8, 2, 8, 7, ~
3, 4, 6, 6, 0, ~
2, 2, ~
7, ~
7, 6, ~
3, 8, 2, 1, 0, 8, ~
1, 3, 9, 8, 6],
364 [ 1, ~
2, ~
3, 6, 5, 5, ~
6, ~
4, ~
5, 1, 1, 6, ~
7, ~
4, ~
3, 4, 4, ~
8, ~
9, 7, ~
2, ~
3, ~
7, ~
2, 1, 2, 0, 8, ~
6, ~
5, ~
5, 7, 8, 5, ~
2, 3, 9, 0, 5, 1, 3, ~
4, ~
6, 1, 4, ~
9, ~
2, 5, 4, 3],
365 [ 3, 3, 9, ~
2, 6, 9, 4, 9, 4, ~
8, 5, ~
1, 3, ~
2, 1, ~
7, ~
3, 2, 2, 0, ~
3, 3, 8, 2, 0, ~
5, 7, 1, 4, ~
8, 8, ~
9, ~
1, 1, ~
9, ~
4, 5, 2, 2, 8, 6, 1, 6, ~
2, 2, 7, 1, ~
6, ~
1, ~
1],
366 [ 4, ~
2, 4, ~
1, ~
5, ~
1, 5, ~
2, 3, ~
4, ~
5, 0, 2, ~
4, 6, 4, ~
3, 2, 2, 5, ~
6, ~
7, ~
9, ~
1, ~
9, ~
9, 6, 0, 6, 5, 9, ~
1, 3, ~
3, ~
8, 8, ~
8, 8, 4, 5, ~
1, ~
5, 1, 0, 3, ~
2, 5, 6, 6, 5],
367 [~
4, 9, 6, 8, ~
9, 5, 5, ~
3, ~
7, 7, 6, 8, ~
8, 0, 4, ~
1, 9, 5, ~
7, 0, ~
1, ~
2, 3, 6, 0, 4, ~
3, 1, 4, 6, 4, 0, 5, ~
1, 7, ~
7, ~
6, ~
8, ~
3, ~
6, 7, ~
1, ~
3, ~
2, ~
3, ~
5, 3, 1, ~
8, ~
9],
368 [~
6, 4, ~
5, 9, 9, ~
7, ~
1, ~
8, ~
4, 2, ~
6, 0, ~
6, ~
6, 7, 6, 0, 1, 7, ~
7, 0, ~
4, ~
6, ~
8, ~
9, 5, ~
6, ~
9, 2, ~
7, ~
2, ~
6, 9, 4, ~
5, 0, 4, ~
4, ~
5, 6, 9, 1, ~
6, ~
5, 3, ~
1, 7, ~
7, ~
6, 7],
369 [~
8, 7, 7, ~
6, 7, ~
4, 8, 0, ~
9, ~
8, ~
3, 7, ~
3, 3, 8, ~
7, ~
2, ~
7, 5, 5, ~
5, 4, 6, 2, 4, 1, 4, ~
9, ~
3, 8, 8, ~
9, ~
4, ~
2, 1, ~
3, 1, 3, 9, ~
5, ~
8, ~
2, 7, 8, 9, 2, 0, 1, ~
9, 6],
370 [~
7, 1, ~
9, 5, ~
5, ~
5, 7, 6, ~
5, ~
9, ~
6, ~
8, ~
6, 9, 7, 9, 0, ~
5, 7, 7, ~
6, 4, 5, ~
9, ~
1, ~
2, ~
7, 3, ~
5, ~
2, ~
5, 5, ~
3, ~
4, ~
2, ~
8, 2, ~
8, 0, ~
8, 0, ~
8, 9, 8, ~
5, ~
5, 1, 3, 5, ~
4],
371 [~
8, ~
8, 0, ~
5, ~
8, ~
6, 3, ~
6, ~
4, 6, 1, ~
5, ~
6, ~
8, ~
4, ~
6, ~
2, ~
6, 6, ~
4, 8, 8, 4, ~
5, ~
1, 0, 9, ~
8, ~
3, ~
1, ~
8, 7, ~
3, 0, ~
7, 1, ~
7, ~
1, ~
7, 3, ~
7, 3, ~
4, ~
8, 8, ~
7, ~
9, ~
8, 3, 2],
372 [ 3, 6, 8, ~
9, 7, 1, ~
9, 9, 3, 8, 6, 4, ~
2, 1, ~
8, 4, ~
7, ~
4, ~
3, 3, ~
5, ~
6, ~
7, ~
2, 0, ~
4, 5, 2, 5, 6, 3, ~
8, 2, ~
5, ~
7, 6, 8, ~
2, ~
5, ~
4, 9, 9, 2, ~
2, ~
2, 7, 4, 4, ~
2, 3],
373 [ 6, 6, ~
5, ~
2, ~
8, ~
2, ~
9, 0, 2, 4, ~
6, ~
9, 9, 0, ~
8, ~
3, ~
1, ~
2, ~
1, 6, 8, 2, ~
9, 5, ~
2, 1, 7, ~
6, 5, 1, ~
1, 4, ~
4, ~
7, ~
6, ~
3, ~
8, 2, 2, 5, 5, ~
6, 5, 3, 3, 7, 4, 7, ~
3, ~
9],
374 [~
9, 6, ~
4, 1, 3, ~
8, ~
8, ~
8, ~
1, 5, 1, 1, ~
1, 6, 5, 1, ~
1, 5, ~
8, 8, ~
7, ~
5, ~
1, ~
1, 6, ~
8, ~
3, ~
1, ~
2, ~
6, ~
5, ~
5, ~
6, 0, 2, 2, 7, ~
1, ~
5, ~
7, ~
1, ~
3, 7, 6, 0, 2, 4, ~
5, 0, ~
4]]
376 fun f (x
, y
) = List.nth (List.nth (table
, x
), y
)
377 fun show m
= print (Matrix
.toString (m
, IntInf
.toString
))
380 val big
= Matrix
.map (Matrix
.make (dim
, dim
, f
), IntInf
.fromInt
)
383 show (smithNormalForm big
)