На этом шаге мы начнем описывать созданное приложение, в частности, остановимся на представлении сети Петри в памяти компьютера.
Сети Петри можно представить в виде двудольного мультиграфа. Этим представлением мы и воспользовалась. Структура состоит из двух заголовочных списков: списка переходов и списка позиций. Каждый элемент списка позиций - это запись, содержащая семь полей:
Каждый элемент списка переходов содержит десять полей:
Необходимо еще описать типы элементов трех "дуговых" списков, заявленных в описании элементов "заголовочных" списков и два рабочих поля. Именно с помощью "дуговых" списков осуществляется связь между позициями и переходами сети Петри. Там же будет храниться информация о количестве дуг, связывающих данный переход с данной позицией или данную позицию с данным переходом.
Каждый элемент "дугового" списка переходов, "подвешенного" к какому-то элементу списка позиций, содержит три поля:
К каждому элементу "заголовочного" списка переходов "подвешено" два почти одинаковых "дуговых" списка, их структура совершенно идентична; они содержат:
Type Lref=^Leader; {указатель на заголовочный узел позиции} Mref=^Murder; {указатель на заголовочный узел перехода} Tref=^Trailer; {указатель на дуговой узел позиции} Uref=^User; {указатель на дуговой узел перехода} Leader=Record {описание типа заголовочного узла позиции} Name:integer; {номер позиции} Fish:integer; {количество фишек} Fish_after:integer; {до запуска перехода} x:integer; y:integer; Trail:Tref; {указатель на список смежности} Next:Lref; {указатель на следующий узел в списке заголовочных узлов} end; Trailer=Record {описание типа дугового узла позиции} chi:integer;{кратность (количество дуг в переход из позиции) } Id:Mref; {указатель на переход из позиции} Next:Tref; {указатель на следующий узел в списке дуговых узлов} end; Murder=Record {тип заголовочного узла перехода} Name: integer; {номер перехода} x:integer; y:integer; Priority:integer;{приоритет перехода} Delay:integer; {задержка перехода} Stoppage:integer; {рабочее поле} Permit:boolean; {разрешен ли переход к запуску} Trail: Uref;{указатель на список последующих позиций} Pred:Uref;{указатель на список предшествующих позиций} Next:Mref;{указатель на следующий узел в списке заголовочных узлов} end; User=Record {тип дугового узла перехода} chi:integer; {количество дуг в позицию из перехода} Id: Lref; {указатель на позицию, исходящую из перехода} Next: Uref;{указатель на следующий узел в списке дуговых узлов} end;
Одна часть полученной структуры подобна структуре Вирта, другая ее часть - модифицированной структуре Вирта. Заголовочные списки не связаны друг с другом. На первый и фиктивный последний элемент каждого из них указывают различные указатели. Дугами служат указатели, "висящие" в "дуговых" списках и указывающие на элемент обязательно другого "заголовочного" списка. Опишем необходимые указатели:
Var Head_l,Tail_l: Lref; { Указатель на список заголовочных } { узлов-позиций и на фиктивный элемент } { в конце списка позиций } Head_m,Tail_m: Mref; { Указатель на заголовочный список пе- } { реходов и на фиктивный элемент} { в конце списка переходов }
Для заполнения динамической структуры, моделирующей сеть Петри, созданы процедуры добавления позиции в список позиций, добавления перехода в список переходов, поиск позиции (с координатами (x,y)) в списке позиций, поиск перехода (с координатами (x,y)) в списке переходов, добавление дуги, очистка памяти от структуры Петри, и другие вспомогательные процедуры и функции.
На следующем шаге мы рассмотрим основные элементы интерфейса.