Using behaviour three notation for behaviour description in Capella in comparison with statechart notation

Interesting notation. I don’t see yet clear advantages over ordinary flow charts, perhaps because this approach is quite new to me. Flow chart notation is also neither supported by Arcadia/Capella, nor by SysML. Arcadia method is just about architecting systems on logical and physical level, not about designing system behaviour down to the last detail. Just my 2¢.

In fact every state machine also can be implemented using a decision tree (flowchart). It’s how code generators implement state machines in code )

Will start with citation from https://arxiv.org/pdf/1709.00084.pdf

The main disadvantages of a Decision Tree are:
• No information flow out from the nodes, making failure handling very difficult

I assume that it’s possible to compare BT possibility to handle failures with functionality of modern programming languages with try-catch statements. Some “Decision trees” is inside try blocks and can generate exceptions. Catch block will be called if an exception occurs to handle the exception. There is no need to handle exceptions inside try blocks. There is a possibility to have several levels of try-catch blocks that handle exceptions on different levels.

Near the same advantage of BT and state machines over decision trees is the ability to easily describe reactive behaviours. It is a big advantage of state machines and BT in comparison with decision trees. While BT are said to be more scalable and easy to maintain then state machines.

For example in ping-pong example it’s easy to describe handling of evStop event in composition state Working. There is no difference whether the Ping or Pong substate of Working state is active now.

Will try to describe how the reactive behaviour can be specified in BTrees.I’ve not provided such examples of BT before. All previous examples were for synchronous actions.

With BT it’s easy to start and stop asynchronous actions on some condition

  • incorporate asynchronous tasks into BT (as a leaf function)
  • check different conditions (on different levels of BT) during asynchronous task running
  • halt and switch from asynchronous task to another task depending on the check results

When asynchronous action is started it returns the RUNNING result to the parent and continues to execute.

There are different types of composition functions that differ in behaviour, for example how they handle RUNNING results from child function. Let’s look at Sequence and ReactiveSequence composition functions.

In this BT Sequence execute Check one time after that waits for RUNNING async action. After AsyncAction is started only grey nodes are ticked. Check is ticked only one time before async action starts.

If Sequence node receives RUNNING result from it’s child it stops execution of current tick (but remember index of running child) and returns RUNNING result to it’s parent. Next time the Sequence node receives a tick from the parent it ticks the child that returned RUNNING on the previous tick. (it does not start execution from the first child). If asynchronous action returns RUNNING result Sequence stops execution one more time and returns RUNNING to the parent. And so on. As a result Sequence node and all BT simply waits until asynchronous action is RUNNING. If Sequence node receives SUCCESS result it will send a tick to the next child (Action 3). If it receives FAILED from AsyncAction it stops execution and returns FAILED to the parent.

There is another type of composition node that has a name ReactiveSequence. It helps to execute Check condition on every tick. It implements possibility to wait RUNNING task and in parallel check something (conditions, events and so on)

Every time it receives RUNNING result from some of it’s child it stops execution and returns RUNNING to it’s parent. But on the next tick it will start execution from the first child (but not RUNNING as in simple Sequence node). It enables to check several conditions before “sending a tick” to a RUNNING child. If some check is not valid ReactiveSequence can halt execution of a running child and returns FAILED to the parent. The Parent will decide what to do in this case (handle failures).

I think you are right to some extent. Capella helps to define atomic functions but does not help in specifying internal behaviour of these atomic functions. I would say Capella provides the tools to specify external behaviour of these atomic functions in interaction with other functions.

Atomic functions are defined in functional hierarchy, allocated to components and components behaviours are defined based on allocated functions. Capella does not provide the tool to describe behaviour of atomic functions.

We can compare atomic functions with members of a class in object oriented programming language. Capella provides tools to define simple methods of the class (using allocation from functional hierarchy). It helps in defining how these functions are used using state machines (in some main Execute method). But it does not provide a tool to formally and visually describe behaviour of simple functions.

That’s why I agree with you that Capella is not about designing system behaviour to the last detail.

I think it would be good to have a tool to formally describe behaviour of atomic functions (using flowchart or something). But Capella does not assume that these atomic functions can be decomposed using functional hierarchy. I would say that some other element types are needed for atomic functions description. I mean elements like code statements, function calls, loops and so on that are used to specify behaviour of class members. And some flowchart representation could be used to visually create these descriptions.

Also there are some questions about non-reactive behaviour description. Not all components have reactive behaviours.

Capella is good in specifying reactive behaviours of components. State machines can be used to describe complex reactive behaviours of components up to atomic functions. Scenarios can be used to fully describe functional\component interactions.

But Capella does not provide the tool to describe simple behaviours of components (flowchart would be good). In fact state machines can be used in the flowchart manner to specify non-reactive behaviours. But I don’t think it’s a good practice.

Capella provides “functional chains” that can specify control flows with if-else statements They can be used as flowcharts-like for simple behaviour (non-reactive) description. But I would say that functional chains have some other purpose in Capella. It’s purpose is a separate scenario description (like scenarios) but not full behaviours of separate components. They also are not linked to components directly (only over used functions allocations).

I could also say there are some usability difficulties in describing behaviours. Functions are defined in functional decomposition hierarchy and behaviours (state machines) are defined for components in structural hierarchy. You can’t create atomic functions when describing behaviour using statecharts. Arcadia processes assume that functions are defined first, allocated and after that behaviours are defined. If you want to start from components and their behaviour you need to define atomic functions in a separate hierarchy.

  • an activity diagram in SysML can be used in flowchart manner
  • flow charts can be used for class’ methods behaviour specification in some SysML tools like IBM Rational Rhapsody

To summarize some thoughts from previous posts

I see the following use cases for BTrees in Capella used as part of functional decomposition:

  1. Specify behaviour of separate components as part of functional decomposition (alternative to statemachine of components)
    1.1. Specify behaviour of low level components (that does not have sub-components)
    1.2. Specify behaviour of high level components based on the behaviour of child components

  2. To formally specify behaviour of “decomposed” “atomic” functions of components

To specify behaviour of “atomic” function this function is decomposed into sub functions and BT notation is used to orchestrate sub functions. Yes, atomic function is decomposed ). I need a new term for a decomposed atomic function that I have not yet.

I formulated these use cases with references to components. It helps me to define several levels for applicability of BTrees. In fact when using BTrees, behaviors are defined as part of functional decomposition and separated from structural decomposition.

Advantages of using behaviour tree notation as part of functional decomposition
1.helps to specify behaviour on all levels of functional decomposition
2. helps to specify behaviour before creating structural decomposition, during functional analysis
3. helps to specify behaviour and functions side by side using the same representations (more scalable, productive and user friendly approach the specify behaviour on external state machines)
4. provides scalable\modular approach for functional decomposition
5 standard Capella approach for specification of data flows between leaf functions
6. this approach in general is compatible with other Capella functionality

Some thoughs and experience about allocation of non-leaf functions to components.

Capella provides capability to allocate only leaf functions to components. It would be great to have a capability to allocate composition functions also. It will help to allocate the decomposed function as a whole. And there is no need to allocate every subfunction. If some subfunction is added there is no need to allocate it as it’s parent functions are allocated as whole.

There is a “workaround” that helps to allocate non-leaf functions to components that I’ve used before. Before starting to analyze the applicability of BTrees in Capella I had an experience with defining behaviours of atomic functions by decomposing them and adding control flows. I used an additional “trace” link between component and decomposed “atomic” function to specify allocation of non-leaf function to a component.

This link can be used for automatic allocation of all leaf-subfunctions of decomposed function and for validation that all leaf-subfunctions are allocated. This approach result in standard Capella structural model in which only leaf-functions are allocated. As Capella can show non-leaf functions on component architecture diagrams leaf-functions can be hidden and only decomposed “atomic” functions are shown.

Usage of state machines inside components in Capella results in some mix of object-oriented approach to system design and functional approach. With the standard Capella approach it’s not possible to use a clear functional approach without a component’s definition. To use a clear functional approach we have a need to specify functions and behaviours without components.

Using BTrees it’s possible to use Capella in a clear functional way. Functions and behaviours are specified as part of functional hierarchy. Clear functional approach can be used at first stage and on the second stage functions and behaviour can be allocated to components.

I’m not sure there is a “standard” Capella approach, as the Arcadia method can be applied in several ways :wink:

But regarding this specific topic, you can indeed perform functional analysis, decomposition of functions and definition of the interdependencies between these functions, without even defining any component. You can take a look at xDFB (dataflow) diagrams, which are quite useful to do this.

One way of working (again, not the only one) is to perform this functional analysis and when a proper level of detail is reached, analyze how these functions may (or could not) be performed by the components of the system. This leads naturally to conflicts and tradeoffs to be done between concerns: latency, performance, safety, … These are healthy conflicts; better to face them when defining the architecture than later during tests :wink:

This is another reason why I wouldn’t associate your BT to a function, neither allocate a “parent” function: making the assumption that all the subfunctions of a function, or that all the functions involved on a behaviour described as a BT, are allocated to the same component, (i) is not necessairly true, and (ii) may be counterproductive shortcut, as it prevents the healthy tradeoffs analysis that I mentioned above.

Ok, I’ll we use the phrase"in a Capella way"
And it’s good! Because in this case it could be easy to include one more way to Arcadia :wink:
Mostly I used the phrase “standard Capella approach” or “In a Capella way” to the result of functional decomposition. And in all the ways of Arcadia usage it is the same. I mean composite functions do not assume execution semantics but only organize leaf functions in some way.

Yes, we can. But we can’t specify FULL behaviours (control flows) until components are defined.
BTrees could be used to specify FULL behaviour before structural composition is selected. And it does not need to be 1 to 1 mapping between BTree and a component (see below)

Arcadia assumes that when functional analysis is performed behaviours are specified externally as a set of scenarios. BTrees can be also used in this way. It will helps to specify more complex scenarios in capabilities. (the same way as functional chains can be used).

Thanks for this comment and your attention to this topic.
Also have some thoughts today about this restriction. As a result have find another solution.

When behaviour trees are used as part of functional hierarchy it could be organized in “a component manner”. And I agree that this approach is not good for trade off analysis. But it’s not the only possible way to organize functional hierarchy when used with BTrees.

Let’s look at another approach that also works with BTrees.
Let’s organize functions around behaviours in the functional hierarchy. And don’t assume that all BTree is allocated to some component. When trade of analysis is performed leaf functions of BTree can be allocated to different components. Let’s assume that there is a high level component that includes all components to which leaf functions are allocated. We can say that this component implements behaviour specified by BTree. We even show it on a component architecture diagram with green BTree high level function inside it. In some circumstances it could be the system as a whole or some more low level component.

Let’s take any composition function from the defined BTree (Sequence, Select and so on). On the same principle there is some component to which (or to it’s sub components) all leaf functions of this BTree branch are allocated. In this case we can say that this composite function (and it’s behaviour) is allocated to this component.

Thank you one more time for your comments.
I hear your advice that it’s not a good way to use BTree as part of functional decomposition. At the same time I “feel” (not understand yet clearly) that when used outside functional decomposition we lose some advantages of BTrees (their modularity and scalability and add some unnecessary complexity mixing functional decomposition with structural decomposition.

Have created an example with allocation of BT to several components.

Leaf functions are allocated

In this case composite functions of BTree (Sequence1 and Sequence1) and their execution behaviour are “linked” to subcomponents.

All BTree is shown as allocated to high level component.

An allocation example with different component structure

All leaf functions can be allocated to subcomponents.

Or some leaf-functions can be allocated to high level component.

In this case “execution behaviour” of Sequence1 and Sequence2 are “linked” to high level component.

This is not a valid model in Capella. Parent components shall not have allocated functions.

There is a difference between the decomposition of functions and components, and the allocation of functions to components - which are strong concepts used when performing architecting, and the visualization of the architecture in diagrams - which is less constrained, and this is quite useful for communicating the architecture to other people.

This is why you can show CrossComponentBT function inside the CrossComponentBT component: the function is not allocated, but the subfunctions of it are allocated to subcomponents of the component. The complexity of the allocation is hidden for communication purposes.

You can define sequence links and other sequence structures such as AND, OR, LOOP… in the Functional Chains or Scenarios, without any allocation of functions neither definition of components :thinking:

OK, I redraw your two examples as activity diagrams and here’s what I’ve got. AsynTreeWSequence is quite simple:

But AsynTreeWReactiveSequence not so anymore:

So here I see clear advantage of BTrees notation. Another problem in introducing this notation to Arcadia is “a scope” of leaf functions. In Arcadia they belong/are parts of one parent function and can’t be part of/belong to another parent function in the same time. In case of BTrees you can have every function on many tree levels in the same time.

So here’s some example how I’d model both sequences. Functional structure:

image

Functional Exchange Items and Item Elelements:

image

Just one example of AsynAction-Error functional chain for Sequence capability:

image

And some functional chain visualisation:

image

This is from architect point of view. Now software engineer has his job to do: design proper BTrees structure out of the stuff above :wink:

BTW perhaps you’d be interested in checking Sirius project (or Obeo Designer incarnation), where you should be able to create BTrees DSL quite easily, which would work exactly as you need.

A assume that from methodological point of view it’s true. (I case I don understand why, because parent component can have it’s own behaviour)

But as I see Capella does not know about this rule.

In this case Action1 and Action6 was allocated me to parent component directly in Capella and model validation does not show validation errors

In case this example does not have any big sense for BTrees allocation.

You are absolutely right :upside_down_face:
I understand that last features of functional chains trying to solve the same task.

I had an experience with Sirius (about 4 years) while worked on creating a specialized modeling tool for emebedded software RE\modeling\documentation\configuration.
As a result it’s easy for me to think about Capella as an platform for enhancements :slight_smile:

You are representing control flow (conditions, trigger, …) as functional exchanges. Arcadia states that these kind of information is best represented with sequence links, leaving functional exchanges to represent data (or energy, mass, …) flows. Have you tried to introduce sequence links to your Functional Chain?

Of course, I refer to Arcadia here. One great thing of Capella is that you can extend it to support other modelling representations and practices. And if you find that BT can be integrated, go on! :slight_smile: My suggestions are only to think about how BT could be integrated and still be “compatible” to the Arcadia method that is the one that is implemented in Capella.

PS: I agree with the comment of @kubsztal, Arcadia is for architecting and not for defining detailed behavior: achitecting is already a major responsibility, especially in complex systems engineering!

I think It’s not correct to use ports in Sequence (or ReactiveSequence). In Capella composition functions should not have ports.

So there should not be functional exchanges used between parent (sequence) and child functions.

Information about calls from parent to child functions should be modelled explicitly but rather implicitly (I mean by definition: Sequnce call each child using some rule). Some another types of composition functions can be defined with different rules.

Why then we still don’t have proper open source BTrees modeling tool available yet?? :wink: