(* %use "Distributions/implode_shape.fsh" ;; *) (* implode_shape : [a] -> [a] converts multi-dimensional arrays into 1d arrays - not to be confused with implode_type : [[a]] -> [a] *) %use "BMF/scan.fsh" ;; let entry_offset = (scan_back times_int 1) . shape2array ;; let implode_shape_pr (ys: var b) (xs: var a) = new offset = entry_offset #xs and #k = int_shape in let pr k ndx x = (k := inner_product_int !offset !ndx ; ys[k] := x) in idoall (pr k) xs end ;; let implode_shape_sh x = succdim (number_of_entries x) (zerodim (zeroShape x)) ;; let implode_shape = proc2fun implode_shape_pr implode_shape_sh ;; (* explode_shape : #[a] -> [a] -> [a] is a partial inverse to implode_shape. it takes the shape of the result, and some inputs, and pours them into the desired shape. *) let fillup_pr sh y (x:var a) = let pr k (ndxi:var [int]) yi = (k := inner_product_int (entry_offset sh) ndxi ; yi := x[k]) in new #k = int_shape in idoall (pr k) y end ;; let fillup sh = proc2fun (fillup_pr sh) (fst sh) ;; let explode_shape sh x = fillup sh (implode_shape x) ;; (* Note: this is rather inefficient, due to the presence of an intermediate data structure. See the incomplete file pour.fsh *)