[clean-list] stuck with uniqueness in records

Carlos Aya carlosayam at yahoo.com.au
Sun Nov 29 16:56:41 MET 2009


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 <johnvg at cs.ru.nl>
To: Carlos Aya <carlosayam at yahoo.com.au>
Cc: clean-list at cs.ru.nl
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/



More information about the clean-list mailing list