コネクティブ ジャンクションを使用した複数パスの表現
ジャンクションに入力される遷移セグメントのラベル形式は、このイメージに示すように、ステートに入力される遷移の場合と同じです。
このイメージでは、実行順序は以下のようになります。
イベントが発生すると、チャートはステート
S1
に、指定されたイベントに一致する出力遷移がないかチェックします。一致するイベントを含む遷移をチャートが検出した場合は、チャートはその遷移を評価します。
condition_1
が真になる場合は、チャートは条件アクションcondition_action
を実行します。チャートは、ジャンクションからの出力遷移に有効な遷移がないかチェックします。
condition_2
は真であるため、S1
からS2
への有効なステート間の遷移が存在します。ステート
S1
の exit アクションが実行されて完了します。ステート
S1
が非アクティブになります。遷移アクション
transition_action
が実行されて完了します。ステート間の遷移 (
S1
からS2
) 全体が発生します。ステート
S2
がアクティブになります。ステート
S2
の entry アクションが実行されて完了します。
if-then-else 判断の構成
以下のイメージは、if-then-else
判断の構成の動作を示しています。
最初は、チャートはスリープ状態です。ステート A
はアクティブであり、条件 [C_two]
は真です。イベント E_one
が発生して、チャートを起動します。このイベントは、チャートのルートからチャートの階層を通じて処理されます。
チャートのルートは、
E_one
の結果、有効な遷移が存在するかどうかをチェックします。ステート
A
からコネクティブ ジャンクションへの有効な遷移セグメントが存在します。チャートは、ラベル付けされた順序で遷移セグメントを評価します。最初の遷移セグメント、条件 [C_one
] は無効です。次の遷移セグメント、条件 [C_two
] は有効です。ステートA
からC
への遷移全体は有効です。ステート
A
の exit アクションexitA()
が実行されて完了します。ステート
A
が非アクティブになります。ステート
C
がアクティブになります。ステート
C
の entry アクションentC()
が実行されて完了します。チャートはスリープします。
自己ループ遷移
以下のイメージは、コネクティブ ジャンクションによる自己ループ遷移の動作を示しています。
最初は、チャートはスリープ状態です。ステート A
はアクティブであり、条件 [C_one]
は偽です。イベント E_one
が発生して、チャートを起動します。このイベントは、チャートのルートからチャートの階層の下方向に処理されます。
チャートのルートは、
E_one
の結果、有効な遷移が存在するかどうかをチェックします。ステートA
からコネクティブ ジャンクションへの有効な遷移セグメントが存在します。チャートは、ラベル付けされた順序で遷移セグメントを評価します。条件 [C_one
] は無効であるため、ステートA
からステートB
への遷移全体が無効です。コネクティブ ジャンクションからステートA
に戻る遷移セグメントは有効です。ステート
A
の exit アクションexitA()
が実行されて完了します。ステート
A
が非アクティブになります。遷移アクション
A_two
が実行されて完了します。ステート
A
がアクティブになります。ステート
A
の entry アクションentA()
が実行されて完了します。チャートはスリープします。
for ループの構成
以下の例は、コネクティブ ジャンクションによる for
ループの動作を示しています。
最初は、チャートはスリープ状態です。ステート A
がアクティブです。イベント E_one
が発生して、チャートを起動します。このイベントは、チャートのルートからチャートの階層の下方向に処理されます。
チャートのルートは、
E_one
の結果、有効な遷移が存在するかどうかをチェックします。ステートA
からコネクティブ ジャンクションへの有効な遷移セグメントが存在します。遷移セグメントの条件アクションi = 0
が実行されて完了します。コネクティブ ジャンクションから出力される 2 つの遷移セグメントのうち、チャートは、コネクティブ ジャンクションへの自己ループである遷移セグメントの妥当性を次に評価します。このセグメントに条件が指定されているのに対して、もう一方のセグメントにはラベルが追加されていないため、このセグメントが優先的に評価されます。この評価の動作は、チャート内の出力遷移の順序付けを反映します。条件
[i < 10]
が真として評価されます。条件が偽になるまで、条件アクションi++
とfunc1
への呼び出しが実行されて完了します。コネクティブ ジャンクションは最終的な遷移先ではないため、遷移先はまだ不明です。ステート
B
への無条件セグメントが有効になっています。ステートA
からB
への遷移全体は有効です。ステート
A
の exit アクションexitA()
が実行されて完了します。ステート
A
が非アクティブになります。ステート
B
がアクティブになります。ステート
B
の entry アクションentB()
が実行されて完了します。チャートはスリープ状態に戻ります。
フロー チャート表記法
以下のイメージでは、フロー チャート表記法を使用した Stateflow® チャートの動作を説明します。
最初は、チャートはスリープ状態です。ステート A.A1
はアクティブであり、条件 [C_one()]
は真です。イベント E_one
が発生して、チャートを起動します。このイベントは、チャートのルートからチャートの階層を通じて処理されます。
チャートのルートは、
E_one
の結果、有効な遷移が存在するかどうかをチェックします。有効な遷移は存在しません。ステート
A
は自身の有効な遷移をチェックして、コネクティブ ジャンクションへの有効な内部遷移が存在することを検出します。チャートは、次に選択可能な遷移セグメントを評価します。出力遷移は 1 つのみであり、この遷移には条件アクションがあります。条件アクションが実行されて完了します。
チャートは、次に選択可能なセグメントを評価します。2 つの出力遷移が存在しており、一方は条件付き自己ループ遷移セグメント、もう一方は無条件遷移セグメントです。割り当てられている評価順序のため、条件付き遷移セグメントの処理が優先されます。条件
[C_one()]
は真であるため、チャートは自己ループ遷移を実行します。最終遷移先には到達していないため、この自己ループは[C_one()]
が偽になるまで継続します。5 回の反復後、
[C_one()]
は偽になると仮定します。チャートは、次に選択可能な遷移セグメントを評価します。この遷移は、条件アクションを含む無条件遷移セグメントです。チャートは遷移セグメントを処理し、条件アクション
{d=my_func()}
が実行されて完了します。d
の戻り値は 84 です。チャートは、次に選択可能な遷移セグメントを評価します。3 つの出力遷移セグメントが存在します。2 つは条件付きで 1 つは無条件です。割り当てられている評価順序のため、2 つの条件付き出力遷移セグメントの配置に基づいて、条件
[d < 100]
をもつセグメントが最初に評価されます。d
の戻り値は 84 であることから、条件[d < 100]
が真であり、この遷移 (遷移先ステートA.A1
への遷移) は有効になります。ステート
A.A1
の exit アクションexitA1()
が実行されて完了します。ステート
A.A1
が非アクティブになります。ステート
A.A1
がアクティブになります。ステート
A.A1
の entry アクションentA1()
が実行されて完了します。チャートはスリープします。
共通の遷移元から複数の遷移先への遷移
以下のイメージは、コネクティブ ジャンクションを経由した共通の遷移元から複数の条件付き遷移先への遷移の動作を示しています。
最初は、チャートはスリープ状態です。ステート A
がアクティブです。イベント E_two
が発生して、チャートを起動します。このイベントは、チャートのルートからチャートの階層を通じて処理されます。
チャートのルートは、
E_two
の結果、有効な遷移が存在するかどうかをチェックします。ステートA
からコネクティブ ジャンクションへの有効な遷移セグメントが存在します。チャートは、割り当てられた順序でセグメントを評価します。最初の遷移セグメントE_one
は無効です。次の遷移セグメントE_two
は有効です。ステートA
からC
への遷移全体は有効です。ステート
A
の exit アクションexitA()
が実行されて完了します。ステート
A
が非アクティブとしてマークされます。ステート
C
がアクティブとしてマークされます。ステート
C
の entry アクションentC()
が実行されて完了します。チャートはスリープします。
等しく有効な遷移パスの解決
チャートに "競合した遷移" が含まれるのは、同じソースから派生する均等に有効な 2 つのパスがある場合です。競合が発生している場合、チャートは、均等に有効な遷移を各遷移に対して指定した順序に基づいて評価します。
たとえば、以下のチャートには、均等に有効な遷移パスが 2 つあります。
デフォルト遷移では、データ a
の値は 1 に、データ b
の値は 10 に設定されます。ステート A
の during
アクションは各タイム ステップ中に、a
を増加させ、 b
を減少させます。ステート A
からステート B
への遷移は、条件 [a > 4]
が真の場合に有効になります。ステート A
からステート C
への遷移は、条件 [b < 7]
が真の場合に有効になります。シミュレーション中に、ステート A
がアクティブになり、両方の条件が真であるタイム ステップが存在します。これが遷移の競合を引き起こします。
既定では、チャートは、作成した順序で条件を実行します。しかし、実行順序は手作業で変更することもできます。たとえば、ステート A
からステート C
への遷移を右クリックし、コンテキスト メニューから [実行順序] 、 [1] を選択すると、チャートによってまずこの遷移が評価されます。このケースでは、ステート A
からステート C
への遷移が発生します。
複数の遷移元から共通の遷移先への遷移
以下のイメージは、コネクティブ ジャンクションを経由した複数の遷移元から単一の遷移先への遷移の動作を示しています。
最初は、チャートはスリープ状態です。ステート A
がアクティブです。イベント E_one
が発生して、チャートを起動します。このイベントは、チャートのルートからチャートの階層を通じて処理されます。
チャートのルートは、
E_one
の結果、有効な遷移が存在するかどうかをチェックします。ステートA
からコネクティブ ジャンクション、コネクティブ ジャンクションからステートC
への有効な遷移セグメントが存在します。ステート
A
の exit アクションexitA()
が実行されて完了します。ステート
A
が非アクティブになります。ステート
C
がアクティブになります。ステート
C
の entry アクションentC()
が実行されて完了します。チャートはスリープします。
共通のイベントに基づく遷移元から遷移先への遷移
以下のイメージは、コネクティブ ジャンクションを経由した複数の遷移元から単一の遷移先への遷移の動作を示しています。ジャンクションの後ろにある遷移セグメントには、イベントが含まれます。
最初は、チャートはスリープ状態です。ステート B
がアクティブです。イベント E_one
が発生して、チャートを起動します。このイベントは、チャートのルートからチャートの階層を通じて処理されます。
チャートのルートは、
E_one
の結果、有効な遷移が存在するかどうかをチェックします。ステートB
からコネクティブ ジャンクション、コネクティブ ジャンクションからステート C への有効な遷移セグメントが存在します。ステート
B
の exit アクションexitB()
が実行されて完了します。ステート
B
が非アクティブになります。ステート
C
がアクティブになります。ステート
C
の entry アクションentC()
が実行されて完了します。チャートはスリープします。
フロー チャートのバックトラック
以下のイメージでは、フロー チャートでのバックトラッキング動作を強制するジャンクションをもつ遷移の動作を説明します。
最初はステート A
はアクティブであり、条件 c1
、c2
、および c3
は真、条件 c4
は偽です。
チャートのルートは、ステート
A
から有効な遷移が存在しないかどうかをチェックします。ステート
A
をコネクティブ ジャンクションに接続する条件c1
は有効です。条件
c1
は真であるため、アクションa1
が実行されます。条件
c3
は真であるため、アクションa3
が実行されます。条件
c4
は真でないため、チャートはステートA
に戻ります。チャートのルートは、ステート
A
から他に有効な遷移が存在しないかどうかをチェックします。ステート
A
をコネクティブ ジャンクションに接続する条件c2
は有効です。条件
c2
は真であるため、アクションa2
が実行されます。条件
c3
は真であるため、アクションa3
が実行されます。条件
c4
は真でないため、チャートはステートA
に戻ります。チャートはスリープします。
前のイメージでは、チャートは a1
と a2
の両方のアクションを実行し、a3
を 2 回実行しています。この問題を解決するには、無条件遷移を終端ジャンクションに追加することを検討してください。
終端ジャンクションを使用すると、c3
または c4
のどちらかが真でない場合にフローを終了できます。これにより、ステート A は不要なアクションを伴わずにアクティブなままです。
意図しないバックトラッキングのその他の例
フロー チャートでの意図しないバックトラッキングのその他の例については、このモデルを開いて確認してください。