質問

ネイティブ(FSM生成ツールなし)の言語に対する推奨事項は、ステートマシン開発と実行およびメッセージ/信号の受け渡しをサポートします。これは通信向けです。たとえば、このレベルの複雑さのFSMの実装です。

Erlangを検討しましたが、フィードバック、提案、チュートリアルへのポインタ、代替手段、特にJavaベースのフレームワークが大好きです。たぶんスカラ?

オープンソースのみ。 UMLや正規表現関連のソリューションを探しているわけではありません。

これは通信プロトコルの実装用であるため、FSMは重要な場合があります。多くの状態、多くの遷移、信号ベース、入力制約/ガード。動的なインスタンス化はプラスになります。 Switchステートメントは問題外で、すぐに使用不能にネストします。 if / elseの方がましです。

グラフィックデザインに依存しない を希望します。フォーマットFSMの記述は、人間が読み取り可能/編集可能/管理可能にする必要があります。

-

C ++のアクターベースのソリューションに焦点を合わせることにしました

たとえば、Theronフレームワークは開始点 http://theron.ashtonmason.net/ を提供します。 FSMベースのイベントハンドラーでswitchステートメントを回避するには、このC ++ FSMテンプレートフレームワークが便利に見えます http:// satsky.spb.ru/articles/fsm/fsmEng.php

役に立ちましたか?

解決

switchステートメントは問題外であるべきであることに同意します...それらは最終的にメンテナンスの悪夢につながります。 状態パターンでFSMを実装しますか?実際の実装に応じて、アクターを使用することができます(複数のFSMが連携している場合-それは可能ですか?)。アクターの良いところは、メッセージを渡すためのフレームワークがすでにあることです。

Stateの使用例は次のとおりです。

trait State {
  def changeState(message: Any): State
}

trait FSM extends Actor {
  var state: State

  def processMessage(message: Any) {
    state = state.changeState(message)
  }

  override def act() {
    loop {
      react {
        case m: Any => processMessage(m)
      }
    }
  }
}

これは非常に基本的なコードですが、要件の詳細がわからないので、それが最も考えられることです。状態の利点は、すべての状態が1つのクラスに含まれていることです。

他のヒント

この特定のアプリケーション、電話会社のプロトコル実装は、Erlangが構築されたものです。エリクソンのErlangの最初のアプリケーションは電話交換機であり、最も初期の商用製品はあらゆる種類の通信プロトコルをサポートするATMスイッチでした。

OTPには、 gen_fsm と呼ばれるFSMを実装するための標準的な動作があります。一部の OTPドキュメント

OSERL は、ErlangのオープンソースSMPP実装であり、 gen_fsm s。良い例は、 gen_esme_session

コードを紹介することはできませんが、電話会社向けの製品を販売しているErlangの企業がかなりあることを知っています。 Corelatus Synapse 動機

FSMの実装は簡単ではないことに同意しません。これは非常に近視眼的であり、代替手段に精通していないか、複雑なステートマシンの経験がないことを示しています。

根本的な問題は、ステートマシンのグラフは明らかですが、FSM code はそうではないということです。数十の状態と遷移のスコアを超えると、FSMコードは見づらくなり、追跡が困難になります。

ステートマシンを描画し、そのためのJavaコードを生成するツールがあります。ただし、そのためのオープンソースツールは知りません。

今、Erlang / Scalaに戻ると、Scalaにはアクターとメッセージパッシングもあり、JVMに基づいているため、制約を考えるとErlangよりも優れた選択肢になるかもしれません。

ScalaにはDFA / NFAライブラリもありますが、特に良いライブラリではありません。任意の正規表現(つまり、リテラルは文字である必要はありません)からDFA / NFAへの変換をサポートしています。

それを使用して以下のコードを投稿します。このコードでは、アイデアは、単語リストの任意のプレフィックスの任意の連続した組み合わせを受け入れるFSMを作成します。アイデアは、事前定義されたキーバインドなしでメニューオプションを検索します。

import scala.util.regexp._
import scala.util.automata._

// The goal of this object below is to create a class, MyChar, which will
// be the domain of the tokens used for transitions in the DFA. They could
// be integers, enumerations or even a set of case classes and objects. For
// this particular code, it's just Char.
object MyLang extends WordExp {
  type _regexpT = RegExp
  type _labelT = MyChar

  case class MyChar(c:Char) extends Label
}

// We now need to import the types we defined, as well as any classes we
// created extending Label.    
import MyLang._

// We also need an instance (singleton, in this case) of WordBerrySethi,
// which will convert the regular expression into an automatum. Notice the
// language being used is MyLang.    
object MyBerrySethi extends WordBerrySethi {
  override val lang = MyLang
}

// Last, a function which takes an input in the language we defined,
// and traverses the DFA, returning whether we are at a sink state or
// not. For other uses it will probably make more sense to test against
// both sink states and final states.
def matchDet(pat: DetWordAutom[MyChar], seq: Seq[Char]): Boolean =
  !pat.isSink((0 /: seq) ((state, c) => pat.next(state, MyChar(c))))

// This converts a regular expression to a DFA, with using an intermediary NFA    
def compile(pat: MyLang._regexpT) = 
  new SubsetConstruction(MyBerrySethi.automatonFrom(pat, 100000)).determinize

// Defines a "?" function, since it isn't provided by the library
def Quest(rs: _regexpT*) = Alt(Eps, Sequ(rs: _*)) // Quest(pat) = Eps|pat = (pat)?


// And now, the algorithm proper. It splits the string into words
// converts each character into Letter[MyChar[Char]],
// produce the regular expression desired for each word using Quest and Sequ,
// then the final regular expression by using Sequ with each subexpression.
def words(s : String) = s.split("\\W+")
def wordToRegex(w : String) : Seq[MyLang._regexpT] = w.map(c => Letter(MyChar(c)))
def wordRegex(w : String) = Quest(wordToRegex(w) reduceRight ((a,b) => Sequ(a, Quest(b))))
def phraseRegex(s : String) = Sequ(words(s).map(w => wordRegex(w)) : _*)

// This takes a list of strings, produce a DFA for each, and returns a list of
// of tuples formed by DFA and string.
def regexList(l : List[String]) = l.map(s => compile(phraseRegex(s)) -> s)

// The main function takes a list of strings, and returns a function that will
// traverse each DFA, and return all strings associated with DFAs that did not
// end up in a sink state.
def regexSearcher(l : List[String]) = {
  val r = regexList(l)
  (s : String) => r.filter(t => matchDet(t._1, s)).map(_._2)
}

FSMの実装が重要な言語はほとんど考えられません。たぶんこれ

...
if (currentState == STATE0 && event == EVENT0) return STATE1;
if (currentState == STATE1 && event == EVENT0) return STATE2;
...

(Java列挙を使用した)状態パターンは、通信アプリケーションで使用するものですが、小さなFSMを使用します:

public class Controller{
    private State itsState = State.IDLE;

    public void setState(State aState){
        itsState = aState;
    }

    public void action1(){
        itsState.action1(this);
    }

    public void action2(){
        itsState.action2(this);
    }

    public void doAction1(){
        // code
    }

    public void doAction2(){
        // code
    }
}

public enum State{
    IDLE{
        @Override
        public void action1(Controller aCtx){
            aCtx.doAction1();
            aCtx.setState(State.STATE1);
        }
    },

    STATE1{
        @Override
        public void action2(Controller aCtx){
            aCtx.doAction2();
            aCtx.setState(State.IDLE);
        }
    },

    public void action1(Controller aCtx){
        throw new IllegalStateException();
    }

    public void action2(Controller aCtx){
        throw new IllegalStateException();
    }
}

FSMは、caseステートメントがある言語で実装するのは簡単なはずです。言語の選択は、その有限状態マシンが行う必要があることに基づいている必要があります。

たとえば、通信開発のためにこれを行う必要があると述べ、メッセージに言及します。分散メッセージパッシングをサポートするシステム/言語を調べます。 Erlangはこれを行います。他のほぼすべての共通言語が、その言語のAPI /ライブラリを介してこれをサポートしていると確信しています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top