Thanks John,
With the change you suggested it works.
This is how it looks now...
----------------- UMatrix.icl --------------------------------
implementation module UMatrix
import StdArray, StdInt, StdBool, StdMisc, StdList, StdEnum
::UMatrix elemType = { rows :: !Int
, cols :: !Int
, vals :: .({#} elemType)
}
make :: .Int .Int elemType -> .(UMatrix elemType) | Array {#} elemType
make n m v
| n > 0 && m > 0 = { rows = n
, cols = m
, vals = createArray (n*m) v
}
= abort "invalid matrix dimension"
// creates a matrix given an array of values
makeFrom :: .Int .Int u:{#a} -> v:(UMatrix a) | Array {#} a, [u <= v]
makeFrom n m arr
| n * m == size arr = { rows = n
, cols = m
, vals = arr
}
= abort "invalid UMatrix creation"
// exports values from a matrix as array
extract :: u:(UMatrix elemType) -> v:({#} elemType) | Array {#} elemType, [u <=
v]
extract m = m.vals
// adds two matrices and produces a new one
add :: .(UMatrix elemType) (UMatrix elemType) -> .(UMatrix elemType) | Array
{#} elemType & Arith elemType
add m1 m2
| sameSize m1 m2 = { rows = m1.rows
, cols = m1.cols
, vals = resp
}
= abort "Invalid matrix add"
where
l = (size (m2.vals)) - 1
base = createArray l m2.vals.[0]
resp = {base & [i] = m1.vals.[i] + m2.vals.[i] \\ i <- [0 .. l] }
// adds one matrix onto another (in place add)
fAdd :: *(UMatrix elemType) (UMatrix elemType) -> *(UMatrix elemType) | Array
{#} elemType & Arith elemType
fAdd m1 m2
| sameSize m1 m2 = {m1 & vals = updateInPlace m1.vals f (size m2.vals)}
= abort "Invalid matrix add"
where
f v p = v + m2.vals.[p]
// --- internal
// true if same size
sameSize :: .(UMatrix e) .(UMatrix e) -> Bool
sameSize m1 m2
| not (m1.rows == m2.rows) = False
| not (m1.cols == m2.cols) = False
= True
// updates array first parameter with a function taking its value at p and p
itself
updateInPlace :: *(a e) (e Int -> e) Int -> *(a e) | Array a e
updateInPlace arr1 f maxPos = updateLoop_ arr1 f 0 maxPos
where
updateLoop_ :: *(a e) (e Int -> e) Int Int -> *(a e) | Array a e
updateLoop_ arr1 f pos maxPos
| pos == maxPos = arr1
# (v, arr1) = arr1![pos]
= {(updateLoop_ arr1 f (pos+1) maxPos) & [pos] = f v pos}
------------------------------------------------------------------
The type of "extract" (*) - which I think should be a reasonable function to
have in the API of such a module - now explains to me why the m1.vals works as
first parameter in updateInPlace within fAdd : if m1.vals is used in a unique
parameter (as in there), then m1 must be unique, which it is.
(*) more precisely, the coercion, the term used in Clean to refer to [u<=v]
Thanks a lot, kind of getting there.
regards
Carlos
----- Original Message ----
From: John van Groningen <[email protected]>
To: Carlos Aya <[email protected]>
Cc: [email protected]
Sent: Sat, 28 November, 2009 12:49:14 AM
Subject: Re: [clean-list] stuck with uniqueness in records
Carlos Aya wrote:
>..
>::UMatrix elemType = { rows :: !Int
> , cols :: !Int
> , vals :: ({#} elemType)
> }
>..
>The problem I am facing is update in place of the array vals, I want to have
>the following function (from implementation)
>
>...........................
>// adds one matrix onto another (in place add)
>fAdd :: *(UMatrix elemType) (UMatrix elemType) -> *(UMatrix elemType) | Array
>{#} elemType & Arith elemType
>fAdd m1 m2
>| sameSize m1 m2
> # (arr, m1) = m1!vals // <--- PROBLEM HERE
> = {m1 & vals = updateInPlace arr f (size m2.vals)}
>= abort "Invalid matrix add"
>where
> f v p = v + m2.vals.[p]
>..
>
>The problem is that updateInPlace expects a unique array, but the signature I
>am getting in PROBLEM HERE is
>
>m1!vals :: ({#a}, u:(UMatrix v:a))
>
>i.e., the array inside the record is not unique (at least, this is how I
>understand it).
>
>I have tried to define UMatrix with . and attribute variables in the hope that
>it will change the signature of the record "!" operator, but with no luck. And
>read the manual and the clean book but nothing said in b&w about the "!"
>operator, at least for me as I couldn't link the whole concept of uniqueness
>propagation for records.
>
>How can I extract the array from the unique parameter in fAdd and expect it to
>be unique?
Add a . before the array type in the declaration of type UMatrix:
::UMatrix elemType = { rows :: !Int
, cols :: !Int
, vals :: . {#elemType}
}
this makes the array unique if the record is unique,
and do not try to use ! to extract unique elements. This doesn't work
because of a limitation in the reference analysis. Instead extract
the element using a pattern match or a selection with .
Kind regards,
John van Groningen
__________________________________________________________________________________
Last chance to win a Sony entertainment pack thanks to Yahoo!7. Hurry, ends Nov
30. Enter now: http://au.docs.yahoo.com/homepageset/
_______________________________________________
clean-list mailing list
[email protected]
http://mailman.science.ru.nl/mailman/listinfo/clean-list