Instance set variables

An instance set variable holds zero, one or many references to instances of the same class. They are useful for grabbing, signaling and performing operations on sets of instances.

Implicit declaration

The .=, ..=, and .=. assignment operators assign one, many or an arbitrary single instance to an instance set variable. The dots represent selection cardinality.

Single instance assignment

Selection using values supplied for an identifier is a common idiom in Scrall. Consequently, the syntax has been streamlined for this action.

Here, a local Pilot instance locates its related Aircraft instance using an aircraft id value passed in as an input parameter.

my aircraft .= Aircraft( Tail number: in.aircraft id )

Assuming that an identifier of the Aircraft class is Tail number, it is known that the selection must yield zero or one instance. Use of the .= assignment operator implicitly defines my aircraft as an instance set variable.

If the aircraft is not found, zero instances are assigned and the my aircraft variable holds the empty set. The empty set tests evaluates to false in a predicate:

my aircraft .= Aircraft( Tail number: in.aircraft id )
if (my aircraft) {
   // not the empty set
} else {
    // no aircraft

Or you can explicitly compare against the empty set:

if (my aircraft != ~) { // if not empty

In this selection example the class has a multiple attribute identifier:

assigned runway .= Runway( Number: directed runway, Airport: local airport code )

Once again, one or zero instance will be assigned.

If more than one instance is possible or selected, a fatal error occurs.

Arbitrary instance assignment

To select an arbitrary instance from a set, use the .=. operator. You can think of the dot on the right as picking one object before sending it through for assignment. Here are some examples:

some aircraft .=. Aircraft
some aircraft .=. Aircraft() // or like this, parenthesis optional
some high flying aircraft .=. Aircraft( Altitude: > high alt )
lowest fastest aircraft .=. Aircraft( ^-Altitude, ^+Airspeed )
fastest lowest aircraft .=. Aircraft( ^+Airspeed, ^-Alititude )

In all of these examples the right hand side may yield zero or multiple instances. The .=. assignment operator will choose one instance arbitrarily and zero if none are available.

To empty a previously defined instance set variable, assign the empty set:

my aircraft .= ~  // Now it is definitely empty

Any instance set assignment operator can be used to assign the empty set.

Multiple object assignment

Multiple instances may be selected and assigned with the ..= operator.

low flying aircraft ..= /R3/Control Zone.Aircraft( Altitude: < low alt )

All instances of Aircraft whose Altitude attribute value is below the specified altitude are assigned to the low flying aircraft variable. This could be zero, one or many instances.

The Aircraft selection below may return zero, one or many instances:

aircraft to land ..= Aircraft( Zone: Code, Altitude < landing altitude and Ready to land )

In the statement above, the set of all Aircraft instances such that each instance has a value for its Zone attribute matching the value of the local instance’s Code attribute and an Altitude attribute value less than the value of the landing altitude scalar variable and a true value for the Ready to land attribute is assigned to the LHS.

Operations on instance set variables

Use the cardinality operator ?# to obtain the cardinality of an instance set variable.

qty hp tasks = ?#next tasks

The result is an unsigned integer. While more powerful set operations are available to table variables, basic set operations such as union, intersection, subtraction (set complement) are supported on instance sets.

o ..= a ^ b // intersect
o ..= a + b // union
o ..= a - b // subtract
o ..= a -- b // symmetric difference

.<, <_, .>, _> operators are proper subset, subset, proper superset, superset
if (o1 .< o2) {...} // o1 is a proper subset of o2

?<var> to get the cardinality (quantity) of objects
?0<var> true if zero instance in var
?1<var> true if one instance in var

You can compare instance sets using standard comparisons:

if ( highest aircraft <_ fastest aircraft )  // is a subset of

The other set operators are: #<, data-preserve-html-node="true" #<_, #_>, #>for proper subset, subset, superset and proper superset. These might look a bit strange, but ideally, a good text editor should replace these symbols with the corresponding math set characters so while you can type these, you should be seeing , , , instead.

Here are some more examples:

fastest aircraft ..= Aircraft( Airspeed > min speed )
highest aircraft ..= Aircraft( Altitude > floor alt )
slow aircraft ..= Aircraft - fastest aircraft // set complement from class population
high and fast aircraft ..= fastest aircraft ^ highest aircraft // intersection
fastest low aircraft ..= fastest aircraft - highest aircraft  // set complement
my aircraft .= /Aircraft( Tail number: my tail number )
my aircraft and slowest aircraft ..= my aircraft + slow aircraft  // single instance in union

Declaring an instance set variable

There is no special action for declaring an empty instance set variable. Instead, you can initialize an instance set variable to the empty set using any assignment operator and the empty set symbol with a class name as shown:

your aircraft .= Aircraft(~) // Selects the empty set of Aircraft

Note that you must assign a class type to the object variable when assigning an empty set.