Library PrimeGapS1.IntMat
From Stdlib Require Import ZArith List.
Import ListNotations.
Open Scope Z_scope.
A matrix is its row-major nested list representation. No
well-formedness invariant is enforced; the correctness lemmas
(proved elsewhere) will assume squareness.
`nth_Z xs i` returns the i-th element of a `list Z`, or 0 if
the index is out of range.
Definition nth_Z (xs : list Z) (i : nat) : Z := nth i xs 0%Z.
Definition mat_get (m : mat) (i j : nat) : Z :=
nth_Z (nth i m nil) j.
Definition mat_get (m : mat) (i j : nat) : Z :=
nth_Z (nth i m nil) j.
`zrow n` is a list of n zeros.
Fixpoint zrow (n : nat) : list Z :=
match n with
| O ⇒ nil
| S k ⇒ 0%Z :: zrow k
end.
Fixpoint mzero_aux (rows : nat) (cols : nat) : mat :=
match rows with
| O ⇒ nil
| S k ⇒ zrow cols :: mzero_aux k cols
end.
match n with
| O ⇒ nil
| S k ⇒ 0%Z :: zrow k
end.
Fixpoint mzero_aux (rows : nat) (cols : nat) : mat :=
match rows with
| O ⇒ nil
| S k ⇒ zrow cols :: mzero_aux k cols
end.
`mzero n` is the n x n zero matrix.
`eye_row n i` is the i-th row of the n x n identity matrix:
a length-n list with 1 in position i and 0 elsewhere.
Fixpoint eye_row (n : nat) (i : nat) : list Z :=
match n with
| O ⇒ nil
| S k ⇒
match i with
| O ⇒ 1%Z :: zrow k
| S i' ⇒ 0%Z :: eye_row k i'
end
end.
Fixpoint meye_aux (n : nat) (i : nat) : mat :=
match i with
| O ⇒ nil
| S k ⇒ meye_aux n k ++ [eye_row n k]
end.
Definition meye (n : nat) : mat := meye_aux n n.
Fixpoint vadd (xs ys : list Z) : list Z :=
match xs, ys with
| nil, _ ⇒ ys
| _, nil ⇒ xs
| x :: xs', y :: ys' ⇒ (x + y) :: vadd xs' ys'
end.
Definition vscale (c : Z) (xs : list Z) : list Z := map (fun x ⇒ c × x) xs.
Fixpoint madd (A B : mat) : mat :=
match A, B with
| nil, _ ⇒ B
| _, nil ⇒ A
| r1 :: A', r2 :: B' ⇒ vadd r1 r2 :: madd A' B'
end.
Definition mscale (c : Z) (A : mat) : mat := map (vscale c) A.
match n with
| O ⇒ nil
| S k ⇒
match i with
| O ⇒ 1%Z :: zrow k
| S i' ⇒ 0%Z :: eye_row k i'
end
end.
Fixpoint meye_aux (n : nat) (i : nat) : mat :=
match i with
| O ⇒ nil
| S k ⇒ meye_aux n k ++ [eye_row n k]
end.
Definition meye (n : nat) : mat := meye_aux n n.
Fixpoint vadd (xs ys : list Z) : list Z :=
match xs, ys with
| nil, _ ⇒ ys
| _, nil ⇒ xs
| x :: xs', y :: ys' ⇒ (x + y) :: vadd xs' ys'
end.
Definition vscale (c : Z) (xs : list Z) : list Z := map (fun x ⇒ c × x) xs.
Fixpoint madd (A B : mat) : mat :=
match A, B with
| nil, _ ⇒ B
| _, nil ⇒ A
| r1 :: A', r2 :: B' ⇒ vadd r1 r2 :: madd A' B'
end.
Definition mscale (c : Z) (A : mat) : mat := map (vscale c) A.
`heads m` is the list of first elements of each row of m
(empty rows contribute 0).
Fixpoint heads (m : mat) : list Z :=
match m with
| nil ⇒ nil
| row :: rest ⇒
match row with
| nil ⇒ 0%Z :: heads rest
| x :: _ ⇒ x :: heads rest
end
end.
match m with
| nil ⇒ nil
| row :: rest ⇒
match row with
| nil ⇒ 0%Z :: heads rest
| x :: _ ⇒ x :: heads rest
end
end.
`tails m` drops the first element of every row.
Fixpoint tails (m : mat) : list (list Z) :=
match m with
| nil ⇒ nil
| row :: rest ⇒
match row with
| nil ⇒ nil :: tails rest
| _ :: r ⇒ r :: tails rest
end
end.
match m with
| nil ⇒ nil
| row :: rest ⇒
match row with
| nil ⇒ nil :: tails rest
| _ :: r ⇒ r :: tails rest
end
end.
Are all rows empty?
Fixpoint all_empty (m : mat) : bool :=
match m with
| nil ⇒ true
| nil :: rest ⇒ all_empty rest
| _ :: _ ⇒ false
end.
match m with
| nil ⇒ true
| nil :: rest ⇒ all_empty rest
| _ :: _ ⇒ false
end.
Transpose by column count: we must recur on a well-founded metric.
Use the (summed) length of the first row as a fuel; on well-formed
matrices this equals the number of columns.
Fixpoint mtrans_fuel (fuel : nat) (m : mat) : mat :=
match fuel with
| O ⇒ nil
| S k ⇒
if all_empty m then nil
else heads m :: mtrans_fuel k (tails m)
end.
Definition mtrans (m : mat) : mat :=
match m with
| nil ⇒ nil
| row :: _ ⇒ mtrans_fuel (length row) m
end.
Fixpoint dot_int (xs ys : list Z) : Z :=
match xs, ys with
| nil, _ ⇒ 0%Z
| _, nil ⇒ 0%Z
| x :: xs', y :: ys' ⇒ x × y + dot_int xs' ys'
end.
match fuel with
| O ⇒ nil
| S k ⇒
if all_empty m then nil
else heads m :: mtrans_fuel k (tails m)
end.
Definition mtrans (m : mat) : mat :=
match m with
| nil ⇒ nil
| row :: _ ⇒ mtrans_fuel (length row) m
end.
Fixpoint dot_int (xs ys : list Z) : Z :=
match xs, ys with
| nil, _ ⇒ 0%Z
| _, nil ⇒ 0%Z
| x :: xs', y :: ys' ⇒ x × y + dot_int xs' ys'
end.
Matrix product via the transpose-trick formulation: this gives
a clean expression that `vm_compute` reduces efficiently.