Правительство Российской Федерации

advertisement
Правительство Российской Федерации
Федеральное государственное автономное образовательное учреждение
высшего профессионального образования
"Национальный исследовательский университет
"Высшая школа экономики"
Факультет: Бизнес-Информатика
Отделение: Программная инженерия
Кафедра: Управление разработкой программного обеспечения
МАГИСТЕРСКАЯ ДИССЕРТАЦИЯ
На тему: Инструментальная среда имитационного моделирования
распределенных систем мобильных агентов
Студент группы № 271мУРПО
Новикова Юлия Александровна
Подпись___________________
Научный руководитель
профессор,
доктор физико-математических
наук
Ломазова Ирина Александровна
Подпись___________________
Москва, 2013 г.
АННОТАЦИЯ
В
данной
работе
представляется
инструментальная
среда
имитационного
моделирования распределенных систем мобильных агентов (Timed Resource Driven
Automata nets Tool - TRDA Tool). Этот инструмент предназначен для моделирования и
анализа распределенных систем с динамически перемещаемыми агентами в течение
времени. В качестве входных данных TRDA Tool использует модели вида TRDA nets.
Модель TRDA nets двухуровневая, состоящая из системного и автоматного уровня.
Системный уровень (системная сеть) представлен сетью активных ресурсов. Графическое
представление сети активных ресурсов – граф с направленными ребрами, обозначающими
или производство, или потребление. В вершинах данного графа могут находиться агенты
и ресурсы. Автоматный уровень (автоматная сеть) - конечные автоматы, расширенные
различными возможностями учета времени, описывающие поведение разных типов
агентов в системной сети. При этом агенты сами могут выступать в качестве ресурсов.
При помощи модели TRDA можно решать классические задачи распределенных
взаимодействующих систем: задача об обедающих философах, задача о курильщиках,
задача о парикмахере. Это означает, что и в реальном мире есть системы, которые можно
моделировать на языке TRDA-модели при помощи TRDA Tool.
Данная работа состоит из трех частей и тридцати пяти приложений. В теоретическом
разделе представлен обзор существующих формальных моделей и дано формальное
определение разработанного на их основе формализма TRDA. Во втором разделе
представлен TRDA язык описания входных данных TRDA моделей, описаны возможности
по работе с TRDA Tool. В третьем разделе разобраны примеры задач для работы в TRDA
Tool. В приложении приведены исходные файла TRDA моделей, а так же исходные файлы
классов TRDA Tool.
Ключевые слова: Timed Resource Driven Automata net Tool, TRDA модель,
имитационное моделирование, двухуровневые сети Петри, анализ поведенческих свойств
2
Оглавление
АННОТАЦИЯ ..................................................................................................................... 2
ВВЕДЕНИЕ ......................................................................................................................... 6
1.
ФОРМАЛЬНЫЕ МОДЕЛИ РАСПРЕДЕЛЕННЫХ СИСТЕМ ................................ 9
1.1. Классические сети Петри ....................................................................................... 9
1.2 Временные сети Петри .......................................................................................... 10
1.3 Сети активных ресурсов ....................................................................................... 11
1.4 Ресурсно-управляемые сети автоматов ............................................................... 12
1.5 Временные автоматы ............................................................................................. 14
1.6
Ресурсно-управляемые сети временных автоматов ........................................ 15
2. СИСТЕМА TRDA TOOL ............................................................................................. 20
2.1 Анализ исходных данных и выбор оптимального решения поставленной
задачи ........................................................................................................................................ 20
2.2 Методы проектирования ....................................................................................... 21
2.3 Обоснование выбора программных и аппаратных средств ............................... 21
2.4 Проектирование связей ключевых компонент языка описания RDA сетей .... 23
2.5
Разработка языка описания модели типа ресурсно-управляемых сетей
временных автоматов .............................................................................................................. 25
2.6 Описание разработанного языка в нотации Бэкуса-Наура ................................ 27
2.7 Возможности TRDA Tool...................................................................................... 29
2.7.1. Возможности моделирования ........................................................................... 29
2.7.2. Возможности анализа ........................................................................................ 29
2.7.3 Поведенческие свойства .................................................................................... 30
2.7.4 Способ установки программы ........................................................................... 33
2.7.5 Соответствие графической визуализации текущего состояния модели ее
структурному представлению ................................................................................................ 34
3
3
ПРИМЕРЫ ПРИМЕНЕНИЯ TRDA TOOL ДЛЯ МОДЕЛИРОВАНИЯ И
АНАЛИЗА НЕКОТОРЫХ КЛАССИЧЕСКИХ ЗАДАЧ............................................................ 38
3.1 Задача об обедающих философах, гуляющих в парке ....................................... 38
3.2 Задача о философах с дедлоком ........................................................................... 47
3.3 Задача о спящем парикмахере .............................................................................. 49
3.4 Задача о мусорщиках ............................................................................................. 54
3.5 Задача о курильщиках ........................................................................................... 64
ЗАКЛЮЧЕНИЕ ................................................................................................................. 70
Список использованной литературы .............................................................................. 72
Приложения ....................................................................................................................... 73
Приложение 1 Задача о философах, гуляющих в парке .......................................... 73
Приложение 2 Задача о философах и дедлоке .......................................................... 77
Приложение 3 Задача о спящем парикмахере .......................................................... 80
Приложение 4.1 Задача о мусорщиках_1 .................................................................. 82
Приложение 4.2 Задача о мусорщиках_2 .................................................................. 84
Приложение 5 Задача курильщиках .......................................................................... 87
Приложение 6 Техническое задание .......................................................................... 89
Приложение 7 Программа и методика испытаний ................................................... 97
Приложение 8 Руководство оператору .................................................................... 102
Приложение 9 Класс ChartInfo.cs ............................................................................. 108
Приложение 10 Form_xml.cs..................................................................................... 110
Приложение 11 Form1.cs ........................................................................................... 112
Приложение 12 Form1.Designer.cs ........................................................................... 130
Приложение 13 Form1_io.cs ...................................................................................... 144
Приложение 14 FormChart.cs .................................................................................... 149
Приложение 15 FormChart.Designer.cs .................................................................... 153
Приложение 16 FormHelp.cs ..................................................................................... 155
Приложение 17 FormHelp.Designer.cs ..................................................................... 158
4
Приложение 18 FormLog.cs ...................................................................................... 160
Приложение 19 FormLog.Designer.cs ....................................................................... 161
Приложение 20 FormRezult.cs .................................................................................. 163
Приложение 21 FormRezult.Designer.cs ................................................................... 164
Приложение 22 FormVisual.cs .................................................................................. 166
Приложение 23 FormVisual.Designer.cs ................................................................... 169
Приложение 24 Lib.cs ................................................................................................ 174
Приложение 25 Model.cs ........................................................................................... 176
Приложение 26 Model_candidates.cs ........................................................................ 189
Приложение 27 Model_ChartInfo.cs ......................................................................... 198
Приложение 28 Model_dot.cs .................................................................................... 200
Приложение 29 Model_exec.cs .................................................................................. 204
Приложение 30 Model_init.cs.................................................................................... 210
Приложение 31 Model_log.cs .................................................................................... 216
Приложение 32 Model_marking.cs ............................................................................ 224
Приложение 33 MultyLanguage.cs ............................................................................ 227
Приложение 34 Program.cs ........................................................................................ 234
Приложение 35 State.cs ............................................................................................. 235
5
ВВЕДЕНИЕ
В настоящее время существует множество сложных систем, состоящих из разных
компонентов, активно между собой взаимодействующих. Для улучшения понимания
взаимодействия
отдельных
компонентов
модели
удобно
использовать
автоматизированное имитационное моделирование, так как это экономит силы и время.
Для
выполнения
автоматизированного
моделирования
необходимо
реализовать
программу-эмулятор исследуемой системы. Для подобных эмуляторов должна быть
определена
формальная
модель,
распознаваемая
и
выполняемая
программным
эмулятором. Под каждую конкретную задачу реального мира сложно создавать отдельную
формальную модель и эмулятор, поэтому необходима обобщенная модель, учитывающая
различные параметры в рассматриваемой области моделирования. В данной работе акцент
ставится на активном взаимодействии агентов, мобильности агентов, сложности
устройства агентов (агент – это объект, принимающий различные состояния и
манипулирующий в процессе своей работы входными и выходными ресурсами), учете
временных параметров. Теоретическими примерами такого класса моделей могут
выступать: задача об обедающих философах, задача о курильщиках, задача о спящем
парикмахере. В реальном мире это могут быть сложные веб-сервисы, передающие
информацию одновременно нескольким пользователям и использующие общие ресурсы;
многоканальные центры с несколькими параллельными линиями, принимающие звонки и
т.д.
В данной работе рассмотрен ряд формализмов, обладающих некоторыми из
необходимых
характеристик.
Приведенная
ниже
таблица
содержит
перечень
интересующих нас характеристик рассматриваемых формальных моделей.
Таблица 1
Интересующие нас свойства формальных моделей
Формальная модель
Классические Сети Петри [8]
Основные
интересные
для
нас
свойства
Известная
классическая
модель,
графическая
визуализация,
наличие
большого количества алгоритмов для
6
Формальная модель
Основные
интересные
для
нас
свойства
проверки свойств
Временные сети Петри: модель Мерлина
Учет временных характеристик: время
[6], модель Штарке [7]
выполнения перехода, время задержки
начала выполнения перехода
Временные автоматы [1]
Учет
временных
несколько
характеристик:
счетчиков
внутри
одной
модели, сбросы счетчиков, ограничения
Сети активных ресурсов [2] – AR nets
Эквиваленты
по
выразительности
классическим
сетям
Петри.
ресурсно-ориентированна:
Модель
вместо
классического разделения вершин на
позиции
и
переходы
(активные
и
пассивные компоненты) в данной модели
один тип вершин, но два типа дуг –
потребляющие и производящие.
Ресурсно-управляемые сети автоматов
Двухуровневое
обобщение
[3] – RDA nets
активных ресурсов. Конечные автоматы,
представляющие
данной
модели
элементные
(аналог
сетей
сети
в
фишки
в
классических сетях Петри) могут вести
себя как активным, так и пассивным
образом
(производить/потреблять
ресурсы или быть потребленными/быть
произведенными ресурсами)
Так же были отобраны и изучены программные инструменты, реализующие данные
формальные модели. Ниже приведена таблица, отражающая взаимосвязь формальной
модели и инструмента, позволяющего ее реализовать.
7
Таблица 2
Программные инструменты и реализуемые ими формальные модели
Программный инструмент
Формальная модель
CPN Tool [10], ProM [11]
Классические сети Петри [8]
UPPAAL [9]
Временные сети Петри: модель Мерлина
[6], модель Штарке [7]
UPPAAL [9]
Временные автоматы [1]
-
Сети активных ресурсов [2]
-
Ресурсно-управляемые сети автоматов [3]
Учитывая
достоинства различных формальных моделей и реализующих их
программных инструментов, необходимо выполнить поставленную в данной работе
задачу:
Разработать формальную модель для описания распределенных систем мобильных
агентов – ресурсо-управляемые сети временных автоматов и создать инструментальную
среду имитационного моделирования на основе данного формализма.
8
1. ФОРМАЛЬНЫЕ МОДЕЛИ РАСПРЕДЕЛЕННЫХ СИСТЕМ
В данном разделе будут изложены теоретические основы выбранных для
исследования моделей. На схеме 1 ниже приведена взаимосвязь разрабатываемой модели
с уже существующими формальными моделями. Зеленым цветом на диаграмме выделена
разрабатываемая модель - TRDA модель. Желтые квадраты - модели, послужившие
основой для разработки ресурсно-управляемых сетей автоматов в данной работе.
Формальные модели в красных квадратах приведены на диаграмме для представления
взаимосвязи
разрабатываемой
модели
с
другими
известными
по
литературе
формализмами.
Схема 1. Предыстория формализма TRDA
1.1. Классические сети Петри
Классические сети Петри - это формальная модель, разработанная Карлом Адамом
Петри в 1962 для описания химических реакций [8]. Модель представляется в виде
двудольного ориентированного графа, где два типа вершин соответствуют позициям
(метсам) и переходам. Внутри вершин типа «Позиция» находятся фишки, изображенные в
9
виде черных точек, символизирующие ресурсы. Позиции соединены с переходами
(вершинами типа «Переход») с помощью направленных дуг, сверху на которых
указывается их кратность. Считается, что переход готов к срабатыванию, если имеется
достаточное количество фишек во входных позициях данного перехода (достаточность
определяется с учетом кратности входных дуг данного перехода).
Дадим формальное определение Сети Петри. Сетью Петри называется набор
N=(P,T,F,M0), где
P — конечное множество мест
T — конечное множество переходов, PT=
F: (PT)(TP)Nat — функция инцидентности (0 включается в множество
натуральных
чисел).
Функция
инцидентности
определяет
наличие
и
кратность
направленных дуг между позициями и переходами (и наоборот, между переходами и
позициями) .
Маркировкой сети Петри N называется функция M: P  Nat, сопоставляющая
каждой позиции сети некоторое натуральное число - количество фишек в данной позиции.
Маркировка M0 – начальная маркировка, то есть начальная разметка системы.
Переход tT активен при разметке M, если pP M(p)F(p,t) . Это условие означает,
что во входных позициях перехода t количество фишек больше или равно кратности
соответствующих входных дуг этого перехода.
Активный при разметке M переход t может сработать, породив при этом новую
разметку M', где pP M'(p) =def M(p)F(p,t)+F(t,p). В новой разметке количество фишек,
в позициях, из которых идут входные дуги перехода, уменьшается на кратность
соответствующих дуг. Аналогичным образом, количество фишек в позициях, в которые
идут выходные дуги перехода, увеличивается на кратность выходных дуг перехода.
1.2 Временные сети Петри
Для более выразительного моделирования можно использоваться сети Петри со
временем. Время может быть введено в различные элементы сети: время срабатывания
перехода; время, которое фишка находится в состоянии, и т.д. Существует две основные
модели временных сетей Петри: модель Мерлина [6] и модель Штарке [7].
Рассмотрим эти две модели, введя время в срабатывание переходов.
Пусть N - множество натуральных чисел, а R – множество рациональных чисел
1)Модель Мерлина – непрерывно временная модель.
Непрерывно-временной сетью Петри называется набор CTN=(P,T,F,M0,D), где
10
(P,T,F,M0) – классическая сеть Петри
D:T→Interv — временная функция, сопоставляющая каждому переходу t ∈ T интервал D(t)
из множества Interv, где множество Interv = {[d1,d2] ⊂R,d1≤d2}.
Активность перехода определяется аналогичным классическим сетям Петри образом.
Пусть V:T→R — множество наборов значений часов, связанных с переходами из T.
Состоянием в CTN называется пара q=<M,ν>, где M — маркировка в CTN и ν∈V.
Будем говорить, что в состоянии q=<M,ν> переход t ∈ T может сработать, если переход T
активен t ∈ En(M) и счетчик времени v(t)∈D(t), соответствующий переходу t v(t), имеет
значение, попадающее в интервал, задаваемый временной функцией данного перехода D(t).
Срабатывание перехода происходит мгновенно.
2)Модель Штарке – дискретно временная модель. [7]
Дискретно-временной сетью Петри называется набор DTN=(P,T,F, M0,D), где
(P,T,F,M0) – классическая сеть Петри
D:T→N — временная функция, сопоставляющая каждому переходу натуральное число,
соответствующее временной длительности его срабатывания.
Для каждого перехода t значение D(t) определяет длительность срабатывания t, т.е
если переход t срабатывает в момент времени x, то фишки из входных мест перехода
t "уходят" в момент времени x и появляются в выходных местах перехода t в момент
времени x + D(t).
Предполагается правило максимального шага срабатывания, т.е. в любой момент
времени срабатывает все, готовые к срабатыванию, переходы.
При этом считается, что никакой переход не может срабатывать параллельно с
самим собой, даже если имеется достаточное количество входных ресурсов для
повторного срабатывания. Так же запрещается, чтобы переход начинал второе свое
срабатывание, не закончив первое.
1.3 Сети активных ресурсов
Сеть активных ресурсов [2], AR nets, - еще один формализм для моделирования
распределенных систем. Идея связана с тем, что активные агенты системы являются
одновременно ее ресурсами. AR nets по выразительности эквиваленты классическим
сетям Петри. Однако они отличаются от классических сетей Петри способом
моделирования. В отличие от классических сетей Петри, в которых вершины разбиты на
позиции и переходы (активные и пассивные компоненты), в AR nets все вершины одного
типа, а дуги делятся на производящие и потребляющие.
Сетью активных ресурсов называется набор AR=(V,I,O), где
11
V — конечное множество вершин
I: (VV)  Nat — множество потребляющих дуг. Потребляющей дуге ставится в
соответствие количество потребляемых ресурсов.
O: (VV)  Nat — множество производящих дуг. Производящей дуге ставится в
соответствие количество производимых ресурсов.
Графически вершины сети изображаются кружками, потребляющие дуги —
пунктирными стрелками, производящие дуги — непрерывными стрелками.
Разметкой сети AR называется функция вида M: V  Nat. Для каждой вершины
определяется количество находящихся в ней фишек (ресурсов).
Ресурс (агент) в вершине vV активен при разметке M, если M(v)>0 (узел v
непустой) и wV M(w)I(w,v) (в потребляемых узлах вершины v, из которых идут
потребляющие дуги в вершину v, содержится достаточное количество фишек). Активный
ресурс v при разметке M может сработать, порождая при этом новую разметку M', где
wV M'(w) =def M(w)I(w,v)+O(v,w). Как видно, вершина, в которой находится
активный ресурс, срабатывает, как если бы она временно стала переходом в обычной сети
Петри.
1.4 Ресурсно-управляемые сети автоматов
Ресурсно-управляемые сети автоматов, RDA-сети, [3] – разработанный на основе
AR-сетей формализм для моделирования взаимодействия распределенных агентов с
учетом ресурсных зависимостей. RDA-сеть имеет два уровня. Системный уровень
задается сетью активных ресурсов, которая описывает распределение агентов/ресурсов и
порты, через которые они могут взаимодействовать. Агенты, представлены конечными
автоматами, взаимодействующими друг с другом через порты системной сети.
Выполнение агентом перехода может быть связано с потреблением и производством
ресурсов.
Константа в модели RDA nets - это аналог фишки в классических сетях Петри.
Константы могут быть как простыми ресурсами, так и агентами, имеющими структуру
конечного автомата. Все константы типизированы. Пусть Ω - конечное множество типов
(types). Типы Ω типизируют как константы, так и порты системной сети. Тип порта
означает, что по нему возможна обработка (потребление или производство) констант
только данного типа.
П – конечное множество типизированных портов. Для порта p П, тип порта
обозначается type(p). При этом type(p)  Ω.
12
Const – Множество констант, каждая из которых принадлежит некоторому типу A,
где А Ω.
Системная сеть - кортеж SN= (V,I,O,π), где
(V,I,O) – сеть активных ресурсов: набор вершин, соединенных между собой
потребляющими и производящими дугами.
π : (IO)  П - функция разметки дуг именами портов
Маркировкой M системной сети SN называется функция M: V  Μ(Const), где
Μ(Const) – мультисет множества Const, множество состоящее из произвольного (в том
числе и равного 0) количества элементов множества Const. Таким образом, в любой
вершине системной сети может находится произвольное количество констант из
множества Const любого типа и маркировка М задает заполнение вершин системной сети
фишками (агентами и ресурсами).
Элементная сеть
Ресурсно-управляемый автомат A=( SA,TA,lA), типа A (AΩ), где
S A - конечное множество состояний
TA⊆ SA SA - конечное множество переходов
lA: TALA пометки переходов (перечень входных и выходных термов перехода)
LA – выражение на языке L для автомата A.
L - язык выражений вида π1σ1e1+ π2σ2e2+…+ πkσkek, где
πi – имена портов ( type(πi)  Ω )
σiσ{?,!}, где ? – потребление, ! - производство
ei – переменная или константа типа πi
Например, выражение get ? fish на переходе автоматной сети (конечного автомата или
агента), означается, что в системе есть объект (агент или ресурс) fish, порт get на системной
сети, и при выполнении рассматриваемого перехода автоматной сети (при условии, что
агент находится в позиции, имеющей порт потребления get, ведущий к другой позиции, в
которой находится ресурс fish) ресурс fish будет потреблен через порт get.
Выполнение перехода t агента А требует ресурсы, перечисленные во входных термах
этого перехода lA(t). Входной терм имеет вид πi?ej, где ej – переменная или константа того
же типа , что и порт πi. Выходной терм имеет вид πi!ej. Выходной терм определяет, где и
какие объекты будут созданы (произведены) в результате выполнения перехода.
13
1.5 Временные автоматы
Формальная модель временных автоматов [1] была разработана Alur и Dill в 1994
году.
Временной
автомат
–
это
конечный
автомат,
расширенный
с
помощью
вещественных переменных (счетчиков). В начале работы все счетчики равны нулю. В
процессе работы счетчики синхронно увеличиваются.
На каждом переходе имеется
охранник (guard) – это разрешающее (а не обязывающее) условие.
Временной автомат – это кортеж A = (L, L0,Lacc , ∑, X, E), где
L –конечное множество позиций (вершин)
L0  L – начальная позиция (вершина)
Lacc ⊆ L – множество принимаемых (в качестве финальных) позиций
∑ - конечный алфавит
X – конечное множество счетчиков
E  LG ∑2XL – множество ребер
G = {x op c | x  X, c  N} – множество охранников
op  {<,<=,=, >=,>}
2X – все возможные комбинации наборов счетчиков (для сброса, обнуления, значений
счетчиков – reset). Сброс счетчика x обозначается на схеме «{x}».
Пример:
Рисунок 1. Пример классического временного автомата.
Зеленым выделены охранники (guard) (x > 0, x=1, y=1) (ττ, в данной нотации, обозначает
отсутствие охранников)
Синим – символы входного слова (a, b)
14
Красным – сбросы счетчиков (reset clocks) ({x}, {y} )
Голубым – счетчики (часы) (clock) ( X ={x,y} )
Значение vR назначает каждому счетчику его часовое значение
Состояние (l,v) LR состоит из позиции и значений счетчиков
Изменение состояний временного автомата могут быть двух типов:
1)
сдвиг по времени, то есть автомат находится в той же позиции, но при выполнении
перехода происходит сдвиг значений счетчиков


(l,v) 
(l,v+τ)
2)
переход в новое состояние, то есть автомат переходит в следующую позицию, а
вместе с этим изменяется и значение счетчиков
a

(l,v) 
(l’,v’)
1.6 Ресурсно-управляемые сети временных автоматов
Модель ресурсно-управляемых сетей временных автоматов, TRDA nets, – модель,
созданная в рамках данной работы. TRDA модель строится на базе ресурсно-управляемых
сетей автоматов с добавлением возможностей временных сетей Петри или временных
автоматов. Тем самым в данной работе были созданы две разновидности TRDA моделей.
Будем обозначать TRDAPetri
nets
– модель, построенную с добавлений возможностей
временных сетей Петри в элементную сеть и TRDATimed
automata
– модель с добавлений
возможностей временных конечных автоматов. В случае, если при изложении нет разницы,
про какую из моделей идет речь, будем обозначать модель как TRDA. TRDA сеть (обеих
разновидностей) является двухуровневой сетью, состоящей из системного и автоматного
(элементного) уровней. Системная сеть – это распределенная система позиций (вершин),
соединенных между собой потребляющими и производящими дугами, аналогичная сетям
активных ресурсов. Автоматные (элементные) сети - это совокупность графов изменения
состояния агентов, которые являются расширенными конечными автоматами, асинхронно
потребляющими/производящими
общие
ресурсы
через
входные/выходные
порты
(поименованные и типизированные дуги) системной сети.
Константа в модели TRDA nets - это аналог фишки в классических сетях Петри.
Константы могут быть как простыми ресурсами, так и агентами, имеющими структуру
конечного
автомата
с
добавлением
временных
характеристик.
Все
константы
15
типизированы. Пусть Ω - конечное множество типов (types). Типы Ω типизируют как
константы, так и порты системной сети. Тип порта означает, что по нему возможна
обработка (потребление или производство) констант только данного типа.
Напомним, что подобно RDA сетям, переход активен, если в системной сети имеются в
наличии ресурсы, описанные во входных термах этого перехода.
Обозначим R как множество вещественных чисел.
Дадим определение системной сети TRDA модели. Оно аналогично системной сети RDA
модели.
(Напомним,
Системная сеть SN=(V,I,O,π) - это сеть активных ресурсов, где
V — конечное множество вершин
I: (VV) — множество потребляющих дуг
O: (VV) — множество производящих дуг
π : (IO)  П - функция разметки дуг именами порта)
Теперь дадим определение элементной сети. Ее определение различно для TRDAPetri
nets
и
TRDATimed automata.
Рассмотрим элементную сеть TRDAPetri nets:
Элементная сеть APetri nets=(SA, TA, lA, WaitA, TimeA) конечный автомат с дополнительными
пометками переходов, где
A=( SA,TA,lA) – RDA сеть.
( Напомним,
SA - конечное множество состояний
TA⊆ SA SA - конечное множество переходов
LA :TA L – функция разметки переходов, сопоставляющая каждому переходу описание
входных и выходных термов на языке выражений (L) вида π1σ1e1+ π2σ2e2+…+ πkσkek, где
πi – имена портов ( type(πi)  Ω )
σi{?,!}, где ? – потребление (вход), ! – производство (выход)
ei – переменная или константа типа πi )
WaitA: TA Interv – функция, сопоставляющая каждому переходу временной интервал,
время ожидания срабатывания перехода. В ходе выполнения модели в момент, когда
переход становится активным, из этого интервала произвольным образом выбирается
число. Это число означает время, когда сработает (начнет выполняться) переход при
условии, если он в течение всего этого времени будет оставаться активными.
16
TimeA: TAInterv – функция, сопоставляющая каждому переходу временной интервал,
время выполнения перехода. В ходе выполнения модели в момент, когда переход начинает
выполняться, из этого интервала произвольным образом выбирается число. Выбранное
число означает длительность выполнения данного перехода.
Interv = {[d1,d2] ⊂R,d1≤d2}.
Теперь рассмотрим элементную сеть TRDA Timed automata.
Элементная сеть ATimed
automata
=(SA, TA, lA, TimeA, XA, GA, ResetA) конечный автомат с
дополнительными пометками переходов, где
A=( SA,TA,lA) – RDA сеть
TimeA - аналогично TRDAPetri nets
XA – множество счетчиков времени. В начале работы все счетчики равны нулю. В процессе
работы все счетчики синхронно увеличиваются.
GA: TA{ConstrA}
- функция, сопоставляющая каждому переходу набор ограничений
ConstrA., где
ConstrA - ограничение, предикат вида x∆c или y+z∆c или x-y∆c, где x,y,z XA, а ∆ может
принимать значения {<,≤,=,≥,>}, с  N.
В случае, если все ограничения GA(t) перехода t автомата A выполняются в некоторый
момент времени, когда данный переход активен, то переход может сработать.
ResetA: TA{reset(x)|xXA} – функция, сопоставляющая каждому переходу набор
счетчиков времени, сбрасывающих свои значения в ноль при выполнении этого перехода.
Сбросы счетчиков могут отсутствовать в некотором переходе, это означается, что ни одно
из значений счетчиков при выполнении этого перехода в ноль не сбрасывается. Так же
возможно сбрасывать
значения сразу нескольких счетчиков при выполнении одного
перехода.
Состояние системы
Y –
это отображение вершины системной
сети
в
мультимножество пар: агент A и его состояние S.
Теперь дадим определение, что будем называть состоянием агента в случае
TRDAPetri nets и TRDATimed automata и как будет выполняться модель.
17
TRDATimed automata:
Возможны следующие варианты смены состояний агента:
1. агент находится в некотором состоянии, и ни один из его переходов не активен
2. агент имеет один или несколько активных переходов, и ожидает того, что
ограничение на одном или нескольких переходах станет выполняться
3. агент потребил все полагающиеся ресурсы, агент находится в переходе, у него идет
отчет времени окончания выполнения перехода
4. агент закончил выполнение перехода, произвел все соответственные ресурсы,
изменил показания счетчиков (согласно заданным во входном файле правилам),
перешел в следующую позицию
Более детальное пояснение приведено ниже. Пусть переходы tr1 и tr2 агента α
активны в состоянии s.
После загрузки системы все счетчики принимают значения 0. В случае, если в
процессе работы системы создается новый агент, т.е. новая автоматная сеть, а с ней и новые
счетчики, то они получают начальные значения так же равные 0. В случае, если на текущий
момент, у нас есть два активных (с точки зрения наличия необходимых для их выполнения
ресурсов) перехода tr1 и tr2, рассматриваются их ограничения (охранники). В случае, если
ограничение ни на перехода tr1, ни на переходе tr2 не выполняется, значения счетчиков
(совместно с глобальным временем системы) увеличивается до тех пор, пока одно их
ограничений не начнет выполняться. ( В случае, если ограничения на переходах tr1 и tr2
выполняются одновременно, то переход для выполнения выбирается либо случайным
образом с учетом весовых коэффициентов вероятности соответствующих переходов, либо
на усмотрение пользователя.) Затем для того перехода, для которого выполнилось
ограничение, начинается отчет длительности выполнения перехода. В конце выполнения
перехода осуществляется обнуление счетчиков, указанных в спецификации reset данного
перехода. После этого агент производит все ресурсы, указанные в выходных термах
перехода.
Если в системе нет активных (имеющих активные переходы) агентов, то
рассматривается множество работающих агентов и их временные характеристики оставшееся время выполнения работающих переходов. Находится минимальное время:
timemin. Время всех агентов перевычисляется путем вычитания timemin и те агенты,
которые получили время 0, завершают работу своего перехода и производят ресурсы,
предусмотренные для этого перехода.
18
TRDAPetri nets
Возможны следующие варианты смены состояний агента:
1. агент находится в некотором состоянии, и ни один из его переходов не активен
2. агент имеет один или несколько активных переходов, и ожидает того, что задержка
(wait) на одном или нескольких переходах закончится, а соответствующие(ий)
переходы(д) не перестанет быть активным
3. агент потребил все полагающиеся ресурсы, агент находится в переходе, у него идет
отчет времени окончания выполнения перехода
4. агент закончил выполнение перехода, произвел все соответственные ресурсы,
перешел в следующую позицию
. Пусть Y некоторое состояние системы, и пусть переходы tr1 и tr2 агента α активны
в состоянии s.
Тогда агент α переходит в состояние {<s, w1>, <s,w2>}, где wi - время ожидания
начала работы перехода tri, выбранное из соответствующих временных интервалов
переходов tr1 и tr2. В дальнейшем возможны три варианта: если w1<w2, если w1>w2 и
если w1=w2.
В первом случае, по истечению w1, для перехода tr1 определится время t1, выбранное
из своего соответствующего интервала, означающее длительности работы перехода tr1. Во
втором случае, по истечению w2, для перехода tr2 определится время t2, выбранное из
своего соответствующего интервала, означающее длительности работы перехода tr2. В
третьем случае, в ход вступает весовой коэффициент вероятности, заданный для переходов
(либо, в случае пошагового выполнения, решение принимает пользователь). Если для
перехода весовой коэффициент вероятности не задан, то, по умолчанию весовой
коэффициент равен 100 (для всех переходов). Если весовые коэффициенты вероятности
конкурирующих переходов одинаковые, то вероятность их выполнения так же одинаковая.
Согласно имеющимся весовым коэффициентам вероятности, система решает, какой
переход будет работать. И для соответствующего перехода определится время ti –
длительность выполнения этого перехода. По окончании работы перехода агент производит
все ресурсы, указанные в выходных термах перехода.
Если в системе нет активных агентов, то поведение системы аналогично поведению
модели TRDATimed automata в аналогичной ситуации.
19
2. СИСТЕМА TRDA TOOL
2.1 Анализ исходных данных и выбор оптимального решения
поставленной задачи
Для построения в TRDA Tool программе моделей типа ресурсно-управляемых сетей
временных автоматов необходимо было, во-первых, придумать способ представления
входных данных. Ввиду сложности модели, было решено разработать язык, позволяющий
в текстовом виде описывать и сохранять в файле структуру модели и начальную разметку
сети, а не выполнять ввод исходных данных с помощью графического представления.
Стоит так же отметить, что стандартный язык PNML (Petri Net Markup Language) [12] для
описания необходимой нам структуры и конфигурации моделей использовать было
нельзя, поскольку в нем нет всех необходимых для нас возможностей: вложенность, учет
времени, возможность задания мобильного перемещения агентов, т.д.
Второй задачей было добавление в систему возможности анализа различных
поведенческих свойств выполняемой модели, типичных для формальных моделей,
подобных сетям Петри: достижимость, ограниченность, наличие тупиковых ситуаций,
живость. Также необходимо было реализовать возможности статистического анализа,
заключающегося в определении: количества агентов в модели; количества различных
состояний, в которых побывал агент в процессе выполнения модели; среднего время
нахождения агента в том или ином состоянии, т.д.
После создания TRDA Tool программы, реализующей ресурсно-управляемые сети
автоматов, необходимо было расширить возможности формализма RDA-сети: добавить в
модель возможности учета временных характеристик. В процессе анализа было
рассмотрены следующие интересные модели, учитывающее время по-разному: модель
Мерлина временных сетей Петри, модель Штарке временных сетей Петри, временные
автоматы. Именно они и легли в основу расширения автоматной уровня RDA сети.
Так же стояла задача визуализации текущего представления системы. Не
исключалась возможность использования сторонних программ для решения задачи
визуализации.
20
2.2 Методы проектирования
В проектирование включается:
•
Построение модели данных ключевых элементов внутреннего представления
модели RDA сетей
•
Проектирование классов
•
Проектирование интерфейса
•
Встраивание сторонней программы, с помощью которой было бы возможно
реализовать визуализацию как системного, так и автоматного уровня TRDA-сети.
2.3 Обоснование выбора программных и аппаратных средств
Для разработки была выбрана операционная система Windows 7, Windows 8 и среда
разработки Microsoft Visual Studio 2008 с программным языком С#. Так как от программы
не требуется обладать свойством кроссплатформенности, то для ее реализации был
выбран язык С#. Язык C# - объектно-ориентированный, а значит легок в использовании и
был основным предметом изучения в Национальном Исследовательском Университете
Высшей Школе Экономике на отделении программной инженерии факультета бизнесинформатики.
Для проектирования ER моделей была выбрана программа Oracle SQL Developer
Data Modeler 3.0.0., которая обладает всеми требуемыми атрибутами для создания
задуманной ER модели.
Для визуализации текущего состояния модели была выбрана программа Graphviz
версии 2.28, которая является открытым программным обеспечением. Программа была
выбрана по совету предшествующих курсов, а так же соответствовала всем требуемым
задачам текущего учебного проекта.
Диаграмма классов TRDA Tool приведена на рис.2
21
Рисунок 2. Диаграмма классов TRDA Tool
22
2.4 Проектирование связей ключевых компонент языка описания
RDA сетей
Для разработки входного языка описания модели RDA
определить
взаимосвязь между элементами
типа, необходимо
внутреннего представления модели
ресурсно-управляемых сетей автоматов. Для этого была построена ER-модель (Схема 2)
этого представления.
Схема 2. ER модель модели (метамодель) ресурсно-управляемых сетей автоматов
В прямоугольники заключены объекты метамодели. Линиями показаны связи между
ними. Обозначения «прямой вход» в прямоугольник и «лапка» означают возможную
кратность связей, где прямая линия – это 1, где лапка – многие. К примеру, рассмотрим,
все элементы, связанные с элементом Type. Это: port, state, trans, const, VAR. Связь
элемента Type с каждым из выше перечисленных - один ко многим. У одного типа
объекта может быть множество портов, состояний, переходов из состояния в состояние,
констант, переменных.
23
Для улучшения понимания, ниже приводится таблица соответствий объектов
метамодели и элементов формализма ресурсно-управляемых сетей автоматов [3] (таблица
3).
Таблица 3
Таблица соответствий объектов метамодели и элементов формализма ресурсноуправляемых сетей автоматов
Ссылки на
Объект
описание формализма
Комментарии
метамодели
ресурсно-управляемых
сетей автоматов
Place
Места (вершины)
resource node,
системной сети
элемент множества V
(preliminaries)1
arc_in
arc_out
Type
State
Const
Port
Trans
term_in
term_out
Inst
1
input arc,
consumption relation,
элемент множества I
(preliminaries)
output arc,
production relation,
элемент множества O
(preliminaries)
Элемент
множества Ω (def.4)1
state , элемент
множества SA (def.3)
Элемент
множества Const
(3.2definitions начало)
arc label, элемент
множества П (def.1)
resource
transformation expression,
элемент transition relation,
элемент множества TA
(def.3)
input term (p?e)
output term (p!e)
элемент marking M
(def.2)
Пунктирные дуги
системной сети
Непрерывные дуги
системной сети
Возможный
идентификатор (их может
быть несколько) для
обозначения экземпляра
объекта
соответствующего типа
Экземпляр объекта
соответствующего типа.
Их совокупность
составляет маркировку
сети
Здесь и далее в таблице приведены ссылки на статью и определения из статьи [3].
24
Ссылки на
описание формализма
ресурсно-управляемых
сетей автоматов
Var(def.5)
Объект
метамодели
var
2.5
Комментарии
Разработка языка описания модели типа ресурсно-управляемых
сетей временных автоматов
В данном разделе приводится описание разработанного входного языка (TRDA
языка), используемого в TRDA Tool
для загрузки модели TRDA типа. Следует
использовать описанную ниже последовательности задания конфигурации модели:
сначала описывается название модели, затем ее системная сеть, затем ее автоматные сети,
затем начальное состояние, затем, при необходимости, требуемые для проверки свойства.
Подробнее о способах задания свойств анализа см. раздел Параметры анализа.
model(<название модели>) – определение названия модели
Системная сеть описывается следующим образом:
place(<название места системного слоя>) – определение места (вершины)
системной сети
arc_in(<название
вершины
потребителя>,<название
вершины
источника>,<название порта>) – определение потребляющей (входной) дуги системной
сети с названием соответствующего порта
arc_out(<название вершины производителя>, <название вершины назначения >,
<название порта>)
– определение производящей (выходной) дуги системной сети c
названием соответствующего порта
Автоматный слой описывается следующим образом:
type(<название типа объекта >)
state(<название состояния типа объекта>)
const(<название объекта в программе, показываемое пользователю>)
var(<название переменной>)
port(<название порта для производства/потребления объектов данного>)
trans (<текущее состояние>, <следующее состояние>,<название перехода>)
25
1. constr (<счетчик_1>, [арифметический оператор: + или - ], [счетчик_2],
<оператор сравнения>,<натуральное число >)
1.
reset(<счетчик>)
2. wait(<нижняя граница ожидания начала работы перехода>,<верхняя
граница ожидания начала работы перехода>)
priority(<числовое значение приоритета>)
time(<нижняя граница длительности работы перехода>,<верхняя граница
длительности работы перехода>)
trans_chart_name(<название перехода для временной диаграммы>)
term_in (<название порта>, <название объекта>,[состояние объекта]) потребление
term_out (<название порта>,<название объекта>,[состояние объекта]) –
производство
- определение типа объекта:

его название

все возможные состояния данного типа объекта (если это не элементарный тип)

константы - возможные обозначения объектов данного типа в модели

названия всех возможных переменных

названия всех портов для производства/потребления данного типа объектов

список возможных переходов из состояния в состояние для данного типа объекта и
название перехода
o 1. ограничение (охранник) на переходе
o 1. сброс счетчика после выполнения того или иного перехода
o 2. время до начала выполнения перехода с того момент, как переход становится
активным
Одновременно возможно использовать либо ограничение и сброс (вариант 1), либо
время задержки (вариант 2).
o Приоритет – весовой коэффициент вероятности, что в объекте сработает именно
в этот переход
o длительность перехода из состояния в состояние
o название перехода на временной диаграмме (задав для разных переходов одно и
то же название, можно получит объединенное отображение этих переходов на
временной диаграмме для удобства просмотра)
26
o описание
потребления/производства
для
данного
перехода
с
помощью
входных/выходных термов
Начальное состояние модели (начальная маркировка) описывается следующим
образом:
place(<название места системного слоя>)
inst(<const - обозначение объекта в программе >,<состояние объекта
автоматного слоя>) - если объект не элементарный
inst (<const - обозначение объекта>) - если объект элементарный
- начальная разметка (маркировка):
места (вершины) системной сети, и объекты (экземпляры типов объектов),
которые в нем находятся и их состояния, если объекты не элементарны
2.6 Описание разработанного языка в нотации Бэкуса-Наура
<Описание модели> ::= model(<название модели>)
<системная сеть>
<автоматный слой>
<начальная разметка>
<системная сеть> ::=
[<определение вершины системного слоя>, … ]
[<определение дуги системного слоя>, … ]
<определение вершины системного слоя> ::= place(<название вершины>)
<определение дуги системного слоя> ::=
<определение входящей дуги> | <определение исходящей дуги>
<определение входящей дуги> ::=
arc_in(<вершина приемник>, <вершина источник>, <название порта>)
<определение исходящей дуги> ::=
arc_out(<вершина источник>, <вершина приемник>, <название порта>)
<автоматный слой> ::= [<определение типа>, … ]
<определение типа> ::= type(<имя типа>)
[<определение элемента типа>, … ]
[<обозначение состояния на графике>, … ]
[<определение перехода>, … ]
<определение элемента типа> ::=
<определение состояния> | < определение
порта>
| < определение константы> | < определение переменной>
<определение состояния> ::= state(<имя состояния>)
<определение переменной> ::= var(<имя переменной>)
<определение константы> ::= const(<имя константы>)
<определение порта> ::= port(<имя порта>)
27
<обозначение состояния на графике> ::=
state_chart_name(<имя состояния>,
<имя состояния на графике>)
<определение перехода> ::=
trans(<имя исходного состояния>, <имя итогового состояния> [,
<название перехода>])
[<атрибут перехода>, … ]
[<определение преобразования ресурсов>, … ]
<атрибут перехода> ::= <параметр задержки>
| <ограничение>, <сброс счетчика>
| <ожидание начала работы перехода>
<ограничение> ::=
constr(<счетчик_1>[,<арифметический оператор: + или >][,<счетчик_2>],<оператор сравнения>, <натуральное число>)
<сброс счетчика>::=
reset(<счетчик>)
<атрибут перехода> ::= <продолжительность перехода>
| <обозначение перехода на графике>
| <вероятность перехода>
<ожидание начала работы перехода> ::=
wait(<минимальное время ожидания перехода>[, <максимальное время
ожидания перехода>])
<продолжительность перехода> ::=
time(<минимальное время длительности работы перехода>[, <максимальное
время длительности работы перехода>])
<вероятность перехода> ::=
priority(<приоритет перехода>)
<обозначение перехода на графике> ::=
trans_chart_name(<имя перехода на графике>)
<определение преобразования ресурсов> ::=
<определение потребления ресурсов> | <определение производства
ресурсов>
<определение потребления ресурсов> ::=
term_in(<имя порта>, <имя ресурса>[, <состояние потребляемого
ресурса>])
<определение производства ресурсов> ::=
term_out(<имя порта>, <имя ресурса>[, <состояние производимого
ресурса>])
<имя ресурса> ::= <имя константы> | <имя переменной>
<начальная разметка> ::= place(<имя вершины>)
[<определение объекта>, … ]
<определение объекта> ::=
inst(<имя константы>[, <имя состояния>])
28
2.7 Возможности TRDA Tool
2.7.1. Возможности моделирования
TRDA Tool позволяется выполнять следующие действия с моделями вида TRDA
1) Загружать модель. Для того, чтобы загрузить модель необходимо воспользоваться
функцией Файл – Открыть – выбрать текстовый файл с расширением .rda на TRDA
языке.
2) Выполнять моделирование (выполнять переходы). Для выполнения моделирования
необходимо воспользоваться
кнопками «1шаг», или указать необходимое
количество шагов, или указать необходимое количество интервалов времени. При
переходе из временного режима в режим по шагам, требуется воспользоваться
кнопкой «По шагам».
3) Просматривать временную диаграмму. Для просмотра временной диаграммы
необходимо нажать кнопку Временная диаграмма. Для динамической прорисовки
временной диаграммы в режиме моделирования требуется выставить галочку
Диаграмма на основной форме.
4) Проверять поведенческие свойства. Для просмотра результатов анализа необходимо
воспользоваться кнопкой «Результаты анализа». Более детально о возможностях
анализа TRDA Tool написано в разделе «Возможности анализа».
5) Просматривать графическую картинку как системной, так и автоматной сети. Для
динамического отображения информации в
течение выполнения моделирования
требуется выставить галочки в полях Системная сеть и Автоматная сеть. Для того,
чтобы автоматная сеть того или иного агента стала отображаться, необходимо
пометить конкретного агента специальным образом: двойной клик по имени агента в
левой части главной формы. Агент будет выводиться на форму, если у него стоит
специальный значок * перед именем константы.
2.7.2. Возможности анализа
Для целей анализа было необходимо создать следующую функциональность TRDA
Tool:
1) добавить возможность выполнения определенного количества моментов времени
или определенного количество шагов по задаваемому пользователем числу.
2) разработать способ задания параметров анализа.
3) реализовать анализатор модели. Анализатор включает в себя следующее:
29
Поведенческие свойства:

Живость

Живость переходов системной сети

Ограниченность

Достижимость

Наличие тупиковой ситуации
Статистический анализ по каждому агенту:

Количество состояний, в которых побывал конкретный агент

Количество состояний, в которых мог бы побывать конкретный агент

Анализ состояний
o Среднее время нахождения в состоянии
o Общее время нахождения в состоянии
o Количество нахождений в состоянии

Анализ переходов
o Среднее время нахождения в переходе
o Общее время нахождения в переходе
o Количество нахождений в переходе
2.7.3 Поведенческие свойства
Поведенческие свойства реализованы в эмуляторе не совсем в классическом их
понимании. Поэтому, опишем, что мы будем под ними понимать.
Введем определение хода выполнения модели, обозначив XB.
Ход выполнения модели - множество состояний системы и множество переходов
системы, начиная из начального состояния системы и заканчивая текущим состоянием
системы.
2.7.3.1 Живость
Свойство живости выполняется в модели, если все переходы, определенные для
всех типов, выполнялись хотя бы раз в ходе выполнения модели.
( tr ,time)
Иначе говоря, свойство живости выполняется, если tr  T : st  ...  st ' где
st – начальное состояние агента (описанное в разделе 1.1.)
st' – текущее состояние агента
30
2.7.3.2 Живость переходов системной сети
Свойство живости переходов системной сети выполняется в модели, если все
переходы системной сети (дуги производства и потребления) были задействованы хотя
бы в одном переходе за ход выполнения модели.
2.7.3.3 Ограниченность
Свойство ограниченности выполняется в модели, если ограничение на количество
типов ресурсов заданное в параметрах анализа* соблюдается в ходе выполнения модели.
2.7.3.4 Достижимость
Свойство достижимости выполняется в модели, если разметка системы, заданная в
параметрах анализа**, достигалась хотя бы раз за ход выполнения модели.
2.7.3.5 Наличие тупиковой ситуации
Свойство наличие «тупиковой» ситуации выполняется в модели, если за ход
выполнения модели система пришла в такое состояние, что ресурсы в системе есть, но ни
один переход системной/элементной сети выполниться не может.
2.7.3.6 Параметры анализа
Для анализа ограниченности и достижимости требуется задавать входные
параметры. Параметры описываются в том же входном файле, что и модель. Требуется
записывать их в конце входного файла (после задания начальной разметки).
Для анализа свойств ограниченности и достижимости конкретной модели
требуется убедиться, что во входном файле заданы необходимые параметры и галка
Достижимость и/или галка Ограниченность стоит на форме.
*Ограниченность
Синтаксис задачи параметров:
bound(<название вершины системной сети>|*,<тип объекта>|* ,<количество>)
Символ * используется, когда конкретный параметр нужно опустить. То есть, если
первый или второй параметр требуется опустить, то есть сгруппировать количество
агентов по вершине или по типу объекту, следует воспользоваться оператором * в
соответствующем месте. В качестве третьего параметра всегда задается число. Таким
образом, можно проверять:

общее количество объектов в системе: bound(*,*,<число>)
31

количество всех объектов в вершине: bound(<вершина>,*,<число>)

количество объектов определенного типа в системе:
bound(*,<тип>,<число>)

количество объектов определенного типа в определенной вершине:
bound(<вершина>,<тип>,<число>)
Количество проверяемых условий, описанных во входном файле, не ограничено.
**Достижимость
Синтаксис задачи параметров:
marking(<название разметки для поиска>,[like])
place(<название вершины системной сети>)
inst(<экземпляр агента>,<состояние агента>)
Если требуется задать «точную» разметку, то есть описать каждую вершину
системной сети и агентов, которые должны в ней быть и их состояния, то слово like можно
опустить.
Если требуется задать «примерную» разметку, то есть описать только некоторые
вершины системной сети и агентов, которые должны в ней быть и их состояния, то нужно
написать слово like.
Количество разметок для анализа, описанных во входном файле, не ограничено.
Предусмотрена
достижении
возможность
остановки
при
контроле
Достижимости
по
заданных разметок. Для этого необходимо поставить галку «Пауза при
нахождении» (Рисунок 3)
32
Рисунок 3. Галка «Пауза при нахождении» на главной форме
2.7.4 Способ установки программы
Для
того
чтобы
воспользоваться
описанными
в
последующих
разделах
возможностями визуализации системной и автоматной сети, необходимо дополнительно
установить на компьютер стороннюю программу визуализации Graphviz 2.28.
Для установки программы Graphviz 2.28 необходимо скачать ее на локальный диск
Вашего
компьютера.
Программа
доступна
для
скачивания
на
сайте
http://www.graphviz.org/Home.php. После установки программы, требуется перезагрузить
операционную систему, для того, чтобы путь к программе dot.exe добавился в пути по
умолчанию (path).
Программа Automata.exe, эмулятор TRDA Tool, должна быть сохранена в папке, на
пути которой имеются только папки с названиями на английском языке, в названии
которых не встречается символ пробела.
33
2.7.5 Соответствие графической визуализации текущего состояния
модели ее структурному представлению
Визуализацию текущего состояния модели можно посмотреть, нажав на кнопку
«Временная диаграмма» на главной форме TRDA Tool. В случае, если требуется
динамическая перерисовка графической картинки в процессе выполнения модели,
необходимо выставить галочку «Диаграмма» так же на главной форме TRDA Tool, и далее
выполнять моделирование в обычном режиме.
Ниже
приведена
представлением
таблица,
текущего
отражающая
состояния
взаимосвязь
модели
и
между
графической
структурным
картинкой.
Рисунок 4. Структурный вид текущего состояния модели
34
Рисунок 5. Визуализация текущего состояния системной сети
Рисунок 6. Визуализация текущего состояния автоматной сети
35
Таблица 4
Соотнесения структурного и графического представления текущей конфигурации
модели
Структурное
Графическое
представление
представление
кластер
Комментарии
Вершина,
внутри
Серый
внутри
с
которой
может
белым овалом. Белый овал
находиться
характеризует
раскрывающийся список
системной сети, к которой
«Главная
вершина»,
вершина системной сети
вершину
присоединяются
потребляющие/производящие
дуги. Имя кластера совпадает
с белым овалом.
Агенты
из
раскрывающего списка
Количество
Агенты, ресурсы
кластера
в
Число в квадратных скобках
Количество
раскрывающемся списке
внутри разноцветного овала
внутри главной вершины
главной вершины
кластера
На
агентов
Разноцветные овалы внутри
форме
не
отображается
Синяя
стрелочка
и
ее
подпись. Стрелка выходит из
агентов
Потребляющая
дуга
+
дуга
+
имя порта
вершины источника и входит
в вершину назначения.
На
форме
не
отображается
Черная
стрелочка
и
ее
подпись. Стрелка выходит из
Производящая
имя порта
вершины источника и входит
в вершину назначения.
Вершина
Зеленые стрелки на форме
Активные
сети: агент его текущее
визуализации
автоматной сети
состояние --> агент его
сети
возможное
системной
Автоматной
переходы
новое
36
Структурное
Графическое
представление
представление
Комментарии
состояние
На
форме
отображается
не
Красные стрелки на форме
Выполняющиеся
визуализации
переходы
сети
Автоматной
автоматной
сети
37
3
ПРИМЕРЫ
ПРИМЕНЕНИЯ
МОДЕЛИРОВАНИЯ
И
TRDA
АНАЛИЗА
TOOL
ДЛЯ
НЕКОТОРЫХ
КЛАССИЧЕСКИХ ЗАДАЧ
В данном разделе будут рассмотрены классические задачи на распределенные
системы, их TRDA представление и анализ при помощи TRDA Tool.
3.1 Задача об обедающих философах, гуляющих в парке
Постановка задачи
Имеется круглый стол, вокруг которого стоят стулья, на которых сидят философы.
В центре стола находится тарелка с макаронами. Рядом с каждым философом лежит
салфетка (между 2 соседними философами лежит одна салфетка), а на каждой салфетке
лежит вилка. Философ может либо думать, либо есть макароны, либо гулять в парке. Для
того чтобы думать ему достаточно находится на стуле. Для того чтобы есть ему
необходимо держать в каждой руке по вилке. Для того чтобы гулять он должен
освободить стул и переместиться в парк. Возвращаясь из парка, философ может занимать
любой из свободных стульев.
Цели моделирования и анализа
На примере данной задачи
проведем анализ свойства живости переходов
автоматных сетей и живости дуг системной сети.
Решение
Графическое представление задачи
Рисунок 7. Системная сеть
38
Рисунок 8. Автоматная сеть
В автоматной сети
каждый переход помечен термом, обозначающим, какие
ресурсы и по каким портам системной сети (т.е. откуда и куда) потребляются и
производятся в процессе выполнения данного перехода. Красным цветом обозначена
стрелочка с выполняющимся переходом, зеленым – активные переходы.
Входной файл для данной модели можно взять из приложения 2.
Загрузим входной файл в эмулятор – рис. 9
39
Рисунок 9. Задача об философах, гуляющих в парке загружена
Выполним 500 шагов и нажмем кнопку «Результаты анализа», увидим – Рисунок10
40
Рисунок 10. Результаты анализа живости модели о философах, гуляющих в парке
41
Как видно из протокола анализа, не все переходы, как автоматной, так и системной
сети сработали.
Однако в нашем понимании свойства живости и живости переходов системной
сети одного прогона модели недостаточно, чтобы убедиться в невыполнении данного
свойства.
Поэтому загрузим модель еще раз и опять запустим выполнение на 500 шагов,
нажмем «Результаты анализа». – Рис.11
Рисунок 11. Результаты повторного анализа живости модели о философах,
гуляющих в парке
Как видно на картинке, на этот раз, все переходы элементной сети выполнены.
Стоит отменить, что при анализе живости проверяет лишь выполнение перехода для
42
определенного типа в целом, а не для конкретного агента этого типа. Если же мы хотим
просмотреть параметры поведения конкретного агента, то следует обратиться к разделу
статистического анализа по агентам – Рисунок 12 и 13.
43
Рисунок 12. Статистический анализ агентов (часть 1)
44
Рисунок 13. Статистический анализ агентов (часть 2)
45
Еще раз загрузим модель
и запустим ее на 500 шагов, нажмем «Результаты
анализа» - Рис. 14
Рисунок 14. Результаты анализа живости модели о философах, гуляющих в парке
46
На рисунке видно, что на третий раз все переходы как элементной, так и системной
сети выполнены. То есть, мы убедились в том, что свойство живости и свойство живости
переходов системной сети выполняется.
3.2 Задача о философах с дедлоком
Постановка задачи
Имеется круглый стол, вокруг которого стоят стулья, на которых сидят философы.
В центре стола находится тарелка с макаронами. Рядом с каждым философом лежит
салфетка (между 2 соседними философами лежит одна салфетка), а на каждой салфетке
лежит вилка. Философ может либо думать, либо есть макароны. Для того чтобы думать
ему достаточно находится на стуле. Для того чтобы есть ему необходимо держать в
каждой руке по вилке.
Цели моделирования и анализа
Данная задача интересна на предмет анализа свойства наличие «тупиковой
ситуации».
Решение
Входной файл с моделью для решения данной задачи находится в приложении
3.Схемы системной и элементной сети данного решения приведены на рисунке 15 и 16.
Рисунок 15. Системная сеть задачи о философах с дедлоком
47
Рисунок 16. Автоматная сеть задачи о философах с дедлоком на примере третьего
философа в некоторый момент времени
48
Загрузим модель в TRDA Tool – выполним 50 шагов – Нажмем кнопку «Результаты
анализа»
-
Рис.
17
Рисунок 17. Загружена модель задачи о философах с дедлоком, возник дедлок на 12
шаге
Как видно из разметки системной сети, прошло только 12 шагов и 2 момента
времени, а все философы взяли по левой вилке, и вариантов дальнейшего переходов нет.
Это произошло из-за того, что ни один философ не может взять левую вилку, чтобы
поесть. А положить вилку по модели из Приложения 3 философ может только, когда
поест (см. Рисунок 16)
В протоколе «Результаты анализа» отмечено наличие «тупиковой ситуации» в
данной модели.
3.3 Задача о спящем парикмахере
Классическая постановка задачи
Рассмотрим парикмахерскую, в которой работает один парикмахер, имеется одно
кресло для стрижки и несколько кресел в приемной для посетителей, ожидающих своей
очереди. Если в парикмахерской нет посетителей, парикмахер засыпает прямо на своем
рабочем месте. Появившийся посетитель должен его разбудить, в результате чего
парикмахер приступает к работе. Если в процессе стрижки появляются новые посетители,
они должны либо подождать своей очереди, либо покинуть парикмахерскую, если в
49
приемной нет свободного кресла для ожидания. Задача состоит в том, чтобы корректно
запрограммировать поведение парикмахера и посетителей.
Начальная разметка системной сети построенной TRDA модели имеет следующий
вид
Рисунок 18. Визуализированная системная сеть в задаче о спящем парикмахере
Как видно есть три вершины системной сети:
Street – улица, по которой гуляют люди, как стриженные, так и нестриженные
Reception – приемная, где люди ожидают своей очереди к парикмахеру
Chair – место, где человек стрижется
Имеются следующие агенты и/или ресурсы:
На улице имеется 4 стриженных человека
В приемной парикмахерской находится менеджер и есть 4 свободных места
В кресле «спит» парикмахер
Текущая интерпретация данной задачи имеет следующее описание:
В вершине системной сети street находится некоторое количество стриженых людей,
(сложных агентов). На улице люди через некоторое время по счетчику «x» (ограничение
x>30) обрастают волосами, становятся нестрижеными. Обросшие люди могут быть
50
доставлены в приемную парикмахерской, в случае наличие там свободных мест. Данную
операцию выполняет менеджер парикмахерской. «Спящий» (находящийся в состоянии
«спит») парикмахер берет человека из очереди парикмахерской на стул стрижки и
начинает его стричь (переходит в состояние «работает»). После стрижки, которую
выполняется парикмахер над человеком, парикмахер отправляет человека на улицу в
состоянии new_shorn, то есть свежеподстриженный, а сам «засыпает» (переходит в
состоянии «спит»). Человек сам меняет свое состояние с new_shorn на shorn, при этом
обнуляется счетчик «x» у этого человека.
Иными словами, можно сказать, что счетчик «x» – контроль необходимости в
стрижке.
Зададим в исходном файле (приложение 3) необходимость проверки свойства
достижимости, а именно, что все люди в течение выполнения модели попадут на стул
парикмахера и, соответственно, будут там стричься. Проверяемое свойство выглядит
следующим образом:
marking(m1,like)
place(chair)
inst(m01,shorning)
inst(barber,work)
Задавая свойство достижимости m1, мы говорим, что хотим проверить не все
вершины системной сети (для этого в определении разметки используется ключевое слово
like), а лишь проверить агентов и их состояния в вершине системной сети chair. Так, мы
хотим убедиться, что там есть парикмахер (агент barber) в состоянии «работающий»
(work) и агент типа «Человек» (m01, в данном случае) в состоянии «стрижка» (shorning).
Аналогичным образом зададим разметки m2, m3, m4 для агентов m02, m03 и m04
соответственно.
Загрузив модели в TRDA Tool, проверим данное свойство, выставив галочку
Достижимость,
выполним
некоторое
количество
шагов.
Затем,
нажав
кнопку
«Результаты», проверим достижимости заданной маркировки.
51
Рисунок 19. Достижимость для задачи о спящем парикмахере
Как видно, все требуемые разметки (m1, m2, m3, m4) были достигнуты, значит,
модель составлена правильно.
Теперь посмотрим отображение хода выполнения модели на временной диаграмме
(нажав кнопку Временная диаграмма – Рис. 20)
Рисунок 20. Временная диаграмма задачи о спящем парикмахере
52
Так же на примере данной модели просмотрим структурное и графическое
представление текущего состояния автоматной сети на примере агента m02. Для этого
выставим звездочку на этом агенте в структурном виде представления модели. Звездочка
выставляется двойным кликом по агенту – Рис. 21.
Рисунок 21. Звездочка на агенте m02
Теперь выставим галочку Автоматная сеть и просмотрим структуру агента – рис. 22
53
Рисунок 22. Агент m02
Видно, что не все состояния связаны стрелочками. Это происходит из-за того, что в
некоторые состояния агент «человек» переходит «пассивным» путем, то есть другой агент
потребляет его как ресурс в одном состоянии и производит того же агента в другом
состоянии (и, возможно, в другом месте). Желтый цвет состояния обозначает текущее
состояние агента, зеленая стрелка – активный переход.
3.4 Задача о мусорщиках
Рассмотрим задачу о мусорщиках.
Постановка задачи
54
Имеется три комнаты, соединенные в кольцо, а так же стол и мусорная корзина.
Обходить комнаты можно только по часовой стрелке. В каждой комнате имеется агент по
генерации предметов. Под предметами понимаем бумагу и собственно мусор как два
различных ресурса. Также в каждой комнате имеется уборщик, который этот мусор
убирает: бумагу - на стол, мусор - в мусорную корзину. Уборщики могут перемещаться
из комнаты в комнату.
Цели моделирования и анализа
Предлагается промоделировать данную задачу в нотации TRDA сетей при помощи
TRDA Tool.
На примере этой задачи рассмотрим, во-первых, работу временной характеристики
– времени Мерлина, и, во-вторых, рассмотрим свойство ограниченности.
Решение
Вершинами системной сети станут: три комнаты, стол и мусорная корзина.
Сложными агентами станут генератор предметов и уборщик. Генератор
может
производить бумагу или мусор, либо отдыхать. Уборщик может или брать бумагу из
комнаты и класть бумагу на стол, или брать мусор из комнаты и класть мусор в корзину,
или перемещаться в соседнюю комнату (потреблять себя самого из текущей комнаты и
производить себя же, но уже в другой комнате в соответствии с портами системной сети).
Перемещение уборщика в соседнюю комнату реализовано с помощью механизма
переменных (использованных во входных и выходных термах одного из переходов этого
агента).
Для проведения моделирования необходимо также задать начальную разметку сети.
При помощи различных конфигураций (начальных состояний) мы проследим, что влияет
на наличие или отсутствие порядка в комнате.
Графическая иллюстрация к данной задаче представлена на рисунке 23 и 24.
Подробно на картинке изображена только первая комната, но следует понимать, что во
всех остальных комнатах входные/выходные дуги такие же.
55
Room2
go
getp, getc, getc
go
genp,geng
go
Room3
Room1
putp
putg
Basket
Table
pap – w(1,2) t(10,12),
garb – w(1,2) t(12,14),
pause – w(1,2)
clean – w(1,2) t(2,5),
org – w(1,2) t(2,5),
go – w(1,2) t(10,15)
wait_gen
Generator
wait_cl
Cleaner
Рисунок 23. Иллюстрация к задаче о «мусорщиках»
56
Рисунок 24 Системная сеть задачи о мусорщиках в TRDA Tool
57
Время Мерлина
Для моделирования возьмем конфигурацию из приложения 4.1 Данная модель
включает применение временной характеристики wait (ожидание срабатывания активного
перехода) для некоторых переходов агента «Уборщик».
Начальная имеет следующий вид:
place(room1)
inst(clr1) inst(gen1)
place(room2)
inst(gen2) inst(clr2)
place(room3)
inst(gen3)
inst(clr3)
В каждой комнате по одному «Уборщику» и по одному «Генератору».
Загрузим модель и запустим выполнение на 50 шагов – Рисунок 25
58
Рисунок 25. Временная диаграмма, показывающая время Мерлина
Вывод
Как видно из временной диаграммы, время wait_cl и wait_gen как раз соответствует
тем самым искусственным задержкам пребывания в состояниях (в ожидании начала
выполнения активного перехода), времени Мерлина. Понятно, что такое время удобно
использовать в моделировании, когда, даже если все ресурсы есть в наличии, требуется
некоторая задержка, например, для согласования начала выполнения действия.
Ограниченность
Смысловой формулировкой проверяемого свойство ограниченности сделаем
ограничение количества предметов в комнате комнаты: в каждой комнате может быть не
более 5 экземпляров бумаги и не более 5 экземпляров мусора.
Для первой конфигурации берем входной файл из приложения 4.1
59
Так же зададим свойства для проверки ограниченности:
bound(room1,paper,5)
bound(room1,garbage,5)
bound(room2,paper,5)
bound(room2,garbage,5)
bound(room3,paper,5)
bound(room3,garbage,5))
Загрузим модель в эмулятор – рис. 26
Рисунок 26. Загружена модель о «мусорщиках»
Поставим галку Ограниченность, выполним (автоматически) произвольные 500
шагов и нажмем кнопку «Результаты анализа» - Рисунок 27
60
Рисунок 27. Результат анализа ограниченности из приложения 4.1
Как видно из результатов анализа, уже при первом прогоне свойство ограниченности
не выполняется. Поэтому изменим конфигурацию входного файла, разместив в каждой
комнате еще по одному уборщику – входной файл в приложении 4.2
Загрузим модель, выставим галку Ограниченности, запустим 500 произвольных
шагов, нажмем «Результаты анализа». – рис 28
61
Рисунок 28. Результаты анализа ограниченности из приложения 4.2
Тут видно, что за данный прогон количество мусора в комнатах удовлетворяет
неравенству:
Количество бумаги в каждой комнате <= 5
Количество мусора в каждой комнате <= 5
Для того, что набрать статистику, запустим еще один экземпляр эмулятора и вновь
запустим входной файл (приложение 4.2) и прогоним модель (несколько раз по 500
шагов). – Рисунок 29
62
Рисунок 29.1. Результаты анализа ограниченности из приложения 4.2
63
Рисунок
29.2.
Результаты
анализа
ограниченности
из
приложения
4.2
(многократные прогоны)
Вывод
Как видно и данная конфигурация (4.2, с увеличенным количеством уборщиков) не
помогает обеспечению заданного условия ограниченности модели и не переполнению
комнаты. Выполняя пошаговое моделирование, либо проанализировав временную
диаграмму, можно заметить, что это происходит из-за мобильности уборщиков. Иногда
они собираются в одной комнате, а другая при этом остается без уборки и в ней
набирается критическое количество мусора.
3.5 Задача о курильщиках
Постановка задачи
Имеется три курильщика. У одного из них в кармане есть некоторое количество
табака, у другого – бумаги, у третьего – спичек. Имеется стол, на который банкир кладет
два из трех ингредиентов курения: либо бумагу и спички, либо спички и табак, либо табак
и бумагу. Как только на столе оказывается 2 необходимых ингредиента курения для
данного курильщика, он их забирает и начинает курить.
Цели моделирования и анализа
Предлагается проанализировать свойство справедливости – все ли курильщики
смогут покурить? Данное свойство будет проверяться с помощью анализа достижимости.
Графическое представление задачи – Рисунок 30
64
tobacco
Bank
paper
matches
put
get
get
3
get
7
put
Pocket1
Table
Smoke1
get tobacco
get paper
get matches
put give
t(5)
s=no_smoking
Smoker
Smoke3
!matches
Smoke2
4
Pocket3
get give
t(1)
put tobacco
put paper
t(1)
put matches
put paper
t(1)
get give
t(1)
!paper
put tobacco
s
put matches
get give
t(1)
t(1)
!tobacco
Pocket2
Banker
Рисунок 30. Иллюстрации к задаче о курильщиках
Входной файл для данной задачи находится в приложении 5.
Чтобы проанализировать свойство справедливости, зададим следующие параметры
анализа достижимости разметки:
marking(m1,like)
place(smoke1)
inst(s1,smoking)
marking(m2,like)
place(smoke2)
inst(s2,smoking)
marking(m3,like)
place(smoke3)
inst(s3,smoking)
Что означает, что мы хотим найти три разметки, в каждой из которых указанный
курильщик курит (для каждой из этих разметок не имеет значения, что происходит в
других позициях).
Загрузим файл в эмулятор, поставим галку «Достижимость» и галку «Паузка при
нахождении» - Рисунок 31
65
Рисунок 31. Загружена модель о курильщиках
Запустим выполнение на 500 шагов.
Первая остановке представлена на Рисунок 32. Она произошла из-за того, что одна
из указанных в параметрах разметка была достигнута (m3).
66
Рисунок 32. Достигнута первая желаемая разметка в задаче о курильщиках (m3)
Заметим, что это произошло на 12 шаге (см. первую строку результата анализа) и
автоматическое выполнение остановилось раньше заданного числа шагов благодаря
выставленной галке «Пауза при нахождении»
Идем дальше еще на 500 шагов. – Рисунок 33 - еще одна желаемая разметка (m2)
достигнута (но перед этим еще два раза была достигнута m3). Опять же, все это
произошло гораздо раньше 500 шагов.
67
Рисунок 33. Вторая желаемая разметка достигнута (m2)
Идем дальше. – рис.34 - и еще одна желаемая разметка достигнута (m1)
68
Рисунок 34. Третья желаемая разметка достигнута (m1)
Итак, все желаемые разметки были достигнуты. Результаты анализа можно
сохранить в выходной текстовый файл, нажав на кнопку «Сохранить».
Цели моделирования были достигнуты: все курильщики могут покурить.
69
ЗАКЛЮЧЕНИЕ
Подводя итог проделанной работе, надо сказать, что поставленная в начале данной
работы
задача
распределенных
была
решена:
систем
разработана
временных
формальная
автоматов
(TRDA
модель
модель)
для
и
описания
создана
инструментальная среда имитационного моделирования на основе данного формализма
(TRDA Tool). Разработанный TRDA язык позволяет создавать описание TRDA модели в
текстовом файле. TRDA Tool позволяет загружать созданные текстовые файлы на TRDA
языке, выполнять имитационное моделирование, как в автоматическом, так и в ручном
режиме, как в режиме по шагам, так и во временном режиме. TRDA Tool имеет функции
поведенческого и статистического анализа поведения модели, а так же позволяет строить
временную диаграмму, благодаря которой можно делать различные выводы о качестве
построенной модели. TRDA Tool имеет функцию построения графической картинки как
системной, так и автоматной сети загруженной модели. TRDA Tool можно использовать
как с русским, так и с английским интерфейсом.
Программный инструмент TRDA Tool имеет свои достоинства и недостатки. Как
показали практические эксперименты, многие свойства моделей TRDA сетей могут быть
проверены и без построения полного графа покрытия или достижимости. Простое
моделирование позволяет акцентировать внимание на деталях, а разумный выбор
вероятностей на переходах элементной сети и установка временных параметров
увеличивает точность соответствия модели реальным системам.
Однако очевидно, что такие свойства как:
1) отсутствие живости
2) отсутствие живости переходов системной сети
3) ограниченность
4) недостижимость разметки
5) отсутствие тупиковой ситуации
могут быть установлены только при наличии полного графа покрытия или
достижимости. Это является недостатком реализованных в системе средств анализа.
К достоинствам разработанного анализатора можно отнести то, что он позволяет не
только проверять различные поведенческие свойства моделей, но и определять статистику
по интересующим параметрам. То есть с помощью данного анализатора можно, например,
установить, не только достижимость разметки, но и отследить частоту попадания в данное
состояние. Для более подробного анализа, имеется набор статистических параметров,
70
которые можно применять для каждого конкретного агента и его состояний. Интересным
является и возможность задания частичных параметров анализа. В примере с
достижимость можно указать не всю разметку полностью, а лишь некоторые, интересные
для анализа вершины системной сети.
Теперь отметим дальнейшие области развития и применения данного программного
инструмента. Наиболее наглядным и полезным свойством, проверяемым данной
программой, является достижимость: можно посмотреть как текстовый отчет о
результатах автоматического анализа данного свойства, так и его графическое
представление (при помощи временной диаграммы). В пояснительной записке не были
рассмотрены примеры, где ключевым параметром служило бы время. Однако, очевидно,
что
в реальных системах всегда присутствует некое время задержки выполнения
переходов, по истечении которого необходимые ресурсы могут закончиться, и переход,
который 5 минут назад был активным, больше не сможет выполниться. Возможность
задания длительности выполнения перехода так же интересна, ведь это позволит оценочно
имитировать наиболее длительные бизнес-процессы, после чего их можно будет
проанализировать более детально. Надо сказать, что в случае, если функциональность
TRDA Tool найдет реальное практическое применение, потребуется реализовать
возможность построения моделей графическим способом, интерактивно, через двумерную
наглядную схему, содержащую кружочки, стрелочки и т.д., аналогично CPN Tool, в
дополнение к используемой сейчас загрузке TRDA-модели из входного текстового файла
создаваемого вручную.
Следует отметить, что рассмотренные в данной работе примеры носят чисто
теоретический и искусственный характер. Это связано с тем, что рассмотрение и
спецификация реальных, имеющих практический смысл примеров, является само по себе
достаточно сложной задачей, которую было бы невозможно решить одновременно с
разработкой действующего прототипа возможной реальной системы моделирования.
Одним из самых необходимых шагов возможного дальнейшего развития данной
разработки является ее опробация на имеющих практическое значение примерах. Это, в
свою очередь, может потребовать развития практической функциональности системы, как
в части расширения набора параметров моделирования, так и части обеспечения
необходимой производительности.
В заключении отметим, что TRDA Tool с теоретическими примерами из пояснительной
записки использован в статье «Timed Resource Driven Automata Nets for Distributed Real-Time
Systems Modelling», которая принята к выступлению на PaCT-2013 Conference и публикации
в LNCS volume Springer Verlag, Germany.
71
Список использованной литературы
1. R. Alur, D. Dill. A theory of timed automata. Theoretical Computer Science,
vol.126(2), 1994. P.183 - 235.
2. V.A. Bashkin. Nets of active resources for distributed systems modeling. Joint
Bulletin of NCC&IIS, Comp. Science., vol.28. Novosibirsk, 2008. P.43-54.
3. V.A. Bashkin, I.A. Lomazova. Resource Driven Automata Nets. Fundamenta
Informaticae., vol.109(3). 2011. P.223-236.
4. T. Bolognesi, F. Lucidi, and S. Trigila. From timed Petri nets to timed LOTOS.
In Proc. of the IFIP WG 6.1 Tenth International Symposium on Protocol Specification,
Testing
and Verication, 1990. P.1-14.
5. I.A. Lomazova. Nested Petri Nets - a Formalism for Specication and Verication
of Multi-Agent Distributed Systems. Fundamenta Informaticae., vol.43(1-4). 2000. P.195214.
6. P.M. Merlin. A Study of the Recoverability of Computing Systems. PhD thesis,
University of California, Irvine, CA, USA, 1974. Automata Network. Int.J. of Algebra and
Computation, 14(5-6). 2004. P.719-739.
7. C. Ramchandani. Analysis of asynchronous concurrent systems by timed Petri nets.
Technical report. Massachusetts Institute of Technology Cambridge,1974.
8. Reisig W., Rozenberg. Lectures on Petri Nets I: Basic Models, Springer, 1998.
9. UPPAAL Home, Режим доступа: http://www.uppaal.org/, свободный. (дата обращения:
07.01.2013)
10. CPN Tool, Режим доступа: http://cpntools.org/, свободный. (дата обращения:
07.01.2013)
11. ProM, Режим доступа: http://www.promtools.org/prom6/, свободный. (дата обращения:
07.01.2013)
12. Petri Net Markup Language, Режим доступа: http://www.pnml.org/, свободный. (дата
обращения: 25.12.2011)
72
Приложения
Приложение 1 Задача о философах, гуляющих в парке
model(Dinning_philosophers_wandering)
place(chair1)
place(chair2)
place(chair3)
place(chair4)
place(napkin23)
place(napkin34)
place(dish)
place(napkin12)
place(napkin41)
place(park)
arc_in(chair1,napkin41,getr)
arc_in(chair1,napkin12,getl)
arc_out(chair1,napkin41,putr)
arc_out(chair1,napkin12,putl)
arc_out(chair1,park,ToPark)
arc_in(chair1,chair1,Leave)
arc_out(chair1,chair1,put)
arc_in(chair2,napkin12,getr)
arc_in(chair2,napkin23,getl)
arc_out(chair2,napkin12,putr)
arc_out(chair2,napkin23,putl)
arc_out(chair2,park,ToPark)
arc_in(chair2,chair2,Leave)
arc_out(chair2,chair2,put)
arc_in(chair3,napkin23,getr)
arc_in(chair3,napkin34,getl)
arc_out(chair3,napkin23,putr)
arc_out(chair3,napkin34,putl)
arc_out(chair3,park,ToPark)
arc_in(chair3,chair3,Leave)
arc_out(chair3,chair3,put)
arc_in(chair4,napkin34,getr)
arc_in(chair4,napkin41,getl)
arc_out(chair4,napkin34,putr)
arc_out(chair4,napkin41,putl)
arc_out(chair4,park,ToPark)
arc_in(chair4,chair4,Leave)
arc_out(chair4,chair4,put)
arc_in(chair1,dish,eat)
arc_in(chair2,dish,eat)
arc_in(chair3,dish,eat)
arc_in(chair4,dish,eat)
arc_in(park,park,Leave)
73
arc_in(park,chair1,get1)
arc_in(park,chair2,get2)
arc_in(park,chair3,get3)
arc_in(park,chair4,get4)
arc_out(park,chair1,ToChair1)
arc_out(park,chair2,ToChair2)
arc_out(park,chair3,ToChair3)
arc_out(park,chair4,ToChair4)
type(fork)
const(f)
port(putr) port(putl) port(getr) port(getl)
type(spag)
const(s)
port(eat)
type(free)
const(free)
port(put) port(get1) port(get2) port(get3) port(get4)
type(philosopher)
state(thinking)
port(Leave)
port(ToChair1)
port(ToChair4) port(ToPark)
const(p1) const(p2) const(p3)
var(ph)
port(ToChair2)
port(ToChair3)
const(p4)
state_chart_name(LFork_before_eating,1fork)
state_chart_name(RFork_before_eating,1fork)
state_chart_name(RFork_after_eating,1fork)
state_chart_name(LFork_after_eating,1fork)
trans(eating,eating,do_eating) trans_chart_name(eating)
trans_symbol($) priority(60) duration(10)
term_in(eat,s)
trans(eating,LFork_after_eating,L_A) priority(20) duration(1)
trans_chart_name(put_fork)
term_out(putr,f)
trans(eating,RFork_after_eating,R_A) priority(20) duration(1)
trans_chart_name(put_fork)
term_out(putl,f)
trans(thinking,LFork_before_eating,L_B)
duration(2)
trans_chart_name(get_fork)
term_in(getl,f)
trans(thinking,RFork_before_eating,R_B)
duration(2)
trans_chart_name(get_fork)
term_in(getr,f)
trans(thinking,thinking,do_thinking) trans_chart_name(thinking)
duration(5) trans_symbol(?)
trans(thinking,thinking,to_park)
duration(2)
trans_chart_name(walking)
term_in(Leave,ph,thinking)
term_out(put,free)
term_out(ToPark,ph,thinking)
74
trans(thinking,thinking,to_chair1)
trans_chart_name(walking)
term_in(get1,free)
term_in(Leave,ph,thinking)
term_out(ToChair1,ph,thinking)
trans(thinking,thinking,to_chair2)
trans_chart_name(walking)
term_in(get2,free)
term_in(Leave,ph,thinking)
term_out(ToChair2,ph,thinking)
trans(thinking,thinking,to_chair3)
trans_chart_name(walking)
term_in(get3,free)
term_in(Leave,ph,thinking)
term_out(ToChair3,ph,thinking)
trans(thinking,thinking,to_chair4)
trans_chart_name(walking)
term_in(get4,free)
term_in(Leave,ph,thinking)
term_out(ToChair4,ph,thinking)
duration(4)
duration(4)
duration(4)
duration(4)
trans(LFork_before_eating,eating,lets_eat1)
trans_chart_name(get_fork)
priority(80) duration(1)
term_in(getr,f)
trans(LFork_before_eating,thinking,lets_think2)
trans_chart_name(put_fork)
priority(20) duration(1)
term_out(putl,f)
trans(RFork_before_eating,eating,lets_eat1)
trans_chart_name(get_fork)
priority(80) duration(1)
term_in(getl,f)
trans(RFork_before_eating,thinking,lets_think2)
trans_chart_name(put_fork)
priority(20) duration(1)
term_out(putr,f)
trans(LFork_after_eating,eating,lets_eat2)
trans_chart_name(get_fork)
priority(20) duration(2)
term_in(getr,f)
trans(LFork_after_eating,thinking,lets_think1)
trans_chart_name(put_fork)
priority(80) duration(2)
term_out(putl,f)
trans(RFork_after_eating,eating,lets_eat2)
trans_chart_name(get_fork)
priority(20) duration(3)
term_in(getl,f)
trans(RFork_after_eating,thinking,lets_think1)
trans_chart_name(put_fork)
priority(80) duration(1)
term_out(putr,f)
place(chair1)
75
inst(p1,thinking)
place(chair2)
inst(p2,thinking)
place(chair3)
inst(p3,thinking)
place(chair4)
inst(p4,thinking)
place(napkin23)
inst(f)
place(napkin34)
inst(f)
place(dish)
inst(s) inst(s)
inst(s) inst(s)
inst(s) inst(s)
inst(s) inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
place(napkin12)
inst(f)
place(napkin41)
inst(f)
/* Проверка достижимости */
marking(m1)
place(dish)
inst(s) inst(s)
marking(m2,like)
place(chair3)
inst(p1,thinking)
76
Приложение 2 Задача о философах и дедлоке
model(Dinning_philosophers_deadlock)
place(chair1)
place(chair2)
place(chair3)
place(chair4)
place(napkin23)
place(napkin34)
place(dish)
place(napkin12)
place(napkin41)
arc_in(chair1,napkin41,getr)
arc_in(chair1,napkin12,getl)
arc_out(chair1,napkin41,putr)
arc_out(chair1,napkin12,putl)
arc_in(chair1,chair1,Leave)
arc_out(chair1,chair1,put)
arc_in(chair2,napkin12,getr)
arc_in(chair2,napkin23,getl)
arc_out(chair2,napkin12,putr)
arc_out(chair2,napkin23,putl)
arc_in(chair2,chair2,Leave)
arc_out(chair2,chair2,put)
arc_in(chair3,napkin23,getr)
arc_in(chair3,napkin34,getl)
arc_out(chair3,napkin23,putr)
arc_out(chair3,napkin34,putl)
arc_in(chair3,chair3,Leave)
arc_out(chair3,chair3,put)
arc_in(chair4,napkin34,getr)
arc_in(chair4,napkin41,getl)
arc_out(chair4,napkin34,putr)
arc_out(chair4,napkin41,putl)
arc_in(chair4,chair4,Leave)
arc_out(chair4,chair4,put)
arc_in(chair1,dish,eat)
arc_in(chair2,dish,eat)
arc_in(chair3,dish,eat)
arc_in(chair4,dish,eat)
type(fork)
77
const(f)
port(putr) port(putl) port(getr) port(getl)
type(spag)
const(s)
port(eat)
type(free)
const(free)
port(put) port(get1) port(get2) port(get3) port(get4)
type(philosopher)
state(thinking)
port(Leave)
port(ToChair1)
port(ToChair4)
const(p1) const(p2) const(p3)
var(ph)
port(ToChair2)
port(ToChair3)
const(p4)
state_chart_name(LFork_before_eating,1fork)
state_chart_name(RFork_before_eating,1fork)
state_chart_name(RFork_after_eating,1fork)
state_chart_name(LFork_after_eating,1fork)
trans(eating,eating,do_eating) trans_chart_name(eating)
priority(60) duration(10)
term_in(eat,s)
trans(eating,LFork_after_eating,L_A) priority(20) duration(1)
trans_chart_name(put_fork)
term_out(putr,f)
trans(eating,RFork_after_eating,R_A) priority(20) duration(1)
trans_chart_name(put_fork)
term_out(putl,f)
trans(thinking,LFork_before_eating,L_B)
duration(2)
trans_chart_name(get_fork)
term_in(getl,f)
trans(thinking,RFork_before_eating,R_B)
duration(2)
trans_chart_name(get_fork)
term_in(getr,f)
trans(LFork_before_eating,eating,lets_eat1)
trans_chart_name(get_fork)
priority(80) duration(1)
term_in(getr,f)
trans(RFork_before_eating,eating,lets_eat1)
trans_chart_name(get_fork)
priority(80) duration(1)
term_in(getl,f)
trans(LFork_after_eating,eating,lets_eat2)
trans_chart_name(get_fork)
priority(20) duration(2)
term_in(getr,f)
trans(LFork_after_eating,thinking,lets_think1)
trans_chart_name(put_fork)
priority(80) duration(2)
term_out(putl,f)
78
trans(RFork_after_eating,eating,lets_eat2)
trans_chart_name(get_fork)
priority(20) duration(3)
term_in(getl,f)
trans(RFork_after_eating,thinking,lets_think1)
trans_chart_name(put_fork)
priority(80) duration(1)
term_out(putr,f)
place(chair1)
inst(p1,thinking)
place(chair2)
inst(p2,thinking)
place(chair3)
inst(p3,thinking)
place(chair4)
inst(p4,thinking)
place(napkin23)
inst(f)
place(napkin34)
inst(f)
place(dish)
inst(s) inst(s)
inst(s) inst(s)
inst(s) inst(s)
inst(s) inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
inst(s)
place(napkin12)
inst(f)
place(napkin41)
inst(f)
79
Приложение 3 Задача о спящем парикмахере
place(street)
place(reception)
place(chair)
arc_in(reception,reception,free)
arc_in(reception,street,man_from_street)
arc_out(reception,reception,man_to_queue)
arc_in(chair,reception,man_from_queue)
arc_out(chair,chair,man_to_chair)
arc_out(chair,reception,free)
arc_in(chair,chair,man_from_chair)
arc_out(chair,street,man_to_street)
type(man)
const(m)
const(m01) const(m02) const(m03) const(m04)
const(m05) const(m06) const(m07) const(m08)
const(m09) const(m10) const(m11) const(m12)
var(x)
port(new_man) port(old_man)
port(man_to_queue)
port(man_from_queue)
port(man_from_chair)
port(man_to_chair)
port(man_from_street)
port(man_to_street)
state(shorn) state(unshorn) state(unshorn_wait) state(shorning)
trans(new_shorn,shorn)
duration(1)
reset(x)
trans_chart_name(after_barber)
trans(shorn,unshorn)
duration(1)
constr(x>30)
reset(y)
trans_chart_name(with_new_hair)
type(free)
const(free) port(free)
type(barber)
const(barber)
state(sleep) state(work)
trans(sleep,work) duration(1) reset(x)
term_in(man_from_queue,x,unshorn_wait)
term_out(man_to_chair,x,shorning)
term_out(free,free)
trans(work,sleep) duration(1) constr(x>5)
term_in(man_from_chair,x,shorning)
term_out(man_to_street,x,new_shorn)
type(manager)
80
const(manager)
trans(s,s) wait(1,2) duration(1) trans_chart_name(take_str_man)
term_in(free,free)
term_in(man_from_street,x,unshorn)
term_out(man_to_queue,x,unshorn_wait)
place(reception)
inst(manager)
inst(free) inst(free) inst(free) inst(free)
place(chair)
inst_viz(barber)
place(street)
inst(m03) inst(m04) inst(m01) inst(m02)
marking(m1,like)
place(chair)
inst(m01,shorning)
inst(barber,work)
marking(m2,like)
place(chair)
inst(m02,shorning)
inst(barber,work)
marking(m3,like)
place(chair)
inst(m03,shorning)
inst(barber,work)
marking(m4,like)
place(chair)
inst(m04,shorning)
inst(barber,work)
81
Приложение 4.1 Задача о мусорщиках_1
place(room1)
place(room2)
place(room3)
place(basket)
place(table)
arc_in(room1,room1,getp)
arc_in(room1,room1,getg)
arc_in(room1,room1,getc)
arc_out(room1,room1,genp)
arc_out(room1,room1,geng)
arc_out(room1,table,putp)
arc_out(room1,basket,putg)
arc_out(room1,room2,go)
arc_in(room2,room2,getp)
arc_in(room2,room2,getg)
arc_in(room2,room2,getc)
arc_out(room2,room2,genp)
arc_out(room2,room2,geng)
arc_out(room2,table,putp)
arc_out(room2,basket,putg)
arc_out(room2,room3,go)
arc_in(room3,room3,getp)
arc_in(room3,room3,getg)
arc_in(room3,room3,getc)
arc_out(room3,room3,genp)
arc_out(room3,room3,geng)
arc_out(room3,table,putp)
arc_out(room3,basket,putg)
arc_out(room3,room1,go)
type(garbage)
const(g) port(getg) port(putg) port(geng)
type(paper)
const(p) port(getp) port(putp) port(genp)
type(cleaner)
const(clr) const(clr1) const(clr2) const(clr3)
var(x)
port(getc) port(go)
state_chart_name(s,wait_cl)
trans(s,s,clean)
wait(1,2)
time(2,5)
priority(49)
trans_chart_name(clean)
term_in(getg,g)
term_out(putg,g)
trans(s,s,org) wait(1,2) time(2,5) priority(49) trans_chart_name(org)
term_in(getp,p)
term_out(putp,p)
trans(s,s,go) wait(1,2) time(10,15) priority(1) trans_chart_name(go)
term_in(getc,x,s)
term_out(go,x,s)
82
type(generator)
const(gen) const(gen1) const(gen2) const(gen3)
state(s)
state_chart_name(s,wait_gen)
trans(s,s,pap) wait(1,2) time(10,12) trans_chart_name(pap)
term_out(genp,p)
trans(s,s,garb) wait(1,2) time(12,14) trans_chart_name(garb)
term_out(geng,g)
trans(s,s,pause) wait(1,2)
place(room1)
inst(clr1) inst(gen1)
place(room2)
inst(gen2)
inst(clr2)
place(room3)
inst(gen3)
inst(clr3)
bound(room1,paper,5)
bound(room1,garbage,5)
bound(room2,paper,5)
bound(room2,garbage,5)
bound(room3,paper,5)
bound(room3,garbage,5))
83
Приложение 4.2 Задача о мусорщиках_2
place(room1)
place(room2)
place(room3)
place(basket)
place(table)
arc_in(room1,room1,getp)
arc_in(room1,room1,getg)
arc_in(room1,room1,getc)
arc_out(room1,room1,genp)
arc_out(room1,room1,geng)
arc_out(room1,table,putp)
arc_out(room1,basket,putg)
arc_out(room1,room2,go)
arc_in(room2,room2,getp)
arc_in(room2,room2,getg)
arc_in(room2,room2,getc)
arc_out(room2,room2,genp)
arc_out(room2,room2,geng)
arc_out(room2,table,putp)
arc_out(room2,basket,putg)
arc_out(room2,room3,go)
arc_in(room3,room3,getp)
arc_in(room3,room3,getg)
arc_in(room3,room3,getc)
arc_out(room3,room3,genp)
arc_out(room3,room3,geng)
arc_out(room3,table,putp)
arc_out(room3,basket,putg)
arc_out(room3,room1,go)
type(garbage)
const(g) port(getg) port(putg) port(geng)
type(paper)
const(p) port(getp) port(putp) port(genp)
type(cleaner)
const(clr)
const(clr11)
const(clr21)
const(clr12) const(clr22) const(clr32)
var(x)
port(getc) port(go)
state_chart_name(s,wait_cl)
const(clr31)
84
trans(s,s,clean)
wait(1,2)
time(2,5)
trans_chart_name(clean)
term_in(getg,g)
term_out(putg,g)
trans(s,s,org)
wait(1,2)
time(2,5)
trans_chart_name(org)
term_in(getp,p)
term_out(putp,p)
trans(s,s,go)
wait(1,2)
time(10,15)
trans_chart_name(go)
term_in(getc,x,s)
term_out(go,x,s)
priority(49)
priority(49)
priority(1)
type(generator)
const(gen) const(gen1) const(gen2) const(gen3)
state(s)
state_chart_name(s,wait_gen)
trans(s,s,pap) wait(1,2) time(10,12) trans_chart_name(pap)
term_out(genp,p)
trans(s,s,garb)
wait(1,2)
time(12,14)
trans_chart_name(garb)
term_out(geng,g)
trans(s,s,pause) wait(1,2)
place(room1)
inst(clr11)
inst(clr12)
inst(gen1)
place(room2)
inst(clr21)
inst(clr22)
inst(gen2)
place(room3)
inst(clr31)
inst(clr32)
inst(gen3)
bound(room1,paper,5)
bound(room1,garbage,5)
bound(room2,paper,5)
bound(room2,garbage,5)
85
bound(room3,paper,5)
bound(room3,garbage,5))
86
Приложение 5 Задача курильщиках
model(smokers)
place(smoke1) place(smoke2) place(smoke3)
place(pocket1) place(pocket2) place(pocket3)
place(table)
place(bank)
arc_in(smoke1,table,get)
arc_in(smoke2,table,get)
arc_in(smoke3,table,get)
arc_out(smoke1,table,put)
arc_out(smoke2,table,put)
arc_out(smoke3,table,put)
arc_in(smoke1,pocket1,get)
arc_in(smoke2,pocket2,get)
arc_in(smoke3,pocket3,get)
arc_in(bank,table,get)
arc_out(bank,table,put)
type(resource)
const(tobacco) const(paper) const(matches) const(give)
port(get) port(put)
type(smoker)
const(s1) const(s2) const(s3)
state(no_smoking) state_chart_name(no_smoking,no_smoking)
trans(no_smoking,smoking)
duration(5)
trans_chart_name(smoking)
term_in(get,tobacco)
term_in(get,paper)
term_in(get,matches)
term_out(put,give)
trans(smoking,no_smoking)
duration(1)
trans_chart_name(no_smoking)
type(banker)
const(banker)
state_chart_name(s,ready)
trans(!matches,s)
term_in(get,give)
trans_chart_name(ready)
trans(!paper,s)
term_in(get,give)
trans_chart_name(ready)
duration(1)
duration(1)
87
trans(!tobacco,s)
trans_chart_name(ready)
term_in(get,give)
duration(1)
trans(s,!matches)
term_out(put,tobacco)
term_out(put,paper)
duration(1)
trans(s,!paper)
term_out(put,tobacco)
term_out(put,matches)
duration(1)
trans(s,!tobacco)
term_out(put,matches)
term_out(put,paper)
duration(1)
place(table)
inst(give)
place(bank) inst(banker)
place(smoke1) inst(s1)
place(smoke2) inst(s2)
place(smoke3) inst(s3)
place(pocket1)
inst(tobacco) inst(tobacco) inst(tobacco) inst(tobacco)
place(pocket2)
inst(paper) inst(paper) inst(paper) inst(paper) inst(paper)
place(pocket3)
inst(matches)
inst(matches)
inst(matches)
inst(matches) inst(matches) inst(matches)
inst(matches)
marking(m1,like)
place(smoke1)
inst(s1,smoking)
marking(m2,like)
place(smoke2)
inst(s2,smoking)
marking(m3,like)
place(smoke3)
inst(s3,smoking)
88
Приложение 6 Техническое задание
Правительство Российской Федерации
Федеральное государственное автономное образовательное
учреждение
высшего профессионального образования
Национальный исследовательский университет
Высшая школа экономики
Факультет бизнес информатики
Отделение программной инженерии
Кафедра «Управление разработкой программного
обеспечения»
МАГИСТЕРСКАЯ ДИССЕРТАЦИЯ
Техническое задание
Инструментальная среда имитационного моделирования распределенных систем
мобильных агентов
Исполнитель: студентка группы 271мУРПО
___________________ /Новикова Ю.А./
«_____»_______________________ 2013 г.
Руководитель работы:
профессор, доктор физико-математических наук
____________________ / Ломазова И.А./
«_____»_______________________ 2013 г.
Москва 2013
89
Оглавление
Оглавление......................................................................................................................... 90
1.
Введение ..................................................................................................................... 91
2.
Основания для разработки ........................................................................................ 91
3. Назначение разработки................................................................................................. 91
3.1.Функциональное назначение. .................................................................................... 91
3.2.Эксплуатационное назначение. ................................................................................. 91
4. Требования к программе .............................................................................................. 91
4.1.Требования к функциональным характеристикам .................................................. 91
4.1.1 Требования к выполняемым функциям ................................................................ 91
4.1.2 Графические требования ......................................................................................... 92
4.1.3 Требования к исходным данным ............................................................................ 92
4.1.4 Требования к выходным данным ........................................................................... 92
4.2. Требования к надежности ......................................................................................... 93
4.3. Условия эксплуатации ............................................................................................... 93
4.4.Требования к информационной и программной совместимости ........................... 93
4.5.Требования к составу и параметрам технических средств ..................................... 93
5.
Стадии и этапы разработки ...................................................................................... 93
6.
Технико-экономические показатели ........................................................................ 96
7.
Порядок контроля и приемки ................................................................................... 96
8.
Требования к программной документации ............................................................. 96
90
1. Введение
Наименование
программы:
Инструментальная
среда
имитационного
моделирования распределенных систем временных автоматов.
2. Основания для разработки
Основанием является тот факт, что данная программа является магистерской
диссертацией за второй год обучения в магистратуре отделения программной инженерии
факультета бизнес информатики Национального Исследовательского Университета Высшей
Школы Экономики.
Организация, утвердившая этот документ – НИУ – ВШЭ, отделение программной
инженерии
факультета
бизнес
-
информатики,
кафедра
управление
разработкой
программного обеспечения.
Наименование темы разработки: магистерская диссертация.
3. Назначение разработки
3.1.Функциональное назначение.
Программа
предназначена
для
моделирования,
анализа
и
визуализации
распределенной системы временных автоматов. Под моделированием понимается
возможность загрузки моделей вида «распределенных систем временных автоматов»,
возможность
демонстрации
выполнения
этих
моделей
и
выгрузки
результатов
моделирования. Под анализом понимается возможность проводить исследования
построенных моделей при помощи текстовых отчетов о полученных/проверенных
автоматическим образом ее поведенческих свойствах, включая статистические данные, а
также при помощи временной диаграммы. Под визуализацией понимается графическое
представление системной и автоматной сети модели типа распределенной системы
временных
автоматов.
Визуализация
выполняется
в
виде
графа
с
выводом
специализированной информации: имена портов, подпись вершин, и т.д.
3.2.Эксплуатационное назначение.
Программа предназначена для использования учащимися или преподавателями,
или другими заинтересованными лицами с целью визуального просмотра автоматического
или пошагового выполнения построенных ими моделей заданного типа.
4. Требования к программе
4.1.Требования к функциональным характеристикам
4.1.1 Требования к выполняемым функциям

чтение данных из файла

проведение моделирования
91

сохранение результатов в файл

вывод справочной информации

анализ и проверка поведенческих свойств моделей

построение временной диаграммы

вывод статической аналитической информации

визуализация системной и автоматной сетей

поддержка двуязычного интерфейса: русский, английский язык
4.1.2 Графические требования

Графическое отражение загруженной модели

Возможность наглядного просмотра поведения (выполнения) модели

Просмотр временной диаграммы длительности состояний сложных
агентов
4.1.3 Требования к исходным данным
Требования в исходным данным описаны в Пояснительной Записке, в разделе
Разработка языка описания модели типа ресурсно-управляемых сетей временных
автоматов.
4.1.4 Требования к выходным данным
Программа должна предоставлять возможность сохранить полученную модель в
виде текстового файла. Структура текстового файла должна соответствовать тем же
требованиям, предъявляемым к исходному файлу.
При выборе опции по визуализации или системной, или автоматной сети
автоматическим образом в директорию, в которой размещен входной файл модели (*.rda)
должно сохраняться два файла: построенная модель графа в формате (*.dot) и визуальная
картинка модели (*.jpg).
Специальные
требования
к
емкостным
характеристикам
программы
не
предъявляются.
92
4.2. Требования к надежности

синтаксический контроль исходных данных
4.3. Условия эксплуатации
Квалификация эксплуататора программы – пользователь ПК и выше.
4.4.Требования к информационной и программной
совместимости
Программа предназначена для работы под операционной системой Windows XP SP2.
Кроме того, на компьютере должна быть установлена среда исполнения .NET Framework
версии 2.0 или выше. Для работы с визуализацией на компьютере должна быть
установлена программа Graphviz 2.28. Программа доступна для скачивания на сайте
http://www.graphviz.org/Home.php. После установки программы, требуется перезагрузить
операционную систему, для того, чтобы команда dot.exe прописалась в пути (path).
4.5.Требования к составу и параметрам технических средств
Таблица 1
Требования к составу и параметрам технических средств
Необх
№
одимый
процессор
Рекоменд
Необх
Рекомен
уемый процессор
одимое ОЗУ
дуемое ОЗУ
1 Gb
2Gb
Pentium 2
GHz или с более
Pentiu
1
высоким
m
1GHz
быстродействием
5. Стадии и этапы разработки
Таблица 2
Стадии и этапы разработки
№
Стадии
разработки
Этапы работ
Содержание работ
93
№
1
Стадии
Этапы работ
Содержание работ
Техническое
Обоснование
задание
необходимости
Постановка задачи
Сбор исходных
материалов
разработки
разработки
программы
Научноисследовательские
работы
Разработка и
утверждение
технического
задания
2
Технический
Разработка
проект
технического
проекта
Определение
структуры
входных и
выходных данных.
Предварительный
выбор методов
решения задач.
Определение
требований к
техническим
средствам.
Определение
требований к
программе.
Разработка
техникоэкономического
обоснования
разработки
программы.
Определение
стадий, этапов и
сроков разработки
программы и
документации на
неё.
Выбор языков
программирования.
Согласование и
утверждение
технического
задания.
Уточнение
структуры
входных и
выходных данных.
Разработка
алгоритма решения
задачи.
Определение
формы
представления
94
№
Стадии
разработки
Этапы работ
Утверждение
технического
проекта
3
Рабочий проект
Разработка
программы
Разработка
программной
Содержание работ
входных и
выходных данных.
Разработка
структуры
программы.
Разработка плана
мероприятий по
разработке и
внедрению
программ.
Разработка
пояснительной
записки.
Согласование и
утверждение
технического
проекта.
Разработка
программы
Разработка
программных
документов.
документации
Испытания
программы
4
Внедрение
Подготовка и
передача
программы.
Разработка,
согласование и
утверждение
порядка и
методики
испытаний.
Корректировка
программы и
программной
документации по
результатам
испытаний.
Сдача программы
и программной
документации
заказчику.
95
6. Технико-экономические показатели
От разрабатываемой программы требуется уметь открывать файл модели за период
времени в пределах 10 секунд, уметь находить варианты дальнейшего поведения
загруженной модели за период времени в пределах 10 секунд.
7. Порядок контроля и приемки
Контроль и приемка разработки осуществляются в соответствии с документом
«Программа и методика испытаний».
8. Требования к программной документации
В процессе разработки должны быть созданы следующие документы:

текст программы

пояснительная записка

программа и методика испытаний

руководство оператора
96
Приложение 7 Программа и методика испытаний
Правительство Российской Федерации
Федеральное государственное автономное образовательное
учреждение
высшего профессионального образования
Национальный исследовательский университет
Высшая школа экономики
Факультет бизнес информатики
Отделение программной инженерии
Кафедра «Управление разработкой программного
обеспечения»
МАГИСТЕРСКАЯ ДИССЕРТАЦИЯ
Программа и методика испытаний
«Инструментальная среда имитационного моделирования распределенной
системы мобильных агентов»
Исполнитель: студентка группы 271мУРПО
___________________ /Новикова Ю.А./
«_____»_______________________ 2013 г.
Руководитель работы
Профессор, доктор физико-математических наук
____________________ / Ломазова И.А./
«_____»_______________________ 2013 г.
Москва 2013
97
1.Объект испытаний
На испытание выносится программа «Инструментальная среда имитационного
моделирование распределенной системы временных автоматов» (TRDA Tool).
Программа выполняет следующий набор функций:

Чтение выбранного пользователем входного файла на описанном в ПЗ языке

Построение модели ресурсно-управляемых сетей временных автоматов по входному
файлу

Просмотр выполнения построенной модели

Построение временной диаграммы по просмотренным шагам выполнения модели

Сохранение получившейся модели в файл

Проверка поведенческих свойств модели

Вывод статической информации

Визуализация системной и автоматной сети

Поддержка мультиязычности: русский, английские языки
2.Цель испытания
Испытания проводятся с целью проверки работоспособности предъявляемой
программы и соответствия ее требованиям технического задания (ТЗ) по составу и
функциональным характеристикам.
3.Состав предъявляемой документации
При
проведении
испытаний
предъявляются
следующая
программная
документация:

руководство оператора;

пояснительная записка

код программы (приложения к ПЗ);

техническое задание
4.Технические требования
4.1Требования к программной документации
Состав программной документации:
 Имитационная среда имитационного моделирования распределенной системы временных
автоматов. Пояснительная записка.
98
 Имитационная среда имитационного моделирования распределенной системы временных
автоматов. Код программы.
 Имитационная среда имитационного моделирования распределенной системы временных
автоматов. Программа и методика испытаний.
 Имитационная среда имитационного моделирования распределенной системы временных
автоматов. Руководство оператора.
4.2Требования к программе
Программа выполняет следующий набор функций:

Чтение выбранного пользователем входного файла на описанном в ПЗ языке

Построение модели ресурсно-управляемых сетей временных автоматов по входному
файлу

Просмотр выполнения построенной модели

Построение временной диаграммы по просмотренным шагам выполнения модели

Сохранение получившейся модели в файл

Проверка поведенческих свойств модели

Вывод статической информации

Визуализация системной и автоматной сети

Поддержка мультиязычности: русский, английские языки
5. Средства и порядок испытаний
Для
функционирования
программы
необходим
стандартный
комплект
оборудования (персональный компьютер) со следующей конфигурацией:
1) Системный блок
- процессор с тактовой частотой не ниже 1ГГц
- 1024Мб ОЗУ
- 40Гб НЖМД
- видеокарта, поддерживающая разрешение 1024х768 и 256 цветов
2) Монитор, поддерживающий разрешение 1024х768 и 256 цветов
3) Клавиатура
4) Мышь
5.2.Программные средства
Программа представляет собой автономный программный продукт, для ее
функционирования необходима установленная ОС MS Windows 2000\XP\7\8.
Так же
необходима установка .NET Framework 2.0. Для работы с визуализацией на компьютере
99
должна быть установлена программа Graphviz 2.28, доступная для скачивания по ссылке:
http://www.graphviz.org/Download.php.
После
установки
программы,
требуется
перезагрузить операционную систему, для того, чтобы команда dot.exe прописалась в пути
(path), и стала доступна для выполнения из любой директории.
5.3 Порядок Проведения Испытаний
Испытания должны выполняться в следующем порядке:
1)
Выполнить стандартную процедуру начальной загрузки операционной системы.
2)
Запустить программу. Для этого необходимо запустить файл Automata.exe.
3)
Провести необходимые испытания, описанные в разделе «Методы испытаний».
4)
Выйти из программы
6.Методы испытаний
Испытания представляют собой процесс установления соответствия программы
заданным требованиям и программной документации.
6.1 Испытания общего хода работы программы
Испытание выполняется следующим образом:
1) Выбрать входной файл с текстом не соответствующим синтаксису разработанного языка
(файл -> открыть);
2) Просмотреть сообщения об ошибке;
3) Выбрать входной файл с правильным синтаксисом (файл -> открыть) и заданной
необходимостью проверки свойства достижимости для одной из позиций
4) Просмотреть загруженную модель в левой стороне главной формы;
5) Выставить галочку «Достижимость» на главной форме
6) Выбрать
(выполнить
по
средствам
двойного
нажатия)
необходимые
переходы,
представленные в правой стороне главной формы;
7) Нажать кнопку «Просмотр временной диаграммы»;
8) Просмотреть форму с цветной диаграммой;
9) Вернуться на главную форму;
10) Запустить модель по времени (выбрать значение в выпадающем меню);
11) Просмотреть результат в левой стороне главной формы;
12) Нажать кнопку «по шагам»;
13) Выбрать нужные переходы;
14) Сохранить результаты выполнения модели в файл (файл -> сохранить);
15) Нажать кнопку «Результаты анализа»;
100
16) Проверить, была ли достигнута заданная маркировка в течение выполнения модели;
17) Просмотреть статистическую информацию об агентах;
18) Выбрать агента в левой части главной формы для визуализации (двойной клик по агенту);
19) Выставить галочку «Системная сеть»;
20) Выставить галочку «Автоматная сеть»;
21) Просмотреть картинку системной сети;
22) Просмотреть картинку автоматной сети;
23) Переключить язык на английский (файл->English/Русский)
24) Убедиться, что текстовые элементы главной формы переведены на английский язык
101
Приложение 8 Руководство оператору
Правительство Российской Федерации
Федеральное государственное автономное образовательное
учреждение
высшего профессионального образования
Национальный исследовательский университет
Высшая школа экономики
Факультет бизнес информатики
Отделение программной инженерии
Кафедра «Управление разработкой программного
обеспечения»
МАГИСТЕРСКАЯ ДИССЕРТАЦИЯ
Руководство оператору
Инструментальная среда имитационного моделирования распределенных систем
мобильных агентов
Исполнитель: студентка группы 271мУРПО
___________________ /Новикова Ю.А./
«_____»_______________________ 2013 г.
Руководитель работы:
профессор, доктор физико-математических наук
____________________ / Ломазова И.А./
«_____»_______________________ 2013 г.
Москва 2013
102
1.Назначение программы
Программа
предназначена
для
моделирования,
анализа
и
визуализации
распределенной системы временных автоматов. Под моделированием понимается
возможность загрузки моделей вида «распределенных систем временных автоматов»,
возможность
демонстрации
выполнения
этих
моделей
и
выгрузки
результатов
моделирования. Под анализом понимается возможность проводить исследования
построенных моделей при помощи полученных/проверенных автоматическим образом
поведенческих свойств, статического анализа и временной диаграммы. Под визуализацией
понимается графическое представление системной и автоматной сети модели типа
распределенной системы временных автоматов. Визуализация выполняется в виде графа с
выводом специализированной информации: имена портов, подпись вершин, и т.д.
Программа предназначена для использования учащимися или преподавателями, или
другими заинтересованными лицами с целью визуального просмотра автоматического или
пошагового выполнения построенных ими моделей типа «распределенных систем
временных автоматов».
2.Условие выполнения программы
Для
функционирования
программы
необходим
стандартный
комплект
оборудования (персональный компьютер) со следующей конфигурацией:
1) Системный блок
- процессор с тактовой частотой не ниже 1ГГц
- 1024Мб ОЗУ
- 40Гб НЖМД
- видеокарта, поддерживающая разрешение 1024х768 и 256 цветов
2) Монитор, поддерживающий разрешение 1024х768 и 256 цветов
3) Клавиатура
4) Мышь
Программа представляет собой автономный программный продукт, для ее
функционирования необходима установленная ОС MS Windows 2000\XP\7\8.
Так же
необходима установка .NET Framework 2.0. Для работы с визуализацией на компьютере
должна быть установлена программа Graphviz 2.28, доступная для скачивания по ссылке:
http://www.graphviz.org/Download.php.
После
установки
программы,
требуется
перезагрузить операционную систему, для того, чтобы команда dot.exe прописалась в пути
(path), и стала доступна для выполнения из любой директории.
103
3.Выполнение программы
Использование программы требует базовых знаний работы с компьютером и
знаний математики, а также базовые знания в области сетей Петри.
3.1 Моделирование
Для начала моделирования следует загрузить модель (файл -> открыть ->
WanderingPhilosofers.rda) или выбрать демомодель (файл-> загрузить демо модель). После
загрузки демомодели главная форма программы будет иметь следующий вид:
Рисунок 1. Главная форма TRDA Tool
Как видно, в левой панели отражается структура модели: в вершинах системной сети
отражены агенты и их состояния. В правой панели видны активные переходы системной
сети. Так можно выбрать вручную нужный переход путем двойного нажатия, либо
запустить недетерминированный выбор перехода (либо цикл переходов). После выбора
перехода в правой части формы, в левой части можно наблюдать изменение разметки
системной сети.
104
Модель можно так же выполнять и в цикле по времени (условному внутреннему
времени моделирования). Для этого надо установить количество моментов условного
времени в нижней части правой панели и нажать кнопку «время+». Затем, после
автоматического выполнения шагов моделирования, по достижении системой заданного
момента условного времени отобразится новая разметка системной сети. В случае, если
после выполнения моделирования по времени, требуется вернуть систему обратно в режим
пошагового моделирования, следует нажать кнопку «по шагам».
3.2 Временная диаграмма
После выполнения некоторого количества переходов можно просмотреть временную
диаграмму.(Рисунок2) Для этого нужно нажать кнопку «Временная диаграмма» в правой
панели или поставить чек-бокс «Диаграмма».
Рисунок 2. Временная диаграмма модели Обедающих философов, гуляющих в парке
105
На временной диаграмме по горизонтали отложены моменты времени, а по
вертикали – сложные агенты. Цветные дорожки соответствуют временной длительности
состояний, в которых находились агенты за время выполнения модели. Снизу в цветных
квадратиках приводится расшифровка состояний.
3.3 Статистический анализ
Для просмотра статической аналитической информации, а так же информации о
поведенческих свойствах следует нажать кнопку «Результаты анализа».
Рисунок 3. Результаты анализа
Более подробное описание аналитических возможностей TRDA Tool приведено в
основной части Пояснительной записки.
3.4 Визуализация
Для просмотра графической визуализации системной и автоматной сети следует
выставить галочки в полях Системная сеть, Автоматная сеть. Визуализироваться будут
только те автоматные сети, для соответствующих агентов которых выставлены знаки * в
структурном виде отображения текущей разметки модели (левая часть главной формы).
106
Знак * выставляется пользователем двойным кликом по агенту в левой части главной
формы. Соответствующие представления автоматной и системной сети для демомодели
приведены на Рисунках 4 и 5.
Рисунок 4. Системная сеть (фрагмент)
Рисунок 5. Выбор агента p1 для отображения на форме «Автоматная сеть»
107
Рисунок 6. Автоматная сеть агента p1 типа philosopher.
Приложение 9 Класс ChartInfo.cs
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
namespace Automata {
public class ChartInfo {
public double x_max;
public List<string> positions = new List<string>();
public List<string> pos_ids = new List<string>();
public List<string> states = new List<string>();
public List<string> state_ids = new List<string>();
public List<ChartItem> items = new List<ChartItem>();
public void add_position(string i_title) {
add_position(i_title, i_title);
}
public void add_position(string i_title, string i_id) {
positions.Add(i_title);
pos_ids.Add(i_id);
}
public void add_state(string i_title) {
add_state(i_title, i_title);
108
}
public void add_state(string i_title, string i_id) {
states.Add(i_title);
state_ids.Add(i_id);
}
public void add_item(string i_pos, string i_state, double
i_from, double i_to) {
int pos = pos_ids.IndexOf(i_pos);
if(pos == -1) {
pos = positions.Count;
add_position(i_pos);
}
int state = state_ids.IndexOf(i_state);
if(state == -1) {
state = states.Count;
add_state(i_state);
}
add_item(pos, state, i_from, i_to);
}
public void add_item(int i_pos, int i_state, double i_from,
double i_to) {
items.Add(new ChartItem(i_pos,i_state,i_from,i_to));
x_max = Math.Max(x_max,i_to);
}
}
public struct ChartItem {
public int position;
public int state;
public double x_from;
public double x_to;
public ChartItem(int i_pos, int i_state, double i_from,
double i_to) {
state = i_state;
position = i_pos;
x_from = i_from;
x_to = i_to;
}
}
}
109
Приложение 10 Form_xml.cs
using
using
using
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
System.IO;
System.Windows.Forms;
System.Xml;
namespace Automata {
partial class Form1: Form {
static private String get_config_fname() {
String ss = Application.ExecutablePath;
String
dir = Path.GetDirectoryName(ss)
, fname = Path.GetFileName(ss)
, fname_woe = Path.GetFileNameWithoutExtension(ss)
;
String path = dir + "\\" + fname_woe + ".xml";
//
log("ss=" + ss);
log("dir=" + Path.GetDirectoryName(ss));
log("fname=" + Path.GetFileName(ss));
log("fname_woe=" + Path.GetFileNameWithoutExtension(ss));
log("fname=" + fname);
//
return path;
}
private void config_save() {
XmlDocument doc = new XmlDocument();
XmlElement e_root = doc.CreateElement("root");
doc.AppendChild(e_root);
//
/*
XmlElement e_main = doc.CreateElement("form_main");
Lib.form_attr_write(e_main, this);
e_root.AppendChild(e_main);
*/
//
XmlElement e_pars = doc.CreateElement("pars");
e_pars.SetAttribute("page_length", "" + Model.page_length);
e_pars.SetAttribute("gap", "" + Model.gap);
e_pars.SetAttribute("title_length", "" +
Model.title_length);
e_pars.SetAttribute("loop_count", "" + loop_count);
e_root.AppendChild(e_pars);
//
String path = get_config_fname();
doc.Save(path);
}
110
public void show_main_size() {
log("main top=" + this.Top + " left=" + this.Left
+ " width=" + this.Width + " height=" + this.Height
);
}
private void config_restore() {
//
String path = get_config_fname();
XmlDocument doc = new XmlDocument();
XmlElement e_root = null;
try {
doc.Load(path);
e_root = doc.DocumentElement;
log("docElement name=" + e_root.Name);
log("do read_config");
show_main_size();
/*
foreach(XmlElement e in
e_root.GetElementsByTagName("form_main")) {
Lib.form_attr_read(e, this);
break;
}
*/
foreach(XmlElement e in
e_root.GetElementsByTagName("pars")) {
loop_count = Lib.nvl_int(e.GetAttribute("loop_count"),
loop_count);
Model.page_length =
Lib.nvl_int(e.GetAttribute("page_length"), Model.page_length);
Model.gap = Lib.nvl_int(e.GetAttribute("gap"),
Model.gap);
Model.title_length =
Lib.nvl_int(e.GetAttribute("title_length"), Model.title_length);
break;
}
show_main_size();
} catch(Exception e) {
Lib.alarm("exp=" + e.Message);
}
}
}
}
111
Приложение 11 Form1.cs
using
using
using
using
using
using
using
using
System;
System.Collections.Generic;
System.ComponentModel;
System.Data;
System.Drawing;
System.Linq;
System.Text;
System.Windows.Forms;
namespace Automata {
public enum VisualNet { system_net, automata_net };
public partial class Form1 : Form {
static
static
static
static
static
static
static
Form1 frmMain;
FormLog frmLog;
bool is_logging = false;
bool is_visible = false;
bool is_autonet = false;
bool only_trace_logging = false;
bool is_chart_visible = false;
static string build_id = "67 20.05.2013";
void log_only_trace(bool only_trace) {
only_trace_logging = only_trace;
}
public static void log_t(string ss) {
log(ss + "$trc");
}
public static void log(string ss) {
if (!is_logging) return;
if(only_trace_logging) {
if(!ss.Contains("$trc")){
return;
}
}
string new_ss = ss.Replace("$trc", "");
check_log_form();
frmLog.log(new_ss);
}
public void log_visible(bool i_visible) {
check_log_form();
is_logging = i_visible;
frmLog.Visible = i_visible;
cb_Log.Checked = i_visible;
}
public void chart_visible(bool i_visible) {
is_chart_visible = i_visible;
cb_chart.Checked = is_chart_visible;
if (is_chart_visible) {
show_chart();
}else{
112
if (frmChart != null) {
frmChart.Visible = false;
}
}
}
static void check_log_form() {
if (frmLog == null) {
frmLog = new FormLog(frmMain);
}
if (frmLog.IsDisposed) {
frmLog = new FormLog(frmMain);
}
}
/*
static void check_visual_form2() {
if(frm_viz == null) {
frm_viz = new FormVisual(frmMain);
}
if(frm_viz.IsDisposed) {
frm_viz = new FormVisual(frmMain);
}
}
*/
void show_log() {
log_visible(true);
cb_Log.Checked = true;
frmLog.Focus();
}
public Form1() {
InitializeComponent();
init();
frmMain = this;
this.Text = ml["form1_title"];
}
//
//
private void init(){
//config_restore();
status("Welcome");
numericUpDown2.Value = loop_count;
btn_Loop.Text = loop_count + " шагов";
btn_Loop.Enabled = false;
btn_exec.Enabled = false;
set_text();
}
static MultyLanguage ml = MultyLanguage.get_MultyLanguage();
void set_text() {
this.Text = ml["title_Form1"];
cb_visual.Text = ml["title_SystemNet"];
113
cb_autonet.Text = ml["title_AutomataNet"];
btn_chart.Text = ml.msg_btn_chart.Str; // "Time chart";
btn_Trace.Text = ml.msg_btn_trace.Str; //"Трассировка";
btn_rezult.Text = ml.msg_btn_rezult.Str; //Результаты
анализа
cb_chart.Text = ml.cb_chart.Str; //Диаграмма
cb_Log.Text = ml.cb_log.Str; //Лог
cb_Trace.Text = ml.cb_trace.Str;//Только трассировка
cb_Marking.Text = ml.cb_marking.Str;//Достижимость
cb_stop.Text = ml.cb_stop.Str;//Пауза при нахождении
cb_Finiteness.Text = ml.cb_Finiteness.Str;//Ограниченность
btn_exec.Text = ml.btn_exec.Str;//1Шаг
btn_Loop.Text = ml.btn_Loop.Str;//шагов
btn_steps.Text = ml.btn_steps.Str;//По шагам
label1.Text = ml.label1.Str;//Сделать
btn_time.Text = ml.btn_time.Str;//время+
fileToolStripMenuItem.Text = ml.menu_file.Str;//Файл
openToolStripMenuItem.Text =
ml.openToolStripMenuItem.Str;//Открыть
загрузитьДемоМодельToolStripMenuItem.Text =
ml.загрузитьДемоМодельToolStripMenuItem.Str;// Загрузить демо модель
saveToolStripMenuItem.Text =
ml.saveToolStripMenuItem.Str;//Сохранить
выходToolStripMenuItem.Text =
ml.выходToolStripMenuItem.Str;//Выход
справкаToolStripMenuItem.Text =
ml.справкаToolStripMenuItem.Str;//Справка
оПрограммеToolStripMenuItem.Text =
ml.оПрограммеToolStripMenuItem.Str;//О программе
языкОписанияМоделиToolStripMenuItem.Text =
ml.языкОписанияМоделиToolStripMenuItem.Str;//Язык описани модели
//cb_chart.Text = ml["cb_chart"]; // Диаграмма
// cb_Log.Text = ml["cb_log"]; // Журнал
// cb_Trace.Text = ml["cb_trace"]; // Only Trace
//cb_Marking.Text = ml["cb_marking"]; // Достижимость
// cb_stop.Text = ml["cb_stop"]; // Пауза при нахождении
//cb_Finiteness.Text = ml["cb_finiteness "];
//Ограниченность
}
private Model m;
void init_model() {
if(m != null) {
if(!confirm(ml["q_delete_model"]/*"Удалить текущую
модель?"*/)) return;
}
try {
m = Model.init();
trda_file_name = "demo.tda";
model_ready(ml["model_init"]/*"Модель инициализована"*/);
} catch (Exception e) {
status(ml["error:"]/*"ошибка: "*/ + e.Message);
}
114
}
private void status(String ss){
toolStripStatusLabel1.Text = ss;
log(ss);
}
void error(string i_ss) {
string ss = ml["***Error:"]/*"***Ошибка: "*/+i_ss;
log(ss);
status(ss);
}
bool multy_alarm = false;
List<String> alarm_string_list = new List<string>();
void multy_alarm_on() {
multy_alarm = true;
alarm_string_list = new List<string>();
}
void multy_alarm_off() {
multy_alarm = false;
if(alarm_string_list.Count > 0) {
string ss = "";
foreach(string s in alarm_string_list) {
ss += s+"\r\n";
}
alarm(ss);
}
}
void alarm(string ss) {
if(multy_alarm) {
alarm_string_list.Add(ss);
} else {
MessageBox.Show(ss, "Message");
}
}
Boolean confirm(string ss) {
DialogResult result =
MessageBox.Show(ss, "Confirm", MessageBoxButtons.YesNo);
return(result == DialogResult.Yes);
}
void model_not_ready() {
treeView1.Nodes.Clear();
lb_Vars.Items.Clear();
btn_exec.Enabled = false;
btn_Loop.Enabled = false;
btn_time.Enabled = false;
}
void model_ready(string ss) {
115
m.set_test_marking(cb_Marking.Checked);
m.set_test_stop(cb_stop.Checked);
m.set_test_bounds(cb_Finiteness.Checked);
m.set_test_lock(cb_lock.Checked);
status(ss);
next_step();
}
void next_step() {
next_step(false);
}
bool next_step(bool in_loop) {
if(m == null) {
error(ml["no_init_model"]/*"Не инициализирована
модель"*/);
return false;
}
List<string> step_list = m.get_candidates();
// tb_StepInfo.Text = m.get_step_info();
bool rez = (step_list != null);
if (m.do_pause) rez = false;
if (in_loop) return rez;
status(m.get_step_info());
lb_Vars.Items.Clear();
if (step_list != null) {
foreach (String ss in step_list) {
lb_Vars.Items.Add(ss);
}
lb_Vars.SelectedIndex = m.get_champ_index();
btn_exec.Enabled = true;
btn_Loop.Enabled = true;
btn_time.Enabled = true;
} else {
btn_exec.Enabled = false;
btn_Loop.Enabled = false;
if(m.get_exec_mode() == Model.Exec_Mode_Stop) {
btn_time.Enabled = false;
} else {
btn_time.Enabled = true;
}
}
toolStripProgressBar1.Visible = false;
show_places();
if(is_chart_visible) show_chart();
if (is_visible) show_visual_system_net();
if(is_autonet) show_visual_automata_net();
return rez;
}
int loop_count = 50;
void exec_loop() {
if (m == null) {
116
error(ml["no_init_model"]/*"Не инициализирована
модель"*/);
return;
}
log_visible(false);
status(ml["executing_cycle"]/*"Выполняется цикл ..."*/);
toolStripProgressBar1.Visible = true;
loop_count = (int)numericUpDown2.Value;
toolStripProgressBar1.Maximum = loop_count;
statusStrip1.Refresh();
int i = 0;
do {
i++;
if (i % 10 == 0) {
status(ml["executing_cycle"]/*"Выполняется цикл
..."*/);
toolStripProgressBar1.Value = i;
}
m.exec_step();
if (!next_step(true)) break;
if (cb_Stop.Checked) break;
} while (i<loop_count);
next_step();
//
}
void exec_time(double delta_t) {
if(m == null) {
error(ml["no_init_model"]/*"Не инициализирована
модель"*/);
return;
}
Double time_to = m.get_t_current() + delta_t;
m.time_limit_on(time_to);
status(ml["executing_cycle_to"]/*"Выполняется цикл до
"*/+time_to+ "...");
do {
log_t("do next_step t_current=" + m.get_t_current());
if(!next_step(true)) break;
log_t("posle next_step t_current=" + m.get_t_current());
m.exec_step();
log_t("posle exec_step t_current=" + m.get_t_current());
} while(true);
status("Выполнился цикл до " + time_to + ".");
m.set_t_current(time_to);
next_step();
m.time_limit_off();
/*
status(m.get_step_info());
show_places();
*/
}
void go_by_steps() {
if(m == null) {
117
error(ml["no_init_model"]/*"Не инициализирована
модель"*/);
return;
}
m.time_limit_off();
next_step();
}
void exec_1_step() {
int n = lb_Vars.SelectedIndex;
log("Выбран вариант " + n);
if(m==null){
error(ml["no_init_model"]/*"Не инициализирована
модель"*/);
return;
}
m.exec_step(n);
//
show_places();
next_step();
}
string get_inst_title(Instance inst) {
string ss = inst.con.name;
if (inst.is_visual) {
ss = "*" + ss;
}
if (inst.current_state != null) {
ss += ":" + inst.current_state.name;
}
if (inst.current_step != null) {
ss += "->" + inst.current_step.trans.name;
}
if (inst.con.type.initial_state != null) {
foreach (Register reg in inst.con.type.list_regs) {
//ss += " reg.name="+reg.name+" reg.id="+reg.id;
if (reg.reg_type == RegType.rt_timer) {
ss += "[" + reg.name + "=" + inst.registers[reg.id] +
"]";
}
}
}
return ss;
}
void show_places(){
if (m == null)
{
status(ml["no_init_model"]/*"Модель не инициализирована:
"*/ + DateTime.Now);
return;
}
treeView1.Visible = false;
treeView1.Nodes.Clear();
foreach (Place p in m.p_list){
TreeNode p_node = new TreeNode(p.name);
p_node.Tag = p;
118
treeView1.Nodes.Add(p_node);
int n = 0;
foreach (Instance inst in p.list_inst) {
n++;
/*
string ss = inst.con.name;
if (inst.is_visual) {
ss = "*" + ss;
}
if(inst.current_state != null){
ss += ":"+inst.current_state.name;
}
if(inst.current_step != null) {
ss += "->" + inst.current_step.trans.name;
}
if(inst.con.type.initial_state != null) {
foreach(Register reg in inst.con.type.list_regs) {
//ss += " reg.name="+reg.name+" reg.id="+reg.id;
if(reg.reg_type == RegType.rt_timer) {
ss += "["+reg.name + "=" +
inst.registers[reg.id]+"]";
}
}
}
*/
string ss = get_inst_title(inst);
TreeNode i_node = new TreeNode(ss);
i_node.Tag = inst;
p_node.Nodes.Add(i_node);
}
if(!p.is_expanded) p_node.Text += "(total " + n + ")";
if(p.is_expanded) p_node.Expand();
}
//treeView1.ExpandAll();
treeView1.Visible = true;
}
void show_dump() {
if (m == null) {
status(ml["no_init_model"]/*"Модель не инициализирована:
"*/ + DateTime.Now);
return;
}
FormRezult fr = new FormRezult("");
string ss = m.get_dump();
//
log(ss);
fr.log(m.get_dump());
fr.Show();
}
void show_model(Model m) {
if(m == null) {
status(ml["no_init_model"]/*"Модель не инициализирована:
"*/ +DateTime.Now);
treeView1.Nodes.Clear();
return;
119
}
//
treeView1.Nodes.Clear();
TreeNode root_node = new TreeNode(m.name);
treeView1.Nodes.Add(root_node);
//
TreeNode places_node = new
TreeNode(ml["place"]/*"места"*/);
root_node.Nodes.Add(places_node);
foreach(Place p in m.p_list){
TreeNode place_node = places_node.Nodes.Add(p.name);
TreeNode place_in_node = place_node.Nodes.Add("arc_in");
foreach(Arc a in p.list_in) {
place_in_node.Nodes.Add("" + a.p.name + ":" +
a.port.name);
}
TreeNode place_out_node =
place_node.Nodes.Add("arc_out");
foreach(Arc a in p.list_out) {
place_out_node.Nodes.Add("" + a.p.name + ":" +
a.port.name);
}
TreeNode place_inst_node =
place_node.Nodes.Add("instances");
foreach(Instance i in p.list_inst) {
string st = "";
if(i.current_state != null) {
st = ":" + i.current_state.name;
}
place_inst_node.Nodes.Add("" + i.con.name+st);
}
}
TreeNode types_node = new TreeNode(ml["types"]/*"типы"*/);
root_node.Nodes.Add(types_node);
foreach(Type t in m.t_list) {
string init_state = "";
if(t.initial_state != null){
init_state = " (init="+t.initial_state.name+")";
}
TreeNode type_node =
types_node.Nodes.Add(t.name+init_state);
//
TreeNode consts_node = new
TreeNode(ml["constants"]/*"константы"*/);
type_node.Nodes.Add(consts_node);
foreach(Const c in t.list_const) {
TreeNode const_node = new TreeNode(c.name);
consts_node.Nodes.Add(const_node);
}
//
TreeNode vars_node = new
TreeNode(ml["variables"]/*"переменные"*/);
type_node.Nodes.Add(vars_node);
foreach(Var v in t.list_var) {
TreeNode var_node = new TreeNode(v.name);
vars_node.Nodes.Add(var_node);
120
}
//
TreeNode ports_node = new
TreeNode(ml["ports"]/*"порты"*/);
type_node.Nodes.Add(ports_node);
foreach(Port p in t.list_port) {
TreeNode port_node = new TreeNode(p.name);
ports_node.Nodes.Add(port_node);
}
//
TreeNode states_node = new
TreeNode(ml["states"]/*"состояния"*/);
type_node.Nodes.Add(states_node);
foreach(State s in t.list_states) {
TreeNode state_node = new
TreeNode(s.name+"("+s.symbol+")");
states_node.Nodes.Add(state_node);
foreach(Transition tr in s.list_trans) {
TreeNode trans_node = new TreeNode(tr.state_from.name
+ " -> " + tr.state_to.name+" ("+tr.symbol+")");
state_node.Nodes.Add(trans_node);
}
}
//
TreeNode transes_node = new
TreeNode(ml["transitions"]/*"переходы"*/);
type_node.Nodes.Add(transes_node);
foreach(Transition tr in t.list_trans) {
TreeNode trans_node = new TreeNode(tr.state_from.name+"
-> "+tr.state_to.name);
transes_node.Nodes.Add(trans_node);
foreach(Term term in tr.list_term_in) {
TreeNode term_node = new TreeNode("in:" +
term.port.name + ":" + term.res.name+":"+term.res.GetType().Name);
trans_node.Nodes.Add(term_node);
}
foreach(Term term in tr.list_term_out) {
TreeNode term_node = new TreeNode("out:" +
term.port.name + ":" + term.res.name + ":" + term.res.GetType().Name);
trans_node.Nodes.Add(term_node);
}
}
}
//
TreeNode all_ports_node = new
TreeNode(ml["ports"]/*"порты"*/);
root_node.Nodes.Add(all_ports_node);
foreach(Port p in m.port_list) {
string ss = p.name;
if(p.type != null) {
ss = ss+":"+p.type.name;
}
TreeNode port_node = new TreeNode(ss);
all_ports_node.Nodes.Add(port_node);
}
121
TreeNode all_trace_node = new TreeNode("trace");
root_node.Nodes.Add(all_trace_node);
for(int i = 0; i < m.trace_hash.Count; i++) {
Trace t = (Trace)m.trace_hash[i];
string ss = t.show();
TreeNode trace_node = new TreeNode(ss);
all_trace_node.Nodes.Add(trace_node);
}
status(ml["view_model"]/*"Просмотр модели: "*/ +
DateTime.Now);
//
treeView1.ExpandAll();
}
void log_total() {
if (m == null) {
status(ml["no_init_model"]/*"Модель не инициализирована:
"*/ + DateTime.Now);
return;
}
show_log();
cb_Trace.Checked = false;
if(!m.log_total()) {
status(ml["show_rez"]/*"Показ итогов невозможен: смотрите
сообщения в журнале."*/);
}
}
void log_trace() {
if(m == null) {
status(ml["no_init_model"]/*"Модель не инициализирована:
"*/ + DateTime.Now);
return;
}
show_log();
m.log_trace();
}
private void btn_Init_Click(object sender, EventArgs e) {
init_model();
}
private void btn_Show_Click(object sender, EventArgs e) {
show_model(m);
}
private void btn_Log_Click(object sender, EventArgs e) {
show_log();
}
/*
private void btn_Step_Click(object sender, EventArgs e) {
next_step();
}
*/
private void btn_exec_Click(object sender, EventArgs e) {
122
exec_1_step();
}
private void saveToolStripMenuItem_Click(object sender,
EventArgs e) {
save_model();
}
private void openToolStripMenuItem_Click(object sender,
EventArgs e) {
load_model();
}
private void btn_ShowPlaces_Click(object sender, EventArgs e)
{
show_places();
}
private void cb_Log_CheckedChanged(object sender, EventArgs
e) {
log_visible(cb_Log.Checked);
}
private void lb_Vars_DoubleClick(object sender, EventArgs e)
{
log("double click selectedIndex="+lb_Vars.SelectedIndex);
if(lb_Vars.SelectedIndex >= 0) exec_1_step();
}
private void btn_Trace_Click(object sender, EventArgs e) {
log_trace();
}
private void cb_Trace_CheckedChanged(object sender, EventArgs
e) {
log_only_trace(cb_Trace.Checked);
}
private void btn_total_Click(object sender, EventArgs e) {
log_total();
}
private void btn_Loop_Click(object sender, EventArgs e) {
exec_loop();
}
private void Form1_FormClosing(object sender,
FormClosingEventArgs e) {
bool do_confirm = false;
if(do_confirm && !Lib.confirm("Good buy?")) {
e.Cancel = true;
return;
}
//config_save();
}
static FormChart frmChart;
123
void show_chart() {
if (m == null) {
status(ml["no_init_model"]/*"Модель не инициализирована:
"*/ + DateTime.Now);
return;
}
if (frmChart == null) {
frmChart = new FormChart(frmMain);
}
if (frmChart.IsDisposed) {
frmChart = new FormChart(frmMain);
}
ChartInfo chin = m.get_chin();
frmChart.set_chin(chin);
frmChart.Visible = true;
frmChart.Focus();
}
private void btn_chart_Click(object sender, EventArgs e) {
show_chart();
}
private void выходToolStripMenuItem_Click(object sender,
EventArgs e) {
this.Close();
}
private void button1_Click(object sender, EventArgs e) {
int i = (int)numericUpDown1.Value;
exec_time(0.0+i);
}
private void
загрузитьДемоМодельToolStripMenuItem_Click(object sender, EventArgs e)
{
init_model();
}
private void btn_steps_Click(object sender, EventArgs e) {
go_by_steps();
}
private void cb_chart_CheckedChanged(object sender, EventArgs
e) {
chart_visible(cb_chart.Checked);
}
static void help(string p_title, string p_text) {
FormHelp frm_help = new FormHelp(p_title,p_text);
frm_help.Show();
}
124
private void оПрограммеToolStripMenuItem_Click(object sender,
EventArgs e) {
FormHelp.help_about(build_id);
}
private void языкОписанияМоделиToolStripMenuItem_Click(object
sender, EventArgs e) {
FormHelp.help_bnf();
}
void exec_place_expand(TreeNode n, bool i_expand) {
Object tag = n.Tag;
if(tag != null) {
if(tag.GetType() == typeof(Place)) {
Place p = (Place)tag;
p.is_expanded = i_expand;
}
}
}
void exec_change_inst_visual(TreeNode n) {
Object tag = n.Tag;
if (tag != null) {
if (tag.GetType() == typeof(Instance)) {
Instance inst = (Instance)tag;
inst.is_visual = !inst.is_visual;
n.Text = get_inst_title(inst);
}
}
}
private void treeView1_BeforeCollapse(object sender,
TreeViewCancelEventArgs e) {
/*
TreeView tv = (TreeView)sender;
alarm("e=" + e + " sender=" + sender
+ " type=" + sender.GetType()
+ " tv="+ tv
+ " selected node=" + tv.SelectedNode
+ "e.node="+e.Node
);
*/
exec_place_expand(e.Node, false);
}
private void treeView1_BeforeExpand(object sender,
TreeViewCancelEventArgs e) {
exec_place_expand(e.Node, true);
}
static FormVisual frm_viz;
static FormVisual frm_autonet;
void show_visual_system_net() {
if(m == null) {
125
status(ml["no_init_model"]/*"Модель не инициализирована:
"*/ + DateTime.Now);
return;
}
bool new_form_viz = false;
if(frm_viz == null) {
new_form_viz = true;
} else if(frm_viz.IsDisposed) {
new_form_viz = true;
}
if(new_form_viz) {
frm_viz = new FormVisual(this,VisualNet.system_net);
}
frm_viz.new_dot(trda_file_name);
m.show_system_net(frm_viz);
frm_viz.Show();
frm_viz.Focus();
}
void show_visual_automata_net() {
if (m == null) {
status(ml["no_init_model"]/*"Модель не инициализирована:
"*/ + DateTime.Now);
return;
}
bool new_form = false;
if (frm_autonet == null) {
new_form = true;
} else if (frm_autonet.IsDisposed) {
new_form = true;
}
if (new_form) {
frm_autonet = new
FormVisual(this,VisualNet.automata_net);
}
frm_autonet.new_dot(trda_file_name);
m.show_automata_net(frm_autonet);
frm_autonet.Show();
frm_autonet.Focus();
}
public void set_visual_automata_net(bool i_do_set) {
is_autonet = i_do_set;
if (i_do_set) {
show_visual_automata_net();
} else {
if (frm_autonet != null) {
frm_autonet.Visible = false;
}
}
cb_autonet.Checked = i_do_set;
}
126
public void set_visual_system_net(bool i_do_set) {
is_visible = i_do_set;
if(i_do_set) {
show_visual_system_net();
} else {
if(frm_viz != null) {
frm_viz.Visible = false;
}
}
cb_visual.Checked = i_do_set;
}
public void set_visual(bool i_do_set, VisualNet i_net) {
if (i_net == VisualNet.system_net)
set_visual_system_net(i_do_set);
if (i_net == VisualNet.automata_net)
set_visual_automata_net(i_do_set);
}
static FormRezult frm_rez;
public static void rez(string ss) {
frm_rez.log(ss);
}
void show_rezult() {
if (m == null) {
status(ml["no_init_model"]/*"Модель не инициализирована:
"*/ + DateTime.Now);
return;
}
//
bool new_form_rez = false;
if (frm_rez == null) {
new_form_rez = true;
} else if (frm_rez.IsDisposed) {
new_form_rez = true;
}
if (new_form_rez) {
frm_rez = new FormRezult(trda_file_name);
}
//
frm_rez.log_begin();
m.show_rezult();
//
frm_rez.Show();
frm_rez.Focus();
}
private void btn_rezult_Click(object sender, EventArgs e) {
show_rezult();
}
private void cb_Marking_CheckedChanged(object sender,
EventArgs e) {
127
if (m == null) {
error(ml["no_init_model"]/*"Не инициализирована
модель"*/);
return;
}
m.set_test_marking(cb_Marking.Checked);
}
private void cb_stop_CheckedChanged(object sender, EventArgs
e) {
if (m == null) {
error(ml["no_init_model"]/*"Не инициализирована
модель"*/);
return;
}
m.set_test_stop(cb_stop.Checked);
}
private void cb_Finiteness_CheckedChanged(object sender,
EventArgs e) {
if(m == null) {
error(ml["no_init_model"]/*"Не инициализирована
модель"*/);
return;
}
m.set_test_bounds(cb_Finiteness.Checked);
}
private void cb_lock_CheckedChanged(object sender, EventArgs
e) {
if(m == null) {
error(ml["no_init_model"]/*"Не инициализирована
модель"*/);
return;
}
m.set_test_lock(cb_lock.Checked);
}
private void panel4_MouseDoubleClick(object sender,
MouseEventArgs e) {
show_dump();
}
void set_eng_rus() {
if (MultyLanguage.current_language ==
MultyLanguage.Language.english) {
set_rus();
} else {
set_eng();
}
}
void set_eng() {
MultyLanguage.current_language =
MultyLanguage.Language.english;
set_text();
}
128
void set_rus() {
MultyLanguage.current_language =
MultyLanguage.Language.russian;
set_text();
}
/*
private void btn_visual_Click(object sender, EventArgs e) {
show_visual_system_net();
}
*/
private void cb_visual_CheckedChanged(object sender,
EventArgs e) {
set_visual_system_net(cb_visual.Checked);
}
private void cb_autonet_CheckedChanged(object sender,
EventArgs e) {
set_visual_automata_net(cb_autonet.Checked);
}
private void treeView1_NodeMouseDoubleClick(object sender,
TreeNodeMouseClickEventArgs e) {
exec_change_inst_visual(e.Node);
}
private void englishToolStripMenuItem_Click(object sender,
EventArgs e) {
set_eng_rus();
}
}
}
129
Приложение 12 Form1.Designer.cs
namespace Automata {
partial class Form1 {
/// <summary>
/// Требуется переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс
должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing) {
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором форм
Windows
/// <summary>
/// Обязательный метод для поддержки конструктора - не
изменяйте
/// содержимое данного метода при помощи редактора кода.
/// </summary>
private void InitializeComponent() {
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.toolStripStatusLabel1 = new
System.Windows.Forms.ToolStripStatusLabel();
this.toolStripProgressBar1 = new
System.Windows.Forms.ToolStripProgressBar();
this.panel1 = new System.Windows.Forms.Panel();
this.splitContainer1 = new
System.Windows.Forms.SplitContainer();
this.treeView1 = new System.Windows.Forms.TreeView();
this.splitContainer2 = new
System.Windows.Forms.SplitContainer();
this.cb_autonet = new System.Windows.Forms.CheckBox();
this.cb_visual = new System.Windows.Forms.CheckBox();
this.panel3 = new System.Windows.Forms.Panel();
this.cb_stop = new System.Windows.Forms.CheckBox();
this.cb_lock = new System.Windows.Forms.CheckBox();
this.cb_Finiteness = new System.Windows.Forms.CheckBox();
this.cb_Marking = new System.Windows.Forms.CheckBox();
this.btn_rezult = new System.Windows.Forms.Button();
this.cb_chart = new System.Windows.Forms.CheckBox();
this.btn_chart = new System.Windows.Forms.Button();
this.cb_Trace = new System.Windows.Forms.CheckBox();
this.btn_Trace = new System.Windows.Forms.Button();
this.cb_Log = new System.Windows.Forms.CheckBox();
this.panel2 = new System.Windows.Forms.Panel();
this.panel4 = new System.Windows.Forms.Panel();
130
this.numericUpDown2 = new
System.Windows.Forms.NumericUpDown();
this.btn_steps = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.numericUpDown1 = new
System.Windows.Forms.NumericUpDown();
this.btn_time = new System.Windows.Forms.Button();
this.btn_Loop = new System.Windows.Forms.Button();
this.btn_exec = new System.Windows.Forms.Button();
this.lb_Vars = new System.Windows.Forms.ListBox();
this.menuStrip1 = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();
this.openToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();
this.загрузитьДемоМодельToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();
this.saveToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();
this.englishToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();
this.выходToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();
this.справкаToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();
this.оПрограммеToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();
this.языкОписанияМоделиToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();
this.statusStrip1.SuspendLayout();
this.panel1.SuspendLayout();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
this.splitContainer2.Panel1.SuspendLayout();
this.splitContainer2.Panel2.SuspendLayout();
this.splitContainer2.SuspendLayout();
this.panel3.SuspendLayout();
this.panel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown2)).Begi
nInit();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).Begi
nInit();
this.menuStrip1.SuspendLayout();
this.SuspendLayout();
//
// statusStrip1
//
this.statusStrip1.Items.AddRange(new
System.Windows.Forms.ToolStripItem[] {
this.toolStripStatusLabel1,
this.toolStripProgressBar1});
this.statusStrip1.Location = new System.Drawing.Point(0,
471);
this.statusStrip1.Name = "statusStrip1";
131
this.statusStrip1.Padding = new
System.Windows.Forms.Padding(1, 0, 13, 0);
this.statusStrip1.Size = new System.Drawing.Size(717, 26);
this.statusStrip1.TabIndex = 0;
this.statusStrip1.Text = "statusStrip1";
//
// toolStripStatusLabel1
//
this.toolStripStatusLabel1.Name = "toolStripStatusLabel1";
this.toolStripStatusLabel1.Size = new
System.Drawing.Size(141, 21);
this.toolStripStatusLabel1.Text = "toolStripStatusLabel1";
//
// toolStripProgressBar1
//
this.toolStripProgressBar1.Name = "toolStripProgressBar1";
this.toolStripProgressBar1.Size = new
System.Drawing.Size(100, 20);
//
// panel1
//
this.panel1.Controls.Add(this.splitContainer1);
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel1.Location = new System.Drawing.Point(0, 26);
this.panel1.Margin = new System.Windows.Forms.Padding(3, 2,
3, 2);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(717, 445);
this.panel1.TabIndex = 1;
//
// splitContainer1
//
this.splitContainer1.Dock =
System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.FixedPanel =
System.Windows.Forms.FixedPanel.Panel2;
this.splitContainer1.Location = new System.Drawing.Point(0,
0);
this.splitContainer1.Margin = new
System.Windows.Forms.Padding(3, 2, 3, 2);
this.splitContainer1.Name = "splitContainer1";
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.Controls.Add(this.treeView1);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.splitContainer2);
this.splitContainer1.Size = new System.Drawing.Size(717,
445);
this.splitContainer1.SplitterDistance = 341;
this.splitContainer1.TabIndex = 0;
//
// treeView1
//
132
this.treeView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.treeView1.Location = new System.Drawing.Point(0, 0);
this.treeView1.Margin = new System.Windows.Forms.Padding(3,
2, 3, 2);
this.treeView1.Name = "treeView1";
this.treeView1.Size = new System.Drawing.Size(341, 445);
this.treeView1.TabIndex = 0;
this.treeView1.NodeMouseDoubleClick += new
System.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeView1_Nod
eMouseDoubleClick);
this.treeView1.BeforeExpand += new
System.Windows.Forms.TreeViewCancelEventHandler(this.treeView1_BeforeE
xpand);
this.treeView1.BeforeCollapse += new
System.Windows.Forms.TreeViewCancelEventHandler(this.treeView1_BeforeC
ollapse);
//
// splitContainer2
//
this.splitContainer2.BorderStyle =
System.Windows.Forms.BorderStyle.FixedSingle;
this.splitContainer2.Dock =
System.Windows.Forms.DockStyle.Fill;
this.splitContainer2.FixedPanel =
System.Windows.Forms.FixedPanel.Panel1;
this.splitContainer2.Location = new System.Drawing.Point(0,
0);
this.splitContainer2.Margin = new
System.Windows.Forms.Padding(3, 2, 3, 2);
this.splitContainer2.Name = "splitContainer2";
this.splitContainer2.Orientation =
System.Windows.Forms.Orientation.Horizontal;
//
// splitContainer2.Panel1
//
this.splitContainer2.Panel1.Controls.Add(this.cb_autonet);
this.splitContainer2.Panel1.Controls.Add(this.cb_visual);
this.splitContainer2.Panel1.Controls.Add(this.panel3);
this.splitContainer2.Panel1.Controls.Add(this.btn_rezult);
this.splitContainer2.Panel1.Controls.Add(this.cb_chart);
this.splitContainer2.Panel1.Controls.Add(this.btn_chart);
this.splitContainer2.Panel1.Controls.Add(this.cb_Trace);
this.splitContainer2.Panel1.Controls.Add(this.btn_Trace);
this.splitContainer2.Panel1.Controls.Add(this.cb_Log);
//
// splitContainer2.Panel2
//
this.splitContainer2.Panel2.Controls.Add(this.panel2);
this.splitContainer2.Panel2.Controls.Add(this.lb_Vars);
this.splitContainer2.Size = new System.Drawing.Size(372,
445);
this.splitContainer2.SplitterDistance = 219;
this.splitContainer2.TabIndex = 10;
//
// cb_autonet
//
this.cb_autonet.AutoSize = true;
133
this.cb_autonet.Location = new System.Drawing.Point(156,
47);
this.cb_autonet.Name = "cb_autonet";
this.cb_autonet.Size = new System.Drawing.Size(142, 21);
this.cb_autonet.TabIndex = 15;
this.cb_autonet.Text = "Автоматная сеть";
this.cb_autonet.UseVisualStyleBackColor = true;
this.cb_autonet.CheckedChanged += new
System.EventHandler(this.cb_autonet_CheckedChanged);
//
// cb_visual
//
this.cb_visual.AutoSize = true;
this.cb_visual.Location = new System.Drawing.Point(156,
24);
this.cb_visual.Name = "cb_visual";
this.cb_visual.Size = new System.Drawing.Size(135, 21);
this.cb_visual.TabIndex = 14;
this.cb_visual.Text = "Системная сеть";
this.cb_visual.UseVisualStyleBackColor = true;
this.cb_visual.CheckedChanged += new
System.EventHandler(this.cb_visual_CheckedChanged);
//
// panel3
//
this.panel3.BorderStyle =
System.Windows.Forms.BorderStyle.Fixed3D;
this.panel3.Controls.Add(this.cb_stop);
this.panel3.Controls.Add(this.cb_lock);
this.panel3.Controls.Add(this.cb_Finiteness);
this.panel3.Controls.Add(this.cb_Marking);
this.panel3.Location = new System.Drawing.Point(147, 125);
this.panel3.Margin = new System.Windows.Forms.Padding(3, 2,
3, 2);
this.panel3.Name = "panel3";
this.panel3.Size = new System.Drawing.Size(217, 89);
this.panel3.TabIndex = 13;
//
// cb_stop
//
this.cb_stop.AutoSize = true;
this.cb_stop.Location = new System.Drawing.Point(29, 30);
this.cb_stop.Margin = new System.Windows.Forms.Padding(3,
2, 3, 2);
this.cb_stop.Name = "cb_stop";
this.cb_stop.Size = new System.Drawing.Size(181, 21);
this.cb_stop.TabIndex = 3;
this.cb_stop.Text = "Пауза при нахождении";
this.cb_stop.UseVisualStyleBackColor = true;
this.cb_stop.CheckedChanged += new
System.EventHandler(this.cb_stop_CheckedChanged);
//
// cb_lock
//
this.cb_lock.AutoSize = true;
this.cb_lock.Checked = true;
134
this.cb_lock.CheckState =
System.Windows.Forms.CheckState.Checked;
this.cb_lock.Location = new System.Drawing.Point(11, 84);
this.cb_lock.Margin = new System.Windows.Forms.Padding(3,
2, 3, 2);
this.cb_lock.Name = "cb_lock";
this.cb_lock.Size = new System.Drawing.Size(144, 21);
this.cb_lock.TabIndex = 2;
this.cb_lock.Text = "Наличие тупиков";
this.cb_lock.UseVisualStyleBackColor = true;
this.cb_lock.Visible = false;
this.cb_lock.CheckedChanged += new
System.EventHandler(this.cb_lock_CheckedChanged);
//
// cb_Finiteness
//
this.cb_Finiteness.AutoSize = true;
this.cb_Finiteness.Location = new System.Drawing.Point(11,
57);
this.cb_Finiteness.Margin = new
System.Windows.Forms.Padding(3, 2, 3, 2);
this.cb_Finiteness.Name = "cb_Finiteness";
this.cb_Finiteness.Size = new System.Drawing.Size(139, 21);
this.cb_Finiteness.TabIndex = 1;
this.cb_Finiteness.Text = "Ограниченность";
this.cb_Finiteness.UseVisualStyleBackColor = true;
this.cb_Finiteness.CheckedChanged += new
System.EventHandler(this.cb_Finiteness_CheckedChanged);
//
// cb_Marking
//
this.cb_Marking.AutoSize = true;
this.cb_Marking.Location = new System.Drawing.Point(11, 2);
this.cb_Marking.Margin = new
System.Windows.Forms.Padding(3, 2, 3, 2);
this.cb_Marking.Name = "cb_Marking";
this.cb_Marking.Size = new System.Drawing.Size(126, 21);
this.cb_Marking.TabIndex = 0;
this.cb_Marking.Text = "Достижимость";
this.cb_Marking.UseVisualStyleBackColor = true;
this.cb_Marking.CheckedChanged += new
System.EventHandler(this.cb_Marking_CheckedChanged);
//
// btn_rezult
//
this.btn_rezult.Location = new System.Drawing.Point(11,
125);
this.btn_rezult.Margin = new
System.Windows.Forms.Padding(3, 2, 3, 2);
this.btn_rezult.Name = "btn_rezult";
this.btn_rezult.Size = new System.Drawing.Size(128, 89);
this.btn_rezult.TabIndex = 12;
this.btn_rezult.Text = "Результаты анализа";
this.btn_rezult.UseVisualStyleBackColor = true;
this.btn_rezult.Click += new
System.EventHandler(this.btn_rezult_Click);
//
135
// cb_chart
//
this.cb_chart.AutoSize = true;
this.cb_chart.Location = new System.Drawing.Point(156, 2);
this.cb_chart.Margin = new System.Windows.Forms.Padding(3,
2, 3, 2);
this.cb_chart.Name = "cb_chart";
this.cb_chart.Size = new System.Drawing.Size(104, 21);
this.cb_chart.TabIndex = 11;
this.cb_chart.Text = "Диаграмма";
this.cb_chart.UseVisualStyleBackColor = true;
this.cb_chart.CheckedChanged += new
System.EventHandler(this.cb_chart_CheckedChanged);
//
// btn_chart
//
this.btn_chart.Location = new System.Drawing.Point(11, 1);
this.btn_chart.Margin = new System.Windows.Forms.Padding(3,
2, 3, 2);
this.btn_chart.Name = "btn_chart";
this.btn_chart.Size = new System.Drawing.Size(128, 50);
this.btn_chart.TabIndex = 3;
this.btn_chart.Text = "Временная диаграмма";
this.btn_chart.UseVisualStyleBackColor = true;
this.btn_chart.Click += new
System.EventHandler(this.btn_chart_Click);
//
// cb_Trace
//
this.cb_Trace.AutoSize = true;
this.cb_Trace.Location = new System.Drawing.Point(156, 98);
this.cb_Trace.Margin = new System.Windows.Forms.Padding(3,
2, 3, 2);
this.cb_Trace.Name = "cb_Trace";
this.cb_Trace.Size = new System.Drawing.Size(164, 21);
this.cb_Trace.TabIndex = 10;
this.cb_Trace.Text = "Только трассировка";
this.cb_Trace.UseVisualStyleBackColor = true;
this.cb_Trace.CheckedChanged += new
System.EventHandler(this.cb_Trace_CheckedChanged);
//
// btn_Trace
//
this.btn_Trace.Location = new System.Drawing.Point(11, 57);
this.btn_Trace.Margin = new System.Windows.Forms.Padding(3,
2, 3, 2);
this.btn_Trace.Name = "btn_Trace";
this.btn_Trace.Size = new System.Drawing.Size(128, 37);
this.btn_Trace.TabIndex = 9;
this.btn_Trace.Text = "Трассировка";
this.btn_Trace.UseVisualStyleBackColor = true;
this.btn_Trace.Click += new
System.EventHandler(this.btn_Trace_Click);
//
// cb_Log
//
this.cb_Log.AutoSize = true;
136
this.cb_Log.Location = new System.Drawing.Point(156, 73);
this.cb_Log.Margin = new System.Windows.Forms.Padding(3, 2,
3, 2);
this.cb_Log.Name = "cb_Log";
this.cb_Log.Size = new System.Drawing.Size(82, 21);
this.cb_Log.TabIndex = 8;
this.cb_Log.Text = "Журнал";
this.cb_Log.UseVisualStyleBackColor = true;
this.cb_Log.CheckedChanged += new
System.EventHandler(this.cb_Log_CheckedChanged);
//
// panel2
//
this.panel2.Controls.Add(this.panel4);
this.panel2.Controls.Add(this.numericUpDown2);
this.panel2.Controls.Add(this.btn_steps);
this.panel2.Controls.Add(this.label1);
this.panel2.Controls.Add(this.numericUpDown1);
this.panel2.Controls.Add(this.btn_time);
this.panel2.Controls.Add(this.btn_Loop);
this.panel2.Controls.Add(this.btn_exec);
this.panel2.Dock = System.Windows.Forms.DockStyle.Bottom;
this.panel2.Location = new System.Drawing.Point(0, 150);
this.panel2.Margin = new System.Windows.Forms.Padding(3, 2,
3, 2);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(370, 70);
this.panel2.TabIndex = 7;
//
// panel4
//
this.panel4.Location = new System.Drawing.Point(347, 6);
this.panel4.Margin = new System.Windows.Forms.Padding(3, 2,
3, 2);
this.panel4.Name = "panel4";
this.panel4.Size = new System.Drawing.Size(25, 20);
this.panel4.TabIndex = 13;
this.panel4.MouseDoubleClick += new
System.Windows.Forms.MouseEventHandler(this.panel4_MouseDoubleClick);
//
// numericUpDown2
//
this.numericUpDown2.Location = new System.Drawing.Point(16,
39);
this.numericUpDown2.Margin = new
System.Windows.Forms.Padding(3, 2, 3, 2);
this.numericUpDown2.Maximum = new decimal(new int[] {
500,
0,
0,
0});
this.numericUpDown2.Name = "numericUpDown2";
this.numericUpDown2.Size = new System.Drawing.Size(53, 22);
this.numericUpDown2.TabIndex = 12;
this.numericUpDown2.Value = new decimal(new int[] {
50,
0,
137
0,
0});
//
// btn_steps
//
this.btn_steps.Location = new System.Drawing.Point(209, 2);
this.btn_steps.Margin = new System.Windows.Forms.Padding(3,
2, 3, 2);
this.btn_steps.Name = "btn_steps";
this.btn_steps.Size = new System.Drawing.Size(124, 27);
this.btn_steps.TabIndex = 11;
this.btn_steps.Text = "По шагам";
this.btn_steps.UseVisualStyleBackColor = true;
this.btn_steps.Click += new
System.EventHandler(this.btn_steps_Click);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(13, 6);
this.label1.Margin = new System.Windows.Forms.Padding(4, 0,
4, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(67, 17);
this.label1.TabIndex = 10;
this.label1.Text = "Сделать:";
//
// numericUpDown1
//
this.numericUpDown1.Anchor =
((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyle
s.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.numericUpDown1.Location = new
System.Drawing.Point(316, 41);
this.numericUpDown1.Margin = new
System.Windows.Forms.Padding(3, 2, 3, 2);
this.numericUpDown1.Maximum = new decimal(new int[] {
500,
0,
0,
0});
this.numericUpDown1.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.numericUpDown1.Name = "numericUpDown1";
this.numericUpDown1.Size = new System.Drawing.Size(52, 22);
this.numericUpDown1.TabIndex = 9;
this.numericUpDown1.Value = new decimal(new int[] {
50,
0,
0,
0});
//
// btn_time
//
138
this.btn_time.Anchor =
((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyle
s.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btn_time.Location = new System.Drawing.Point(222, 39);
this.btn_time.Margin = new System.Windows.Forms.Padding(3,
2, 3, 2);
this.btn_time.Name = "btn_time";
this.btn_time.Size = new System.Drawing.Size(77, 26);
this.btn_time.TabIndex = 7;
this.btn_time.Text = "время +";
this.btn_time.UseVisualStyleBackColor = true;
this.btn_time.Click += new
System.EventHandler(this.button1_Click);
//
// btn_Loop
//
this.btn_Loop.Location = new System.Drawing.Point(87, 36);
this.btn_Loop.Margin = new System.Windows.Forms.Padding(3,
2, 3, 2);
this.btn_Loop.Name = "btn_Loop";
this.btn_Loop.Size = new System.Drawing.Size(83, 30);
this.btn_Loop.TabIndex = 6;
this.btn_Loop.Text = "шагов";
this.btn_Loop.UseVisualStyleBackColor = true;
this.btn_Loop.Click += new
System.EventHandler(this.btn_Loop_Click);
//
// btn_exec
//
this.btn_exec.Location = new System.Drawing.Point(87, 1);
this.btn_exec.Margin = new System.Windows.Forms.Padding(3,
2, 3, 2);
this.btn_exec.Name = "btn_exec";
this.btn_exec.Size = new System.Drawing.Size(83, 31);
this.btn_exec.TabIndex = 5;
this.btn_exec.Text = "1 шаг";
this.btn_exec.UseVisualStyleBackColor = true;
this.btn_exec.Click += new
System.EventHandler(this.btn_exec_Click);
//
// lb_Vars
//
this.lb_Vars.Dock = System.Windows.Forms.DockStyle.Fill;
this.lb_Vars.FormattingEnabled = true;
this.lb_Vars.ItemHeight = 16;
this.lb_Vars.Location = new System.Drawing.Point(0, 0);
this.lb_Vars.Margin = new System.Windows.Forms.Padding(3,
2, 3, 2);
this.lb_Vars.Name = "lb_Vars";
this.lb_Vars.Size = new System.Drawing.Size(370, 212);
this.lb_Vars.TabIndex = 6;
this.lb_Vars.DoubleClick += new
System.EventHandler(this.lb_Vars_DoubleClick);
//
// menuStrip1
//
139
this.menuStrip1.Items.AddRange(new
System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.справкаToolStripMenuItem});
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.Padding = new
System.Windows.Forms.Padding(5, 2, 0, 2);
this.menuStrip1.Size = new System.Drawing.Size(717, 26);
this.menuStrip1.TabIndex = 2;
this.menuStrip1.Text = "menuStrip1";
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new
System.Windows.Forms.ToolStripItem[] {
this.openToolStripMenuItem,
this.загрузитьДемоМодельToolStripMenuItem,
this.saveToolStripMenuItem,
this.englishToolStripMenuItem,
this.выходToolStripMenuItem});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new
System.Drawing.Size(54, 22);
this.fileToolStripMenuItem.Text = "Файл";
//
// openToolStripMenuItem
//
this.openToolStripMenuItem.Name = "openToolStripMenuItem";
this.openToolStripMenuItem.ShortcutKeys =
((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control |
System.Windows.Forms.Keys.O)));
this.openToolStripMenuItem.Size = new
System.Drawing.Size(254, 22);
this.openToolStripMenuItem.Text = "Открыть";
this.openToolStripMenuItem.Click += new
System.EventHandler(this.openToolStripMenuItem_Click);
//
// загрузитьДемоМодельToolStripMenuItem
//
this.загрузитьДемоМодельToolStripMenuItem.Name =
"загрузитьДемоМодельToolStripMenuItem";
this.загрузитьДемоМодельToolStripMenuItem.Size = new
System.Drawing.Size(254, 22);
this.загрузитьДемоМодельToolStripMenuItem.Text = "Загрузить
демо модель";
this.загрузитьДемоМодельToolStripMenuItem.Click += new
System.EventHandler(this.загрузитьДемоМодельToolStripMenuItem_Click);
//
// saveToolStripMenuItem
//
this.saveToolStripMenuItem.Name = "saveToolStripMenuItem";
this.saveToolStripMenuItem.ShortcutKeys =
((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control |
System.Windows.Forms.Keys.S)));
this.saveToolStripMenuItem.Size = new
System.Drawing.Size(254, 22);
140
this.saveToolStripMenuItem.Text = "Сохранить";
this.saveToolStripMenuItem.Click += new
System.EventHandler(this.saveToolStripMenuItem_Click);
//
// englishToolStripMenuItem
//
this.englishToolStripMenuItem.Name =
"englishToolStripMenuItem";
this.englishToolStripMenuItem.Size = new
System.Drawing.Size(254, 22);
this.englishToolStripMenuItem.Text = "English/Русский";
this.englishToolStripMenuItem.Click += new
System.EventHandler(this.englishToolStripMenuItem_Click);
//
// выходToolStripMenuItem
//
this.выходToolStripMenuItem.Name =
"выходToolStripMenuItem";
this.выходToolStripMenuItem.ShortcutKeys =
((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control |
System.Windows.Forms.Keys.Q)));
this.выходToolStripMenuItem.Size = new
System.Drawing.Size(254, 22);
this.выходToolStripMenuItem.Text = "Выход";
this.выходToolStripMenuItem.Click += new
System.EventHandler(this.выходToolStripMenuItem_Click);
//
// справкаToolStripMenuItem
//
this.справкаToolStripMenuItem.DropDownItems.AddRange(new
System.Windows.Forms.ToolStripItem[] {
this.оПрограммеToolStripMenuItem,
this.языкОписанияМоделиToolStripMenuItem});
this.справкаToolStripMenuItem.Name =
"справкаToolStripMenuItem";
this.справкаToolStripMenuItem.Size = new
System.Drawing.Size(76, 22);
this.справкаToolStripMenuItem.Text = "Справка";
//
// оПрограммеToolStripMenuItem
//
this.оПрограммеToolStripMenuItem.Name =
"оПрограммеToolStripMenuItem";
this.оПрограммеToolStripMenuItem.Size = new
System.Drawing.Size(247, 22);
this.оПрограммеToolStripMenuItem.Text = "О программе";
this.оПрограммеToolStripMenuItem.Click += new
System.EventHandler(this.оПрограммеToolStripMenuItem_Click);
//
// языкОписанияМоделиToolStripMenuItem
//
this.языкОписанияМоделиToolStripMenuItem.Name =
"языкОписанияМоделиToolStripMenuItem";
this.языкОписанияМоделиToolStripMenuItem.Size = new
System.Drawing.Size(247, 22);
this.языкОписанияМоделиToolStripMenuItem.Text = "Язык
описания модели";
141
this.языкОписанияМоделиToolStripMenuItem.Click += new
System.EventHandler(this.языкОписанияМоделиToolStripMenuItem_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F,
16F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(717, 497);
this.Controls.Add(this.panel1);
this.Controls.Add(this.statusStrip1);
this.Controls.Add(this.menuStrip1);
this.MainMenuStrip = this.menuStrip1;
this.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);
this.Name = "Form1";
this.Text = "Модель типа TRDA";
this.FormClosing += new
System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
this.statusStrip1.ResumeLayout(false);
this.statusStrip1.PerformLayout();
this.panel1.ResumeLayout(false);
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel2.ResumeLayout(false);
this.splitContainer1.ResumeLayout(false);
this.splitContainer2.Panel1.ResumeLayout(false);
this.splitContainer2.Panel1.PerformLayout();
this.splitContainer2.Panel2.ResumeLayout(false);
this.splitContainer2.ResumeLayout(false);
this.panel3.ResumeLayout(false);
this.panel3.PerformLayout();
this.panel2.ResumeLayout(false);
this.panel2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown2)).EndI
nit();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndI
nit();
this.menuStrip1.ResumeLayout(false);
this.menuStrip1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.StatusStrip statusStrip1;
private System.Windows.Forms.ToolStripStatusLabel
toolStripStatusLabel1;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.SplitContainer splitContainer1;
private System.Windows.Forms.TreeView treeView1;
private System.Windows.Forms.Button btn_exec;
private System.Windows.Forms.ListBox lb_Vars;
private System.Windows.Forms.MenuStrip menuStrip1;
142
private System.Windows.Forms.ToolStripMenuItem
fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem
openToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem
saveToolStripMenuItem;
private System.Windows.Forms.CheckBox cb_Log;
private System.Windows.Forms.SplitContainer splitContainer2;
private System.Windows.Forms.Panel panel2;
private System.Windows.Forms.Button btn_Trace;
private System.Windows.Forms.CheckBox cb_Trace;
private System.Windows.Forms.Button btn_Loop;
private System.Windows.Forms.ToolStripProgressBar
toolStripProgressBar1;
private System.Windows.Forms.Button btn_chart;
private System.Windows.Forms.ToolStripMenuItem
выходToolStripMenuItem;
private System.Windows.Forms.Button btn_time;
private System.Windows.Forms.NumericUpDown numericUpDown1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.ToolStripMenuItem
справкаToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem
загрузитьДемоМодельToolStripMenuItem;
private System.Windows.Forms.Button btn_steps;
private System.Windows.Forms.CheckBox cb_chart;
private System.Windows.Forms.ToolStripMenuItem
оПрограммеToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem
языкОписанияМоделиToolStripMenuItem;
private System.Windows.Forms.NumericUpDown numericUpDown2;
private System.Windows.Forms.Button btn_rezult;
private System.Windows.Forms.Panel panel3;
private System.Windows.Forms.CheckBox cb_Finiteness;
private System.Windows.Forms.CheckBox cb_Marking;
private System.Windows.Forms.CheckBox cb_lock;
private System.Windows.Forms.CheckBox cb_stop;
private System.Windows.Forms.Panel panel4;
private System.Windows.Forms.CheckBox cb_visual;
private System.Windows.Forms.CheckBox cb_autonet;
private System.Windows.Forms.ToolStripMenuItem
englishToolStripMenuItem;
}
}
143
Приложение 13 Form1_io.cs
using
using
using
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Windows.Forms;
System.IO;
System.Reflection;
namespace Automata {
public partial class Form1: Form {
void save_model() {
if(m == null) {
log(ml["model_undef"]/*"Модель не определена!"*/);
return;
}
SaveFileDialog d = new SaveFileDialog();
DialogResult rez = d.ShowDialog();
if(rez != DialogResult.OK) return;
log(ml["save_in_file"]/*"Сохраняем в файл "*/ +
d.FileName);
using(StreamWriter sw = File.CreateText(d.FileName)) {
wr = sw;
write_model();
}
status(ml["file_is_saved"]/*"Файл сохранен"*/);
}
StreamWriter wr;
void sp() {
wr.WriteLine("");
}
void sp(string s1, string
wr.WriteLine(s1 + "(" +
}
void sp(string s1, string
wr.WriteLine(s1 + "(" +
s3.Replace(' ','_') + ")");
}
void sp(string s1, string
wr.WriteLine(s1 + "(" +
+ "," + s3.Replace('
'_') + ")");
}
s2) {
s2.Replace(' ','_') + ")");
s2,string s3) {
s2.Replace(' ','_') + "," +
s2, string s3, string s4) {
s2.Replace(' ', '_')
', '_') + "," + s4.Replace(' ',
void write_model() {
sp("model", m.name);
sp();
foreach(Place p in m.p_list) {
144
sp("place",p.name);
}
foreach(Place p in m.p_list) {
foreach(Arc a in p.list_in) {
sp("arc_in",p.name,a.p.name,a.port.name);
}
foreach(Arc a in p.list_out) {
sp("arc_out",p.name,a.p.name,a.port.name);
}
}
foreach(Type t in m.t_list) {
sp();
sp("type", t.name);
if(t.initial_state != null) {
sp(" state", t.initial_state.name);
}
foreach(Const c in t.list_const) {
sp(" const", c.name);
}
foreach(Var v in t.list_var) {
sp(" var", v.name);
}
foreach(Port port in t.list_port) {
sp(" port", port.name);
}
foreach(Transition trans in t.list_trans) {
sp(" trans", trans.state_from.name,
trans.state_to.name);
if(trans.priority != Transition.default_priority) {
sp("
priority", ""+trans.priority);
}
if(trans.duration_max != Transition.default_duration) {
if(trans.duration_max == trans.duration_min) {
sp("
duration", ""+trans.duration_min);
} else {
sp("
duration",
""+trans.duration_min,""+trans.duration_max);
}
}
foreach(Term term in trans.list_term_in) {
sp("
term_in", term.port.name, term.res.name);
}
foreach(Term term in trans.list_term_out) {
sp("
term_out", term.port.name, term.res.name);
}
}
}
foreach(Place p in m.p_list) {
sp();
sp("place", p.name);
foreach(Instance inst in p.list_inst) {
if(inst.current_state == null) {
sp(" inst", inst.con.name);
} else {
sp(" inst", inst.con.name,inst.current_state.name);
}
}
145
}
}
string trda_file_name = "";
void load_model() {
if(m != null) {
if(!confirm(ml["del_cur_model"]/*"Удалить текущую
модель?"*/)) return;
}
log(ml["loading_new_model..."]/*"Загружаем новую модель
..."*/);
OpenFileDialog d = new OpenFileDialog();
DialogResult rez = d.ShowDialog();
if(rez != DialogResult.OK) return;
log(ml["loading_new_model_from_file"]/*"Загружаем новую
модель из файла "*/+d.FileName);
m = new Model(ml["new model"]/*"Новая модель"*/);
int n_err = 0;
multy_alarm_on();
using(StreamReader sr = File.OpenText(d.FileName)) {
string line = "";
int n_str = 0;
comment_deep = 0;
while ((line = sr.ReadLine()) != null) {
n_str++;
log("sou("+n_str+")="+line);
if (!scan_blank(line, n_str)) {
n_err++;
if (n_err > 5) {
alarm(ml["too_many_errors_in_input_file"]/*"Слишком
много ошибок во входном файле."*/);
break;
}
}
}
}
if(n_err == 0){
m.fix_marking();
model_ready(ml["model_is_loaded"]/*"модель загружена"*/);
this.Text = ml["TRDA_typed_model"]/*"Модель типа TRDA "*/
+ d.SafeFileName;
this.trda_file_name = d.FileName;
}else{
status(ml["model_is_not_loaded"]/*"Модель не
загружена"*/);
m = null;
model_not_ready();
}
multy_alarm_off();
}
146
int comment_deep = 0;
bool scan_blank(string ss,int n_str) {
Char[] null_c_list = null;
bool rez = true;
foreach(string s in
ss.Split(null_c_list,StringSplitOptions.RemoveEmptyEntries) ){
log("==>"+s);
if (!scan(s, n_str, ss)) {
rez = false;
}
}
return rez;
}
bool scan(string ss, int n_str, string sou) {
Char[] delim = {'(',',',')',';'};
string[] s_list = ss.Split(delim,
StringSplitOptions.RemoveEmptyEntries);
foreach(string s in s_list) {
log("---->" + s);
}
try {
if(s_list[0] == "/*") {
comment_deep++;
log("----> /* deep=" + comment_deep);
return true;
}
if(s_list[0] == "*/") {
comment_deep--;
log("----> */ deep="+comment_deep);
return true;
}
if(comment_deep > 0) return true;
if(comment_deep < 0) {
error(ml["unopened comment id closed"]/*"закрыт не
открытый комиментарий"*/);
}
decode(s_list, n_str, sou);
return true;
} catch(Exception e) {
log("n_str=" + n_str + ": " + sou);
log("decode_error: " + e.Message );
string err_msg = e.Message;
if(e.InnerException != null) {
log("innerException: " + e.InnerException.Message);
err_msg = e.InnerException.Message;
}
alarm("decode_error in "+s_list[0]+": " + err_msg);
return false;
}
}
void decode(string[] sl, int n_str, string sou) {
147
System.Type t = m.GetType();
int n = sl.Length;
Object[] pars = null;
System.Type[] types = null;
if(n > 1) {
pars = new Object[n - 1];
types = new System.Type[n - 1];
for(int i = 1; i < n; i++) {
pars[i - 1] = sl[i];
types[i-1]=typeof(string);
}
}
string func_name = sl[0];
if(func_name.Equals("const")) {
func_name = "dconst";
} else if(func_name.Equals("var")) {
func_name = "dvar";
} else if(func_name.Equals("time")) {
func_name = "duration";
}
MethodInfo method = t.GetMethod(func_name,types);
method.Invoke(m, pars);
}
}
}
148
Приложение 14 FormChart.cs
using
using
using
using
using
using
using
using
System;
System.Collections.Generic;
System.ComponentModel;
System.Data;
System.Drawing;
System.Linq;
System.Text;
System.Windows.Forms;
namespace Automata {
public partial class FormChart : Form {
public FormChart() {
InitializeComponent();
}
void log(string ss) {
Form1.log(ss);
}
MultyLanguage ml = MultyLanguage.get_MultyLanguage();
Form1 main_form;
ChartInfo chin = null;
public FormChart(Form1 i_form) {
InitializeComponent();
main_form = i_form;
}
void set_text() {
this.Text = ml["chart_diagram_title"];
}
public void set_chin(ChartInfo i_chin) {
chin = i_chin;
panel1.Refresh();
}
Graphics gr;
Color[] colors = {Color.Red, Color.Orange, Color.Yellow
,Color.Green, Color.LightBlue,Color.Blue
,Color.Violet, Color.Aquamarine, Color.Brown, Color.Black
,Color.Aqua,Color.Bisque,Color.Coral,Color.BurlyWood
};
List<Pen> pens = new List<Pen>();
List<SolidBrush> brushes = new List<SolidBrush>();
int ix_by_dx(double dx, int i_max, double d_max, int X0, int
X_GAP) {
double f1 = dx * (i_max - X0-X_GAP) / d_max;
int ix = X0 + (int)f1;
return ix;
}
149
private void panel1_Paint(object sender, PaintEventArgs e) {
gr = panel1.CreateGraphics();
int xmax = panel1.ClientSize.Width;
int ymax = panel1.ClientSize.Height;
for (int i = 0; i < colors.Length; i++) {
Pen p = new Pen((Color)colors[i], 10);
pens.Add(p);
}
int x1,y1,x2,y2;
for (int i = 0; i < colors.Length; i++) {
SolidBrush b = new SolidBrush((Color)colors[i]);
brushes.Add(b);
}
int X0 = 80;
int X_GAP = 10;
// считаю размер шага по оси времени
int n_x =
(int) Math.Round(Math.Log10(chin.x_max));
double s_x = Math.Pow(10, n_x - 1);
log("x_max="+chin.x_max
+ " log10="+Math.Log10(chin.x_max)
+ " n_x="+n_x
+ " s_x="+s_x
);
// ось времени
int y0 = ymax - 65;
gr.DrawLine(new Pen(colors[9], 3), X0, y0, xmax - X_GAP,
y0);
// формирование подписей оси времени
double x0=0;
int j = 0;
while (x0 < chin.x_max) {
x1 = ix_by_dx(x0,xmax,chin.x_max,X0,X_GAP);
/*
double f1 = x0 * (xmax-X0) / chin.x_max;
x1 = X0 + (int) f1 ;
*/
y1 = ymax - 60;
x0 += s_x;
gr.DrawString(""+s_x*j, new Font(Font.SystemFontName,
10), brushes[8], x1-5,y1);
// отметки на оси времени
gr.DrawLine(new Pen(colors[9], 3), x1+1, y0+2, x1+1, y05);
j++;
}
// позиции
for (int i = 0; i < chin.positions.Count; i++) {
x1 = 2;
y1 = ymax - 100 - i * 35;
gr.DrawString(chin.positions[i], new
Font(Font.SystemFontName, 10), brushes[8], x1,y1);
}
150
// рисование линий по позициям
int n_color;
foreach(ChartItem item in chin.items) {
x1 = ix_by_dx(item.x_from, xmax, chin.x_max, X0, X_GAP);
x2 = ix_by_dx(item.x_to, xmax, chin.x_max, X0, X_GAP);
y1 = ymax - 90 - item.position * 35;
n_color = item.state % colors.Length;
gr.DrawLine(new Pen(colors[n_color], 10), x1, y1, x2,
y1);
}
// легенда - цвета состояний
int n = chin.states.Count;
n = Math.Max(n, 10);
int dx = xmax / n;
int gap_x = dx/2;
int gap_y = 10;
log("y0=" + y0);
for (int i = 0; i < chin.states.Count; i++) {
log(chin.states[i]);
x1 = 20 + dx*i;
y1= ymax - 3*gap_y;
x2 = x1 + gap_x;
y2=y1;
n_color = i % colors.Length;
gr.DrawLine(new Pen(colors[n_color], 10),x1,y1,x2,y2);
System.Drawing.Point p = new System.Drawing.Point();
p.X = x1;
p.Y = y1 + gap_y;
gr.DrawString(chin.states[i],new
Font(Font.SystemFontName,10),brushes[8],p);
}
}
private void panel1_Resize(object sender, EventArgs e) {
panel1.Refresh();
}
private void FormChart_FormClosing(object sender,
FormClosingEventArgs e) {
main_form.chart_visible(false);
/*
this.Visible = false;
e.Cancel = true;
*/
}
private void FormChart_Activated(object sender, EventArgs e)
{
set_text();
}
}
}
151
152
Приложение 15 FormChart.Designer.cs
namespace Automata {
partial class FormChart {
/// <summary>
/// Требуется переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс
должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing) {
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором форм
Windows
/// <summary>
/// Обязательный метод для поддержки конструктора - не
изменяйте
/// содержимое данного метода при помощи редактора кода.
/// </summary>
private void InitializeComponent() {
this.panel1 = new System.Windows.Forms.Panel();
this.SuspendLayout();
//
// panel1
//
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel1.Location = new System.Drawing.Point(0, 0);
this.panel1.Margin = new System.Windows.Forms.Padding(2);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(671, 743);
this.panel1.TabIndex = 0;
this.panel1.Paint += new
System.Windows.Forms.PaintEventHandler(this.panel1_Paint);
this.panel1.Resize += new
System.EventHandler(this.panel1_Resize);
//
// FormChart
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F,
13F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(671, 743);
this.Controls.Add(this.panel1);
this.Margin = new System.Windows.Forms.Padding(2);
153
this.Name = "FormChart";
this.Text = "Временная диаграмма";
this.Activated += new
System.EventHandler(this.FormChart_Activated);
this.FormClosing += new
System.Windows.Forms.FormClosingEventHandler(this.FormChart_FormClosin
g);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Panel panel1;
}
}
154
Приложение 16 FormHelp.cs
using
using
using
using
using
using
using
using
System;
System.Collections.Generic;
System.ComponentModel;
System.Data;
System.Drawing;
System.Linq;
System.Text;
System.Windows.Forms;
namespace Automata {
public partial class FormHelp : Form {
public FormHelp(string i_title, string i_text) {
InitializeComponent();
this.Text = i_title;
textBox1.Text = i_text;
textBox1.Select(0, 0);
}
static MultyLanguage ml = MultyLanguage.get_MultyLanguage();
static void help(string p_title, string p_text) {
FormHelp frmhelp = new FormHelp(p_title,p_text);
frmhelp.Show();
}
public static void help_about(string i_build_id) {
help(ml["about_program"]/*"О программе"*/,
ml["program_implements_trda"]+" (build="+i_build_id+")"
/*@"Программа реализует систему временных конечных автоматов"*/
);
}
public static void help_bnf() {
help(ml["model_description_language"]/*"Язык описания
модели"*/,
ml["bnf"]/*@"Описание модели с помощью формализма
БНФ
<Описание модели> ::= model(<название модели>)
<системная сеть>
<автоматный слой>
<начальная разметка>
<системная сеть> ::=
[<определение вершины системного слоя>, … ]
[<определение дуги системного слоя>, … ]
<определение вершины системного слоя> ::= place(<название
вершины>)
<определение дуги системного слоя> ::=
<определение входящей дуги> | <определение исходящей
дуги>
<определение входящей дуги> ::=
155
arc_in(<вершина приемник>, <вершина источник>,
<название порта>)
<определение исходящей дуги> ::=
arc_out(<вершина источник>, <вершина приемник>,
<название порта>)
<автоматный слой> ::= [<определение типа>, … ]
<определение типа> ::= type(<имя типа>)
[<определение элемента типа>, … ]
[<обозначение состояния на графике>, … ]
[<определение перехода>, … ]
<определение элемента типа> ::=
<определение состояния> | <
определение порта>
| < определение константы> | < определение переменной>
<определение состояния> ::= state(<имя состояния>)
<определение переменной> ::= var(<имя переменной>)
<определение константы> ::= const(<имя константы>)
<определение порта> ::= port(<имя порта>)
<обозначение состояния на графике> ::=
state_chart_name(<имя состояния>,
графике>)
<имя состояния на
<определение перехода> ::=
trans(<имя исходного состояния>, <имя итогового
состояния> [, <название перехода>])
[<атрибут перехода>, … ]
[<определение преобразования ресурсов>, … ]
<атрибут перехода> ::= <продолжительность перехода>
| <обозначение перехода на графике>
| <вероятность перехода>
<ожидание начала работы перехода> ::=
wait(<минимальное время ожидания перехода>[,
<максимальное время ожидания перехода>])
<продолжительность перехода> ::=
time(<минимальное время длительности работы перехода>[,
<максимальное время длительности работы перехода>])
<вероятность перехода> ::=
priority(<приоритет перехода>)
<обозначение перехода на графике> ::=
trans_chart_name(<имя перехода на графике>)
<определение преобразования ресурсов> ::=
<определение потребления ресурсов> | <определение
производства ресурсов>
<определение потребления ресурсов> ::=
term_in(<имя порта>, <имя ресурса>[, <состояние
потребляемого ресурса>])
156
<определение производства ресурсов> ::=
term_out(<имя порта>, <имя ресурса>[, <состояние
производимого ресурса>])
<имя ресурса> ::= <имя константы> | <имя переменной>
"*/
);
}
}
}
157
Приложение 17 FormHelp.Designer.cs
namespace Automata {
partial class FormHelp {
/// <summary>
/// Требуется переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс
должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing) {
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором форм
Windows
/// <summary>
/// Обязательный метод для поддержки конструктора - не
изменяйте
/// содержимое данного метода при помощи редактора кода.
/// </summary>
private void InitializeComponent() {
this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.textBox1.Location = new System.Drawing.Point(0, 0);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.ReadOnly = true;
this.textBox1.ScrollBars =
System.Windows.Forms.ScrollBars.Both;
this.textBox1.Size = new System.Drawing.Size(365, 313);
this.textBox1.TabIndex = 0;
//
// FormHelp
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F,
16F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(365, 313);
this.Controls.Add(this.textBox1);
this.Name = "FormHelp";
this.Text = "frmHelp";
this.ResumeLayout(false);
158
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox textBox1;
}
}
159
Приложение 18 FormLog.cs
using
using
using
using
using
using
using
using
System;
System.Collections.Generic;
System.ComponentModel;
System.Data;
System.Drawing;
System.Linq;
System.Text;
System.Windows.Forms;
namespace Automata {
public partial class FormLog : Form {
Form1 main_form;
public FormLog(Form1 i_form) {
main_form = i_form;
InitializeComponent();
}
public void log(string ss) {
textBox1.AppendText(ss+"\r\n");
}
private void FormLog_FormClosing(object sender,
FormClosingEventArgs e) {
main_form.log_visible(false);
//
this.Visible = false;
e.Cancel = true;
}
}
}
160
Приложение 19 FormLog.Designer.cs
namespace Automata {
partial class FormLog {
/// <summary>
/// Требуется переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс
должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing) {
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором форм
Windows
/// <summary>
/// Обязательный метод для поддержки конструктора - не
изменяйте
/// содержимое данного метода при помощи редактора кода.
/// </summary>
private void InitializeComponent() {
this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.textBox1.Font = new System.Drawing.Font("Courier New",
7.8F, System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.textBox1.Location = new System.Drawing.Point(0, 0);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.ScrollBars =
System.Windows.Forms.ScrollBars.Both;
this.textBox1.Size = new System.Drawing.Size(292, 260);
this.textBox1.TabIndex = 0;
this.textBox1.WordWrap = false;
//
// FormLog
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F,
16F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(292, 260);
this.Controls.Add(this.textBox1);
161
this.Name = "FormLog";
this.Text = "FormLog";
this.FormClosing += new
System.Windows.Forms.FormClosingEventHandler(this.FormLog_FormClosing)
;
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox textBox1;
}
}
162
Приложение 20 FormRezult.cs
using
using
using
using
using
using
using
using
using
System;
System.Collections.Generic;
System.ComponentModel;
System.Data;
System.Drawing;
System.Linq;
System.Text;
System.Windows.Forms;
System.IO;
namespace Automata {
public partial class FormRezult : Form {
string file_name;
static MultyLanguage ml = MultyLanguage.get_MultyLanguage();
public FormRezult(string fname) {
InitializeComponent();
file_name = fname + ".rez";
textBox2.Text = file_name;
this.Text = ml["title_FormRezults"];
btn_save.Text = ml["save"];
}
public void log_begin() {
textBox1.Text = "";
}
public void log(string ss){
textBox1.AppendText(ss+"\r\n");
}
private void btn_save_Click(object sender, EventArgs e) {
SaveFileDialog d = new SaveFileDialog();
d.FileName = file_name;
if(d.ShowDialog() != DialogResult.OK) {
return;
}
using(StreamWriter sw = File.CreateText(d.FileName)) {
sw.Write(textBox1.Text);
}
}
}
}
163
Приложение 21 FormRezult.Designer.cs
namespace Automata {
partial class FormRezult {
/// <summary>
/// Требуется переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс
должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing) {
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором форм
Windows
/// <summary>
/// Обязательный метод для поддержки конструктора - не
изменяйте
/// содержимое данного метода при помощи редактора кода.
/// </summary>
private void InitializeComponent() {
this.panel1 = new System.Windows.Forms.Panel();
this.textBox2 = new System.Windows.Forms.TextBox();
this.btn_save = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// panel1
//
this.panel1.Controls.Add(this.textBox2);
this.panel1.Controls.Add(this.btn_save);
this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.panel1.Location = new System.Drawing.Point(0, 500);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(646, 63);
this.panel1.TabIndex = 0;
//
// textBox2
//
this.textBox2.Anchor =
((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyl
es.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textBox2.Location = new System.Drawing.Point(12, 23);
this.textBox2.Name = "textBox2";
this.textBox2.Size = new System.Drawing.Size(516, 22);
164
this.textBox2.TabIndex = 1;
//
// btn_save
//
this.btn_save.Anchor =
((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyle
s.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btn_save.Location = new System.Drawing.Point(544, 17);
this.btn_save.Name = "btn_save";
this.btn_save.Size = new System.Drawing.Size(90, 34);
this.btn_save.TabIndex = 0;
this.btn_save.Text = "Сохранить";
this.btn_save.UseVisualStyleBackColor = true;
this.btn_save.Click += new
System.EventHandler(this.btn_save_Click);
//
// textBox1
//
this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.textBox1.Location = new System.Drawing.Point(0, 0);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.ScrollBars =
System.Windows.Forms.ScrollBars.Both;
this.textBox1.Size = new System.Drawing.Size(646, 500);
this.textBox1.TabIndex = 1;
//
// FormRezult
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F,
16F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(646, 563);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.panel1);
this.Name = "FormRezult";
this.Text = "Результаты анализа";
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private
private
private
private
System.Windows.Forms.Panel panel1;
System.Windows.Forms.Button btn_save;
System.Windows.Forms.TextBox textBox1;
System.Windows.Forms.TextBox textBox2;
}
}
165
Приложение 22 FormVisual.cs
using
using
using
using
using
using
using
using
using
System;
System.Collections.Generic;
System.ComponentModel;
System.Data;
System.Drawing;
System.Linq;
System.Text;
System.IO;
System.Windows.Forms;
namespace Automata {
public partial class FormVisual : Form {
string dot_file_name;
Form1 main_form;
VisualNet net;
static MultyLanguage ml = MultyLanguage.get_MultyLanguage();
public FormVisual(Form1 i_form1, VisualNet i_net) {
InitializeComponent();
net = i_net;
set_text();
this.main_form = i_form1;
}
void set_text() {
if (net == VisualNet.system_net) {
this.Text = ml["title_SystemNet"];
}
if (net == VisualNet.automata_net) {
this.Text = ml["title_AutomataNet"];
}
btn_save_dot.Text = ml["save"];
}
public void new_dot(string i_file_name) {
dot_file_name = i_file_name + ".dot";
textBox2.Text = dot_file_name;
textBox1.Text = "";
}
public void write_dot(string ss){
textBox1.AppendText(ss + "\r\n");
}
private void btn_save_dot_Click(object sender, EventArgs e) {
SaveFileDialog d = new SaveFileDialog();
d.FileName = textBox2.Text;
if(d.ShowDialog() != DialogResult.OK) {
return;
}
dot_file_name = d.FileName;
textBox2.Text = dot_file_name;
save_dot_file();
}
void save_dot_file() {
using(StreamWriter sw = File.CreateText(dot_file_name)) {
sw.Write(textBox1.Text);
}
}
166
private void log(string ss){
toolStripStatusLabel1.Text = ss;
Form1.log(ss);
}
private void tabVisual_Enter(object sender, EventArgs e) {
log("tab_Visual_Enter fire at " + System.DateTime.Now);
draw_graph();
}
public void draw_graph() {
log("save_dot_file");
save_dot_file();
string jpg_file_name = dot_file_name + ".jpg";
log("jpg_file_name=" + jpg_file_name);
if(pictureBox1.Image != null) {
log("pictureBox1.Image.Dispose()");
pictureBox1.Image.Dispose();
}
try {
log("do delete_dot_file");
File.Delete(jpg_file_name);
log("posle delete_dot_file");
} catch(Exception e) {
log("Error while delete old jpg file " + jpg_file_name
+": "+e.Message
);
}
try {
string ss = "dot.exe -Tjpg -o\"" + jpg_file_name + "\"
\"" + dot_file_name + "\"";
log("try begin. ss=" + ss);
System.Diagnostics.Process p =
System.Diagnostics.Process.Start("dot.exe", ss);
log("in try. p=" + p);
p.WaitForExit();
int exit_code = p.ExitCode;
log("in try. p exit. exit_code="+exit_code);
p.Close();
} catch(Exception e) {
log("on run e=" + e.Message);
}
Image mem;
try{
Stream stream = File.Open(jpg_file_name, FileMode.Open);
//
mem = Image.FromFile(jpg_file_name);
mem = Image.FromStream(stream);
stream.Close();
pictureBox1.Image = mem;
log("mem size = " + mem.Size
+" pbi size = " + pictureBox1.Image.Size
);
pictureBox1.Size = mem.Size;
//
log("image size = " + pictureBox1.Size);
167
} catch(Exception e) {
log("on load e=" + e.Message);
}
}
private void FormVisual_FormClosing(object sender,
FormClosingEventArgs e) {
main_form.set_visual(false, net);
e.Cancel = true;
}
private void FormVisual_Activated(object sender, EventArgs e)
{
set_text();
}
}
}
168
Приложение 23 FormVisual.Designer.cs
namespace Automata {
partial class FormVisual {
/// <summary>
/// Требуется переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс
должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing) {
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором форм
Windows
/// <summary>
/// Обязательный метод для поддержки конструктора - не
изменяйте
/// содержимое данного метода при помощи редактора кода.
/// </summary>
private void InitializeComponent() {
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tabVisual = new System.Windows.Forms.TabPage();
this.panel2 = new System.Windows.Forms.Panel();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.tabDot = new System.Windows.Forms.TabPage();
this.textBox1 = new System.Windows.Forms.TextBox();
this.panel1 = new System.Windows.Forms.Panel();
this.btn_save_dot = new System.Windows.Forms.Button();
this.textBox2 = new System.Windows.Forms.TextBox();
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.toolStripStatusLabel1 = new
System.Windows.Forms.ToolStripStatusLabel();
this.tabControl1.SuspendLayout();
this.tabVisual.SuspendLayout();
this.panel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginIn
it();
this.tabDot.SuspendLayout();
this.panel1.SuspendLayout();
this.statusStrip1.SuspendLayout();
this.SuspendLayout();
//
// tabControl1
//
this.tabControl1.Controls.Add(this.tabVisual);
169
this.tabControl1.Controls.Add(this.tabDot);
this.tabControl1.Dock =
System.Windows.Forms.DockStyle.Fill;
this.tabControl1.Location = new System.Drawing.Point(0, 0);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(430, 300);
this.tabControl1.TabIndex = 0;
//
// tabVisual
//
this.tabVisual.Controls.Add(this.panel2);
this.tabVisual.Location = new System.Drawing.Point(4, 25);
this.tabVisual.Name = "tabVisual";
this.tabVisual.Padding = new
System.Windows.Forms.Padding(3);
this.tabVisual.Size = new System.Drawing.Size(422, 271);
this.tabVisual.TabIndex = 1;
this.tabVisual.Text = "visual";
this.tabVisual.UseVisualStyleBackColor = true;
this.tabVisual.Enter += new
System.EventHandler(this.tabVisual_Enter);
//
// panel2
//
this.panel2.AutoScroll = true;
this.panel2.Controls.Add(this.pictureBox1);
this.panel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel2.Location = new System.Drawing.Point(3, 3);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(416, 265);
this.panel2.TabIndex = 1;
//
// pictureBox1
//
this.pictureBox1.Location = new System.Drawing.Point(0, 0);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(0, 0);
this.pictureBox1.SizeMode =
System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
//
// tabDot
//
this.tabDot.Controls.Add(this.textBox1);
this.tabDot.Controls.Add(this.panel1);
this.tabDot.Location = new System.Drawing.Point(4, 25);
this.tabDot.Name = "tabDot";
this.tabDot.Padding = new System.Windows.Forms.Padding(3);
this.tabDot.Size = new System.Drawing.Size(422, 271);
this.tabDot.TabIndex = 0;
this.tabDot.Text = "dot";
this.tabDot.UseVisualStyleBackColor = true;
//
// textBox1
//
170
this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.textBox1.Location = new System.Drawing.Point(3, 3);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.ScrollBars =
System.Windows.Forms.ScrollBars.Both;
this.textBox1.Size = new System.Drawing.Size(416, 223);
this.textBox1.TabIndex = 0;
//
// panel1
//
this.panel1.Controls.Add(this.btn_save_dot);
this.panel1.Controls.Add(this.textBox2);
this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.panel1.Location = new System.Drawing.Point(3, 226);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(416, 42);
this.panel1.TabIndex = 1;
//
// btn_save_dot
//
this.btn_save_dot.Anchor =
((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyle
s.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btn_save_dot.Location = new System.Drawing.Point(307,
14);
this.btn_save_dot.Name = "btn_save_dot";
this.btn_save_dot.Size = new System.Drawing.Size(104, 23);
this.btn_save_dot.TabIndex = 1;
this.btn_save_dot.Text = "Save";
this.btn_save_dot.UseVisualStyleBackColor = true;
this.btn_save_dot.Click += new
System.EventHandler(this.btn_save_dot_Click);
//
// textBox2
//
this.textBox2.Anchor =
((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyl
es.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textBox2.Location = new System.Drawing.Point(5, 15);
this.textBox2.Name = "textBox2";
this.textBox2.Size = new System.Drawing.Size(296, 22);
this.textBox2.TabIndex = 0;
//
// statusStrip1
//
this.statusStrip1.Items.AddRange(new
System.Windows.Forms.ToolStripItem[] {
this.toolStripStatusLabel1});
this.statusStrip1.Location = new System.Drawing.Point(0,
300);
this.statusStrip1.Name = "statusStrip1";
this.statusStrip1.Size = new System.Drawing.Size(430, 23);
this.statusStrip1.TabIndex = 0;
this.statusStrip1.Text = "statusStrip1";
//
171
// toolStripStatusLabel1
//
this.toolStripStatusLabel1.Name = "toolStripStatusLabel1";
this.toolStripStatusLabel1.Size = new
System.Drawing.Size(141, 18);
this.toolStripStatusLabel1.Text = "toolStripStatusLabel1";
//
// FormVisual
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F,
16F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(430, 323);
this.Controls.Add(this.tabControl1);
this.Controls.Add(this.statusStrip1);
this.Name = "FormVisual";
this.Text = "FormVisual";
this.Activated += new
System.EventHandler(this.FormVisual_Activated);
this.FormClosing += new
System.Windows.Forms.FormClosingEventHandler(this.FormVisual_FormClosi
ng);
this.tabControl1.ResumeLayout(false);
this.tabVisual.ResumeLayout(false);
this.panel2.ResumeLayout(false);
this.panel2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit
();
this.tabDot.ResumeLayout(false);
this.tabDot.PerformLayout();
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.statusStrip1.ResumeLayout(false);
this.statusStrip1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage tabDot;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.TabPage tabVisual;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Button btn_save_dot;
private System.Windows.Forms.TextBox textBox2;
private System.Windows.Forms.StatusStrip statusStrip1;
private System.Windows.Forms.ToolStripStatusLabel
toolStripStatusLabel1;
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Panel panel2;
}
}
172
173
Приложение 24 Lib.cs
using
using
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Windows.Forms;
System.Xml;
namespace Automata {
public class Lib {
static Random r = new Random();
public static double get_random_from_interval(double min,
double max) {
int N = 100000;
int i = r.Next(N);
double x = min + (max - min) * i / N;
x = Math.Round(x, 2);
return x;
}
public static void alarm(string ss) {
MessageBox.Show(ss, "Сообщение");
}
public static bool confirm(string ss) {
DialogResult result =
MessageBox.Show(ss, "Подтверждение",
MessageBoxButtons.YesNo);
return (result == DialogResult.Yes);
}
public static int nvl_int(String value, int default_value) {
int rez = default_value;
try {
rez = int.Parse(value);
} catch(Exception e) {
Lib.alarm("nvl_int e=" + e.Message);
}
return rez;
}
public static void form_attr_read(XmlElement e, Form f) {
String ss = e.GetAttribute("window_state");
FormWindowState st = FormWindowState.Normal;
if(ss.Equals("Maximized")) st = FormWindowState.Maximized;
if(ss.Equals("Minimized")) st = FormWindowState.Minimized;
f.Top = nvl_int(e.GetAttribute("top"), f.Top);
f.Left = nvl_int(e.GetAttribute("left"), f.Left);
f.Width = nvl_int(e.GetAttribute("width"), f.Width);
f.Height = nvl_int(e.GetAttribute("height"), f.Height);
f.WindowState = st;
}
public static void form_attr_write(XmlElement e, Form f) {
FormWindowState s = f.WindowState;
if(f.WindowState != FormWindowState.Normal) {
174
f.WindowState = FormWindowState.Normal;
}
e.SetAttribute("top", "" + f.Top);
e.SetAttribute("left", "" + f.Left);
e.SetAttribute("width", "" + f.Width);
e.SetAttribute("height", "" + f.Height);
e.SetAttribute("window_state", "" + s);
f.WindowState = s;
}
}
}
175
Приложение 25 Model.cs
using
using
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Collections;
System.Text.RegularExpressions;
namespace Automata {
partial class Model {
enum Context { nil, type, trans, place, marking,
marking_place };
Context context = Context.nil;
//
Hashtable Places = new Hashtable();
Place current_place;
public List<Place> p_list = new List<Place>();
//
Hashtable Types = new Hashtable();
Type current_type;
Transition current_transition;
public List<Type> t_list = new List<Type>();
//
Hashtable Constants = new Hashtable();
//
Hashtable Vars = new Hashtable();
//
Hashtable Ports = new Hashtable();
public List<Port> port_list = new List<Port>();
//
List<Instance> inst_list = new List<Instance>();
//
Hashtable markings = new Hashtable();
Marking current_marking;
//
List<Bound> bound_list = new List<Bound>();
//
public string name;
static Model m = null;
public Model(string i_name) {
name = i_name;
m = this;
}
public static Model get_model() {
return m;
}
static void log(string ss) {
Form1.log(ss);
}
static void rez(string ss) {
Form1.rez(ss);
}
static void log_t(string ss) {
176
Form1.log_t(ss);
}
static void error(string ss) {
Form1.log("error: " + ss);
Exception e = new Exception(ss);
throw e;
}
public void model(string ss) {
this.name = ss;
}
public Type type(string i_name) {
context = Context.type;
if(Types.Contains(i_name)) {
current_type = (Type)Types[i_name];
return current_type;
} else {
Type t = new Type(i_name);
current_type = t;
Types.Add(i_name, t);
t.id = Types.Count;
t_list.Add(t);
return t;
}
}
public Port port(string i_name) {
Port p;
if(Ports.Contains(i_name)) {
p = (Port)Ports[i_name];
} else {
p = new Port(i_name);
Ports.Add(i_name, p);
port_list.Add(p);
}
if(context == Context.type) {
if(p.type == null){
p.type = current_type;
current_type.list_port.Add(p);
}else{
if(current_type != p.type) {
Exception e = new Exception("Разные типы для порта "
+ i_name
+ ". Был " + p.type.name + ", определяется " +
current_type.name);
throw e;
}
}
}
return p;
}
177
public void dconst(string i_name) {
Const c;
if(Constants.Contains(i_name)) {
c = (Const)Constants[i_name];
if(current_type != c.type) {
Exception e = new Exception("Разные типы для константы
" + i_name
+ ". Был " + c.type.name + ", определяется " +
current_type.name);
throw e;
}
} else {
c = new Const(i_name);
c.type = current_type;
Constants.Add(i_name, c);
c.id = Constants.Count - 1;
current_type.list_const.Add(c);
}
}
public void dvar(string i_name) {
Var v;
if(Vars.Contains(i_name)) {
v = (Var)Vars[i_name];
if(current_type != v.type) {
error("Разные типы для переменной " + i_name
+ ". Был " + v.type.name + ", определяется " +
current_type.name);
}
} else {
v = new Var(i_name);
v.type = current_type;
Vars.Add(i_name, v);
current_type.list_var.Add(v);
}
}
public Place place(string i_name){
if (context == Context.marking
|| context == Context.marking_place
) {
context = Context.marking_place;
if (Places.Contains(i_name)) {
if (current_marking.places.Contains(i_name)) {
error("marking " + current_marking.name + ": place"
+ i_name + " already present in marking");
}
Place p = (Place)Places[i_name];
Place place = new Place(i_name);
place.id = p.id;
//current_marking.current_place = place;
current_place = place;
current_marking.places.Add(i_name,place);
} else {
error("marking "+current_marking.name +": place"
+ i_name + " not found");
178
}
return null;
} else {
context = Context.place;
if (Places.Contains(i_name)) {
current_place = (Place)Places[i_name];
return current_place;
} else {
Place p = new Place(i_name);
current_place = p;
Places.Add(i_name, p);
p_list.Add(p);
p.id = p_list.Count - 1;
return p;
}
}
}
public void arc_in(string i_place_to, string i_place_from,
string i_port_name) {
Place p_to = this.place(i_place_to);
Place p_from = this.place(i_place_from);
Port port_ = port(i_port_name);
Arc arc = new Arc(p_from, port_);
arc.p0 = p_to;
arc.in_out = Arc.IN;
p_to.list_in.Add(arc);
}
public void arc_out(string i_place_from, string i_place_to,
string i_port_name) {
Place p_to = this.place(i_place_to);
Place p_from = this.place(i_place_from);
Port port_ = port(i_port_name);
Arc arc = new Arc(p_to, port_);
arc.p0 = p_from;
arc.in_out = Arc.OUT;
p_from.list_out.Add(arc);
}
public State state(string i_name) {
return state(i_name, null);
}
public State state(string i_name,string i_symbol) {
if(context != Context.type && context != Context.trans) {
error("При определении состояния " + i_name + " не
определен контекст типа. "+context);
}
Type type = current_type;
State s;
Form1.log("->state " + i_name);
if(type.States.Contains(i_name)) {
Form1.log("-->old state " + i_name);
s = (State)type.States[i_name];
}else{
Form1.log("-->new state " + i_name);
179
s = new State(i_name, type);
type.States.Add(i_name,s);
type.list_states.Add(s);
s.id = type.list_states.Count -1;
}
if(i_symbol != null) s.symbol = i_symbol[0];
if(type.initial_state == null) {
type.initial_state = s;
}
return s;
}
public Register timer(string i_name) {
return register(i_name, RegType.rt_timer);
}
public Register register(string i_name, RegType i_reg_type){
if(context != Context.type && context != Context.trans) {
error("При определении регистра " + i_name + " не
определен контекст типа. " + context);
}
Type type = current_type;
Register reg;
if(type.Registers.Contains(i_name)) {
Form1.log("-->old register " + i_name);
reg = (Register)type.Registers[i_name];
if(reg.reg_type != i_reg_type) {
error("Регистр " + i_name + " уже определен с другим
типом в типе " + type.name);
}
} else {
Form1.log("-->new register " + i_name);
reg = new Register(i_name, i_reg_type);
type.Registers.Add(i_name, reg);
type.list_regs.Add(reg);
reg.id = type.list_regs.Count - 1;
}
return reg;
}
public void reset(string i_timer) {
if(context != Context.trans) {
error("reset timer=" + i_timer + ": контекст не
переход");
}
Type type = current_type;
Transition trans = current_transition;
Register t_reg;
if(type.Registers.Contains(i_timer)) {
t_reg = (Register)type.Registers[i_timer];
if(t_reg.reg_type != RegType.rt_timer) {
error("Тип регистра " + i_timer + " в типе " +
type.name + " не Timer");
}
} else {
t_reg = timer(i_timer);
180
}
trans.list_reset.Add(t_reg);
}
public void constr(string i_text){
if(context != Context.trans) {
error("constraint=" + i_text + ": контекст не переход");
}
Type type = current_type;
Transition trans = current_transition;
log("constr=" + i_text);
Regex rx = new Regex(@"^([a-zA-Z]*)\s*([+|-]*)\s*([a-zAZ]*)(>=|<=|>|<|=)(\d+)");
Match match = rx.Match(i_text);
if(match.Success) {
log("constr ----> match");
} else {
log("constr ----> not match");
error("Error in constraint " + i_text + ". Constraint
must look like X + Y < 10");
}
GroupCollection gc = match.Groups;
/*
foreach(Group g in gc) {
log("g=" + g.Value);
}
*/
int[] gn = rx.GetGroupNumbers();
foreach(int i in gn) {
log("group i[" + i + "]="+gc[i].Value);
}
if(gc[1].Value == "") {
error("Error in constraint " + i_text + ": first variable
is null");
}
Constraint constr = new Constraint();
constr.r1 = timer(gc[1].Value);
constr.a = 1;
if(gc[2].Value == ""){
constr.r2 = null;
constr.b = 0;
}else {
if(gc[3].Value == "") {
error("Error in constraint " + i_text + ": sign found,
but second variable is null");
}
constr.r2 = timer(gc[3].Value);
if(gc[2].Value == "+"){
constr.b = 1;
} else if(gc[2].Value == "-"){
constr.b = -1;
}
}
if(gc[4].Value == ">=") {
181
constr.rel = ConstraintRelation.ge;
} else if(gc[4].Value == "<=") {
constr.rel = ConstraintRelation.le;
} else if(gc[4].Value == "<") {
constr.rel = ConstraintRelation.lt;
} else if(gc[4].Value == ">") {
constr.rel = ConstraintRelation.gt;
} else if(gc[4].Value == "=") {
constr.rel = ConstraintRelation.eq;
}
constr.c = stoi(gc[5].Value);
trans.list_constr.Add(constr);
log("a=" + constr.a + " b=" + constr.b + " c=" + constr.c);
}
public void trans_symbol(string i_symbol) {
if(context != Context.trans) {
error("trans_symbol=" + i_symbol
+ ": контекст не переход");
}
if(i_symbol.Length > 0) current_transition.symbol =
i_symbol[0];
}
public void trans(string i_state_from, string i_state_to) {
trans(i_state_from, i_state_to, null);
}
public void trans(string i_state_from, string i_state_to,
string i_name) {
Form1.log("trans " + i_state_from + " -> " + i_state_to);
if(context != Context.type && context != Context.trans) {
error("При определении перехода " + i_state_from + ">"+i_state_to
+ " не определен контекст типа. "+context);
}
State s_from = state(i_state_from);
State s_to = state(i_state_to);
Transition trans = new Transition(s_from,s_to);
if(i_name != null) {
trans.name = i_name;
trans.chart_name = i_name;
}
current_type.list_trans.Add(trans);
s_from.list_trans.Add(trans);
trans.id = s_from.list_trans.Count()-1;
//
trans.name += "(" + trans.id + ")";
context = Context.trans;
current_transition = trans;
}
int stoi(string i_ss) {
return stoi(i_ss, 0);
182
}
int stoi(string i_ss, int i_default) {
int rez = i_default;
rez = Int32.Parse(i_ss);
return rez;
}
double stod(string i_ss) {
return stod(i_ss, 0);
}
double stod(string i_ss, double i_default) {
double rez = i_default;
rez = double.Parse(i_ss);
return rez;
}
public void wait(string i_time) {
wait(i_time, i_time);
}
public void wait(string time_from, string time_to) {
if(context != Context.trans) {
error("wait time_from=" + time_from
+ " time_to=" + time_to
+ ": контекст не переход");
}
double time1 = stod(time_from, Transition.default_wait);
double time2 = stod(time_to, time1);
current_transition.wait_min = time1;
current_transition.wait_max = time2;
}
public void duration(string i_time) {
duration(i_time, i_time);
}
public void duration(string time_from, string time_to) {
if(context != Context.trans) {
error("duration time_from=" + time_from
+ " time_to="+ time_to
+ ": контекст не переход");
}
double time1 = stod(time_from,
Transition.default_duration);
double time2 = stod(time_to, time1);
current_transition.duration_min = time1;
current_transition.duration_max = time2;
}
public void priority(string i_prty) {
if(context != Context.trans) {
error("priority=" + i_prty
+ ": контекст не переход");
}
int prty = stoi(i_prty, 1);
current_transition.priority = prty;
}
183
public void term_in(string i_port_name, string i_con_var,
string i_state) {
term("in", i_port_name, i_con_var, i_state);
}
public void term_in(string i_port_name, string i_con_var) {
term("in", i_port_name,i_con_var, null);
}
public void term_out(string i_port_name, string i_con_var,
string i_state) {
term("out", i_port_name, i_con_var, i_state);
}
public void term_out(string i_port_name, string i_con_var) {
term("out", i_port_name,i_con_var, null);
}
public void term(string i_dir, string i_port_name, string
i_cv, string i_state) {
if(context != Context.trans) {
error("term_" + i_dir + "=" + i_port_name + "," + i_cv
+ ": контекст не переход");
}
Transition trans = current_transition;
if(!Ports.Contains(i_port_name)) {
error("term_" + i_dir + "=" + i_port_name + "," + i_cv
+ "порт не найден");
}
Port port = (Port)Ports[i_port_name];
Term term = null;
Res res = null;
if(Constants.Contains(i_cv)) {
Const c = (Const)Constants[i_cv];
if(c.type != port.type) {
error("term_" + i_dir + "=" + i_port_name + "," +
i_cv
+ ": не совпадают типы! type(" + i_port_name + ")="
+ port.type.name
+ ", type(" + i_cv + ")=" + c.type.name
);
}
term = new Term(port, c);
res = c;
} else if(Vars.Contains(i_cv)) {
Var v = (Var)Vars[i_cv];
if(port.type == null) {
error("term_" + i_dir + "=" + i_port_name + "," +
i_cv
+ ": не определен тип порта");
}
log("1: v.type="+v.type.name
//+ " port.type="+port.type.name
);
if(v.type != port.type) {
error("term_" + i_dir + "=" + i_port_name + "," +
i_cv
+ ": не совпадают типы! type(" + i_port_name + ")="
+ port.type.name
184
+ ", type(" + i_cv + ")=" + v.type.name
);
}
log("2");
term = new Term(port, v);
log("3");
res = v;
/*
if(i_state != null) {
log("111: term_" + i_dir + "=" + i_port_name + "," +
i_cv);
if(!v.type.States.Contains(i_state)) {
error("term_" + i_dir + "=" + i_port_name + "," +
i_cv
+ ": тип " + i_state + " не найден");
}
State st = (State)v.type.States[i_state];
log("222: st created");
term.state = st;
}
*/
} else {
error("term_" + i_dir + ": port=" + i_port_name + ",
const/var=" + i_cv
+ ": объект не найден (возможно тип ресурса определен
по тексту позже типа агента)");
}
if(i_state != null) {
log("111: term_" + i_dir + "=" + i_port_name + "," +
i_cv);
if(!res.type.States.Contains(i_state)) {
error("term_" + i_dir + "=" + i_port_name + "," +
i_cv
+ ": тип " + i_state + " не найден");
}
State st = (State)res.type.States[i_state];
log("222: st created");
term.state = st;
}
if(i_dir.Equals("in")) {
trans.list_term_in.Add(term);
} else {
trans.list_term_out.Add(term);
}
}
public Instance inst_viz(string i_const_name) {
return this.inst_viz(i_const_name, null);
}
public Instance inst_viz(string i_const_name, string i_state)
{
Instance inst = this.inst(i_const_name,i_state);
inst.is_visual = true;
return inst;
}
185
public Instance inst(string i_const_name) {
return this.inst(i_const_name, null);
}
public Instance inst(string i_const_name, string i_state) {
if(context != Context.place && context!=
Context.marking_place) {
error("Определение объекта " + i_const_name + ": контекст
не 'место хранения'");
}
if(!Constants.Contains(i_const_name)) {
error("place=" + current_place.name
+ ": константа " + i_const_name + " не найдена"
);
}
Const c = (Const)Constants[i_const_name];
Instance inst = new Instance(this,c);
inst.set_place(current_place);
if(context == Context.place) {
inst_list.Add(inst);
}
if(i_state != null) {
if(!inst.con.type.States.Contains(i_state)) {
error("для типа " + inst.con.type.name + " константы "
+ i_const_name
+ " не определено состояние " + i_state
);
}
State s = (State)inst.con.type.States[i_state];
inst.current_state = s;
}
if(context == Context.marking_place) {
return null;
}
if(inst.current_state != null) {
inst.reset_transitions();
inst.start_timers(t_current);
}
trace(inst, null);
return inst;
}
/*
public void inst(string i_const_name, string i_state) {
Instance inst = this.inst(i_const_name);
if(!inst.con.type.States.Contains(i_state)) {
error("для типа " + inst.con.type.name + " константы " +
i_const_name
+ " не определено состояние " + i_state
);
}
State s = (State)inst.con.type.States[i_state];
inst.current_state = s;
}
*/
186
public void trans_chart_name(string i_name) {
if(context != Context.trans) {
error("trans_chart_name i_name=" + i_name
+ ": контекст не переход");
}
Transition trans = current_transition;
trans.chart_name = i_name;
}
public void state_chart_name(string i_state, string i_name) {
State st = state(i_state);
st.chart_name = i_name;
}
public void marking(string i_name) {
marking(i_name, null);
}
public void marking(string i_name, string i_par) {
context = Context.marking;
if(markings.Contains(i_name)){
error("marking "+i_name + " already used.");
}
Marking mark = new Marking(i_name);
if (i_par != null) {
if (i_par == "like") {
mark.like = true;
} else {
error("marking_begin " + i_name + ": режим может быть
только like");
}
}
markings.Add(i_name, mark);
current_marking = mark;
}
public void marking_end(string i_name) {
if (current_marking.name != i_name) {
error("marking " + current_marking.name + ": "
+ " different name (" +i_name +") in marking_end.");
}
}
public void bound(string i_place, string i_type, string
i_num) {
string bname = "bound("+i_place+","+i_type+","+i_num+")";
string pref = bname + ": ";
Bound b = new Bound(bname);
if(i_place != "*") {
if(!Places.Contains(i_place)) {
error(pref + "place " + i_place + " not found");
}
b.place = (Place)Places[i_place];
}
if(i_type != "*") {
if(!Types.Contains(i_type)) {
error(pref + "type " + i_type + " not found");
}
187
b.type = (Type)Types[i_type];
}
b.limit = Lib.nvl_int(i_num, 0);
if(b.limit <= 0) {
error(pref + "limit " + i_num + " не больше 0");
}
bound_list.Add(b);
}
}
}
188
Приложение 26 Model_candidates.cs
using
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Collections;
namespace Automata {
interface IModel {
}
partial class Model {
List<Step> Candidates = new List<Step>();
Hashtable applicants = new Hashtable();
List<Instance> app_list = new List<Instance>();
int champ_index = 0; // кандидат-победитель
int Exec_Mode;
public int get_exec_mode(){
return Exec_Mode;
}
public int get_champ_index() {
return champ_index;
}
public const int Exec_Mode_Consume = 1;
public const int Exec_Mode_Produce = 2;
public const int Exec_Mode_Stop = 3;
public bool do_pause = false;
public string pause_reason ="";
public List<string> get_candidates() {
List<string> ss;
if(Exec_Mode == Exec_Mode_Consume) {
ss = get_consumers();
if(ss != null) {
return ss;
}
if(move_time_point()){
Exec_Mode = Exec_Mode_Produce;
} else if(points_list.Count == 0) {
Exec_Mode = Exec_Mode_Stop;
return null;
//error("Полный финиш!");
} else {
// в пределах time_to нет завершающихся переходов
return null;
}
}
ss = get_producers();
if(ss != null){
return ss;
189
}
remove_time_point(t_current);
Exec_Mode = Exec_Mode_Consume;
return get_candidates();
}
bool time_to_on = false;
double time_to;
public void time_limit_on(Double i_time_to) {
time_to_on = true;
time_to = i_time_to;
}
public void time_limit_off() {
time_to_on = false;
}
public void set_t_current(Double i_time) {
t_current = i_time;
}
bool move_time_point(){
if(points_list.Count < 1) {
return false;
}
points_list.Sort();
double next_time = points_list[0];
if(time_to_on)
if(next_time > time_to) {
// t_current не меняется
return false;
}
t_current = next_time;
foreach(Instance inst in inst_list){
inst.move_timers(t_current);
}
return true;
}
public List<string> get_producers(){
Point p = (Point)points_hash[t_current];
if(p == null || p.steps.Count < 1) {
return null;
}
List<string> ss = new List<string>();
foreach(Step step in p.steps) {
ss.Add("t(" + step.start_time + ")
n("+step.inst.n_last_trace+") " + step.title);
}
champ_index = 0; // первый попавшийся
return ss;
}
public List<string> get_consumers(){
log("====================NEXT_STEP================");
Candidates = new List<Step>();
applicants = new Hashtable();
app_list = new List<Instance>();
190
foreach(Instance inst in inst_list) {
log("instance=" + inst.con.name);
if(inst.current_state == null) continue;
if (inst.place == null) continue;
log("instance=" + inst.con.name);
// Все инстансы, которые имеют какое-нибудь состояние
State state = inst.current_state;
log("---->state=" + state.name);
foreach(Transition trans in state.list_trans) {
log("------->trans "+trans.name+" to=" +
trans.state_to.name);
// Все транзиции (переходы) из состоятельных инстансов
Step step = check_step(inst, trans);
//
/* timed_automata
*
satisfy_time == -1, то step := null - переход стал
невыполнимым
*
либо сейчас выполняется (satisfy_time ==0)
*
либо никогда не выполняется (satisfy_time == -1)
*
либо м.б. выполнится через satisfy_time (надо еще будет
проверять)
* */
double satisfy_time = -1;
if(step != null && trans.has_timed_constraints()) {
satisfy_time = inst.get_satisfy_time(trans);
log("------inst="+inst.con.name+"->satisfy_time=" +
satisfy_time + " time=" + t_current);
if(satisfy_time == -1) {
step = null;
}
}
if(step != null) {
/* timed_automata
*
здесь должны определить ожидаемое время
удовлетворения
*
констрейнта - тоже fire_time, для этого нужна
информация
*
о inst (там реальные таймеры).
*
Возможные значения (satisfy_time):
*
0 - сейчас удовлетворяется
*
t(>0) - через время t будет удовлетворяться
*
-1 - сейчас не удовлетворяется, t(>0) определить
не удалось
*
* */
double fire_time = t_current + trans.get_wait_time();
if(trans.has_timed_constraints() && satisfy_time >=
0.0) {
fire_time = t_current + satisfy_time;
}
log("------->fire_time=" + fire_time+ "
time="+t_current);
191
//
if(inst.check_charge_transition(trans, t_current,
fire_time)) {
/* timed_automata
*
для случая констрейнта is_ready_to_fire == true только
если он
*
удовлетворяется сейчас (sutisfy_time == 0)
*
* */
if(inst.is_ready_to_fire(trans, t_current,
fire_time)) {
log("------->check_charge_ok");
Applicant app = null;
if(applicants.Contains(inst)) {
app = (Applicant)applicants[inst];
} else {
app = new Applicant(inst);
applicants.Add(inst, app);
app_list.Add(inst);
}
app.steps.Add(step);
Candidates.Add(step);
} else {
/* timed_automata
*
если satisfy_time == -1, то ничего не делаем
*
если satisfy_time == t (>0), то это t надо "зарядить"
*
*
* */
log("------->charge trans " + trans.name + " time="
+ fire_time);
if(trans.has_timed_constraints()) {
discharge_transition(inst, trans);
}
if(inst.charge_transition(trans, fire_time)) {
log("------->add_fire_point " + fire_time);
add_fire_to_point(fire_time);
} else {
log("------->already charged!");
}
/*
Point p = find_add_point(fire_time);
p.fire_count++;
*/
}
} else {
/* timed_automata
*
условия стали невыполнимыми, кончились ресурсы, (а если
*
сбросился таймер?),
=> переход надо "разрядить"
* */
log(inst.con.name + ":" + inst.current_state.name );
foreach(Transition trn in
inst.current_state.list_trans) {
log("
" + trn.name + " time="
+ inst.trans_fire_time[trn.id]
);
}
192
discharge_transition(inst,trans);
/*
double discharge_time =
inst.trans_fire_time[trans.id];
log("discharge trans=" + trans.name + " id=" +
trans.id
+ " discharge_time="+discharge_time
);
clear_fire_point(discharge_time);
inst.discharge_transition(trans);
*/
}
}
}
log_candidates();
if(Candidates.Count < 1) {
log("Не найдено ни одного кандидата");
return null;
}
champ_index = make_choice();
List<string> ss = new List<string>();
foreach(Step step in Candidates) {
ss.Add(step.title);
}
return ss;
}
void discharge_transition(Instance inst, Transition trans) {
double discharge_time = inst.trans_fire_time[trans.id];
log("discharge trans=" + trans.name + " id=" + trans.id
+ " discharge_time="+discharge_time
);
clear_fire_point(discharge_time);
inst.discharge_transition(trans);
}
void log_candidates() {
// show candidates
log("Список кандидатов:");
foreach(Instance inst in app_list) {
log("__Объект " + inst.con.name);
Applicant app = (Applicant) applicants[inst];
foreach(Step step in app.steps) {
log("____переход " + step.title);
log("\t input:");
foreach(Bind b in step.Binds.Values) {
log("\t " + b.term.port.name + " " +
b.inst.place.name);
}
log("\t output:");
foreach(Outcome o in step.Outcomes) {
log("\t " + o.arc.port.name + " " + o.arc.p.name + "
==> " + o.term.res.name);
}
}
}
/*
193
foreach(Step step in Candidates) {
log("__объект " + step.title);
log("\t input:");
foreach(Bind b in step.Binds.Values) {
log("\t "+b.term.port.name + " " + b.inst.place.name);
}
log("\t output:");
foreach(Outcome o in step.Outcomes) {
log("\t "+o.arc.port.name + " " + o.arc.p.name+" ==>
"+ o.term.res.name);
}
}
*/
}
Step check_step(Instance i_inst, Transition i_trans) {
Place place = i_inst.place;
Step step = new Step(i_inst,i_trans);
Boolean term_bind = false;
// проверяем все входные термы проверяемого перехода
foreach(Term term in i_trans.list_term_in) {
term_bind = false;
foreach(Arc arc in place.list_in) {
// все входные дуги проверяемого инстанса
if(term.port == arc.port) {
// дуга одного порта с данным входным термом
log("----------->term_in=" + term.port.name + " from
place=" + arc.p.name
+" term.cv="+term.cv + " term.res.name="+
term.res.name
);
Place place_res = arc.p;
// откуда эта дуга (из какого места)- входная позиция
foreach(Instance inst_res in place_res.list_inst){
// все инстансы во входной позиции
if(step.Binds.Contains(inst_res)){
log("+++>"+"inst="+inst_res.con.name+"
place="+place_res.name+" already used");
continue;
}
log("+++>" + "inst=" + inst_res.con.name + "
place=" + place_res.name + " not used yet");
if(inst_res.flag == Instance.flag_busy) {
log("+++>" + "inst=" + inst_res.con.name + "
place=" + place_res.name + " is busy");
continue;
}
log("+++>" + "inst=" + inst_res.con.name + "
place=" + place_res.name + " is not busy");
/*
log("term.res_type=" + term.res.type);
log("inst_res.con.type=" + inst_res.con.type);
log("term.state=" + term.state);
log("ins_res.current_state=" +
inst_res.current_state);
*/
194
if(term.cv == Term.c &&
(term.res.name).Equals(inst_res.con.name)
&& (term.state == null || term.state ==
inst_res.current_state)
|| term.cv == Term.v && term.res.type ==
inst_res.con.type
&& (term.state == null || term.state ==
inst_res.current_state)
) {
log("-------------->bind term_in.res=" +
term.res.name);
if(term.cv == Term.v) {
if(step.Vars_in.Contains(term.res.name)) {
error("term_in port=" + term.port.name + ",
var=" + term.res.name
+ ": переменная использована на вход более
1 раза");
}
}
Bind b = new Bind(term, inst_res, arc);
step.Binds.Add(inst_res, b);
if(term.cv == Term.v) {
step.Vars_in.Add(term.res.name, inst_res);
}
term_bind = true;
break;
}
}
}
}
if(!term_bind) {
log("Transition not bind!");
return null;
}
}
// проверяем все выходные термы
foreach(Term term in i_trans.list_term_out) {
term_bind = false;
foreach(Arc arc in place.list_out) {
if(term.port != arc.port) continue; // ищем другую дугу
log("----------->term_out=" + term.port.name + " to
place=" + arc.p.name);
Place place_new = arc.p;
Outcome outcome = new Outcome(term,arc);
if(term.cv == Term.v) {
string v_name = term.res.name;
if(!step.Vars_in.Contains(v_name)) {
error("Term_out port=" + term.port.name + ", var="
+ v_name
+ ": no input var");
}
Instance bind_inst = (Instance) step.Vars_in[v_name];
if(step.Vars_out.Contains(v_name)) {
error("Term_out port=" + term.port.name + ", var="
+ v_name
+ ": использована на выход более 1 раза");
}
195
step.Vars_out.Add(term.res.name,bind_inst);
}
step.Outcomes.Add(outcome);
term_bind = true;
break;
}
if(!term_bind) {
log("Transition not outcome!");
return null;
}
}
return step;
}
Random r = new Random();
//
int make_choice() {
// выбираем объект
int n = app_list.Count;
Random r = new Random();
int n_inst = r.Next(n); // определили объект случайным
образом
log("выбран объект " + n_inst + " из " + n + ": " +
app_list[n_inst].con.name);
// выбираем переход объекта номер n_inst
Instance inst = app_list[n_inst];
Applicant app = (Applicant)applicants[inst];
n = app.steps.Count;
int sum = 0;
foreach(Step step in app.steps) {
sum += step.trans.priority;
}
int r_prty = r.Next(sum);
int n_trans = -1;
Step champ_step = null;
foreach(Step step in app.steps) {
n_trans++;
champ_step = step;
if(r_prty <= step.trans.priority) {
break;
}
r_prty -= step.trans.priority;
}
log("выбран переход " + n_trans + " из " + n + ": " +
app.steps[n_trans].title);
log("champ_step: " + champ_step.title);
// выбран переход n_trans !
champ_index = Candidates.IndexOf(champ_step);
log("champ_index=" + champ_index + ": " +
Candidates[champ_index].title);
return champ_index;
}
}
196
}
197
Приложение 27 Model_ChartInfo.cs
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
namespace Automata {
partial class Model {
public ChartInfo get_chin() {
ChartInfo chin = new ChartInfo();
string pos;
string state;
double time_from, time_to;
chin.x_max = t_current;
List<string> pos_list = new List<string>();
foreach (int n in n_trace_list){
Trace trace = (Trace)trace_hash[n];
//log("trace.com.name=" + trace.con.name);
if (trace.con.type.initial_state != null) {
pos = trace.con.name;
if (trace.place != null) {
pos += ":" + trace.place.name;
}
if(pos_list.IndexOf(pos)==-1){
log("pos_list.add " + pos + " indexof=" +
pos_list.IndexOf(pos));
pos_list.Add(pos);
}
}
}
pos_list.Sort();
foreach (string s in pos_list) {
chin.add_position(s);
}
foreach(int n in n_trace_list) {
Trace trace = (Trace)trace_hash[n];
//log("trace.com.name=" + trace.con.name);
if(trace.con.type.initial_state != null) {
pos = trace.con.name;
if (trace.place != null){
pos += ":" + trace.place.name;
}
if(trace.state != null) {
state = trace.state.chart_name;
}else {// if(trace.trans != null) {
state = trace.trans.chart_name;
}
//
chin.add_item(pos, state, trace.time_start,
Math.Max(trace.time_finish, t_current));
//
log("pos=" + pos + " state=" + state + " time_start="
+ trace.time_start + " time_finifsh=" + trace.time_finish);
198
//
chin.add_item(pos, state, trace.time_start,
Math.Max(trace.time_start, trace.time_finish));
time_from = trace.time_start;
time_to = trace.time_finish;
if(time_to == -1) {
time_to = t_current;
}
chin.add_item(pos, state, time_from, time_to);
}
}
return chin;
}
}
}
199
Приложение 28 Model_dot.cs
using
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Collections;
namespace Automata {
partial class Model {
FormVisual frm_viz = null;
void wd(string ss) {
frm_viz.write_dot(ss);
}
struct StrKey {
public Instance inst;
public State state;
public int count;
}
public void show_automata_net(FormVisual i_frm_viz) {
frm_viz = i_frm_viz;
wd("digraph G {");
foreach(Instance inst in inst_list){
if(!inst.is_visual)continue;
string i_key = inst.con.name + inst.GetHashCode();
wd("subgraph cluster_" + i_key + " { style=filled;
color=lightgrey;");
wd("node [style=filled];");
wd("label=\"" +
inst.con.name+"("+inst.con.type.name+")\"");
foreach(State st in inst.con.type.list_states){
wd(i_key+st.name+"[label="+st.name);
if (inst.current_state == st) {
wd(" color = yellow");
}
wd("]; ");
}
foreach (State st in inst.con.type.list_states) {
foreach (Transition trans in st.list_trans) {
wd(i_key + st.name + " -> " + i_key +
trans.state_to.name);
string ss_trans_color = "black";
foreach(Step step in Candidates){
if (step.inst == inst && step.trans == trans) {
ss_trans_color="green";
}
}
string ss_get = "";
foreach (Term term in trans.list_term_in) {
ss_get += (ss_get == "") ? "" : ",";
ss_get += term.port.name + "?" + term.res.name;
}
200
log("ss_get=" + ss_get);
string ss_put = "";
foreach (Term term in trans.list_term_out) {
ss_put += (ss_put == "") ? "" : ",";
ss_put += term.port.name + "!" + term.res.name;
}
string ss3 = "";
if (inst.current_step != null) {
if (inst.current_step.trans == trans) {
ss_trans_color = "red";
ss3 +=
"finish_time="+inst.current_step.finish_time;
}
}
if (st == inst.current_state) {
//ss3 += "current: ";
for (int i = 0; i < inst.trans_fire_time.Length;
i++) {
if (i != trans.id) continue;
//ss3 += " i=" + i;
double d = inst.trans_fire_time[i];
if (d >= 0) {
ss3 += " fire_time=" + d;
if (!ss_trans_color.Equals("green")) {
ss_trans_color = "yellow";
}
}
}
}
ss3 = ""; // не нравится это время на картинке
string ss4 = "";
if (st.name != "") {
//ss4 = st.name;
}
string ss_constr = "";
foreach (Constraint constr in trans.list_constr) {
ss_constr += (ss_constr == "") ? "" : ",";
ss_constr += constr.title(true);
}
foreach (Register r in trans.list_reset) {
ss_constr += (ss_constr == "") ? "" : ",";
ss_constr += "reset("+r.name+")";
}
/*
log("ss2=" + ss2);
if (ss2 == "") {
log("ss2==\"\"");
} else {
log("ss2!=\"\"");
}
*/
wd("[color=" + ss_trans_color);
if (ss_get != "" || ss_put != "" || ss3 != "" || ss4
!= ""
|| ss_constr != ""
201
) {
string ss = "";
ss += " ,label=<<TABLE border=\"0\"
cellborder=\"0\"> <TR><TD>";
if (ss4 != "") {
ss += ss4 + "<br/>";
}
if (ss_get != "") {
ss += ss_get + "<br/>";
}
if (ss_put != "") {
ss += ss_put+"<br/>";
}
if (ss_constr != "") {
ss += ss_constr+"<br/>";
}
if (ss3 != "") {
ss += ss3 + "<br/>";
}
ss += " </TD></TR></TABLE>>";
wd(ss);
}
wd("]");
}
}
wd("}");
}
wd("}");
frm_viz.draw_graph();
}
public void show_system_net(FormVisual i_frm_viz) {
frm_viz = i_frm_viz;
wd("digraph G {");
foreach(Place p in m.p_list) {
wd("subgraph cluster_" + p.name+" { style=filled;
color=lightgrey;");
//
wd("node [style=filled,color=white];")
wd("node [style=filled];");
wd("label=" + p.name);
wd("
"+p.name +";");
Hashtable t = new Hashtable();
foreach(Instance inst in p.list_inst) {
string s_key = p.name+"_"+inst.con.name;
if(inst.current_state != null){
s_key += "_" + inst.current_state.name;
}
if(t.Contains(s_key)){
StrKey sk = (StrKey)t[s_key];
sk.count += 1;
t[s_key] = sk;
}else{
StrKey sk = new StrKey();
202
sk.inst = inst;
sk.state = inst.current_state;
sk.count = 1;
t.Add(s_key, sk);
}
}
//
wd(" " + p.name + "_x [label=\"");
string[] colors = {"red","orange","yellow","green",
"LightBlue","Blue"
,"Violet", "Aquamarine", "Brown",
"Black","Aqua","Bisque"
,"Coral","BurlyWood"
};
foreach(string ss in t.Keys) {
StrKey sk = (StrKey)t[ss];
string color = "white";
if(sk.inst.con.type.id < colors.Count()) {
color = colors[sk.inst.con.type.id];
}
wd(" "+ss+" [label = \""+sk.inst.con.name
+(sk.state == null?"":":"+sk.state.name)
+(sk.count == 1?"":" ["+sk.count+"]") +"\" "
+" shape=box style=\"filled,rounded\""
+" color=\""+color+"\""
+" ]");
//
wd(" " + ss +":"+i+"");
}
//
wd("\"];");
wd("}");
foreach(Arc a in p.list_in) {
wd(a.p.name + "->" + a.p0.name + "[label=\""
+ a.port.name+ "\",color=\"#0000ff\"];");
}
foreach(Arc a in p.list_out) {
wd(a.p0.name + "->" + a.p.name + "[label=\"" +
a.port.name + "\"];");
}
}
wd("}");
frm_viz.draw_graph();
}
}
}
203
Приложение 29 Model_exec.cs
using
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Collections;
namespace Automata {
partial class Model {
static MultyLanguage ml = MultyLanguage.get_MultyLanguage();
List<Double> points_list = new List<Double>();
Hashtable points_hash = new Hashtable();
Double t_current = 0.0; // текущее время
//double next_t_current = 0.0; // время следующего шага
List<int> n_trace_list = new List<int>();
public Hashtable trace_hash = new Hashtable();
int n_trace = 0; //текущий шаг
//
public void reset_model(){
t_current = 0.0;
next_t_current = 0.0;
points_list = new List<Double>();
points_hash = new Hashtable();
n_trace = 0;
n_trace_list = new List<int>();
trace_hash = new Hashtable();
}
public Double get_t_current() {
return t_current;
}
public string get_step_info() {
string ss = "time=" + t_current + " n="+n_trace;
switch (Exec_Mode) {
case Model.Exec_Mode_Consume:
ss += ml["consume"]/*" потребление"*/;
break;
case Exec_Mode_Produce:
ss += ml["production"]/*" производство"*/;
break;
case Exec_Mode_Stop:
ss += ml["end"]/*" конец"*/;
break;
}
if (do_pause) {
ss += ml["Pause"]/*". Пауза: "*/ + pause_reason;
do_pause = false;
}
return ss;
204
}
/*
void execmain_proc2() {
List<Step> steps = get_steps_on_point(t_current);
foreach(Step step in steps) {
exec_finish(step);
}
remove_point(t_current);
do {
get_candidates();
if(Candidates.Count < 1) break;
int n_step = make_choice();
exec_start(n_step);
} while(true);
}
*/
Point find_add_point(double i_time) {
Point p = null;
if(points_hash.Contains(i_time)) {
p = (Point)points_hash[i_time];
} else {
p = new Point(i_time);
points_hash.Add(i_time, p);
points_list.Add(i_time);
}
return p;
}
void add_fire_to_point(double i_fire_time) {
Point p = find_add_point(i_fire_time);
p.fire_count++;
}
void add_step_to_point(Step i_step){
Double time = i_step.finish_time;
Point p = find_add_point(time);
/*
Point p = null;
if(points_hash.Contains(time)) {
p = (Point) points_hash[time];
} else {
p = new Point(time);
points_hash.Add(time, p);
points_list.Add(time);
}
*/
p.steps.Add(i_step);
}
void clear_fire_point(double i_time) {
Point p = (Point)points_hash[i_time];
log("clear_fire_point time=" + i_time + " point=" + p);
if(p == null) return;
p.fire_count--;
if(p.fire_count <= 0 && p.steps.Count == 0) {
remove_time_point(i_time);
205
}
}
//
void remove_time_point(double i_time) {
Point p = (Point) points_hash[i_time];
points_list.Remove(i_time);
points_hash.Remove(i_time);
}
List<Step> get_steps_on_point(double i_time) {
if(points_hash.Contains(i_time)) {
Point p = (Point)points_hash[i_time];
return p.steps;
}
return null;
}
void trace(Instance inst, Step step) {
if(inst.n_last_trace != -1) {
Trace old_t = (Trace)trace_hash[inst.n_last_trace];
old_t.time_finish = t_current;
old_t.n_finish = n_trace;
}
if(inst.flag == Instance.flag_consumed) return;
if(inst.current_state == null && inst.current_step == null)
return;
Trace new_t = new Trace();
new_t.con = inst.con;
new_t.place = inst.place;
new_t.step = step;
new_t.state = inst.current_state;
new_t.trans = (inst.current_step == null? null :
inst.current_step.trans);
new_t.n_start = n_trace;
new_t.time_start = t_current;
new_t.time_finish = -1;
inst.n_last_trace = n_trace;
trace_hash.Add(n_trace, new_t);
n_trace_list.Add(n_trace);
n_trace++;
log_t(new_t.show());
check_marking();
check_bounds();
}
void exec_start(int n_step) {
// потребление
Step step = Candidates[n_step];
foreach(Bind b in step.Binds.Values) {
log("delete con=" + b.inst.con.name + " place=" +
b.inst.place.name);
b.inst.flag = Instance.flag_consumed;
trace(b.inst, null);
if(b.term.cv == Term.c) { // если константа
delete_inst(b.inst);
} else if(b.term.cv == Term.v) { // если переменная
// инстанс теряет состояние и становится занят
206
b.inst.flag = Instance.flag_busy;
/* может можно сохранить состояние, чтобы его не обязательно было
указывать
* при производстве ??
b.inst.current_state = null;
*/
// удаляем инстанс со старого места
Place place = b.inst.place;
place.list_inst.Remove(b.inst);
b.inst.place = null;
}
}
step.start_time = t_current;
double step_duration = step.trans.get_duration_time();
step.finish_time = t_current + step_duration;
//
if (1 ==2 && step_duration == 0.0) { // никогда! т.е.
завершение на этапе производства
// дезактивировать объект, обнулить состояние, установить
переход
// Это нужно в обоих случаях, чтобы работала trace
step.inst.current_state = null;
//step.inst.current_trans = step.trans;
step.inst.current_step = step;
step.inst.flag = Instance.flag_busy;
trace(step.inst,step);
if (step_duration == 0.0) {
// если нулевая длительность, то сразу производство
exec_finish(step);
} else {
//
step.inst.reset_enable_time();
// нет смысла - у inst нет состояния, когда появится тогда reset
// создать закладку на проиводство в будущем
add_step_to_point(step);
}
}
void exec_finish(Step step) {
// производство
foreach(Outcome outcome in step.Outcomes) {
log("create con=" + outcome.term.res.name + " port=" +
outcome.term.port.name
+ " place=" + outcome.arc.p.name
);
Instance new_inst = null;
if(outcome.term.cv == Term.c) {
place(outcome.arc.p.name);
if(outcome.term.state != null) {
new_inst = inst(outcome.term.res.name,
outcome.term.state.name);
} else {
new_inst = inst(outcome.term.res.name);
}
} else if(outcome.term.cv == Term.v) {
207
new_inst =
(Instance)step.Vars_in[outcome.term.res.name];
new_inst.place = outcome.arc.p;
new_inst.flag = Instance.flag_free;
if(outcome.term.state != null) {
new_inst.current_state = outcome.term.state;
}
new_inst.place.list_inst.Add(new_inst);
new_inst.reset_transitions(); // обнулить счетчики
ожидания у новых
/* пусть счетчики остаются ???
inst.start_timers(t_current); // запустить таймеры
*/
}
trace(new_inst, null);
}
// установить новое состояние (активировать)
step.inst.current_state = step.trans.state_to; // новое
состояние установилось
step.inst.current_step = null; // переход завершился
step.inst.flag = Instance.flag_free;
step.inst.reset_transitions(); // обнулить счетчика
ожидания у активного
step.inst.reset_timers(step.trans,t_current); // сбросить
таймеры (если на переходе есть сбросы)
trace(step.inst,step);
log(step.inst.con.name + " place=" + step.inst.place.name
+ " ==> " + step.inst.current_state.name);
}
public void exec_step() {
exec_step(get_champ_index());
log_t(".");
log_t(".");
for (int i = 0; i < m.trace_hash.Count; i++) {
Trace t = (Trace)m.trace_hash[i];
string ss = t.show();
log_t(ss);
}
}
public void exec_step(int n_step) {
if(Exec_Mode == Model.Exec_Mode_Consume) {
log("Execute consume step " + Candidates[n_step].title);
exec_start(n_step);
} else if(Exec_Mode == Model.Exec_Mode_Produce) {
//t_current = next_t_current;
Point p = (Point)points_hash[t_current];
Step step = p.steps[n_step];
log("Execute produce step " + step.title);
exec_finish(step);
p.steps.Remove(step);
}
208
}
void delete_inst(Instance i_inst) {
inst_list.Remove(i_inst);
i_inst.place.list_inst.Remove(i_inst);
}
}
}
209
Приложение 30 Model_init.cs
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
namespace Automata {
partial class Model {
public static Model init() {
Model m = new Model("wandering philosophers");
try {
m.place("chair1");
m.place("chair2");
m.place("chair3");
m.place("chair4");
m.place("napkin23");
m.place("napkin34");
m.place("napkin12");
m.place("napkin41");
m.place("dish");
m.place("park");
m.arc_in("chair1", "napkin41", "getr");
m.arc_in("chair1", "napkin12", "getl");
m.arc_out("chair1", "napkin41", "putr");
m.arc_out("chair1", "napkin12", "putl");
m.arc_out("chair1", "park", "ToPark");
m.arc_in("chair1", "chair1", "Leave");
m.arc_out("chair1", "chair1", "put");
m.arc_in("chair2", "napkin12", "getr");
m.arc_in("chair2", "napkin23", "getl");
m.arc_out("chair2", "napkin12", "putr");
m.arc_out("chair2", "napkin23", "putl");
m.arc_out("chair2", "park", "ToPark");
m.arc_in("chair2", "chair2", "Leave");
m.arc_out("chair2", "chair2", "put");
m.arc_in("chair3", "napkin23", "getr");
m.arc_in("chair3", "napkin34", "getl");
m.arc_out("chair3", "napkin23", "putr");
m.arc_out("chair3", "napkin34", "putl");
m.arc_out("chair3", "park", "ToPark");
m.arc_in("chair3", "chair3", "Leave");
m.arc_out("chair3", "chair3", "put");
m.arc_in("chair4", "napkin34", "getr");
m.arc_in("chair4", "napkin41", "getl");
m.arc_out("chair4", "napkin34", "putr");
m.arc_out("chair4", "napkin41", "putl");
m.arc_out("chair4", "park", "ToPark");
m.arc_in("chair4", "chair4", "Leave");
210
m.arc_out("chair4", "chair4", "put");
m.arc_in("chair1",
m.arc_in("chair2",
m.arc_in("chair3",
m.arc_in("chair4",
"dish",
"dish",
"dish",
"dish",
"eat");
"eat");
"eat");
"eat");
m.arc_in("park", "park", "Leave");
m.arc_in("park", "chair1", "get1");
m.arc_in("park", "chair2", "get2");
m.arc_in("park", "chair3", "get3");
m.arc_in("park", "chair4", "get4");
m.arc_out("park", "chair1", "ToChair1");
m.arc_out("park", "chair2", "ToChair2");
m.arc_out("park", "chair3", "ToChair3");
m.arc_out("park", "chair4", "ToChair4");
m.type("fork");
m.dconst("f");
m.port("putr"); m.port("putl"); m.port("getr");
m.port("getl");
m.type("spag");
m.dconst("s");
m.port("eat");
m.type("free");
m.dconst("free");
m.port("put"); m.port("get1"); m.port("get2");
m.port("get3"); m.port("get4");
m.type("philosopher");
m.state("thinking"); // начальное состояние
m.port("Leave"); m.port("ToChair1"); m.port("ToChair2");
m.port("ToChair3"); m.port("ToChair4"); m.port("ToPark");
m.dconst("p1"); m.dconst("p2"); m.dconst("p3");
m.dconst("p4");
m.dvar("ph");
m.state_chart_name("LFolk_before_eating", "1folk");
m.state_chart_name("RFolk_before_eating", "1folk");
m.state_chart_name("RFolk_after_eating", "1folk");
m.state_chart_name("LFolk_after_eating", "1folk");
m.trans("eating", "eating", "do_eating");
m.trans_chart_name("eating");
m.priority("60"); m.duration("10");
m.term_in("eat", "s");
m.trans("eating", "LFolk_after_eating", "L_A");
m.trans_chart_name("put_folk");
m.priority("20"); m.duration("1");
211
m.term_out("putr", "f");
m.trans("eating", "RFolk_after_eating", "R_A");
m.trans_chart_name("put_folk");
m.priority("20"); m.duration("1");
m.term_out("putl", "f");
m.trans("thinking", "LFolk_before_eating", "L_B");
m.trans_chart_name("get_folk");
m.duration("2");
m.term_in("getl", "f");
m.trans("thinking", "RFolk_before_eating", "R_B");
m.trans_chart_name("get_folk");
m.duration("2");
m.term_in("getr", "f");
m.trans("thinking", "thinking", "do_thinking");
m.trans_chart_name("thinking");
m.duration("5");
m.trans("thinking", "thinking", "to_park");
m.trans_chart_name("walking");
m.duration("2");
m.term_in("Leave","ph","thinking");
m.term_out("put","free");
m.term_out("ToPark","ph","thinking");
m.trans("thinking", "thinking", "to_chair1");
m.trans_chart_name("walking");
m.duration("4");
m.term_in("get1","free");
m.term_in("Leave", "ph","thinking");
m.term_out("ToChair1", "ph", "thinking");
m.trans("thinking", "thinking", "to_chair2");
m.trans_chart_name("walking");
m.duration("4");
m.term_in("get2", "free");
m.term_in("Leave", "ph", "thinking");
m.term_out("ToChair2", "ph", "thinking");
m.trans("thinking", "thinking", "to_chair3");
m.trans_chart_name("walking");
m.duration("4");
m.term_in("get3", "free");
m.term_in("Leave", "ph", "thinking");
m.term_out("ToChair3", "ph", "thinking");
m.trans("thinking", "thinking", "to_chair4");
m.trans_chart_name("walking");
m.duration("4");
m.term_in("get4", "free");
m.term_in("Leave", "ph", "thinking");
m.term_out("ToChair4", "ph", "thinking");
212
m.trans("LFolk_before_eating","eating", "lets_eat1");
m.trans_chart_name("get_folk");
m.duration("1"); m.priority("80");
m.term_in("getr", "f");
m.trans("LFolk_before_eating", "thinking",
"lets_think2"); m.trans_chart_name("put_folk");
m.duration("1"); m.priority("20");
m.term_out("putl", "f");
m.trans("RFolk_before_eating", "eating", "lets_eat1");
m.trans_chart_name("get_folk");
m.duration("1"); m.priority("80");
m.term_in("getl", "f");
m.trans("RFolk_before_eating", "thinking",
"lets_think2"); m.trans_chart_name("put_folk");
m.duration("1"); m.priority("20");
m.term_out("putr", "f");
m.trans("LFolk_after_eating", "eating", "lets_eat2");
m.trans_chart_name("get_folk");
m.duration("2"); m.priority("20");
m.term_in("getr", "f");
m.trans("LFolk_after_eating", "thinking", "lets_think1");
m.trans_chart_name("put_folk");
m.duration("2"); m.priority("80");
m.term_out("putl", "f");
m.trans("RFolk_after_eating", "eating", "lets_eat2");
m.trans_chart_name("get_folk");
m.duration("3"); m.priority("20");
m.term_in("getl", "f");
m.trans("RFolk_after_eating", "thinking", "lets_think1");
m.trans_chart_name("put_folk");
m.duration("1"); m.priority("80");
m.term_out("putr", "f");
m.place("chair1");
m.place("chair2");
m.place("chair3");
m.place("chair4");
m.inst("p1",
m.inst("p2",
m.inst("p3",
m.inst("p4",
m.place("napkin12");
m.place("napkin23");
m.place("napkin34");
m.place("napkin41");
"thinking");
"thinking");
"thinking");
"thinking");
m.inst("f");
m.inst("f");
m.inst("f");
m.inst("f");
m.place("dish");
m.inst("s"); m.inst("s"); m.inst("s"); m.inst("s");
m.inst("s");
m.inst("s"); m.inst("s"); m.inst("s"); m.inst("s");
m.inst("s");
213
m.inst("s"); m.inst("s"); m.inst("s"); m.inst("s");
m.inst("s");
m.inst("s"); m.inst("s"); m.inst("s"); m.inst("s");
m.inst("s");
} catch (Exception e) {
error("ошибка: " + e.Message);
}
return m;
}
}
}
/*
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
namespace Automata {
partial class Model {
public static Model init() {
Model m = new Model("Dinning philosophers");
try {
m.place("chair1");
m.place("chair2");
m.place("chair3");
m.place("chair4");
m.arc_in("chair3", "napkin23", "getr");
m.arc_out("chair3", "napkin23", "putr");
m.arc_in("chair3", "napkin34", "getl");
m.arc_out("chair3", "napkin34", "putl");
m.type("fork");
m.dconst("f");
m.port("putr"); m.port("putl"); m.port("getr");
m.port("getl");
m.type("spag");
m.dconst("s");
m.port("eat");
m.type("philosopher");
m.dconst("p1"); m.dconst("p2"); m.dconst("p3");
m.dconst("p4");
m.state("thinking"); // начальное состояние
m.trans("eating", "eating");
m.term_in("eat", "s");
// m.term_in("get","H2"); m.term_in("get","H2");
m.term_in("get","O2");
214
// m.term_out("put","H2O");
m.term_out("put","H2O");
m.trans("eating", "LFork");
m.priority("20"); m.duration("10", "12");
m.term_out("putr", "f");
m.trans("eating", "RFork");
m.term_out("putl", "f");
m.trans("thinking", "LFork");
m.term_in("getl", "f");
m.trans("thinking", "RFork");
m.term_in("getr", "f");
m.trans("LFork", "eating");
m.term_in("getr", "f");
m.trans("LFork", "thinking");
m.term_out("putl", "f");
m.trans("RFork", "eating");
m.term_in("getl", "f");
m.trans("RFork", "thinking");
m.term_out("putr", "f");
m.place("dish");
m.inst("s"); m.inst("s"); m.inst("s"); m.inst("s");
m.inst("s"); m.inst("s"); m.inst("s"); m.inst("s");
m.inst("s"); m.inst("s"); m.inst("s"); m.inst("s");
m.place("napkin12"); m.inst("f");
m.place("napkin23"); m.inst("f");
m.place("napkin34"); m.inst("f");
m.place("napkin41"); m.inst("f");
m.place("chair1"); m.inst("p1");
m.place("chair2"); m.inst("p2");
m.place("chair3"); m.inst("p3");
m.place("chair4"); m.inst("p4");
} catch (Exception e) {
error("ошибка: " + e.Message);
}
return m;
}
}
}
*/
215
Приложение 31 Model_log.cs
using
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Collections;
namespace Automata {
partial class Model {
public
static
public
public
static
double
static
static
int page_length = 900;
max_time;
int title_length = 50;
int gap = 30;
public bool log_total() {
if(t_current <= 0) {
log(ml["show_of_rezults"]/*"Показ итогов невозможен:
t_current="*/ + t_current + ml["time_doesn't move"]/*" - время не
продвинулось."*/);
return false;
}
log(ml["=REZULTS="]/*"==================== ИТОГИ
============="*/);
max_time = t_current;
StringBuilder sb;
sb = new StringBuilder(new string(' ', page_length));
for(int i = 0; i < page_length - gap; i += gap) {
double time_i = max_time / page_length * i;
sb.Insert(i, String.Format("|<-{0:f}сек.", time_i));
}
string fin = string.Format("max {0:f}сек.->|",max_time);
sb.Insert(page_length - fin.Length, fin);
string line_x = sb.ToString().Substring(0,page_length);
foreach (Const con in Constants.Values) {
if(con.type.list_states.Count <= 0) {
continue; // если у типа нет состояний, то нечего
показывать
}
log("..");
int n = 0;
double time = 0;
sb = new StringBuilder(new string(' ',title_length));
sb.Insert(2, "============= Const " + con.name+"
=============");
string title = sb.ToString().Substring(0, title_length);
string ss = title + line_x;
//log("ss.length=" + ss.Length);
log(ss);
foreach (State state in con.type.list_states) {
sb = new StringBuilder(new String(' ', page_length));
int st_n = 0;
double st_time = 0;
216
//
foreach (int n_trace in n_trace_list) {
Trace trace = (Trace) trace_hash[n_trace];
foreach (Trace trace in trace_hash.Values) {
if (trace.con == con && trace.state == state) {
st_n++;
double time_finish = trace.time_finish;
if(time_finish == -1) time_finish = t_current;
if (time_finish > 0) {
st_time += time_finish - trace.time_start;
}
double d = page_length * trace.time_start/max_time;
int beg = (int)d;
d = page_length * (time_finish - trace.time_start)
/ max_time;
int len = (int) d;
sb.Insert(beg, new string(state.symbol, len));
}
}
string time_line =
sb.ToString().Substring(0,page_length);
sb = new StringBuilder(new string(' ', title_length));
sb.Insert(0, "" + state.name + " (" + st_n + "; " +
st_time+"сек.)");
title = sb.ToString().Substring(0, title_length);
log(title + time_line);
n += st_n;
time += st_time;
//
}
foreach (Transition trans in con.type.list_trans) {
sb = new StringBuilder(new String(' ', page_length));
int tr_n = 0;
double tr_time = 0;
foreach (int n_trace in n_trace_list) {
Trace trace = (Trace) trace_hash[n_trace];
foreach (Trace trace in trace_hash.Values) {
if (trace.con == con && trace.trans == trans) {
tr_n++;
double time_finish = trace.time_finish;
if(time_finish == -1) time_finish = t_current;
if(time_finish > 0) {
tr_time += time_finish - trace.time_start;
}
double d = page_length * trace.time_start /
max_time;
int beg = (int)d;
d = page_length * (time_finish - trace.time_start)
/ max_time;
int len = (int)d;
/*
log("n_start=" + trace.n_start + " time_start=" +
trace.time_start
+ " time_fnish=" + time_finish);
log("beg=" + beg + " len=" + len);
*/
217
sb.Insert(beg, new string(trans.symbol, len));
//
sb = new
StringBuilder(sb.ToString().Substring(0,page_length));
}
}
string time_line = sb.ToString().Substring(0,
page_length);
sb = new StringBuilder(new string(' ', title_length));
sb.Insert(0, "" + trans.name + " (" + tr_n + "; " +
tr_time+"сек.)");
title = sb.ToString().Substring(0, title_length);
log(title + time_line);
/*
log("..trans: " + trans.state_from.name + " -> "
+ trans.state_to.name + " n=" + tr_n + " time=" +
tr_time);
*/
n += tr_n;
time += tr_time;
con.name+":
}
log(ml["total_po_const"]/*"Итого по const "*/ +
n="+n+", time="+time+ml["sec"]/*"сек."*/);
}
return true;
}
public void log_trace() {
log_t(".");
log_t(".");
for (int i = 0; i < trace_hash.Count; i++) {
Trace t = (Trace)trace_hash[i];
string ss = t.show();
log_t(ss);
}
}
public void show_rezult(){
rez(ml["performance_time"]/*"Время выполнения "*/ +
t_current + ml["number_of_steps"]/*", число шагов "*/+n_trace);
//Достижимость
if (test_marking) {
rez("");
rez(ml["r_reachability"]/*"Достижимость:"*/);
foreach (Object obj in markings.Values) {
Marking mark = (Marking)obj;
rez(ml[" Marking "]/*" Разметка "*/ + mark.name
+ ml["reached"]/*" достигнута "*/ + mark.count +
ml["times"]/*" раз"*/);
}
}
//Ограниченность
if(test_bounds) {
rez("");
218
rez(ml["Boundedness:"]/*"Ограниченность:"*/);
foreach(Bound bound in bound_list) {
rez(ml["bound"]/*" Ограничение "*/ + bound.name + ":
\t"
+ (bound.max_value <= bound.limit ? ml["yes"]/*"да"*/
: ml["no"]/*"нет"*/ )
+ " ("+bound.max_value+")"
);
}
}
//Наличие тупиковых ситуаций
if(true /* test_lock*/ ) {
rez("");
rez(ml["presence_od_deadlocks"]/*"Наличие тупиковых
ситуаций: "*/
+ (m.Exec_Mode == Exec_Mode_Stop ? ml["yes"]/*"да"*/ :
ml["no"]/*"нет"*/)
);
}
//Считаем переходы
List<Transition> list_trans = new List<Transition>();
int n_trans = 0;
foreach (Type typ in t_list) {
foreach (Transition trans in typ.list_trans) {
list_trans.Add(trans);
n_trans++;
}
}
int[] trans_count_arr = new int[n_trans];
//Считаем дуги
int n_arc=0;
List<Arc> list_arc = new List<Arc>();
foreach(Place p in p_list){
foreach(Arc a in p.list_in){
n_arc++;
list_arc.Add(a);
}
foreach(Arc a in p.list_out){
n_arc++;
list_arc.Add(a);
}
}
int[] arc_count_arr = new int[n_arc];
// Статистика по агентам, берется из трассировки trace_hash
Hashtable agents = new Hashtable();
AgentTotal agent_total = null;
foreach (int n in n_trace_list) {
Trace trace = (Trace)trace_hash[n];
Const con = trace.con;
double step_time = (trace.time_finish == -1.0 ? t_current
: trace.time_finish)
- trace.time_start;
if (agents.Contains(con)) {
219
agent_total = (AgentTotal) agents[con];
} else {
agent_total = new AgentTotal();
agent_total.con = con;
agent_total.state_count_posible =
con.type.list_states.Count;
agent_total.trans_count_posible =
con.type.list_trans.Count;
foreach (State state in con.type.list_states) {
AgentStateTotal astot = new AgentStateTotal();
astot.state = state;
agent_total.states.Add(state, astot);
}
foreach (Transition trans in con.type.list_trans) {
AgentTransTotal attot = new AgentTransTotal();
attot.trans = trans;
agent_total.transes.Add(trans, attot);
}
agents.Add(con, agent_total);
}
if (trace.trans != null) {
int i_trans = list_trans.IndexOf(trace.trans);
trans_count_arr[i_trans]++;
if (trace.step != null) {
int i_arc;
foreach (Object obj in trace.step.Binds.Values) {
try {
Bind b = (Bind)obj;
i_arc = list_arc.IndexOf(b.arc);
arc_count_arr[i_arc]++;
} catch (Exception e) {
log("rezult arc count from Bind, e = " + e);
log("obj=" + obj);
}
}
foreach (Outcome outcome in trace.step.Outcomes) {
i_arc = list_arc.IndexOf(outcome.arc);
arc_count_arr[i_arc]++;
}
}
agent_total.unstate_count++;
agent_total.unstate_total_time += step_time;
AgentTransTotal trans_tot = null;
if (agent_total.transes.Contains(trace.trans)) {
trans_tot =
(AgentTransTotal)agent_total.transes[trace.trans];
} else {
trans_tot = new AgentTransTotal();
trans_tot.trans = trace.trans;
agent_total.transes.Add(trace.trans, trans_tot);
}
trans_tot.count++;
trans_tot.total_time += step_time;
} else if(trace.state != null){
AgentStateTotal state_tot = null;
if(agent_total.states.Contains(trace.state)){
220
state_tot = (AgentStateTotal)
agent_total.states[trace.state];
}else{
state_tot = new AgentStateTotal();
state_tot.state = trace.state;
agent_total.states.Add(trace.state, state_tot);
}
state_tot.count++;
state_tot.total_time += step_time;
}
}
bool liveness_trans = true;
bool liveness_arc = true;
foreach (int c in trans_count_arr) {
if (c == 0) liveness_trans = false;
}
foreach (int c in arc_count_arr) {
if (c == 0) liveness_arc = false;
}
rez("");
rez(ml["Liveness"]/*"Живость: "*/ + (liveness_trans ?
ml["yes"]/*"да"*/ : ml["no"]/*"нет"*/));
for (int i = 0; i < list_trans.Count; i++) {
Transition trans = list_trans[i];
rez(ml[" Transition:"]/*" Переход:
"*/+trans.state_from.type.name + "/" + trans.state_from.name
+":" + trans.name
+" \t\t"+trans_count_arr[i] + "
"
+ (trans_count_arr[i] == 0 ? "(!!!)" : "")
);
}
rez("");
rez(ml["liveness_by_system_net_transition"]/*"Живость по
переходам системной сети: "*/ + (liveness_arc ? ml["yes"]/*"да"*/ :
ml["no"]/*"нет"*/));
for (int i = 0; i < list_arc.Count; i++) {
Arc arc = list_arc[i];
string dir = (arc.in_out == Arc.IN ? "<-" : "->");
rez(ml["Arc"]/*" Дуга: "*/ + arc.p0.name + dir +
arc.port.name + dir + arc.p.name
+ ": \t\t" + arc_count_arr[i] + "
"
+ (arc_count_arr[i] == 0 ? "(!!!)" : "")
);
}
// Статистика по агентам
foreach (Object obj in agents.Values) {
AgentTotal atot = (AgentTotal) obj;
foreach(Object obj2 in atot.states.Values){
AgentStateTotal astot = (AgentStateTotal)obj2;
if(astot.count > 0) atot.state_count_total++;
}
foreach (Object obj2 in atot.transes.Values) {
AgentTransTotal attot = (AgentTransTotal)obj2;
221
if(attot.count > 0) atot.trans_count_total++;
}
rez("");
rez(ml["Agent"]/*"Агент "*/ + atot.con.name);
rez(ml["number_of_states"]/*"===Количество состояний "*/
+ atot.state_count_total
+ " / " + atot.state_count_posible);
foreach (Object obj2 in atot.states.Values) {
AgentStateTotal astot = (AgentStateTotal)obj2;
rez(ml["cond"]/*"
Состояние "*/ + astot.state.name
+ ml["time_total"]/*": время общее "*/ +
astot.total_time
+ml["average"]/*", среднее "*/ + astot.total_time /
astot.count + ml["number"]/*", кол-во "*/ +astot.count
+ (astot.count == 0 ? " (!!!)" : "")
);
}
rez(ml["number_of_transitions"]/*"===Количество переходов
"*/ + atot.trans_count_total
+ " / " + atot.trans_count_posible);
foreach (Object obj2 in atot.transes.Values) {
AgentTransTotal attot = (AgentTransTotal)obj2;
rez(ml["Transition"]/*"
Переход "*/ +
attot.trans.name
+ ml["time_total"]/*": время общее "*/ +
attot.total_time
+ ml["average"]/*", среднее "*/ + attot.total_time /
attot.count + ml["number"]/*", кол-во "*/ + attot.count
+ (attot.count == 0 ? " (!!!)" : "")
);
}
/*
rez("
Время в переходах: общее " +
atot.unstate_total_time
+ ", среднее " + atot.unstate_total_time /
atot.unstate_count
+ ", кол-во " + atot.unstate_count
);
*/
}
}
string dump;
void d(string ss){
dump += ss+"\r\n";
}
public string get_dump() {
dump = "";
d("t_current=" + t_current + " n_trace=" + n_trace);
string ss = "";
points_list.Sort();
foreach (double t in points_list) {
string s = "";
if(points_hash.Contains(t)) {
222
Point p = (Point)points_hash[t];
if(p.steps.Count > 0) {
s = "hash.steps.count=" + p.steps.Count;
}
}
ss += "(" + t +s+ ")";
}
d(ss);
foreach (Instance inst in inst_list) {
if(inst.current_state != null){
int len=inst.trans_fire_time.Length;
int trans_count = inst.con.type.list_trans.Count;
d(inst.con.name+":"+inst.current_state.name + "
arr_len=" + len+" trans_count="+trans_count);
foreach(Transition trans in
inst.current_state.list_trans) {
d("
" + trans.name + " time="
+ (trans.id>=len? "???" :
""+inst.trans_fire_time[trans.id])
);
}
}
if(inst.current_step != null) {
Step step = inst.current_step;
d(inst.con.name + "->" + step.trans.name+ " start=" +
step.start_time
+ " finish="+step.finish_time
);
}
}
return dump;
}
}
}
223
Приложение 32 Model_marking.cs
using
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Collections;
namespace Automata {
partial class Model {
bool
bool
bool
bool
test_marking = false;
test_bounds = false;
test_stop = false;
test_lock = true;
public void set_test_marking(bool i_value) {
test_marking = i_value;
}
public void set_test_stop(bool i_value) {
test_stop = i_value;
}
public void set_test_bounds(bool i_value) {
test_bounds = i_value;
}
public void set_test_lock(bool i_value) {
test_lock = i_value;
}
public void fix_marking(){
foreach (Object obj in markings.Values) {
Marking mark = (Marking)obj;
mark.hash = make_mark_hash(mark.places,null);
string ss = "marking("+mark.name+"): like="+mark.like
+" hash=";
foreach(int h_item in mark.hash){
ss += "("+h_item+")";
}
log(ss);
}
context = Context.nil;
}
int[] make_mark_hash(Hashtable places, Hashtable
like_places){
List<int> hash = new List<int>();
Hashtable sample = places;
if (like_places != null) sample = like_places;
foreach (Object obj in sample.Keys) {
Place p = (Place) places[(string)obj];
log("hash p.name=" + p.name);
foreach (Instance inst in p.list_inst) {
log("hash p.name=" + p.name+" inst="+inst.con.name);
int n = p.id * 10000 + inst.con.id * 100
+ (inst.current_state == null ? 0:
inst.current_state.id+1);
224
hash.Add(n);
}
}
hash.Sort();
return hash.ToArray();
}
bool arr_eq(int[] a1, int[] a2) {
if (a1.Length != a2.Length) return false;
for (int i = 0; i < a1.Length; i++) {
if (a1[i] != a2[i]) return false;
}
return true;
}
void check_marking() {
if (!test_marking || markings.Count<1) return;
int[] total_hash = make_mark_hash(Places,null);
foreach (Object obj in markings.Values) {
Marking mark = (Marking)obj;
int[] current_hash = total_hash;
if (mark.like) {
current_hash = make_mark_hash(Places,mark.places);
}
if(arr_eq(current_hash,mark.hash)){
if ((n_trace - mark.last_eq_n_trace) > 1) {
mark.count++;
if (test_stop) {
do_pause = true;
pause_reason = "marking " + mark.name;
}
}
mark.last_eq_n_trace = n_trace;
}
}
}
void check_bounds() {
if(!test_bounds || bound_list.Count <1) return;
foreach(Bound bound in bound_list) {
bound.count = 0;
foreach(Instance inst in inst_list) {
if(
(bound.place == null || bound.place == inst.place)
&&
(bound.type == null || bound.type == inst.con.type)
) {
bound.count++;
}
}
}
foreach(Bound bound in bound_list) {
bound.max_value = Math.Max(bound.count, bound.max_value);
bound.min_value = Math.Min(bound.count, bound.min_value);
}
}
225
}
}
226
Приложение 33 MultyLanguage.cs
using
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Collections;
namespace Automata {
class Mess {
string str_rus, str_eng;
public Mess(string russian_text, string english_text){
str_rus = russian_text;
str_eng = english_text;
}
public string Str {
get {
if(MultyLanguage.current_language ==
MultyLanguage.Language.russian) {
return str_rus;
} else {
return str_eng;
}
}
}
}
class MultyLanguage {
public enum Language {russian, english};
public static Language current_language = Language.russian;
static MultyLanguage ml;
public static MultyLanguage get_MultyLanguage(){
if(ml == null){
ml = new MultyLanguage();
}
return ml;
}
static Mess m(string i_rus, string i_eng) {
return new Mess(i_rus, i_eng);
}
public Mess msg_btn_visual = m("Визуализация",
"Visualization");
public Mess msg_btn_chart = m("Временная диаграмма", "Time
chart");
public Mess msg_btn_trace = m("Трассировка", "Trace");
public Mess msg_btn_rezult = m("Результаты анализа",
"Analysis results");
public Mess cb_chart = m("Диаграмма", "Diagram");
public Mess cb_log = m("Журнал", "Log");
public Mess cb_trace = m("Только трассировка", "Trace only");
public Mess cb_marking = m("Достижимость", "Reachability");
public Mess cb_stop = m("Пауза при нахождении", "Pause when
found");
public Mess cb_Finiteness = m("Ограниченность",
"Boundedness");
227
public Mess btn_exec = m("1шаг", "1Step");
public Mess btn_Loop = m("шагов", "steps");
public Mess btn_steps = m("По шагам", "Step by step");
public Mess label1 = m("Сделать", "Make");
public Mess btn_time = m("время+", "time+");
public Mess menu_file = m("Файл", "File");
public Mess openToolStripMenuItem = m("Открыть", "Open");
public Mess загрузитьДемоМодельToolStripMenuItem = m
("Загрузить демо модель","Load demo model");
public Mess saveToolStripMenuItem = m("Сохранить", "Save");
public Mess выходToolStripMenuItem = m("Выход", "Exit");
public Mess справкаToolStripMenuItem = m("Справка", "Help");
public Mess оПрограммеToolStripMenuItem = m("О программе",
"About");
public Mess языкОписанияМоделиToolStripMenuItem = m("Язык
описания модели", "Model desciption language");
Hashtable Messages = new Hashtable();
public string this[string i_key] {
get {
if(Messages.Contains(i_key)) {
Mess mess = (Mess)Messages[i_key];
return mess.Str;
} else {
return "MultyLanguage: key " + i_key+ " not found";
}
}
}
void m(string i_key, string i_rus, string i_eng) {
Messages.Add(i_key, new Mess(i_rus, i_eng));
}
MultyLanguage() {
// m("cb_chart", "Диаграмма", "Temporary Chart");
// m("cb_log", "Журнал", "Log");
// m("cb_trace", "Только трассировка","Trace Only");
// m("cb_marking", "Достижимость", "Marking");
// m("cb_stop", "Пауза при нахождении", "Stop when found");
// m("cb_finiteness", "Ограниченность", "Finiteness");
m("chart_diagram_title","Временная диаграмма","Time
diagram");
m("q_delete_model", "Удалить текущую модель?", "Delete
current model?");
m("model_init", "Модель инициализована", "Model is
initialized");
m("error:", "ошибка: ", "error: ");
m("***Error:","***Ошибка: " ,"***Error: ");
m("no_init_model", "Модель не инициализирована ", "The
model is not initialized ");
m("executing_cycle", "Выполняется цикл ...", "Cycle
execution");
m("place", "места", "place");
m("types", "типы", "types");
m("constants", "константы", "constants");
m("variables", "переменные", "variables");
228
m("ports", "порты", "ports");
m("states", "состояния", "states");
m("transitions", "переходы", "transitions");
m("view_model", "Просмотр модели: ", "View the model: ");
m("show_rez", "Показ итогов невозможен: смотрите сообщения
в журнале.", "Impossible to view rezults. Please, see log. ");
m("model_undef", "Модель не определена!","The model is
undefined");
m("save_in_file","Сохраняем в файл ","Save in file ");
m("file_is_saved","Файл сохранен","File is saved");
m("del_cur_model","Удалить текущую модель?", "Would you
like to delete current model");
m("loading_new_model...","Загружаем новую модель...", "The
new model is being loaded...");
m("loading_new_model_from_file", "Загружаем новую модель из
файла ", "New model is being loaded from file");
m("new model", "Новая модель", "New model");
m("too_many_errors_in_input_file", "Слишком много ошибок во
входном файле", "Too many errors in input file");
m("model_is_loaded", "Модель загружена", "The model is
loaded");
m("TRDA_typed_model", "Модель типа TRDA ", "TRDA typed
model ");
m("model_is_not_loaded", "Модель не загружена", "The model
is not loaded");
m("unopened comment id closed", "Закрыт неоткрытый
комментарий", "Unopened comment is closed");
m("about_program","О программе", "About program");
m("program_implements_trda",
@"Программа реализует систему временных конечных автоматов
"
,
@"Program implements Timed Resource Driven automata nets
"
);
m("model_description_language", "Язык описания
модели","Model description language");
m("bnf",
@"Описание модели с помощью формализма
БНФ
<Описание модели> ::= model(<название модели>)
<системная сеть>
<автоматный слой>
<начальная разметка>
<системная сеть> ::=
[<определение вершины системного слоя>, … ]
[<определение дуги системного слоя>, … ]
<определение вершины системного слоя> ::= place(<название
вершины>)
<определение дуги системного слоя> ::=
<определение входящей дуги> | <определение исходящей
дуги>
<определение входящей дуги> ::=
229
arc_in(<вершина приемник>, <вершина источник>,
<название порта>)
<определение исходящей дуги> ::=
arc_out(<вершина источник>, <вершина приемник>,
<название порта>)
<автоматный слой> ::= [<определение типа>, … ]
<определение типа> ::= type(<имя типа>)
[<определение элемента типа>, … ]
[<обозначение состояния на графике>, … ]
[<определение перехода>, … ]
<определение элемента типа> ::=
<определение состояния> | <
определение порта>
| < определение константы> | < определение переменной>
<определение состояния> ::= state(<имя состояния>)
<определение переменной> ::= var(<имя переменной>)
<определение константы> ::= const(<имя константы>)
<определение порта> ::= port(<имя порта>)
<обозначение состояния на графике> ::=
state_chart_name(<имя состояния>,
графике>)
<имя состояния на
<определение перехода> ::=
trans(<имя исходного состояния>, <имя итогового
состояния> [, <название перехода>])
[<атрибут перехода>, … ]
[<определение преобразования ресурсов>, … ]
<атрибут перехода> ::= <продолжительность перехода>
| <обозначение перехода на графике>
| <вероятность перехода>
<продолжительность перехода> ::=
duration(<минимальное время перехода>[, <максимальное
время перехода>])
<вероятность перехода> ::=
priority(<приоритет перехода>)
<обозначение перехода на графике> ::=
trans_chart_name(<имя перехода на графике>)
<определение преобразования ресурсов> ::=
<определение потребления ресурсов> | <определение
производства ресурсов>
<определение потребления ресурсов> ::=
term_in(<имя порта>, <имя ресурса>[, <состояние
потребляемого ресурса>])
<определение производства ресурсов> ::=
term_out(<имя порта>, <имя ресурса>[, <состояние
производимого ресурса>])
<имя ресурса> ::= <имя константы> | <имя переменной>
<начальная разметка>
::=
place(<имя вершины>)
230
[<определение объекта>, … ]
<определение объекта> ::=
inst(<имя константы>[, <имя
состояния>])
"
,
@"Model description using BNF
<Model description> :: model (<model title>)
<system net>
<automata net>
<initial marking>
<system net> ::=
[<definition of system net node>, …]
[<definition of system net arcs>, …]
<definition of system net node> :: = place (<node name>)
<definition of system net arc> :: = <definition of incoming arc>
| <definition of outcoming arc>
<definition of incoming arc> ::=
arc_in(<receiver node>, <source node>, <port name>)
<definition of outcoming arc> ::=
arc_out (<source arc>, <receiver arc>, <port name>)
<automata net> :: [<type definition>, …]
<type definition> :: = type(<type name>)
[<definition of type element>, …]
[<definition of states on graph>, …]
[<transition definition>, …]
<definition ot type element> ::= <state definition> | <port
definition> | <constant definition> | <variable definition>
<state definiton> ::=state (<state name>)
<variable definition> ::=var(<variable name>)
<constant definition>::= const(<constant name>)
<port definition>:: = port (<port name>)
< definition of state on graph > :: =
state_chart_name (<state name>, <state name on graph>)
<transition definition>::= trans(<source state name>,
<destination state name> [,
transition name>])
[<transition attribute>,…]
[<definition of resource transformation>,…]
<transition attribute>:: = <transition duration>
| < definition of states on graph >
| <transition probability>
<estimation of transition work> ::= wait(<minimum time of
transition estimation>[, <maximum time of transition estimation>])
<transition duration>::=time (<minimum time of transition
work>[,<maximum time of transition work>])
<transition probability>::= priority(<priority of transition>)
< definition of transition on graph >:: =
trans_chart_name(<transition name on graph>)
< definition of resource transformation > = <definition of
resource consume> | <definition of resource production>
<definition of resource consume> :: = term_in (<port name>,
<resource name[,<condition of consumed resource>])
231
<definition of resource production>::=term_out(<port name>,
<resource name>[,<condition of produced resource>])
<resource name>:: = <constant name>|<variable name>
<initial marking>::=place(<node name>)
[<object definition>,…]
<object definition>::=inst(<constant name>[,<state name>])
"
);
m("consume", " потребление", " consume");
m("production"," производство", " production");
m("end", " конец"," end");
m("Pause", ". Пауза: ", ".Pause: ");
m("show_of_rezults", "Показ итогов невозможен:
t_current=","Impossible to show rezults: t_current=");
m("time_doesn't move", " - время не продвинулось.", " time does not move.");
m("=REZULTS=", "==================== ИТОГИ =============",
"================== REZULTS ===========");
m("total_po_const", "Итого по const ", "Total for const");
m("sec", "сек.", "sec.");
m("performance_time", "Время выполнения ", "Performance
time ");
m("number_of_steps", ", число шагов ", ", number of steps
");
m("r_reachability", "Достижимость:", "Reachability:");
m(" Marking "," Маркировка ", " Marking ");
m("reached", " достигнута ", " reached ");
m("Boundedness:", "Ограниченность:", "Boundedness:");
m("bound", " Ограничение ", " Bound ");
m("yes", "да", "yes");
m("no","нет","no");
m("presence_od_deadlocks", "Наличие тупиковых ситуаций: ",
"Presence of deadlocks: ");
m("Liveness", "Живость: ", "Liveness: ");
m(" Transition:", " Переход: "," Transition: ");
m("liveness_by_system_net_transition", "Живость по
переходам системной сети: ", "Liveness by system net transitions: ");
m("Arc", " Дуга: "," Arc: ");
m("Agent", "Агент ","Agent ");
m("number_of_states", "===Количество состояний ",
"===Number of states ");
m("cond", "
Состояние ", " Condition ");
m("time_total", ": время общее ",": total time ");
m("average", ", среднее ", ",average ");
m("number_of_transitions", "===Количество переходов ",
"===Number of transitions ");
m("Transition", "
Переход ", " Transition ");
m("number", ", кол-во "," number ");
m("form1_title", "Модель типа TRDA ","Model of TRDA type
");
m("title_FormRezults", "Результаты анализа", "Analysis");
m("title_FormVisual", "Визуализация модели", "Model
visualization");
m("title_SystemNet", "Системная сеть", "System Net");
m("title_AutomataNet", "Автоматная сеть", "Automata Net");
232
m("title_Form1", "Модель типа TRDA ", "Model of TRDA type "
);
m("times", " раз", " times ");
m("save","Сохранить", "Save");
}
}
}
233
Приложение 34 Program.cs
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Windows.Forms;
namespace Automata {
static class Program {
/// <summary>
/// Главная точка входа для приложения.
/// </summary>
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
234
Приложение 35 State.cs
using
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Collections;
namespace Automata {
class Arc {
public static int IN = 1;
public static int OUT = 2;
public Place p,p0;
public Port port;
public int in_out;
public Arc(Place i_place, Port i_port) {
p = i_place;
port = i_port;
}
}
class Res {
public Type type;
public string name;
}
class Const:Res {
public int id; //номер константы в модели
public Const(string i_name) {
name = i_name;
}
}
class Var:Res {
public Var(string i_name) {
name = i_name;
}
}
class Port {
public Type type;
public string name;
public Port(string i_name) {
name = i_name;
}
}
class Place {
public string name;
public bool is_expanded = true;
public int id; //номер места в модели
public List<Arc> list_in = new List<Arc>();
public List<Arc> list_out = new List<Arc>();
public List<Instance> list_inst = new List<Instance>();
public Place(string i_name) {
name = i_name;
}
235
public void set_is_expanded(bool i_is_expanded){
is_expanded = i_is_expanded;
}
}
class Type {
public int id; // номер типа в модели
public string name;
public List<Const> list_const = new List<Const>();
public List<Var> list_var = new List<Var>();
public List<Port> list_port = new List<Port>();
public List<Transition> list_trans = new List<Transition>();
public List<State> list_states = new List<State>();
public Hashtable States = new Hashtable();
public List<Register> list_regs = new List<Register>();
public Hashtable Registers = new Hashtable();
public State initial_state;
public Type(string i_name) {
name = i_name;
}
}
class Term {
public static int c = 1;
public static int v = 2;
public Port port;
public int cv;
public Res res;
public State state = null;
public Term(Port i_port, Const i_con) {
port = i_port;
res = i_con; cv = Term.c;
}
public Term(Port i_port, Var i_var) {
port = i_port;
res = i_var; cv = Term.v;
}
}
class Transition {
public static int default_priority = 100;
public static float default_duration = 0;
public static float default_wait = 0;
public char symbol = 'o';
public string name = null;
public int id; // номер перехода в данном состоянии
(внутренний id)
public string chart_name = null;
public State state_from, state_to;
public int priority = Transition.default_priority;
public Double duration_min = Transition.default_duration
, duration_max = Transition.default_duration;
public Double wait_min = Transition.default_wait
, wait_max = Transition.default_wait;
//
public double time_enable = -1.0;
public Transition(State i_state_from, State i_state_to) {
state_from = i_state_from;
236
//
state_to = i_state_to;
if(name == null) {
name = state_from.name + "->" + state_to.name;
chart_name = name;
}
time_enable = -1.0;
}
public List<Register> list_reset = new List<Register>(); //
only for registers of type rt_timer
public List<Constraint> list_constr = new List<Constraint>();
public List<Term> list_term_in = new List<Term>();
public List<Term> list_term_out = new List<Term>();
public double get_wait_time() {
return Lib.get_random_from_interval(wait_min,wait_max);
}
public double get_duration_time() {
return
Lib.get_random_from_interval(duration_min,duration_max);
}
public bool has_timed_constraints() {
if(list_constr.Count > 0 || list_reset.Count > 0) {
return true;
}
return false;
}
}
class State {
public string name;
public string chart_name;
public Type type;
public char symbol = 'o';
public int id; //номер состояния в типе
public List<Transition> list_trans = new List<Transition>();
public State(string i_name, Type i_type) {
name = i_name;
chart_name = i_name;
type = i_type;
}
}
enum RegType { rt_int, rt_timer };
class Register {
public string name;
public RegType reg_type;
public int id; // номер регистра в типе
public Register(string i_name, RegType i_reg_type) {
name = i_name;
reg_type = i_reg_type;
}
}
enum ConstraintRelation { gt, ge, lt, le, eq };
class Constraint {
237
public int a=0, b=0, c=0;
public Register r1 = null, r2 = null;
public ConstraintRelation rel=ConstraintRelation.gt;
public string title() {
return title(false);
}
public string title(bool i_esc) {
string ss = r1.name;
if(r2 != null) {
ss += (b == -1) ? "-" : "+";
ss += r2.name;
}
switch (rel){
case ConstraintRelation.lt: ss += i_esc ? "<"
"<";break;
case ConstraintRelation.le: ss += i_esc ? "≤"
"<=";break;
case ConstraintRelation.gt: ss += i_esc ? ">"
">";break;
case ConstraintRelation.ge: ss += i_esc ? "≥"
">=";break;
case ConstraintRelation.eq: ss += "=";break;
}
:
:
:
:
ss += ""+c;
return ss;
}
}
class Instance {
public static int flag_busy = 1;
public static int flag_free = 2;
public static int flag_consumed = 3;
public Const con;
public State current_state;
double saved_global_time = 0.0;
public bool is_visual = false;
public double[] registers = new double[0];
public double[] trans_fire_time = new double[0];
//
public Transition current_trans;
public Step current_step;
public int n_last_trace = -1;
public int flag = flag_free;
public Place place;
public Model model;
public void set_place(Place i_place) {
place = i_place;
place.list_inst.Add(this);
}
public Instance(Model i_model,Const i_con, State i_state) {
con = i_con;
model = i_model;
current_state = i_state;
}
public Instance(Model i_model, Const i_con) {
con = i_con;
238
model = i_model;
if(con.type.initial_state != null) {
current_state = con.type.initial_state;
}
}
public void set(State i_state) {
if(this.current_state == i_state) {
return; // nothing to do
}
//Model.write_change(this,;
}
public void discharge_transition(Transition trans) {
trans_fire_time[trans.id] = -1.0;
}
public bool charge_transition(Transition trans, double
i_fire_time) {
if(trans_fire_time[trans.id] == -1.0) {
trans_fire_time[trans.id] = i_fire_time;
return true;
} else {
return false; // already enabled
}
}
public bool is_ready_to_fire(Transition trans, double
i_current_time
, double i_fire_time) {
if(i_fire_time <= i_current_time) {
return true; // is already ready to fire!
}
if(trans_fire_time[trans.id] > i_current_time
|| trans_fire_time[trans.id] == -1.0
) {
return false; // is not yet ready to fire
}
return true; // is ready to fire!
}
private bool check_charge_transition2(Transition trans
, double i_current_time, double i_fire_time) {
/*
Form1.log("trans.id=" + trans.id
+ " trans_fire_time[id]=" + trans_fire_time[trans.id]
+ " i_current_time=" + i_current_time
+ " i_fire_time=" + i_fire_time
);
*/
if(is_ready_to_fire(trans, i_current_time, i_fire_time)) {
//
Form1.log("return true");
return true;
}
//
Form1.log("charge and return false");
charge_transition(trans, i_fire_time);
return false;
}
// Timers!
public void start_timers(double i_global_time) {
registers = new double[con.type.list_regs.Count];
for(int i = 0; i < registers.Length; i++) {
239
registers[i] = 0.0;
}
saved_global_time = i_global_time;
}
public void move_timers(double i_global_time) {
double delta_t = Math.Round(i_global_time saved_global_time,2);
foreach(Register reg in con.type.list_regs) {
if(reg.reg_type == RegType.rt_timer) {
registers[reg.id] += delta_t;
}
}
saved_global_time = i_global_time;
}
public void reset_timers(Transition trans, double
i_global_time) {
move_timers(i_global_time);
foreach(Register reg in trans.list_reset) {
registers[reg.id] = 0.0;
}
}
public double get_satisfy_time(Transition trans) {
/*
* Возвращает:
* 0 - если выполняется сейчас
* -1 - не выполнится никогда
* >0 - когда выполнится
* Должны использоваться данные из таймеров.
*
*/
double ret_value = 0.0;
double x1=0, x2=0, c0=0;
foreach(Constraint constr in trans.list_constr){
Form1.log("<c><c><c><c><c>"+constr.title());
if(constr.r1 == null) {
x1 = 0;
} else {
x1 = this.registers[constr.r1.id];
}
if(constr.r2 == null) {
x2 = 0;
} else {
x2 = this.registers[constr.r2.id];
}
c0 = constr.a * x1 + constr.b * x2;
Form1.log("get_satisfy_time: x1=" + x1 + " x2=" + x2 + "
c0=" + c0 + " c=" + constr.c);
bool constr_true = false;
switch(constr.rel) {
case ConstraintRelation.lt:
constr_true = (c0 < constr.c);
Form1.log("lt=" + constr_true);
break;
case ConstraintRelation.le:
constr_true = (c0 <= constr.c);
Form1.log("le=" + constr_true);
break;
240
case ConstraintRelation.gt:
constr_true = (c0 > constr.c);
Form1.log("gt=" + constr_true);
break;
case ConstraintRelation.ge:
constr_true = (c0 >= constr.c);
Form1.log("ge=" + constr_true);
break;
case ConstraintRelation.eq:
constr_true = (c0 == constr.c);
Form1.log("eq=" + constr_true);
break;
default:
break;
}
if(constr_true) {
Form1.log("get_satisfy_time: do_nothing");
// do_nothing
} else { // констрейнт не сейчас выполняется
if(constr.a + constr.b == 0) { // никогда не выполнится
ret_value = -1;
} else {
double t = 0.0;
t = (constr.c - constr.a * x1 - constr.b * x2) /
(constr.a + constr.b);
Form1.log("get_satisfy_time: t="+t);
if(t < 0) { // никогда не выполнится
ret_value = -1;
}else{
double round_t = Math.Round(t,2);
if(round_t < t) {
round_t += 0.01;
}
switch(constr.rel) {
case ConstraintRelation.lt:
case ConstraintRelation.gt:
if(round_t == t){
round_t += 0.01;
}
break;
default:
break;
}
Form1.log("get_satisfy_time: round_t=" + round_t);
t = round_t;
if((ret_value == 0 || ret_value > t && ret_value >
0) && t>0) {
ret_value = t;
}
}
}
}
}
return ret_value;
}
// Timers!
public void reset_transitions() {
241
trans_fire_time = new
double[current_state.list_trans.Count()];
for(int i=0; i<trans_fire_time.Length;i++){
trans_fire_time[i] = -1.0;
}
}
}
class Bind {
public Term term; // Входной term из проверяемого перехода
public Instance inst; // соответствующий "пассивный" ресурс
public Arc arc; // Входная дуга
public Bind(Term i_term, Instance i_inst, Arc i_arc) {
term = i_term;
inst = i_inst;
arc = i_arc;
}
}
class Outcome {
public Term term;
public Arc arc;
public Outcome(Term i_term, Arc i_arc){
term = i_term;
arc = i_arc;
}
}
class Step {
public Instance inst; // активный ресурс
public Transition trans; // его проверяемый переход
public string title;
public double start_time; //время старта
public double finish_time; //время завершения
//
public int start_n_trace; //номер такта
public Hashtable Binds = new Hashtable();
public Hashtable Vars_in = new Hashtable();
public Hashtable Vars_out = new Hashtable();
public List<Outcome> Outcomes = new List<Outcome>();
public Step(Instance i_inst, Transition i_trans) {
inst = i_inst;
trans = i_trans;
title = inst.place.name + ": "
+ inst.con.name + "/" + inst.current_state.name
+ " --> " + trans.name;
foreach(Constraint constr in trans.list_constr) {
title += "[" + constr.title() + "]";
}
}
}
class Applicant {
public Instance inst;
public List<Step> steps = new List<Step>();
public Applicant(Instance i_inst) {
inst = i_inst;
}
}
class Point { // TimePoint
public Double time = 0.0;
public List<Step> steps = new List<Step>();
242
public int fire_count = 0;
public Point(Double i_time) {
time = i_time;
steps = new List<Step>();
}
}
class AgentStateTotal{
public State state;
public double total_time = 0.0;
public int count = 0;
}
class AgentTransTotal {
public Transition trans;
public double total_time = 0.0;
public int count = 0;
}
class AgentTotal {
public Const con;
public int state_count_total = 0, state_count_posible = 0;
public int trans_count_total = 0, trans_count_posible = 0;
public double unstate_total_time = 0.0;
public int unstate_count = 0;
//public List<AgentStateTotal> list_states = new
List<AgentStateTotal>();
public Hashtable states = new Hashtable(); //
(AgentStateTotal.state,AgentStateTotal)
public Hashtable transes = new Hashtable(); //
(AgentTransTotal.trans,AgentTransTotal)
}
class Trace { // история изменения объектов
public Const con;
public State state;
public Place place;
public Step step;
public Transition trans;
public double time_start;
public double time_finish;
public int n_start;
public int n_finish;
public string show() {
string ss = "" + this.n_start + "\tfin=" + this.n_finish;
ss += "\ttime(" + this.time_start +" - "+
this.time_finish+")";
ss += ": \t\t"+this.con.name;
if (this.place != null){
ss += ":"+place.name;
}
if(this.state != null) {
ss += " " + this.state.name;
}
if(this.trans != null) {
ss += " " + this.trans.state_from.name+" -> "+
this.trans.state_to.name;
}
243
return ss;
}
}
class Marking {
public string name;
public int last_eq_n_trace; //номер последнего шага с
совпадением
public int count; // кол-во попаданий
public bool like = false;
public int[] hash;
public Hashtable places = new Hashtable();
//public Place current_place;
public Marking(string i_name) {
name = i_name;
}
}
class Bound {
public string name;
public Place place = null;
public Type type = null;
public int limit = 0;
public int max_value = 0;
public int min_value = 0;
public int count = 0;
public Bound(string i_name) {
name = i_name;
}
}
}
244
Download