timelineoperation

Assembles a Timeline (see Handling Data that Changes Over Time) from repeated calls to a child expression. Typically timelineoperation is used in conjunction with intervalvalue, and together these two expressions allow other expressions to operate on values from timelines as if they were primitive values, and then have the resultant data reassembled into a Timeline.

Tip: For each of the Timelines which are used as input into your algorithm, typically you should wrap the expression that returns the Timeline in an intervalvalue, and then wrap the overall result in a timelineoperation.

A brief description of how timelineoperation behaves at evaluation time is as follows:

The behavior described above means that the inner expressions never have to know that they are part of processing involving timelines. Furthermore, processing is efficient because expressions are only invoked for dates on which the input timelines change value.

Note: If a timelineoperation operates on an expression which is not wrapped by an intervalvalue, then the resultant Timeline will have a constant value for all time.
<?xml version="1.0" encoding="UTF-8"?>
<RuleSet name="Example_timelineoperation"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation=
"http://www.curamsoftware.com/CreoleRulesSchema.xsd">

  <Class name="Person">
    <!--
     true during a person's lifetime; false before date of birth,
     and false again after date of death (if any)
      -->
    <Attribute name="isAliveTimeline">
      <type>
        <javaclass name="curam.creole.value.Timeline">
          <javaclass name="Boolean"/>
        </javaclass>
      </type>
      <derivation>
        <specified/>
      </derivation>
    </Attribute>

    <!--
     The assets owned by the person, at some time or another.  Each
     asset's value may vary over time.
      -->
    <Attribute name="ownedAssets">
      <type>
        <javaclass name="List">
          <ruleclass name="Asset"/>
        </javaclass>
      </type>
      <derivation>
        <specified/>
      </derivation>
    </Attribute>



    <!--
     The total value of the assets owned by the person (or by the
     person's estate, if the person has died).
      -->
    <Attribute name="totalAssetValueTimeline">
      <type>
        <javaclass name="curam.creole.value.Timeline">
          <javaclass name="Number"/>
        </javaclass>
      </type>
      <derivation>
        <!--
         Total the value of all the owned assets.  The value of each
         asset may change over time.
          -->

        <!--
         <timelineoperation> will create a timeline from the series
         of <sum> calculations performed within it.

         Each execution of <sum> will calculate the total for a
         particular day; <timelineoperation> will assemble these
         daily totals into a timeline of numbers.
          -->
        <timelineoperation>

          <sum>
            <!--
             For each owned asset, get its countable-value timeline.
              -->
            <dynamiclist>
              <list>
                <reference attribute="ownedAssets"/>
              </list>
              <listitemexpression>

                <!--
                 Wrap the timeline returned by
                 countableValueTimeline, so that the <sum> thinks
                 that it is operating on a list of numbers, not a
                 list of timelines.
                  -->
                <intervalvalue>
                  <reference attribute="countableValueTimeline">
                    <current/>
                  </reference>
                </intervalvalue>
              </listitemexpression>
            </dynamiclist>

          </sum>

        </timelineoperation>

      </derivation>
    </Attribute>


    <!--
     The cut-off point for being entitled to benefit.  Persons with
     assets above this varying threshold do not qualify for benefit.

      -->
    <Attribute name="maximumAssetsThreshold">
      <type>
        <javaclass name="curam.creole.value.Timeline">
          <javaclass name="Number"/>
        </javaclass>
      </type>
      <derivation>
        <!--
         In a real implementation, this value would tend to vary
         over time (e.g. from a rate table).

         However, for the sake of example, this implementation uses
         a <timelineoperation> WITHOUT a nested <intervalvalue> to
         create a Timeline which has a constant value for all time.

         This use of <timelineoperation> can often be useful for
         dummy implementations early on in rule set development.
        -->

        <timelineoperation>
          <!--
           Hard coded forever-constant value - to be replaced by a
           varying value later in rules development.
            -->
          <Number value="10000"/>
        </timelineoperation>
      </derivation>
    </Attribute>

    <!--
     The person qualified for benefit if (on any particular day)
     the person is alive and the total value of the person's assets
     does not exceed the maximum asset threshold.
      -->
    <Attribute name="qualifiesForBenefitTimeline">
      <type>
        <javaclass name="curam.creole.value.Timeline">
          <javaclass name="Boolean"/>
        </javaclass>
      </type>
      <derivation>
        <timelineoperation>
          <all>
            <fixedlist>
              <listof>
                <javaclass name="Boolean"/>
              </listof>
              <members>
                <!--
                 operate on the Timelines as if they were primitive
                 values
                  -->
                <intervalvalue>
                  <reference attribute="isAliveTimeline"/>
                </intervalvalue>

                <compare comparison="&lt;=">
                  <intervalvalue>
                    <reference attribute="totalAssetValueTimeline"/>
                  </intervalvalue>
                  <intervalvalue>
                    <reference attribute="maximumAssetsThreshold"/>
                  </intervalvalue>
                </compare>
              </members>
            </fixedlist>

          </all>
        </timelineoperation>

      </derivation>
    </Attribute>



  </Class>

  <!--
   An asset, owned by a person at some time or other.

   Each asset is bought, and may subsequently be sold.

   The value of an asset varies over time; the asset still has a
   value even before or after it is owned by a Person; however,
   the _countable_ value is zero outside of the period of
   ownership.
    -->
  <Class name="Asset">
    <Attribute name="boughtDate">
      <type>
        <javaclass name="curam.util.type.Date"/>
      </type>
      <derivation>
        <specified/>
      </derivation>
    </Attribute>

    <!-- will be null if the asset has not been sold -->
    <Attribute name="soldDate">
      <type>
        <javaclass name="curam.util.type.Date"/>
      </type>
      <derivation>
        <specified/>
      </derivation>
    </Attribute>

    <Attribute name="isOwnedTimeline">
      <type>
        <javaclass name="curam.creole.value.Timeline">
          <javaclass name="Boolean"/>
        </javaclass>
      </type>
      <derivation>
        <existencetimeline>
          <intervaltype>
            <javaclass name="Boolean"/>
          </intervaltype>
          <intervalfromdate>
            <reference attribute="boughtDate"/>
          </intervalfromdate>
          <intervaltodate>
            <reference attribute="soldDate"/>
          </intervaltodate>
          <preExistenceValue>
            <false/>
          </preExistenceValue>
          <existenceValue>
            <true/>
          </existenceValue>
          <postExistenceValue>
            <false/>
          </postExistenceValue>
        </existencetimeline>

      </derivation>
    </Attribute>

    <!--
     the varying value of the asset, regardless of whether it is
     owned by the person at the time
      -->
    <Attribute name="valueTimeline">
      <type>
        <javaclass name="curam.creole.value.Timeline">
          <javaclass name="Number"/>
        </javaclass>
      </type>
      <derivation>
        <specified/>
      </derivation>
    </Attribute>


    <!--
     The value which counts towards the person's assets - i.e. the
     value of the asset during the period when it is owned,
     otherwise 0 when it is not owned.
      -->
    <Attribute name="countableValueTimeline">
      <type>
        <javaclass name="curam.creole.value.Timeline">
          <javaclass name="Number"/>
        </javaclass>
      </type>
      <derivation>
        <!--
         reassemble the outputs from each <choose> invocation into a
         timeline
          -->
        <timelineoperation>
          <choose>
            <type>
              <javaclass name="Number"/>
            </type>
            <when>
              <condition>
                <!--
                 operate on each of the intervals of constant
                 ownership
                -->

                <intervalvalue>
                  <reference attribute="isOwnedTimeline"/>
                </intervalvalue>
              </condition>
              <value>
                <!--
                 if on a particular date, the asset is owned, then
                 its countable value on that date is simply its
                 value
                  -->
                <intervalvalue>
                  <reference attribute="valueTimeline"/>
                </intervalvalue>
              </value>
            </when>
            <otherwise>
              <value>
                <!--
                 if on a particular date, the asset is owned, then
                 its countable value on that date is zero
                  -->
                <Number value="0"/>
              </value>
            </otherwise>
          </choose>

        </timelineoperation>
      </derivation>
    </Attribute>

  </Class>

</RuleSet>
Tip: If an inner expression returns a Timeline, and you forget to wrap that expression in an intervalvalue, you will see CER validation errors as in this example:
<!--
     The value which counts towards the person's assets - i.e. the
     value of the asset during the period when it is owned,
     otherwise 0 when it is not owned.
      -->
    <Attribute name="countableValueTimeline">
      <type>
        <javaclass name="curam.creole.value.Timeline">
          <javaclass name="Number"/>
        </javaclass>
      </type>
      <derivation>
        <!--
         reassemble the outputs from each <choose> invocation into a
         timeline
          -->
        <timelineoperation>
          <choose>
            <type>
              <javaclass name="Number"/>
            </type>
            <when>
              <condition>
                <!--
                 operate on each of the intervals of constant
                 ownership
                -->

                <!--
                  **** Forgot to wrap the Timeline returned
                  in <intervalvalue> ****
                  -->
                  <reference attribute="isOwnedTimeline"/>
              </condition>
              <value>
                <!--
                 if on a particular date, the asset is owned, then
                 its countable value on that date is simply its
                 value
                  -->
                <intervalvalue>
                  <reference attribute="valueTimeline"/>
                </intervalvalue>
              </value>
            </when>
            <otherwise>
              <value>
                <!--
                 if on a particular date, the asset is owned, then
                 its countable value on that date is zero
                  -->
                <Number value="0"/>
              </value>
            </otherwise>
          </choose>

        </timelineoperation>
      </derivation>
    </Attribute>
ERROR	... Example_timelineoperation.xml(276, 19)
  AbstractRuleItem:INVALID_CHILD_RETURN_TYPE: Child 'condition' returns
  'curam.creole.value.Timeline<? extends java.lang.Boolean>',
  but this item requires a 'java.lang.Boolean'.