(***********************************************************************)
(* *)
(* Applied Type System *)
(* *)
(* Hongwei Xi *)
(* *)
(***********************************************************************)
(*
** ATS - Unleashing the Potential of Types!
**
** Copyright (C) 2002-2009 Hongwei Xi, Boston University
**
** All rights reserved
**
** ATS is free software; you can redistribute it and/or modify it under
** the terms of the GNU LESSER GENERAL PUBLIC LICENSE as published by the
** Free Software Foundation; either version 2.1, or (at your option) any
** later version.
**
** ATS is distributed in the hope that it will be useful, but WITHOUT ANY
** WARRANTY; without even the implied warranty of MERCHANTABILITY or
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
** for more details.
**
** You should have received a copy of the GNU General Public License
** along with ATS; see the file COPYING. If not, please write to the
** Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
** 02110-1301, USA.
*)
(* ****** ****** *)
(* author: Hongwei Xi (hwxi AT cs DOT bu DOT edu) *)
(* ****** ****** *)
#define ATS_DYNLOADFLAG 0 // loaded by [ats_main_prelude]
(* ****** ****** *)
#define i2sz size1_of_int1
(* ****** ****** *)
// matrix0 implementation
(* ****** ****** *)
staload _(*anonymous*) = "prelude/DATS/reference.dats"
(* ****** ****** *)
assume matrix0_viewt0ype_type
(a:viewt@ype) = ref [l:addr] [m,n:nat] [mn:int] (
MUL (m, n, mn), free_gc_v (a, mn, l), @[a][mn] @ l | ptr l, size_t m, size_t n
) // end of [matrix0_viewt0ype_type]
(* ****** ****** *)
implement
matrix0_make_arrsz
{a} {m,n} {mn} (pf_mul | m, n, arrsz) = let
in
ref @(pf_mul, arrsz.0, arrsz.1 | arrsz.2, m, n)
end (* end of [matrix0_make_arrsz] *)
(* ****** ****** *)
implement{a} matrix0_make_elt (row, col, x0) = let
val [m:int] row = size1_of_size (row)
val [n:int] col = size1_of_size (col)
val [mn:int] (pf_mul | asz) = mul2_size1_size1 (row, col)
prval () = mul_nat_nat_nat (pf_mul)
val tsz = sizeof
val (pf_gc, pf_arr | p_arr) = array_ptr_alloc_tsz {a} (asz, tsz)
var ini: a = x0
val () = array_ptr_initialize_elt_tsz {a} (!p_arr, asz, ini, tsz)
in
matrix0_make_arrsz {a} {m,n} {mn} (pf_mul | row, col, @(pf_gc, pf_arr | p_arr, asz))
end // end of [matrix0_make_elt]
(* ****** ****** *)
implement matrix0_row (M) = let
val (vbox pf | p) = ref_get_view_ptr (M) in p->4
end // end of [matrix0_row]
implement matrix0_col (M) = let
val (vbox pf | p) = ref_get_view_ptr (M) in p->5
end // end of [matrix0_col]
(* ****** ****** *)
// this one is proven in [matrix.dats]
extern prfun lemma_for_matrix_subscripting
{m,n:nat} {i:nat | i < m} {mn,p:int}
(pf1: MUL (m, n, mn), pf2: MUL (i, n, p)): [p+n <= mn] void
// end of [lemma_for_matrix_subscripting]
implement{a} matrix0_get_elt_at (M, i, j) = let
val (vbox pf | p) = ref_get_view_ptr (M)
val i = size1_of_size i
val j = size1_of_size j
val p_data = p->3; val row = p->4 and col = p->5
in
if i < row then (
if j < col then let
prval pf_data = p->2
val (pf_mul | icol) = mul2_size1_size1 (i, col)
prval () = lemma_for_matrix_subscripting (p->0, pf_mul)
prval () = mul_nat_nat_nat (pf_mul)
val x = p_data->[icol + j]
prval () = p->2 := pf_data
in
x // return value
end else // out-of-col
$raise MatrixSubscriptException ()
// end of [if]
) else (
$raise MatrixSubscriptException () // out-of-row
) // end of [if]
end (* end of [matrix0_get_elt_at] *)
implement{a} matrix0_set_elt_at (M, i, j, x) = let
val (vbox pf | p) = ref_get_view_ptr (M)
val i = size1_of_size i
val j = size1_of_size j
val p_data = p->3; val row = p->4 and col = p->5
in
if i < row then (
if j < col then let
prval pf_data = p->2
val (pf_mul | icol) = mul2_size1_size1 (i, col)
prval () = lemma_for_matrix_subscripting (p->0, pf_mul)
prval () = mul_nat_nat_nat (pf_mul)
val () = p_data->[icol + j] := x
prval () = p->2 := pf_data
in
// nothing
end else // out-of-col
$raise MatrixSubscriptException ()
// end of [if]
) else (
$raise MatrixSubscriptException () // out-of-row
) // end of [if]
end (* end of [matrix0_set_elt_at] *)
(* ****** ****** *)
implement{a}
matrix0_get_elt_at__intsz (A, i, j) = let
val i = int1_of_int i and j = int1_of_int j in
if i >= 0 then (
if j >= 0 then (
matrix0_get_elt_at (A, i2sz i, i2sz j)
) else (
$raise MatrixSubscriptException ()
) // end of [if]
) else (
$raise MatrixSubscriptException () // out-of-row
) // end of [if]
end (* end of [matrix0_get_elt_at__intsz] *)
implement{a}
matrix0_set_elt_at__intsz (A, i, j, x) = let
val i = int1_of_int i and j = int1_of_int j in
if i >= 0 then (
if j >= 0 then (
matrix0_set_elt_at (A, i2sz i, i2sz j, x)
) else (
$raise MatrixSubscriptException ()
) // end of [if]
) else (
$raise MatrixSubscriptException () // out-of-row
) // end of [if]
end (* end of [matrix0_set_elt_at__intsz] *)
(* ****** ****** *)
implement{a} matrix0_foreach (M, f) = let
fun loop {k:nat} {l:addr} .. (
pf: !array_v (a, k, l)
| p: ptr l, k: size_t k, f: (&a) - void
) :<> void =
if k > 0 then let
prval (pf1, pf2) = array_v_uncons {a} (pf)
val () = f (!p)
val () = loop (pf2 | p+sizeof, k-1, f)
in
pf := array_v_cons {a} (pf1, pf2)
end // end of [if]
// end of [loop]
val (vbox pf | p) = ref_get_view_ptr (M)
val m = p->4 and n = p->5
val (pf_mn | mn) = mul2_size1_size1 (m, n)
prval () = mul_nat_nat_nat (pf_mn)
prval () = mul_isfun (pf_mn, p->0)
in
loop (p->2 | p->3, mn, f)
end // end of [matrix0_foreach]
(* ****** ****** *)
implement{a} matrix0_iforeach (M, f) = let
fun loop {k:nat} {l:addr} .. (
pf: !array_v (a, k, l)
| p: ptr l, k: size_t k
, i: size_t, n: size_t, j: size_t
, f: (size_t, size_t, &a) - void
) :<> void =
if k > 0 then let
prval (pf1, pf2) = array_v_uncons {a} (pf)
val () = f (i, j, !p)
val j1 = j+1
val () = (if j1 < n
then loop (pf2 | p+sizeof, k-1, i, n, j1, f)
else loop (pf2 | p+sizeof, k-1, i+1, n, 0, f)
) : void
in
pf := array_v_cons {a} (pf1, pf2)
end // end of [if]
// end of [loop]
val (vbox pf | p) = ref_get_view_ptr (M)
val m = p->4 and n = p->5
val (pf_mn | mn) = mul2_size1_size1 (m, n)
prval () = mul_nat_nat_nat (pf_mn)
prval () = mul_isfun (pf_mn, p->0)
in
loop (p->2 | p->3, mn, 0, n, 0, f)
end // end of [matrix0_iforeach]
(* ****** ****** *)
implement{a} matrix0_tabulate (row, col, f) = let
val [m:int] m = size1_of_size row
val [n:int] n = size1_of_size col
val [mn:int] (pf_mn | mn) = mul2_size1_size1 (m, n)
prval () = mul_nat_nat_nat (pf_mn)
val (pf_gc, pf_arr | p_arr) = array_ptr_alloc_tsz {a} (mn, sizeof)
fun loop {k:nat} {l:addr} .. (
pf: !array_v (a?, k, l) >> array_v (a, k, l)
| p: ptr l, k: size_t k
, i: size_t, n: size_t n, j: size_t, f: (size_t, size_t) - a
) :<> void =
if k > 0 then let
prval (pf1, pf2) = array_v_uncons {a?} (pf)
val () = !p := f (i, j)
val j1 = j+1
in
if j1 < n then let
val () = loop (pf2 | p+sizeof, k-1, i, n, j1, f)
in
pf := array_v_cons {a} (pf1, pf2)
end else let
val () = loop (pf2 | p+sizeof, k-1, i+1, n, 0, f)
in
pf := array_v_cons {a} (pf1, pf2)
end // end of [if]
end else let
prval () = array_v_unnil {a?} (pf)
in
pf := array_v_nil {a} ()
end // end of [if]
// end of [loop]
val () = loop (pf_arr | p_arr, mn, 0, n, 0, f)
in
matrix0_make_arrsz {a} {m,n} {mn} (pf_mn | m, n, @(pf_gc, pf_arr | p_arr, mn))
end // end of [array0_tabulate]
(* ****** ****** *)
// [matrix0.sats] is already loaded by a call to [pervasive_load]
staload _(*anonymous*) = "prelude/SATS/matrix0.sats" // this forces that the static
// loading function for [matrix0.sats] is to be called at run-time
// this is really needed only if some datatypes are declared in [matrix0.sats]
(* ****** ****** *)
(* end of [matrix0.dats] *)