StateMachines (UML revision 2) - 状態遷移図をどのように状態遷移させるか

# UML 2 をベースにした pxt-mstate の設計

**UML 2 の仕様 - the Unified Modeling Language (UML), revision 2**

https://www.omg.org/spec/UML

:::note warn
本記事は、UML仕様のver.2.5.1を参照しています。
https://www.omg.org/spec/UML/2.5.1/PDF
:::

**参考チュートリアル - UML 2 Tutorial | Sparx Systems**

https://sparxsystems.com/resources/tutorials/uml2/index.html

[→ UML 2 Tutorial - State Machine Diagram](https://sparxsystems.com/resources/tutorials/uml2/state-diagram.html)

# Abstract Syntax - Behavior StateMachines

![uml_statemachine_abstract_syntax.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/69a9a530-f6b6-0623-4e4c-57309024c954.png)

## 必要なクラスの抜粋

**pxt-mstate** に必要と思われるクラスを抜粋しました。
`Pseudostate` クラスに関しては、 その `kind` が `initial` のみを取り扱うので、 `InitialPseudostate` クラスに置き換えています。

```plantuml

' Class
class StateMachine
class Region
abstract Vertex
class InitialPseudostate <<Pseudostate>>
class State
class FinalState
class Transition
class Trigger
class Constraint
class Behavior

' Extension ( <|-- )
Vertex <|-l- InitialPseudostate
Vertex <|-- State
State <|-- FinalState

' Composition/Aggregation ( *-- / o--)
StateMachine *-- Region
Region *-- Vertex
Region *-- Transition

'Vertex -u- StateMachine : submachine >

State *-r- "0..1" Behavior : entry >
State *-r- "0..1" Behavior : exit >
State *-r- "0..1" Behavior : doActivity >

'State *-u- "0..1" Constraint : stateInvariant >

Transition -l- "0..1" Vertex : target >
Transition -- "0..1" Vertex : source >

Transition *-- "0..1" Trigger : trigger >
Transition *-- "0..1" Constraint : guard >
Transition *-r- "0..1" Behavior : effect >

```

## pxt-mstate のUML設計

**StateMachineとRegion**
**pxt-mstate** では、`submachine`の概念を省略しています。
その為、`State`クラスが`StateMachine`クラスを集約することはありません。そこで、`Region`クラスを`StateMachine`クラスに置き換え、`Region`クラスを省略します。

**FinalState**
`FinalState`クラスは、`Transition`クラスから見て、`target`にはなりますが、`source`にはなりません。そこで、`FinalState`クラスの継承元を`Vertex`クラスに変更します。同時に、**pxt-mstate** では、`FinalState`クラスの`entry`、`doActivity`、`exit`が不要ですので、このように継承関係を変更するのは好都合です。

**InitialPseudostate**
疑似状態である`InitialPseudostate`クラスは、`FinalState`クラスの疑似クラスであると考えます。**pxt-mstate**を設計する上での補足情報として残しておきます（クラスとして存在しません）。

**Transition**
**pxt-mstate**では、`start(default)`コマンドで、ステートマシンを開始します。
これを`Transition`クラスで行うと考えた場合、`source`は、`FinalState`クラス(`InitialPseudostate`クラス)であり、`target`は、引数の`default`であると考えることができます。
また、その`Transition`クラスのインスタンスでは、`effect`、`trigger`、`guard`が不要です。
そこで、`trigger`等の代わりに、`start(default)`コマンドで状態遷移する為の`StarterTransition`クラス(疑似クラス)を**pxt-mstate**を設計する上での補足情報として追加します（クラスとして存在しません）。

```plantuml

abstract Vertex
annotation InitialPseudostate
annotation StarterTransition

StateMachine *-- Vertex
StateMachine *-- Transition

InitialPseudostate -[dotted]-|> FinalState
FinalState -r-|> Vertex

Vertex "0..1" -r- Transition : source <
Vertex "0..1" -r- Transition : target <

Vertex <|-- State

State *-r- "0..1" Behavior : exit >
State *-r- "0..1" Behavior : entry >
State *-r- "0..1" Behavior : doActivity >

Transition <|-r[dotted]- StarterTransition

Transition *-- "0..1" Trigger : trigger >
Transition *-- "0..1" Constraint : guard >

Transition *-d- "0..1" Behavior : effect >

'Behavior "0..1" -u-* Transition : effect <

```

## pxt-mstateの内部構造

```plantuml

StateMachine *-- State

State -u[dotted]- "1" Mname.IdName : stateName >

State *-- "0..*" BodyAction : entry >
State *-- "0..*" DoActivityAction : doActivity >
State *-- "0..*" BodyAction : exit >

State *-r- "0..*" StateTransition : stateTransition (source) >

InitialPseudostate -[dotted]-|> FinalState
FinalState -r-|> State

BodyAction *-- "1" Body : body >
DoActivityAction *-- "1" DoActivityBody : body >

BodyAction <|-u- StateTransition
StateTransition *-l[dotted]- "1..*" State : targetName >
StateTransition -u[dotted]- "1" Mname.IdName : triggerName >

StateTransition -- Traverser : --(guard)--
StateTransition -[dotted]- Body : (effect)

Body -r[dotted]- Traverser

StateTransition <|-r[dotted]- StarterTransition

package Mname <<Frame>> {
    class IdName {
        {field} ID : number <<KEY>>
        {field} Name : string <<UNIQUE>>
    }
}

class DoActivityAction {
    {field} interval_ms: number
}

class Traverser {
    {field} targetIndex: number
}

interface Body {
}

interface DoActivityBody {
    {field} counter : number
}

annotation InitialPseudostate
annotation StarterTransition

```

## pxt-mstate の `run-to-complition`

`WaitPoint` で、**トリガー**や**doカウンター**を待ち、`doProc`で、一連の`run-to-complition`ステップを処理する。

```plantuml

@startuml
'
' PlantUML Web server:
' https://www.plantuml.com/plantuml/
'
state __M0__ {
[*] -r-> constructor
state Completed : - entryActionの実行
Completed --> DoAtFirst
state constructor : - 現在状態=FinalState\n(StarterTransition)
constructor --> WaitPoint
state DoAtFirst : - doActivityの実行(初回:counter=0)
DoAtFirst --> EvalCompletion
state EvalCompletion #pink : - completion transitionの評価(gurad)\n- effectの実行と遷移先の決定
EvalCompletion --> Reached : [ 遷移先あり ] / target=遷移先
EvalCompletion --> EvalTrigger : [ 遷移先なし ]
state EvalDoCounter : - doカウンターの評価\n- doActivityの実行(counter=1..)
EvalDoCounter --> EvalCompletion : [ 実行あり ]
EvalDoCounter --> WaitPoint : [ 実行なし ]
state EvalTrigger #pink : - トリガーの評価(trigger,guard)\n- effectの実行と遷移先の決定
EvalTrigger --> Reached : [ 遷移先あり ] / target=遷移先
EvalTrigger --> EvalDoCounter : [ 遷移先なし ]
state Reached #pink : - exitActionの実行
Reached --> Traversed
state Traversed : - 現在状態=(target)\n- doカウンターのリセット
Traversed --> Completed
state WaitPoint #pink : トリガーやdoカウンターを待つ
WaitPoint --> EvalTrigger : doProc
}
'
' generator: https://github.com/jp-rad/pxt-mstate
'
' PlantUML Web server:
' https://www.plantuml.com/plantuml/
'
@enduml

```
:::note info
**実装上のヒント**
switch-caseで、遷移元が複数ある状態（エントリーポイント）へジャンプする。
`doProc`で`EvalTrigger`へジャンプし、`WaitPoint`になったら、一連の処理を終了し、次の`doProc`を待つ。
:::

| # | 状態         |遷移元|エントリーポイント|
|:-:|----------------|---|-----------------|
| 0 | constructor    | 1 |  |
| 1 | WaitPoint      | **2** | **WaitPoint** |
| 2 | EvalTrigger    | **2** | **EvalTrigger** |
| 3 | EvalDoCounter  | 1 |  |
| 4 | EvalCompletion | **2** | **EvalCompletion** |
| 5 | Reached        | **2** | **Reached** |
| 6 | Traversed      | 1 |  |
| 7 | Completed      | 1 |  |
| 8 | DoAtFirst      | 1 |  |

<details><summary>ソースコード</summary>

```js:JavaScript

mstate.defineState(StateMachines.M0, "DoAtFirst", function () {
    mstate.descriptionUml("- doActivityの実行(初回:counter=0)")
    mstate.declareEntry(function () {
    	
    })
    mstate.declareSimpleTransition("", "EvalCompletion")
})
mstate.defineState(StateMachines.M0, "WaitPoint", function () {
    mstate.declareSimpleTransition("doProc", "EvalTrigger")
    mstate.descriptionUml("トリガーやdoカウンターを待つ")
})
mstate.defineState(StateMachines.M0, "EvalDoCounter", function () {
    mstate.descriptionUml("- doカウンターの評価")
    mstate.descriptionUml("- doActivityの実行(counter=1..)")
    mstate.descriptionsUml(["実行あり", "実行なし"])
    mstate.declareStateTransition("", ["EvalCompletion", "WaitPoint"], function () {
    	
    })
})
mstate.defineState(StateMachines.M0, "Reached", function () {
    mstate.descriptionUml("- exitActionの実行")
    mstate.declareEntry(function () {
    	
    })
    mstate.declareSimpleTransition("", "Traversed")
})
mstate.defineState(StateMachines.M0, "EvalTrigger", function () {
    mstate.descriptionUml("- トリガーの評価(trigger,guard)")
    mstate.descriptionUml("- effectの実行と遷移先の決定")
    mstate.declareEntry(function () {
    	
    })
    mstate.descriptionsUml(["遷移先あり/target=遷移先", "遷移先なし"])
    mstate.declareStateTransition("", ["Reached", "EvalDoCounter"], function () {
    	
    })
})
mstate.defineState(StateMachines.M0, "EvalCompletion", function () {
    mstate.descriptionUml("- completion transitionの評価(gurad)")
    mstate.descriptionUml("- effectの実行と遷移先の決定")
    mstate.declareEntry(function () {
    	
    })
    mstate.descriptionsUml(["遷移先あり/target=遷移先", "遷移先なし"])
    mstate.declareStateTransition("", ["Reached", "EvalTrigger"], function () {
    	
    })
})
mstate.defineState(StateMachines.M0, "constructor", function () {
    mstate.declareSimpleTransition("", "WaitPoint")
    mstate.descriptionUml("- 現在状態=FinalState\\n(StarterTransition)")
})
mstate.defineState(StateMachines.M0, "Traversed", function () {
    mstate.descriptionUml("- 現在状態=(target)")
    mstate.descriptionUml("- doカウンターのリセット")
    mstate.declareEntry(function () {
    	
    })
    mstate.declareSimpleTransition("", "Completed")
})
mstate.defineState(StateMachines.M0, "Completed", function () {
    mstate.descriptionUml("- entryActionの実行")
    mstate.declareEntry(function () {
    	
    })
    mstate.declareSimpleTransition("", "DoAtFirst")
})
mstate.exportUml(StateMachines.M0, "constructor", false, true)

```

</details>

### completion transitionの永久ループ問題と解決策

次々と連続する状態遷移で、 **completion transition が繰り返されると、** `WaitPoint` を経由しない **永久ループになる場合があり**、 `run-to-complition` が途切れなくなるという問題がある。

```plantuml

[*] --> Reached
Reached -r-> Traversed
Traversed -r-> Completed
Completed --> DoAtFirst
DoAtFirst -l-> EvalCompletion
EvalCompletion -u-> Reached : [ 遷移あり ]

```

解決策として、**`DoAtFirst`** 実行後の **`EvalCompletion`** が、**`WaitPoint`** を待ってから行われるようにすればよく、**`isFirst`変数** で　**`WaitPoint`**　からの遷移先を切り替えるようにする。

```plantuml
@startuml
'
' PlantUML Web server:
' https://www.plantuml.com/plantuml/
'
state __M0__ {
[*] -r-> constructor
state Completed : - entryActionの実行
Completed --> DoAtFirst
state constructor : - 現在状態=FinalState\n(StarterTransition)\n- isFirst=false
constructor --> WaitPoint
state DoAtFirst #yellow : - doActivityの実行(初回:counter=0)
DoAtFirst --> WaitPoint : / isFirst=true, raiseRunToCompletion()
state EvalCompletion #pink : - completion transitionの評価(gurad)\n- effectの実行と遷移先の決定
EvalCompletion --> Reached : [ 遷移先あり ] / target=遷移先
EvalCompletion --> EvalTrigger : [ 遷移先なし ]
state EvalDoCounter : - doカウンターの評価\n- doActivityの実行(counter=1..)
EvalDoCounter --> EvalCompletion : [ 実行あり ]
EvalDoCounter --> WaitPoint : [ 実行なし ]
state EvalTrigger #pink : - トリガーの評価(trigger,guard)\n- effectの実行と遷移先の決定
EvalTrigger --> Reached : [ 遷移先あり ] / target=遷移先
EvalTrigger --> EvalDoCounter : [ 遷移先なし ]
state Reached #pink : - exitActionの実行
Reached --> Traversed
state Traversed : - 現在状態=(target)\n- doカウンターのリセット
Traversed --> Completed
state WaitPoint #pink : - 初回completionを待つ(isFirst)\n- トリガーやdoカウンターを待つ
WaitPoint --> EvalCompletion : doProc [ isFirst=true ] / isFirst=false
WaitPoint --> EvalTrigger : doProc [ isFirst=false ]
}
'
' generator: https://github.com/jp-rad/pxt-mstate
'
' PlantUML Web server:
' https://www.plantuml.com/plantuml/
'
@enduml
```

<details><summary>ソースコード</summary>

```js:JavaScript
mstate.defineState(StateMachines.M0, "DoAtFirst", function () {
    mstate.descriptionUml("- doActivityの実行(初回:counter=0)")
    mstate.declareEntry(function () {
    	
    })
    mstate.descriptionUml("/isFirst=true, raiseRunToCompletion()")
    mstate.declareSimpleTransition("", "WaitPoint")
})
mstate.defineState(StateMachines.M0, "WaitPoint", function () {
    mstate.descriptionUml("isFirst=true/isFirst=false")
    mstate.declareSimpleTransition("doProc", "EvalCompletion")
    mstate.descriptionUml("isFirst=false")
    mstate.declareSimpleTransition("doProc", "EvalTrigger")
    mstate.descriptionUml("- 初回completionを待つ(isFirst)")
    mstate.descriptionUml("- トリガーやdoカウンターを待つ")
})
mstate.defineState(StateMachines.M0, "EvalDoCounter", function () {
    mstate.descriptionUml("- doカウンターの評価")
    mstate.descriptionUml("- doActivityの実行(counter=1..)")
    mstate.descriptionsUml(["実行あり", "実行なし"])
    mstate.declareStateTransition("", ["EvalCompletion", "WaitPoint"], function () {
    	
    })
})
mstate.defineState(StateMachines.M0, "Reached", function () {
    mstate.descriptionUml("- exitActionの実行")
    mstate.declareEntry(function () {
    	
    })
    mstate.declareSimpleTransition("", "Traversed")
})
mstate.defineState(StateMachines.M0, "EvalTrigger", function () {
    mstate.descriptionUml("- トリガーの評価(trigger,guard)")
    mstate.descriptionUml("- effectの実行と遷移先の決定")
    mstate.declareEntry(function () {
    	
    })
    mstate.descriptionsUml(["遷移先あり/target=遷移先", "遷移先なし"])
    mstate.declareStateTransition("", ["Reached", "EvalDoCounter"], function () {
    	
    })
})
mstate.defineState(StateMachines.M0, "EvalCompletion", function () {
    mstate.descriptionUml("- completion transitionの評価(gurad)")
    mstate.descriptionUml("- effectの実行と遷移先の決定")
    mstate.declareEntry(function () {
    	
    })
    mstate.descriptionsUml(["遷移先あり/target=遷移先", "遷移先なし"])
    mstate.declareStateTransition("", ["Reached", "EvalTrigger"], function () {
    	
    })
})
mstate.defineState(StateMachines.M0, "constructor", function () {
    mstate.declareSimpleTransition("", "WaitPoint")
    mstate.descriptionUml("- 現在状態=FinalState\\n(StarterTransition)")
    mstate.descriptionUml("- isFirst=false")
})
mstate.defineState(StateMachines.M0, "Traversed", function () {
    mstate.descriptionUml("- 現在状態=(target)")
    mstate.descriptionUml("- doカウンターのリセット")
    mstate.declareEntry(function () {
    	
    })
    mstate.declareSimpleTransition("", "Completed")
})
mstate.defineState(StateMachines.M0, "Completed", function () {
    mstate.descriptionUml("- entryActionの実行")
    mstate.declareEntry(function () {
    	
    })
    mstate.declareSimpleTransition("", "DoAtFirst")
})
mstate.exportUml(StateMachines.M0, "constructor", false, true)

```

</details>

### 同一周期で実行される振る舞い

同一の周期内で、状態遷移が繰り返されないように、`WaitPoint`を経由するようにしました。それでも、状態遷移が起こった際には、 (遷移元の)`exitAction`と（遷移先の）`entryAction`、`doActivitry`が同一の周期内で連続して実行されます。
この連続した実行がどのような結果をもたらすのかを十分に考慮する必要があります。

:::note info
【参考文献】ミーリ・ムーアタイプの状態遷移図
実行するアクションにより、その結果（出力）がどのように異なるのか（遅延するのか）を次の書籍で解説しています。

[久保孝行: 組み込みエンジニアのための状態遷移設計手法
TechShare株式会社, p.p.137-149](https://www.amazon.co.jp/%E7%B5%84%E8%BE%BC%E3%81%BF%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E7%8A%B6%E6%85%8B%E9%81%B7%E7%A7%BB%E8%A8%AD%E8%A8%88%E6%89%8B%E6%B3%95%E2%80%95%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B%E7%8A%B6%E6%85%8B%E9%81%B7%E7%A7%BB%E5%9B%B3%E3%83%BB%E7%8A%B6%E6%85%8B%E9%81%B7%E7%A7%BB%E8%A1%A8%E3%81%AE%E8%A8%98%E8%BF%B0%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF%E2%80%95-MBD-Lab-%E4%B9%85%E4%BF%9D%E5%AD%9D%E8%A1%8C/dp/4906864031?pd_rd_w=YDYMO&content-id=amzn1.sym.3b32c2f6-e6f7-43e2-ac40-fd65e56b52d8&pf_rd_p=3b32c2f6-e6f7-43e2-ac40-fd65e56b52d8&pf_rd_r=ENYX3H17CMW4WNF72HFP&pd_rd_wg=SoBmt&pd_rd_r=0ce52385-2b6b-4768-a0a4-ab4e42669249&pd_rd_i=4906864031&psc=1&linkCode=ll1&tag=ahxyz0b-22&linkId=4277cb00ac244cfb26a6021582c74c2f&language=ja_JP&ref_=as_li_ss_tl)

:::

**組み込みエンジニアのための状態遷移設計手法**

https://www.amazon.co.jp/%E7%B5%84%E8%BE%BC%E3%81%BF%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E7%8A%B6%E6%85%8B%E9%81%B7%E7%A7%BB%E8%A8%AD%E8%A8%88%E6%89%8B%E6%B3%95%E2%80%95%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B%E7%8A%B6%E6%85%8B%E9%81%B7%E7%A7%BB%E5%9B%B3%E3%83%BB%E7%8A%B6%E6%85%8B%E9%81%B7%E7%A7%BB%E8%A1%A8%E3%81%AE%E8%A8%98%E8%BF%B0%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF%E2%80%95-MBD-Lab-%E4%B9%85%E4%BF%9D%E5%AD%9D%E8%A1%8C/dp/4906864031?pd_rd_w=YDYMO&content-id=amzn1.sym.3b32c2f6-e6f7-43e2-ac40-fd65e56b52d8&pf_rd_p=3b32c2f6-e6f7-43e2-ac40-fd65e56b52d8&pf_rd_r=ENYX3H17CMW4WNF72HFP&pd_rd_wg=SoBmt&pd_rd_r=0ce52385-2b6b-4768-a0a4-ab4e42669249&pd_rd_i=4906864031&psc=1&linkCode=ll1&tag=ahxyz0b-22&linkId=4277cb00ac244cfb26a6021582c74c2f&language=ja_JP&ref_=as_li_ss_tl

# 引用メモ

**UML 2 の仕様 - the Unified Modeling Language (UML), revision 2**

https://www.omg.org/spec/UML

:::note warn
UML仕様のver.2.5.1を参照しています。
https://www.omg.org/spec/UML/2.5.1/PDF
:::

<details><summary>引用の( ..)φメモメモ</summary>

## 14 StateMachines

> 14 StateMachines
p.305 (347), https://www.omg.org/spec/UML/2.5.1/PDF

### 14.1 Summary - 概要

> **14.1 Summary**
The StateMachines package defines a set of concepts that can be used for modeling **discrete event-driven Behaviors** using **a finite state-machine formalism**. 
...

p.305 (347), https://www.omg.org/spec/UML/2.5.1/PDF

:::note info
**Havid Harel氏の「ハレルの状態遷移図」（ハレルチャート）**

> 14.1 Summary
... 
The specific form of finite state automata used in UML is based on **an object-oriented variant of David Harel’s statecharts formalism.** (However, readers who are familiar with that formalism should note that there is a small number of semantic differences that distinguish the UML version from the original.)

p.305 (347), https://www.omg.org/spec/UML/2.5.1/PDF

:::

## 14.2.3.2 Regions - リージョン

> 14.2.3.2 Regions
p.307 (349), https://www.omg.org/spec/UML/2.5.1/PDF

> It may have its own **initial Pseudostate** as well as its own **FinalState**.

|glossary|用語|
|----|-----|
|initial Pseudostate|開始状態（疑似）|
|FinalState|終了状態|

## 14.2.3.4 States - 状態

> 14.2.3.4 States
p.308 (350), https://www.omg.org/spec/UML/2.5.1/PDF

### 14.2.3.4.3 State entry, exit, and doActivity Behaviors - 状態の振る舞い

> 14.2.3.4.3 State entry, exit, and doActivity Behaviors
p.309 (351), https://www.omg.org/spec/UML/2.5.1/PDF


## 14.2.3.6 FinalState - 終了状態

> 14.2.3.6 FinalState
p.312 (354), https://www.omg.org/spec/UML/2.5.1/PDF

## 14.2.3.7 Pseudostate and PseudostateKind - 疑似状態

> 14.2.3.7 Pseudostate and PseudostateKind
p.312 (354), https://www.omg.org/spec/UML/2.5.1/PDF


|glossary|用語|
|----|-----|
|initial|開始状態|
|choice|選択状態|


## 14.2.3.8 Transitions - 状態遷移

> 14.2.3.8 Transitions
p.314 (356), https://www.omg.org/spec/UML/2.5.1/PDF

>A **Transition** is a single directed arc originating from a single **source** Vertex and terminating on a single **target** Vertex (the source and target may be the same Vertex), which specifies a valid fragment of a StateMachine Behavior. It may have an associated **effect** Behavior, which is executed when the Transition is **traversed** (executed).


|glossary|用語|
|----|-----|
|Transition|状態遷移|
|source|遷移元(状態)|
|target|遷移先(状態)|
|effect|エフェクト（振る舞い）|
|traverse|遷移する（実行する）|

>Transitions are executed as part of a more complex compound transition that takes a StateMachine execution from one stable state configuration to another. The semantics of compound transitions are described below.
>
> In the course of execution, a Transition instance is said to be:
> - **reached**, when execution of its StateMachine execution has reached its source Vertex (i.e., its source State is in the active state configuration);
> - **traversed**, when it is being executed (along with any associated effect Behavior); and
> - **completed**, after it has reached its target Vertex.


|glossary|用語|
|----|-----|
|reached|遷移着手|
|traversed|遷移中|
|completed|遷移完了|

### 14.2.3.8.3 Completion Transitions and completion events - 完了による状態遷移

> 14.2.3.8.3 Completion Transitions and completion events
p.314 (356), https://www.omg.org/spec/UML/2.5.1/PDF

|glossary|用語|
|----|-----|
|Completion Transition|完了時遷移|


## 14.2.3.9 Event Processing for StateMachines - 内部のイベント処理

### 14.2.3.9.1 The run-to-completion paradigm - run-to-completion パラダイム

> 14.2.3.9.1 The run-to-completion paradigm
p.316 (358), https://www.omg.org/spec/UML/2.5.1/PDF

>The processing of Event occurrences by a StateMachine execution conforms to the general semantics defined in Clause 13.
>Upon creation, a StateMachine will perform its initialization during which it executes an initial compound transition prompted by the creation, after which it enters a wait point.
>In case of StateMachine Behaviors, **a wait point** is represented by a stable state configuration.
>It remains thus until **an Event stored** in its **event pool** is **dispatched.**
>This **Event is evaluated** and, if it **matches a valid Trigger** of the StateMachine and there is at least one enabled Transition that can be triggered by that Event occurrence, a single **StateMachine step** is executed.
>A step involves executing a compound transition and terminating on a stable state configuration (i.e., the next wait point).
>**This cycle then repeats until** either the StateMachine completes its Behavior or until it is asynchronously terminated by some external agent.
>StateMachines can respond to any of the Event types described in Clause 13 as well as to completion events (see above).
> **NOTE.** As explained above, completion events have priority and will be dispatched ahead of any pending Event occurrences in the event pool.
>Event occurrences are detected, dispatched, and processed by the StateMachine execution, one at a time.
>**NOTE.** The order of **event dispatching** is left undefined, allowing for **varied scheduling algorithms.**

>**This cycle** is referred to as **the run-to-completion paradigm**, and the corresponding **StateMachine step** is called a **run-to-completion step**.
>**Run-to-completion means that**, in the absence of exceptions or asynchronous destruction of the context Classifier object or the StateMachine execution, a pending Event occurrence is dispatched only after the processing of the previous occurrence is **completed** and a stable state configuration has been **reached**.
>That is, an Event occurrence **will never be dispatched** while the StateMachine execution **is busy** processing the previous one.
>This behavioral paradigm was chosen to avoid complications arising from concurrency conflicts that may arise when a StateMachine tries to respond to multiple concurrent or overlapping events.


|glossary|用語|
|----|-----|
|cycle, run-to-completion paradigm|パラダイム（サイクル）|
|step, run-to-completion step|ステップ|



>When an Event occurrence is detected and dispatched, it may result in one or more Transitions being enabled for firing.
>**If no Transition is enabled** and the corresponding Event type is not in any of the deferrableTriggers lists of the active state configuration, the dispatched Event occurrence is discarded and the run-to-completion step **is completed** trivially.
>Due to the presence of orthogonal Regions, it is possible that multiple Transitions (in different Regions) can be triggered by the same Event occurrence.
>**The order** in which these Transitions are executed **is left undefined.**
>Each orthogonal Region in the active state configuration that does not contain nested orthogonal Regions (i.e., a “bottomlevel” Region) **can fire at most one Transition** as a result of the current Event occurrence.
>When all orthogonal Regions have finished executing the Transition, the current Event occurrence **is fully consumed**, and the run-to-completion step **is completed.**


|glossary|用語|
|----|-----|
|consumed|消費, トリガーなどの発生イベントが全てなくなった状態|
|completed|完了, `run-to-completion`のステップが完了した状態|


>As mentioned above, it is possible for multiple mutually exclusive Transitions in a given Region to be enabled for firing by the same Event occurrence.
>In those cases, **only one is selected and executed**. Which of the enabled Transitions is chosen is determined by the Transition selection algorithm described below.
>During a Transition, a number of actions Behaviors may be executed.
>If such a Behavior includes a synchronous invocation call on another object executing a StateMachine, then the Transition step **is not completed** until **the invoked object method completes** its run-to-completion step.


>**Run-to-completion may be implemented** in various ways.
>**For active Classes**, it may be realized by **an event-loop running** in its own thread, and that reads **event occurrences** from a pool.
>**For passive Classes** it may be implemented using **a monitor**.
>**IMPLEMENTATION NOTE.** Run-to-completion is often mistakenly interpreted as implying that an executing StateMachine cannot be interrupted, which, of course would lead to priority inversion issues in some time-sensitive systems.
>However, this is not the case; in a given implementation a thread executing a StateMachine step can **be suspended**, allowing higher-priority threads to run, and, once it is allocated processor time again by the underlying thread scheduler, it can safely resume its execution and complete its event processing.




## 13 Common Behavior

### 13.1 Summary

>This clause specifies the core concepts underlying all behavioral modeling in UML. 
>Structural models of Classifiers in UML define the allowable instances that may exist at any point in time, what values their StructuralFeatures may have and how those instances may be related to each other.
>Behavioral modeling, on the other hand, models how these instances may change over time.


>UML provides Behavior, Event, and Trigger constructs to model the corresponding fundamental concepts of behavioral modeling.
>Behavior is the basic concept for modeling dynamic change.
>Behavior may be executed, either by direct invocation or through the creation of an active object that hosts the behavior.
>Behavior may also be emergent, resulting from the interaction of one or more participant objects that are themselves carrying out their own individual behaviors.
>Dynamic behavior results in events of interest that occur at specific points in time.
>Such events may be implicit, occurring on the change of some value or the passage of some interval of time.
>They may also be explicit, occurring when an operation is called or an asynchronous signal is received.
>The occurrence of an event may then trigger new behavior, or change the course of already executing behavior.
> Explicit events thus provide the basic mechanism for communication between behaviors, in which an action carried out in one behavior, such as calling an operation or sending a signal, can trigger a response in another behavior.


>The remainder of this clause further details the fundamental UML modeling mechanisms of Behaviors, Events and Triggers.
>These mechanisms then provide the framework for the specification in the following clauses of various complete UML behavioral modeling constructs.


### 13.2 Behaviors

#### 13.2.1 Summary

>This sub clause introduces the framework for modeling behavior in UML. The concrete subtypes of Behavior, described in subsequent clauses, then provide different mechanisms to specify behaviors.
>A variety of behavioral specification mechanisms are supported by UML, including:
>- StateMachines that model finite automata (see Clause 14)
>- Activities defined using Petri-net-like graphs (see Clause 15)
>- Interactions that model partially-ordered sequences of event occurrences (see Clause 17).
>
>These behavioral specification mechanisms differ in their expressive power and domain of applicability.
>This means that not all behaviors can be described by each of the mechanisms. Nevertheless, many behaviors can be described by one or more of the mechanisms, in which case the choice of mechanism is one of convenience, or, alternatively, multiple mechanisms can be used to provide different models of the same behavior.

</details>