[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