[kepler-users] Type resolving problem
Christopher Brooks
cxh at eecs.berkeley.edu
Mon May 16 18:02:43 PDT 2011
Hi Tomasz,
I finally got around to fixing the problem that you pointed out with
the two argument concatenate function in the expression language returning
array(general)
My first fix was to update ptolemy/data/expr/ParseTreeTypeInference.java
with a test for the concatenate expression language function.
Edward wrote:
> This is a also a feature request...
>
> It might be easy to fix for this particular example by providing
> a type constraints function to go with the concatenate function.
> I.e., provide a method concatenateType(Array, Array) in UtilityFunctions.
I backed out my first fix and then added concatenateReturnType() to
UtilityFunctions which seems to do the trick.
I added a similar function and test for the single argument
concatenate function. However, if I have
Const {{"a", "b"},{"c"}} -> Expression concatentate(in)
The the output of the Expression is correctly set to {"a", "b", "c"}
However, the type is arrayType(string), not arrayType(string,3).
This is because the input to the Expression is
arrayType(arrayType(string,2)), and I don't have access to
the length of the individual elements.
There is probably a bug here somewhere, but I've spent enough time here.
> At the same time, we should fix a similar limitation in the
> ArrayAppend actor, which has the following in its constructor:
>
> // FIXME: correct type constraint for length
> output.setTypeAtLeast(ArrayType.ARRAY_UNSIZED_BOTTOM);
>
I can see that the types of the ArrayAppend are unsized, but I'm not
sure how to fix this. (Actually, this margin is too small for my solution :-) )
So, I'm moving on.
_Christopher
> Any volunteers to do these? It would be good practice with
> a modern type system...
>
> Edward
> [kepler-users] Type resolving problem
>
> Christopher Brooks
> Fri, 27 Aug 2010 09:32:38 -0700
>
> Hi Tomasz,
> I created a test case that fails (attached).
>
> The problem is that if I use the Expression actor with concatenate(),
> then the output is arrayType(general) instead of arrayType(string,3).
>
> You wrote:
>
>> Hi,
>>
>> I've read the documentation about expressions, because what I need is to
>> concatenate two arrays of type: string. When I run it inside Expression
>> Evaluator I get:
>>
>>>> t1 = {"a"}
>> {"a"}
>>>> t2 = {"b"}
>> {"b"}
>>>> t1.getType()
>> object(arrayType(string,1))
>>>> t2.getType()
>> object(arrayType(string,1))
>>>> concatenate(t1, t2)
>> {"a", "b"}
>>>> concatenate(t1, t2).getType()
>> object(arrayType(string,2))
>>
>> This is correct and such behaviour is what I'd like to have. However in
>> Kepler, expression actor always returns type "general" after concatenation no
>> matter what are its input types. Because of this, I cannot run my workflow as
>> I get type resolve exception.
>>
>> I tried configuring output port of expression actor with no effect. I tried
>> also to use cast() function, with no effect either. Last thing, I cannot use
>> Concatenate Arrays actor, because the number of arrays is not known during
>> workflow design - it is determined during runtime, so I must do it in a loop.
>>
>> Do you have any ideas what may cause the problem?
>
> I think the problem may be with ptolemy.data.expr.UtilityFunctions.
> The concatenate expression language function is defined as:
>
> /** Concatenate two arrays.
> * The arrays must have the same type.
> * Example: concatenate({1,2,3},{4,5,6}) == {1,2,3,4,5,6}.
> * @param token1 First array from which tokens are copied to the result.
> * @param token2 Second array from which tokens are copied to the result.
> * @return An array containing all of the elements of the first argument
> * (in order), followed by all of the arguments of the second argument
> * (in order).
> * @exception IllegalActionException If the arrays do not have
> * compatible types.
> * @since Ptolemy II 4.1
> */
> public static ArrayToken concatenate(ArrayToken token1, ArrayToken token2)
> throws IllegalActionException {
> Token[] array1 = token1.arrayValue();
> Token[] array2 = token2.arrayValue();
>
> int nElements = array1.length + array2.length;
> Token[] resultArray = new Token[nElements];
>
> System.arraycopy(array1, 0, resultArray, 0, array1.length);
> System.arraycopy(array2, 0, resultArray, array1.length, array2.length);
>
> return new ArrayToken(resultArray);
> }
>
> /** Concatenate an array of arrays into a single array.
> * Example: concatenate({{1,2,3},{4,5},{6,7}}) == {1,2,3,4,5,6,7}.
> * @param token Array of arrays which are to be concatenated.
> * @exception IllegalActionException If the argument is not an array of
> * arrays.
> * @since Ptolemy II 4.1
> */
> public static ArrayToken concatenate(ArrayToken token)
> throws IllegalActionException {
> if (!(token.getElementType() instanceof ArrayType)) {
> throw new IllegalActionException(
> "The argument to concatenate(ArrayToken) "
> + "must be an array of arrays.");
> }
>
> int nElements = 0;
>
> for (int i = 0; i < token.length(); i++) {
> nElements += ((ArrayToken) (token.getElement(i))).length();
> }
>
> Token[] result = new Token[nElements];
> int cursor = 0;
>
> for (int i = 0; i < token.length(); i++) {
> Token[] array = ((ArrayToken) (token.getElement(i))).arrayValue();
> System.arraycopy(array, 0, result, cursor, array.length);
> cursor += array.length;
> }
>
> return new ArrayToken(result);
> }
>
> I wonder if we need to be more explicit about setting the size of the array?
>
> I'm on vacation until September 7 or 8, so someone else would need to take
> a look.
>
> _Christopher
>
>
>
>
> On 8/26/10 11:50 PM, Tomasz ?ok wrote:
>> Christopher Brooks <cxh at eecs.berkeley.edu>:
>>> Do you have a small test case?
>>
>> In the attachment you can find two files:
>> - model.xml is a workflow
>> - scr1.png is a screenshot from workflow execution
>>
>> The screenshot shows also the tooltip displayed on output port of
>> expression actor. There is "arrayType(general)", but according to input
>> array types and an excerpt from expression evaluator, it should be
>> "arrayType(string)".
>>
>> However I found out today that it can work with cast() function:
>> cast(arrayType(string), concatenate(t1, t2))
>>
>> Yesterday I wrote, that cast() did not help, but I made a mistake. Sorry
>> for misleading you with this.
>>
>>
>> But still - is this behaviour without cast() correct and expected?
>>
>> Best regards,
>> Tomek
--
Christopher Brooks, PMP University of California
CHESS Executive Director US Mail: 337 Cory Hall
Programmer/Analyst CHESS/Ptolemy/Trust Berkeley, CA 94720-1774
ph: 510.643.9841 (Office: 545Q Cory)
home: (F-Tu) 707.665.0131 cell: 707.332.0670
More information about the Kepler-users
mailing list