Skip to content

Language extensions

Foretify extensions

In addition to the constructs defined in ASAM OpenSCENARIO 2.0, Foretify supports the extensions described below.

It is Foretellix policy to continue to contribute new constructs to OSC2 once these constructs have been matured with customers and the OSC2 committee is again accepting contributions.

Block comments

Foretify allows the use of the /* and */ characters to mark the beginning and end of multi-line comments.

String type for string concatenation

Foretify allows string concatenation and the use of the $() interpolation operator within strings.

null value

Foretify defines a null constant that is the default value for fields or variables of type struct.

Range expressions

Foretify supports the ASAM standard form for range expressions. For example:

distance in [2m..5m]

Foretify also supports this form:

distance in [2..5]m

Global actor top

Foretify supports the built-in actor top. All members of top (fields, methods etc.), as well as top itself, are considered global. Also, all global scenarios / modifiers (i.e. those defined with no actor) implicitly belong to the top actor. Finally, the built-in, initially-empty top.main scenario is considered the starting point of scenario execution and can be used in print commands. Following is an example of using print with top.main.

Foretify commands: print top.main
> print top.main
top.main = top.main@2 (main)
---------- any_normal_scenario
    duration:  10874281.66second
> print top.main.duration
time = 10874281.66second

Implicit labels

For scenario invocations that are not explicitly labeled, Foretify creates labels using label().

Scenario and modifier declarations

Foretify allows scenario and modifier declarations to be nested within actor declarations.

Unit declarations

The syntax for declaring units in Foretify differs from the ASAM standard. The ASAM standard is:

unit <unit-name> of <physical-type> is SI(<SI-base-exponent-list> [, <factor>] [, <offset>] )
The Foretify syntax is:

unit <unit-name> is <physical-type>(factor: <float> [, offset: <float>])

Field declarations

Foretify allows cover and record in the with blocks of field declarations. If using it, you must use this syntax:

cover(<name>, expression: it)
The expression can be omitted if it can be derived from the name. For example:

max_speed: speed with: cover(max_speed, unit: kph)

with blocks

The ASAM standard requires the use of it when declaring constraints within field declarations. Foretify does not.

car1: vehicle with:
     keep(it.color == white) # 'it' not required by Foretify

To improve readability, Foretify supports two additional ways to specify with members.

For field declarations, the with() construct, for example:

    car1: vehicle with(color: white, category: bus)
For field declarations and scenario invocations, the with: single-line construct, for example:
    car1: vehicle with: keep(color == white); keep(category == bus)
    do car1.drive with: speed(speed: [1..5]kph, slower_than: car1); position(time: 3second, behind: car1, at: end)

Single-line code blocks

To improve readability, you can choose to write any code block on a single line. For example, native methods often contain multiple member blocks of procedural code.

def increment(cnt: int) -> int is:
    return (cnt + 1)
# can be written as
def increment(cnt: int) -> int is: return (cnt + 1)

However, you cannot write two code blocks on a single line. (The start of each code block is marked by ':'.)

OSC2 code: invalid single-line code block (native method)
def x_is_smaller(x: int, y:int) -> bool is:
    if(x < y):
        return true
# CANNOT be written as
def x_is_smaller(x: int, y:int) -> bool is: if(x < y): return true

Constraint support

Foretify supports the following:

  • Soft constraints, such as keep(soft side == right).
  • Weighted constraints, such as keep(soft side == weighted(20:left, 80: right)).
  • Specific distribution methods, such as keep(soft top_speed == random.normal(10, 120, 55.5, 7) * 1kph).

Several methods are defined to allow you to determine whether an event has occurred or to retrieve an event's parameters.

Method extensions

Foretify supports extending methods with is also or is first.

Native methods support

Foretify supports defining methods in OSC2. The procedural or imperative constructs that can be used in native methods is defined in Native methods.

post_plan() and init() methods

Each object (struct, actor or scenario) has predefined post_plan() and init() methods. The init() method is called by Foretify when the object is created. The post_plan() method is called when the generation of the object is completed. You can extend these methods to initialize non-generatable fields to a computed value, for example.

Additional structured type members

Foretify supports the following additional members for structured types:

  • for <item> in <list>
  • set <field> = <value>

Supported composition operators

Foretify supports the following composition operators:

  • match()

do directive

Foretify allows multiple do directives in the same scenario as well as do only in scenario extensions.

The in directive

Foretify supports the use of the in directive to allow modifying the behavior of nested scenarios.

The synchronize() directive

This directive lets you synchronize the timing of two sub-scenario invocations.

Execution order

The execution order of event-triggered actions follows the order in which they are defined in text.

Checker and KPI definition

Foretify supports the use of collect() to define checkers, including simple temporal checkers, and Key Performance Indicators (KPIs).

Foretify also supports various methods and actions used to define a response to a failure, including:

  • sut_error(), sut_warning() and sut_issue()
  • log(), log_info(), log_debug(), log_trace()

Verdict analysis conventions

Foretify supports the definition of issues by their attributes of severity, category, kind and details. You can modify the severity of an issue using the modify() and modify_category() methods.

trace()

trace() collects the value changes of an expression during scenario execution and displays them in a timeline.