Конечный автомат и передача сигналов inter-FSM

Обычно, когда я имею дело с разделением \r или \n, я буду искать обоих путем выполнения чего-то как

lines.gsub(/\r\n?/, "\n");

, я нашел, что в зависимости от того, как данные были сохранены (используемая ОС, редактор использовал, отношение Юпитера к Io в то время) там может или может не быть новая строка после возврата каретки. Действительно кажется странным, что Вы видите оба символа в шестнадцатеричном режиме. Надежда это помогает.

14
задан 19 September 2009 в 09:54
поделиться

5 ответов

Я согласен, что о операторах переключения не может быть и речи ... они в конечном итоге приводят к кошмарам обслуживания. Разве вы не можете использовать State Pattern для реализации вашего 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)
      }
    }
  }
}

Это очень простой код, но, поскольку я не знаю больше требований, это большинство, о чем я могу думать. Преимущество State состоит в том, что каждое состояние автономно в одном классе.

8
ответ дан 1 December 2019 в 12:52
поделиться

Это конкретное приложение, реализация протокола телефонной связи, и было создано для Erlang. Первыми приложениями Erlang в Эрикссон были телефонные коммутаторы, а самыми ранними коммерческими продуктами были коммутаторы ATM, поддерживающие все виды протоколов телекоммуникаций.

OTP имеет стандартное поведение для реализации конечных автоматов, называемое gen_fsm . Пример его использования в нетривиальном автомате есть в некоторой документации OTP .

OSERL - это реализация SMPP с открытым исходным кодом в Erlang, которая демонстрирует, как можно реализовать протокол телефонной связи, используя gen_fsm с. Хороший пример, на который стоит обратить внимание, - это gen_esme_session .

Хотя я не могу указать вам на код, я знаю, что довольно много компаний на Erlang продают продукты, ориентированные на телекоммуникации:

10
ответ дан 1 December 2019 в 12:52
поделиться

Я вряд ли могу придумать какой-либо язык, на котором реализация конечного автомата была бы нетривиальной. Может быть этот .

...
if (currentState == STATE0 && event == EVENT0) return STATE1;
if (currentState == STATE1 && event == EVENT0) return STATE2;
...
0
ответ дан 1 December 2019 в 12:52
поделиться

Я не согласен с тем, что FSM тривиально реализовать. Это очень недальновидно и показывает либо недостаточное знакомство с альтернативами, либо отсутствие опыта работы со сложными конечными автоматами.

Фундаментальная проблема заключается в том, что граф конечного автомата очевиден, но Код FSM - нет. Как только вы выйдете за пределы дюжины состояний и множества переходов, код конечного автомата становится уродливым и трудным для понимания.

Существуют инструменты, с помощью которых вы рисуете конечный автомат и генерируете для него код Java. Однако я не знаю каких-либо инструментов с открытым исходным кодом для этого.

Теперь, возвращаясь к Erlang / Scala, в Scala также есть акторы и передача сообщений, и он основан на JVM, так что это может быть лучшей альтернативой чем Erlang с учетом ваших ограничений.

На Scala также есть библиотека DFA / NFA, хотя он не очень хороший. Он поддерживает преобразование произвольных регулярных выражений (т. Е. Литералы не обязательно должны быть символами) в DFA / NFA.

Я выложу код ниже, используя его. В этом коде идея заключается в создании конечного автомата, который будет принимать любую последовательную комбинацию произвольных префиксов для списка слов, идея заключается в поиске параметров меню без предопределенных сочетаний клавиш.

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)
}
4
ответ дан 1 December 2019 в 12:52
поделиться

Конечный автомат должен быть тривиальным для реализации на любом языке, который имеет оператор case. Ваш выбор языка должен основываться на том, что должен делать этот конечный автомат.

Например, вы заявляете, что вам нужно сделать это для развития телекоммуникаций, и упоминаете сообщения. Я бы посмотрел на системы / языки, которые поддерживают распределенную передачу сообщений. Erlang делает это, и я уверен, что почти любой другой распространенный язык поддерживает это через API / библиотеку для этого языка.

-1
ответ дан 1 December 2019 в 12:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: