(***********************************************************************) (* *) (* Applied Type System *) (* *) (* Hongwei Xi *) (* *) (***********************************************************************) (* ** ATS - Unleashing the Potential of Types! ** ** Copyright (C) 2002-2008 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) *) (* ****** ****** *) %{^ #include "prelude/CATS/array.cats" %} (* ****** ****** *) #define ATS_DYNLOADFLAG 0 // loaded by [ats_main_prelude] (* ****** ****** *) #define i2sz size1_of_int1 (* ****** ****** *) (* persistent matrices *) (* ****** ****** *) local assume matrix_v (a:viewt@ype, m:int, n:int, l:addr) = [mn:int] (MUL (m, n, mn), array_v (a, mn, l)) // end of [assume] in // in of [local] implement array_v_of_matrix_v (pf_mat) = pf_mat implement matrix_v_of_array_v (pf_mul, pf_arr) = @(pf_mul, pf_arr) end // end of [local] (* ****** ****** *) assume matrix_viewt0ype_int_int_type (a:viewt@ype, m:int, n:int) = [l:addr] @{ data= ptr l, view= vbox (matrix_v (a, m, n, l)) } // end of [matrix_viewt0ype_int_int_type] (* ****** ****** *) extern fun vbox_make_view_ptr_matrix {a:viewt@ype} {m,n:int} {l:addr} (pf: matrix_v (a, m, n, l) | p: ptr l):<> (vbox (matrix_v (a, m, n, l)) | void) = "atspre_vbox_make_view_ptr" // end of [vbox_make_view_ptr_matrix] implement matrix_make_arrsz__main {a} (pf_mul | m, n, arrsz) = let prval () = free_gc_elim {a} (arrsz.0) // return the certificate to GC prval pf_mat = matrix_v_of_array_v (pf_mul, arrsz.1) val (pf_mat_box | ()) = vbox_make_view_ptr_matrix (pf_mat | arrsz.2) in @{ data= arrsz.2, view= pf_mat_box } end // end of [matrix_make_arrsize__main] (* ****** ****** *) implement{a} matrix_make_elt (m, n, x) = let val (pf_mul | mn) = mul2_size1_size1 (m, n) prval () = mul_nat_nat_nat pf_mul val (pf_gc, pf_arr | p_arr) = array_ptr_alloc_tsz {a} (mn, sizeof) // end of [val] prval () = free_gc_elim {a} (pf_gc) // return the certificate val () = array_ptr_initialize_elt (!p_arr, mn, x) prval pf_mat = matrix_v_of_array_v (pf_mul, pf_arr) val (pf_mat_box | ()) = vbox_make_view_ptr_matrix (pf_mat | p_arr) in @{ data= p_arr, view= pf_mat_box } end // end of [matrix_make_elt] (* ****** ****** *) %{^ #define atspre_matrix_szdiv(i, n) (i / n) %} extern fun szdiv {m,n:pos; mn,i:nat | i < mn} (pf: MUL (m, n, mn) | i: size_t i, n: size_t n):<> [d:nat | d < m] size_t d = "#atspre_matrix_szdiv" // macro! // end of [szdiv] (* ****** ****** *) infixl ( * ) szmul2; infixl ( mod ) szmod1 implement matrix_make_fun_tsz__main {a} {v} {vt} {m,n} (pf | m, n, f, tsz, env) = let val [mn:int] (pf_mul | mn) = m szmul2 n prval () = mul_nat_nat_nat pf_mul val (pf_gc, pf_arr | p_arr) = array_ptr_alloc_tsz {a} (mn, tsz) prval () = free_gc_elim {a} (pf_gc) // return the certificate viewtypedef fun_t = (!v | &(a?) >> a, sizeLt m, natLt n, !vt) -<> void var !p_f1 = @lam (pf: !v | i: sizeLt mn, x: &(a?) >> a, env: !vt): void = let val d = szdiv (pf_mul | i, n) and r = i szmod1 n in f (pf | d, r, x, env) end // end of [f1] val () = begin array_ptr_initialize_clo_tsz__main {a} {v} {vt} (pf | !p_arr, mn, !p_f1, tsz, env) end // end of [val] prval pf_mat = matrix_v_of_array_v (pf_mul, pf_arr) val (pf_mat_box | ()) = vbox_make_view_ptr_matrix (pf_mat | p_arr) in @{ data= p_arr, view= pf_mat_box } end // end of [matrix_make_fun_tsz__main] implement matrix_make_fun_tsz {a} {v} {m,n} (pf | m, n, f, tsz) = let typedef fun_t = (!v | sizeLt m, sizeLt n, &(a?) >> a) - void typedef fun1_t = (!v | sizeLt m, sizeLt n, &(a?) >> a, !ptr) - void val f = coerce (f) where { extern castfn coerce (f: fun_t):<> fun1_t } // end of [val] in matrix_make_fun_tsz__main {a} {v} (pf | m, n, f, tsz, null) end // end of [matrix_make_fun_tsz] implement matrix_make_clo_tsz {a} {v} {m,n} (pf1 | m, n, f, tsz) = M where { stavar l_f: addr val p_f: ptr l_f = &f typedef clo_t = (!v | sizeLt m, sizeLt n, &(a?) >> a) - void viewdef V = (v, clo_t @ l_f) fn app ( pf: !V | i: sizeLt m, j: sizeLt n, x: &(a?) >> a, p_f: !ptr l_f ) :<> void = let prval (pf1, pf2) = pf val () = !p_f (pf1 | i, j, x) prval () = pf := (pf1, pf2) in // nothing end // end of [app] prval pf = (pf1, view@ f) val M = matrix_make_fun_tsz__main {a} {V} {ptr l_f} (pf | m, n, app, tsz, p_f) prval () = (pf1 := pf.0; view@ f := pf.1) } // end of [matrix_make_clo_tsz] (* ****** ****** *) 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 = let prval MULind pf11 = pf1 in sif i < m-1 then begin lemma_for_matrix_subscripting (pf11, pf2) end else let // i = m-1 prval () = mul_isfun (pf11, pf2) in // empty end // end of [sif] end // end of [lemma_for_matrix_subscripting] implement{a} matrix_get_elt_at (M, i, n, j) = let prval vbox pf_mat = M.view prval (pf_mul_mn, pf_arr) = array_v_of_matrix_v (pf_mat) val (pf_mul_i_n | i_n) = i szmul2 n prval () = mul_nat_nat_nat pf_mul_i_n prval () = lemma_for_matrix_subscripting (pf_mul_mn, pf_mul_i_n) val M_data = M.data val x = !M_data.[i_n+j] prval () = pf_mat := matrix_v_of_array_v (pf_mul_mn, pf_arr) in x // return value end // end of [matrix_get_elt_at] implement{a} matrix_set_elt_at (M, i, n, j, x) = let prval vbox pf_mat = M.view prval (pf_mul_mn, pf_arr) = array_v_of_matrix_v (pf_mat) val (pf_mul_i_n | i_n) = i szmul2 n prval () = mul_nat_nat_nat pf_mul_i_n prval () = lemma_for_matrix_subscripting (pf_mul_mn, pf_mul_i_n) val M_data = M.data val () = !M_data.[i_n+j] := x prval () = pf_mat := matrix_v_of_array_v (pf_mul_mn, pf_arr) in // empty end // end of [matrix_set_elt_at] (* ****** ****** *) implement{a} matrix_get_elt_at__intsz (M, i, n, j) = let val i = i2sz i; val n = i2sz n; val j = i2sz j in matrix_get_elt_at (M, i, n, j) end // end of [matrix_get_elt_at__intsz] implement{a} matrix_set_elt_at__intsz (M, i, n, j, x) = let val i = i2sz i; val n = i2sz n; val j = i2sz j in matrix_set_elt_at (M, i, n, j, x) end // end of [matrix_set_elt_at__intsz] (* ****** ****** *) implement matrix_ptr_takeout_tsz {a} {m,n} {i,j} {l0} (pf_mat | base, i, n, j, tsz) = let prval (pf_mul_mn, pf_arr) = array_v_of_matrix_v {a} (pf_mat) val (pf_mul_i_n | i_n) = i szmul2 n prval () = mul_nat_nat_nat pf_mul_i_n prval () = lemma_for_matrix_subscripting (pf_mul_mn, pf_mul_i_n) val [l:addr] (pf1, fpf2 | p_ofs) = array_ptr_takeout_tsz {a} (pf_arr | base, i_n + j, tsz) // end of [val] prval fpf2 = llam (pf1: a @ l) = matrix_v_of_array_v (pf_mul_mn, fpf2 pf1) // end of [prval] in (pf1, fpf2 | p_ofs) end // end of [val] (* ****** ****** *) implement{a} matrix_foreach_fun__main {v} {vt} {m,n} (pf | M, f, m, n, env) = let typedef fun_t = (!v | &a, !vt) - void typedef mat_t = matrix (a, m, n) fn* loop1 {i:nat | i <= m} .. ( pf: !v | M: mat_t , f: fun_t, m: size_t m, n: size_t n, i: size_t i , env: !vt ) : void = begin if i < m then loop2 (pf | M, f, m, n, i, 0, env) else () end // end of [loop1] and loop2 {i,j:nat | i < m; j <= n} .. ( pf: !v | M: mat_t , f: fun_t, m: size_t m, n: size_t n, i: size_t i, j: size_t j , env: !vt ) : void = begin if j < n then let val () = () where { prval vbox pf_mat = M.view val (pf1, fpf2 | p_ij) = matrix_ptr_takeout_tsz (pf_mat | M.data, i, n, j, sizeof) val () = f (pf | !p_ij, env) val () = pf_mat := fpf2 (pf1) } // end of [val] in loop2 (pf | M, f, m, n, i, j+1, env) end else begin loop1 (pf | M, f, m, n, i+1, env) end end // end of [loop2] in loop1 (pf | M, f, m, n, 0, env) end // end of [matrix_foreach_fun__main] implement{a} matrix_foreach_fun {v} {m,n} (pf_v | M, f, m, n) = let val f = coerce (f) where { extern castfn coerce (f: (!v | &a) -<> void):<> (!v | &a, !ptr) -<> void } // end of [where] in matrix_foreach_fun__main (pf_v | M, f, m, n, null) end // end of [matrix_foreach_fun] implement{a} matrix_foreach_clo {v} {m,n} (pf_v | M, f, m, n) = let stavar l_f: addr val p_f: ptr l_f = &f typedef clo_t = (!v | &a) - void viewdef V = @(v, clo_t @ l_f) fn app (pf: !V | x: &a, p_f: !ptr l_f):<> void = let prval (pf1, pf2) = pf in !p_f (pf1 | x); pf := @(pf1, pf2) end // end of [app] prval pf = (pf_v, view@ f) val () = matrix_foreach_fun__main {V} {ptr l_f} (pf | M, app, m, n, p_f) prval (pf1, pf2) = pf prval () = (pf_v := pf1; view@ f := pf2) in // empty end // end of [matrix_foreach_clo] implement{a} matrix_foreach_cloref {m,n} (M, f, m, n) = let viewtypedef cloref_t = (&a) - void fn app (pf: !unit_v | x: &a, f: !cloref_t):<> void = f (x) prval pf = unit_v () val () = matrix_foreach_fun__main {unit_v} {cloref_t} (pf | M, app, m, n, f) prval unit_v () = pf in // empty end // end of [matrix_foreach_cloref] (* ****** ****** *) implement{a} matrix_iforeach_fun__main {v} {vt} {m,n} (pf | M, f, m, n, env) = let typedef fun_t = (!v | sizeLt m, sizeLt n, &a, !vt) - void typedef mat_t = matrix (a, m, n) fn* loop1 {i:nat | i <= m} .. (pf: !v | M: mat_t, f: fun_t, m: size_t m, n: size_t n, i: size_t i, env: !vt) : void = begin if i < m then loop2 (pf | M, f, m, n, i, 0, env) else () end // end of [loop1] and loop2 {i,j:nat | i < m; j <= n} .. ( pf: !v | M: mat_t, f: fun_t, m: size_t m, n: size_t n, i: size_t i, j: size_t j, env: !vt ) : void = begin if j < n then let val () = () where { prval vbox pf_mat = M.view val (pf1, fpf2 | p_ij) = matrix_ptr_takeout_tsz (pf_mat | M.data, i, n, j, sizeof) val () = f (pf | i, j, !p_ij, env) val () = pf_mat := fpf2 (pf1) } // end of [val] in loop2 (pf | M, f, m, n, i, j+1, env) end else begin loop1 (pf | M, f, m, n, i+1, env) end end // end of [loop2] in loop1 (pf | M, f, m, n, 0, env) end // end of [matrix_iforeach_fun__main] implement{a} matrix_iforeach_fun {v} {m,n} (pf | M, f, m, n) = let val f = coerce (f) where { extern castfn coerce (f: (!v | sizeLt m, sizeLt n, &a) -<> void):<> (!v | sizeLt m, sizeLt n, &a, !ptr) -<> void } // end of [where] in matrix_iforeach_fun__main (pf | M, f, m, n, null) end // end of [matrix_iforeach_fun] implement{a} matrix_iforeach_clo {v} {m,n} (pf_v | M, f, m, n) = let stavar l_f: addr val p_f: ptr l_f = &f typedef clo_t = (!v | sizeLt m, sizeLt n, &a) - void viewdef V = @(v, clo_t @ l_f) fn app ( pf: !V | i: sizeLt m, j: sizeLt n, x: &a, p_f: !ptr l_f ) :<> void = let prval (pf1, pf2) = pf in !p_f (pf1 | i, j, x); pf := (pf1, pf2) end // end of [app] prval pf = (pf_v, view@ f) val () = matrix_iforeach_fun__main {V} {ptr l_f} (pf | M, app, m, n, p_f) prval (pf1, pf2) = pf prval () = (pf_v := pf1; view@ f := pf2) in // empty end // end of [matrix_iforeach_clo] implement{a} matrix_iforeach_cloref {m,n} (M, f, m, n) = let viewtypedef cloref_t = (sizeLt m, sizeLt n, &a) - void prval pf = unit_v () fn app ( pf: !unit_v | i: sizeLt m, j: sizeLt n, x: &a, f: !cloref_t ) :<> void = begin $effmask_all (f (i, j, x)) end // end of [app] val () = matrix_iforeach_fun__main {unit_v} {cloref_t} (pf | M, app, m, n, f) prval unit_v () = pf in // empty end // end of [matrix_iforeach_cloref] (* ****** ****** *) // [matrix.sats] is already loaded by a call to [pervasive_load] staload _(*anonymous*) = "prelude/SATS/matrix.sats" // this forces that the static // loading function for [matrix.sats] is to be called at run-time // this is really needed only if some datatypes are declared in [matrix.sats] (* ****** ****** *) (* end of [matrix.dats] *)