воскресенье, 31 января 2016 г.

Айвика: ветвящееся дискретно-событийное моделирование на Haskell

На днях сделал анонс своих новых наработок на Haskell Cafe. Повторю и здесь.

Выпустил три новых релиза. Это входит в серию библиотек, которую я условно называю Айвикой [1, 2, 3]. Главная новинка - пакет aivika-branches [3], который позволяет делать то, что я для себя назвал «ветвящимся дискретно-событийным моделированием» (англ. «branching discrete event simulation») с возможностью запускать вложенные имитации внутри имитации для предсказания и оценки будущего поведения системы на этапе самой имитации. Сейчас попробую описать подробнее.

Допустим, что у нас есть достаточно общая библиотека, которая позволяет реализовывать дискретно-событийные модели. Там могут быть потоки случайных заданий (требований, они же, тразакты). Могут быть ограниченные ресурсы, за которые идет конкурентная борьба дискретных процессов. Есть глобальная очередь событий. Есть просто очереди сущностей. Есть активности, привязанные к обработке событий и т.п. В общем, все то, что реализовано в моем пакете aivika [1].

Мой метод заключается в том, что мы описываем поведение имитационной модели с помощью абстрактных вычислений. Во время своего запуска основное вычисление имеет состояние, которое сводится к состоянию очереди обработчиков будущих событий и к состоянию всех ссылок (они же, переменные), которые используются в модели.

Теперь главная новинка. Представим, что мы умеем достаточно эффективно клонировать состояние модели, порождая производную ветвь модели в текущий момент времени. То есть, мы клонируем и очередь всех обработчиков будущих событий, которые должны еще отработать в будущем. Мы также клонируем состояние всех изменяемых ссылок для новой ветки модели.

Тогда мы можем запросить из текущего времени будущее значение заданного под-вычисления, как если бы мы продолжили текущую имитацию, но без фактического изменения самой имитации!

Именно это умеет делать следующая функция из нового пакета aivika-branches [3]:

futureEvent :: Double -> Event BrIO a -> Event BrIO a

Здесь мы создаем новую ветку имитационной модели и запускаем заданное под-вычисление в желаемое время в будущем или настоящем, причем текущая имитационная модель остается нетронутой. В порожденной ветке отрабатывают все ожидающие выполнения обработчики событий вплоть до заданного времени.

Что касается типов, то здесь появляются монадные трансоформеры из другого пакета aivika-transformers [2], который является обобщение пакета aivika. На самом деле, пакет aivika-transformers я подготовил для реализации распределенного и параллельного дискретно-событийного моделирования, но он получился таким общим и гибким, что я смог его применить и к ветвящемуся дискретно-событийному моделированию.

Как я уже написал, фишка в том, что функция futureEvent относительно дешевая. Мы можем относительно быстро клонировать состояние целого мира имитационной модели! Это стало возможным во многом благодаря повсеместному использованию приемов функционального программирования (тут в скобках замечу, что очень забавно со стороны смотрятся те, кто наивно полагает по своему неразумению, что монада IO не относится к функциональному программированию. Просто не понимают, что функциональное и императивное программирование - это разные, но совсем не антагонистичные и не исключающие друг друга взгляды на то, как можно писать компьютерные программы. Эти оба взгляда вполне могут сосуществовать). Еще там используются такие вещи, как слабые ссылки для того, чтобы не было утечки пространства (англ. space leak) при разветвлении состояния ссылок, чтобы вовремя подчищалась память.

Фактически получаем дерево имитаций, которое нужно ограничивать или по уровню вложенности или с помощью метода ветвей и границ. Что-то похожее встречается в финансовом моделировании.

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

[1] http://hackage.haskell.org/package/aivika
[2] http://hackage.haskell.org/package/aivika-transformers
[3] http://hackage.haskell.org/package/aivika-branches