(*~\Глагол\ПриложенияLink\МПГ2008 (комп., но не раб.)\~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                                            ОТДЕЛ Данные;
(*============================================================================* 
 * НАЗНАЧЕНИЕ: 1) виды данных
 *             2) чтение и запись общедоступных понятий отдела
 *============================================================================*)

ИСПОЛЬЗУЕТ
        (*  \Глагол\              *)
 оЦепи    ИЗ "..\..\Отделы\Иное\",
  Пустой  ИЗ "..\..\Отделы\Иное\",  
ЧэргаСлеД ИЗ "..\..\Отделы\Иное\",

  Настрой,
  Ошибка,
  Обмен;

(*----------------------------------------------------------------------------*)
ПОСТ
                                                              (* рода понятий *)
  пПост-      = 0; (* постоянная *)
  пВид-       = 1; (* вид данных *)
  пПер-       = 2; (* переменая задачи или приёмник значения *)
  пСсылка-    = 3; (* приёмник ссылки *)
  пСвойство-  = 4; (* свойство набора *)
  пЗадача-    = 5; (* задача *)
  пВстрЗадача-= 6; (* встроенная задача *)
  пОтдел-     = 7; (* отдел *)

ВИД
  ДкВидуВид-     = ДОСТУП К нВидаВид;
  ДкВидуОбласть- = ДОСТУП К нВидаОбласть;
                                              (* рекурсивные структуры данных *)
  ДкВидуПонятие- = ДОСТУП К (*нВидаПонятие;
                            нВидаПонятие =*) НАБОР((*Набор.Вид*)
                                                       ЧэргаСлеД.нПустой)
        родп+:ЦЕЛ;              (* род понятий *)
         имя+:Настрой.Имя;      (* имя в области видимости *)
         обл+:ДкВидуОбласть;    (* область видимости *)
        слеД+:ДкВидуПонятие;    (* для списка понятий области видимости *)
    признаки+:МНОЖ;             (* {Общий,Вложенный,Неизменяемый,Головной} *)
         вид+:ДкВидуВид;        (* пВид       - вид
                                 * пЗадача    - вид ответа
                                 * п...       - вид понятия
                                 *)
     первпон+:ДкВидуПонятие;    (* пЗадача    - начало списка приёмников и др. понятий
                                 * пОтдел     - начало списка понятий
                                 *)
         адр+:ЦЕЛ;              (* пПер       - смещние от FP
                                 * пСсылка    - смещние от FP
                                 * пПост      - значение | (0 | смещение для цепочек)
                                 * пСвойство  - смещение от начала набора
                                 * пВстрЗадача- номер задачи
                                 * пОтдел     - порядковый номер отдела в <вхотд>
                                 *)
       цепьД+:Пустой.ДкЦепи;    (* значение цепочки знаков *)
                                               КОН;

                            нВидаВид = НАБОР((*Пустой.Вид*)
                                               ЧэргаСлеД.нПустой)
       родв+:ЦЕЛ;           (* род вида: вНеопр|вЯчейка|..|вНабор                   *)
    понвида+:ДкВидуПонятие; (* понятие, определяющее этот вид|  ПУСТО *)
     размер+:ЦЕЛ;           (* размер переменной данного вида                       *)
       номв :ЦЕЛ;           (* номер вида для выходного файла: вНеопр|..|вНабор|..  *)
       овид+:ДкВидуВид;     (* опорный вид у вДоступ, вБегунок, вРяд, вЦепь, вНабор| вид ответа у вЗадача *)
    первпон+:ДкВидуПонятие; (* начало списка свойств у вНабор|  начало списка приёмников        у вЗадача *)
     нвхотд+:ЦЕЛ;           (* у вНабор: 0 для тек. отдела|номер входного отдела (в <вхотд>) *)
        шаг+:ЦЕЛ;           (* шаг бегунка                                          *)
                                       КОН;

                            нВидаОбласть = НАБОР((*Пустой.Вид)*)
                                                   ЧэргаСлеД.нПустой)
        имя+:Настрой.Имя;   (* имя для кода *)
     окробл+:ДкВидуОбласть; (* окружающая область *)
    первпон+:ДкВидуПонятие; (* начало списка понятий *)
     видотв+:ДкВидуВид;     (* вид ответа задачи *)
                                           КОН;

  ДкВидуОтдел- = ДОСТУП К (*нВидаОтдел;
                            нВидаОтдел =*) НАБОР((*Пустой.Вид)*)
                                                   ЧэргаСлеД.нПустой)
       имя+:Настрой.Имя;       (* имя отдела *)
       обл+:ДкВидуОбласть;     (* область видимости *)
    нвхотд+:ЦЕЛ;               (* порядковый номер отдела в <вхотд> *)
       имяФ:Пустой.ДкЦепи;     (* имя файла с этим отделом *)
                                           КОН;

(*----------------------------------------------------------------------------*)
ПОСТ
                                                          (* признаки понятия *)
  прОбщедоступное- =0; (* общедоступное понятие       *)
  прТолькоЧт-      =1; (* понятие только для чтения   *)
  прОбщаяПер-      =2; (* переменная на уровне отдела *)
  прОпрЗадача-     =3; (* для уже определённых задач  *)
  прТекущийОтд-    =4; (* для пОтдел и пПер           *)           

                                      (* встроенные задачи с одним приёмником *)
  зСоздать-   = 0;
  зМодуль-    = 1;
  зВЦел-      = 2;
  зЧет-       = 3;
  зАдрес-     = 4;
  зМин-       = 5;
  зМакс-      = 6;
  зВЗнак-     = 7;
  зУзк-       = 8;
  зДлина-     = 9;
  зОбнулить-  =10;
                       (* встроенные задачи которые допускают >= 2 приёмников *)
  зУвеличить- =11;
  зУменьшить- =12;
  зИзПамяти-  =13;
  зВПамять-   =14;
  зЗначение-  =15;
  зСписать-   =16;
  зОбраз-     =17;
  зРазмер-    =18;
  зЗадано-    =19;
  зПоставить- =20;
  зСместить-  =21;

(*----------------------------------------------------------------------------*)
ПОСТ           
                                                                (* рода видов *)
  вНеопр-   = 0;  (* встр.                 *)
  вЯчейка-  = 1;  (* встр. ОБХОД.Ячейка    *)
  вЯчейки-  = 2;  (* встр. ОБХОД.Ячейки    *)
  вКлюч-    = 3;  (* встр. КЛЮЧ            *)
  вЗнак-    = 4;  (* встр. ЗНАК            *)
  вЦел16-   = 5;  (* встр. Цел16           *)
  вЦел32-   = 6;  (* встр. ЦЕЛ             *)
  вМнож-    = 7;  (* встр. МНОЖ            *)
  вПусто-   = 8;  (* встр. ПУСТО           *)
  вНет-     = 9;  (* встр.                 *)
  вДоступ-  = 10; (*       доступ к        *)
  вЗадача-  = 11; (*       ЗАДАЧА(...)     *)
  вБегунок- = 12; (*       бегунок         *)
  вРяд-     = 14; (*       ряд из          *)
  вЦепь-    = 15; (*       ЦЕПЬ            *)
  вНабор-   = 16; (*       набор из        *)

(*----------------------------------------------------------------------------*)
ПОСТ
                                               (* метки в файле общих понятий *)
  мПост      = 0;
  мВид       = 1;
  мПер       = 2;
  мЗадача    = 3;
  мВидЗадача = 4;
  мДоступ    = 5;
  мБегунок   = 6;
  мРяд       = 7;
  мЦепь      = 8;
  мНабор     = 9;
  мПриёмники =10;
  мПриёмник  =11;
  мСсылка    =12;
  мСвойства  =14;
  мСвойство  =15;
  мСкрепка   =16;

(*----------------------------------------------------------------------------*)
ПОСТ
  ВсегоОтделов =  64;  (* наибольшее число отделов (<=256). *)
  ВсегоВидов   = 256;  (* наибольшее число видов в каждом отделе *)

ПЕР
  неопрвид-,оячейкавид-,оячейкивид-,ключвид-,знаквид-,цел16вид-,цел32вид-,
  множвид-,пустовид-,нетвид-,одоствид-:ДкВидуВид;

  текОбласть+:ДкВидуОбласть;  (* текущая область видимости *)
  обхОбласть :ДкВидуОбласть;  (* область видимости отдела ОБХОД *)
  глаОбласть :ДкВидуОбласть;  (* область видимости встроенных понятий *)

  чвхотд-:ЦЕЛ;                             (* число входных отделов *)
   вхотд-:РЯД ВсегоОтделов ИЗ ДкВидуОтдел; (* все входные отделы *)
  
  следномв:ЦЕЛ;                   (* следующий номер вида для выходного файла *)

  неоДоступы:ЧэргаСлеД.нСписок;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА СоздатьПонятие-():ДкВидуПонятие;
ПЕР
  понД:ДкВидуПонятие;
УКАЗ
  СОЗДАТЬ(понД);
  ВОЗВРАТ понД
КОН СоздатьПонятие;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА СоздатьВид-(родв:ЦЕЛ):ДкВидуВид;
ПЕР 
  вид:ДкВидуВид;
УКАЗ 
  СОЗДАТЬ(вид);
  вид.родв:=родв;
  вид.размер:=4;
  вид.овид:=неопрвид;
  ВОЗВРАТ вид
КОН СоздатьВид;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА СоздатьОбласть-(имя-:ЦЕПЬ; окробл:ДкВидуОбласть):ДкВидуОбласть;
ПЕР
  обл:ДкВидуОбласть;
УКАЗ 
  СОЗДАТЬ(обл);
  СПИСАТЬ(имя,обл.имя);
  обл.окробл:=окробл;
  ВОЗВРАТ обл
КОН СоздатьОбласть;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА СоздатьОтдел-(  имя-:Настрой.Имя;
                      имяФ-:ЦЕПЬ;
                     окробл:ДкВидуОбласть):ДкВидуОтдел;
ПЕР
  отд:ДкВидуОтдел;
УКАЗ 
  СОЗДАТЬ(отд);
  СОЗДАТЬ(отд.имяФ,имяФ);
  отд.имя:=имя;
  отд.обл:=СоздатьОбласть(имя,окробл);
  ВОЗВРАТ отд
КОН СоздатьОтдел;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА СоздатьВидЦепь-(размер:ЦЕЛ):ДкВидуВид;
ПЕР 
          вид:ДкВидуВид;
УКАЗ 
  СОЗДАТЬ(вид);
          вид.родв:=вЦепь;
          вид.размер:=размер;
          вид.овид:=знаквид;
  ВОЗВРАТ вид
КОН СоздатьВидЦепь;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА СоздатьПостЦепь-(цепьД:Пустой.ДкЦепи):ДкВидуПонятие;
ПЕР
  понД:ДкВидуПонятие;
УКАЗ 
  понД:=СоздатьПонятие();
  понД.родп:=Данные.пПост;
  понД.цепьД:=цепьД;
  понД.вид:=СоздатьВидЦепь(РАЗМЕР(понД.цепьД^));
  ВОЗВРАТ понД
КОН СоздатьПостЦепь;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ИскатьВСписке-(понД:ДкВидуПонятие; имя-:Настрой.Имя):ДкВидуПонятие;
УКАЗ
  ПОКА понД # ПУСТО ВЫП
    ЕСЛИ понД.имя = имя ТО
      ВОЗВРАТ понД
    КОН;
    понД:=понД.слеД
  КОН;
  ВОЗВРАТ ПУСТО
КОН ИскатьВСписке;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ИскатьПонятие-(имя-:Настрой.Имя):ДкВидуПонятие;
(*
 * Цель:  найти в области видимости <текОбласть> и выше понятие с именем <имя>
 * Возвр: понятие или ПУСТО
 *)
ПЕР
       верх:ДкВидуОбласть;
         понД:ДкВидуПонятие;
УКАЗ
       верх:=текОбласть;
  ПОКА верх # ПУСТО ВЫП
         понД:=ИскатьВСписке(верх.первпон,имя);
    ЕСЛИ
         понД # ПУСТО
    ТО
      ВОЗВРАТ понД
    КОН;
       верх:=верх.окробл
  КОН;
  ВОЗВРАТ ПУСТО
КОН ИскатьПонятие;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ИскатьСвойство-(вид:ДкВидуВид; имя-:Настрой.Имя):ДкВидуПонятие;
(*
 * Цель:  найти в наборе <вид> и его опорных видах свойство с именем <имя>
 * Возвр: понятие или ПУСТО
 *)
ПЕР
         понД:ДкВидуПонятие;
УКАЗ
  ПОКА вид # неопрвид ВЫП
         понД:=ИскатьВСписке(вид.первпон,имя);
    ЕСЛИ
         понД # ПУСТО
    ТО
      ВОЗВРАТ понД
    КОН;
       вид:=вид.овид
  КОН;
  ВОЗВРАТ ПУСТО
КОН ИскатьСвойство;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Вставить-(имя-:ЦЕПЬ):ДкВидуПонятие;
ПЕР
       понД,
            преД:ДкВидуПонятие;
УКАЗ
       понД:=текОбласть.первпон;
  ЕСЛИ
       понД = ПУСТО
  ТО
       понД:=СоздатьПонятие();
    текОбласть.первпон:=понД
  ИНАЧЕ
    ПОКА понД # ПУСТО ВЫП
      ЕСЛИ понД.имя = имя ТО
        Ошибка.ОтметитьИмя(Ошибка.ПЕРЕОПРЕДЕЛЕНИЕ,имя)
      КОН;
      преД:=понД;
      понД:=понД.слеД
    КОН;
                       понД:=СоздатьПонятие();
            преД.слеД:=понД
  КОН;
              понД.обл:=текОбласть;
  СПИСАТЬ(имя,понД.имя);
  ВОЗВРАТ понД
КОН Вставить;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ОткрытьОбласть-(имя-:ЦЕПЬ);
(*
 * Создает головное понятие для новой области видимости и
 * помещает его на вершину <текОбласть>.
 *)
УКАЗ
  текОбласть:=СоздатьОбласть(имя,текОбласть)
КОН ОткрытьОбласть;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ЗакрытьОбласть-;
УКАЗ
  текОбласть:=текОбласть.окробл
КОН ЗакрытьОбласть;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ЭтоПриёмник-(понД:ДкВидуПонятие):КЛЮЧ;
(*
 * Цель:  определить, является ли понятие <пон> приёмником
 * Ответ: ВКЛ, если это так
 *)
УКАЗ
  ВОЗВРАТ (понД # ПУСТО) И (понД.родп В {пПер,пСсылка}) И (понД.адр > 0)
КОН ЭтоПриёмник;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА УстОтдел-(имя-:Настрой.Имя);
УКАЗ
  вхотд[0]:=СоздатьОтдел(имя,Обмен.отдИмяФ,глаОбласть)
КОН УстОтдел;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Использовать-(опчИмя-,опчПуть-:ЦЕПЬ);
ПЕР
     метка,
         ц,
  следномв,
      номв:ЦЕЛ;
       отд,
    испотд:ДкВидуОтдел;
      понД,
     былоД,
      преД:ДкВидуПонятие;
       обл:ДкВидуОбласть;
       вид:ДкВидуВид;
     вхИмя:Настрой.Имя;
    вхИмяФ:ЦЕПЬ[250];
    (* используемый отдел (вхотдисп[0]) и входные отделы используемого отдела *)
 чвхотдисп,
 нвхотдисп:ЦЕЛ;
  вхотдисп:РЯД ВсегоОтделов ИЗ ДкВидуОтдел;
      виды:РЯД ВсегоВидов ИЗ ДкВидуВид;
  урПриёмников,
     урСвойств:ЦЕЛ;
  послПриёмник,
  послСвойство:РЯД 6 ИЗ ДкВидуПонятие;

(*.....................................................подЗадача.....*)
  ЗАДАЧА Перевернуть(понД:ДкВидуПонятие):ДкВидуПонятие;
  (* Цель:  перевернуть список с началом в <понД>
   * Ответ: новое начало списка *)
  ПЕР
         начД,
              слеД:ДкВидуПонятие;
  УКАЗ
         начД:=ПУСТО;
    ПОКА понД # ПУСТО ВЫП
      слеД:=понД.слеД;
      понД.слеД:=начД;
      начД:=понД;
      понД:=слеД
    КОН;
    ВОЗВРАТ начД
  КОН Перевернуть;

УКАЗ
  ЕСЛИ опчИмя = "ОБХОД" ТО
    понД:=Вставить(опчИмя);
    понД.родп:=пОтдел;
    понД.первпон:=обхОбласть.первпон;
    понД.вид:=нетвид;
    ВОЗВРАТ
  КОН;
                         (* приготовимся *)
  следномв:=вНабор+1;
  урПриёмников:=-1;
  урСвойств:=-1;
  виды[вНеопр] :=неопрвид;   виды[вЯчейка]:=оячейкавид;
  виды[вКлюч]  :=ключвид;    виды[вЗнак]  :=знаквид;
  виды[вЦел16] :=цел16вид;   виды[вЦел32] :=цел32вид;
  виды[вМнож]  :=множвид;    виды[вПусто] :=пустовид;
  виды[вНет]   :=нетвид;     виды[вДоступ]:=одоствид;
  виды[вЯчейки]:=оячейкивид;
  Обмен.ОпчОткрыть(опчИмя,опчПуть);
                         (* читаем входные отделы используемого отдела *)
  испотд:=ПУСТО;
  Обмен.ОпчЦел(чвхотдисп);
  ОТ нвхотдисп:=0 ДО чвхотдисп-1 ВЫП
    Обмен.ОпчЦепь(вхИмя);
    Обмен.ОпчЦепь(вхИмяФ);
                         (* ищем отдел с таким же именем файла *)
    ц:=0;
    ПОКА (ц < чвхотд) И (вхИмя # вхотд[ц].имя) ВЫП
      УВЕЛИЧИТЬ(ц)
    КОН;
    ЕСЛИ ц < чвхотд ТО (* такой отдел у нас уже есть *)
      ЕСЛИ ц = 0 ТО (* да это же наш отдел *)
        Ошибка.Отметить(Ошибка.ПЕРЕКРЕСТНОЕ_ИСПОЛЬЗОВАНИЕ)
      АЕСЛИ вхИмяФ # вхотд[ц].имяФ^ ТО
        Ошибка.ОтметитьИмя(Ошибка.ОТДЕЛ_ИЗ_РАЗНЫХ_ФАЙЛОВ,вхотд[ц].имяФ^)
      КОН;
      отд:=вхотд[ц]
    ИНАЧЕ
      ЕСЛИ чвхотд >= ВсегоОтделов ТО
        Ошибка.Отметить(Ошибка.МНОГО_ОТДЕЛОВ)
      КОН;
      отд:=СоздатьОтдел(вхИмя,вхИмяФ,глаОбласть);
      ЕСЛИ
           нвхотдисп = 0
      ТО                         (* это используемый отдел
                                  * и его необходимо поместить в конец <вхотд>, поэтому пока запомним
                                  * этот отдел в промежуточной переменной <испотд> *)
        испотд:=отд
      ИНАЧЕ
        отд.нвхотд:=чвхотд;
        вхотд[чвхотд]:=отд;
        УВЕЛИЧИТЬ(чвхотд)
      КОН
    КОН;
    вхотдисп[нвхотдисп]:=отд
  КОН;
  ЕСЛИ испотд # ПУСТО ТО
    испотд.нвхотд:=чвхотд;
    вхотд[чвхотд]:=испотд;
    УВЕЛИЧИТЬ(чвхотд)
  КОН;
                                (* читаем данные с метками *)
  ПОКА НЕ Обмен.ОпчКонец() ВЫП
    Обмен.ОпчЦел(метка);
    ВЫБРАТЬ метка ИЗ
    | мПост,мВид,мПер,мЗадача:  (* понятия *)
        понД:=СоздатьПонятие();
        Обмен.ОпчЦел(номв);
        вид:=виды[номв];
        понД.вид:=вид;
        нвхотдисп:=0;
        ВЫБРАТЬ метка ИЗ
        | мВид:
            понД.родп:=пВид;
            ЕСЛИ вид.понвида = ПУСТО ТО 
              вид.понвида:=понД 
            КОН;
            Обмен.ОпчМнож(понД.признаки);
            Обмен.ОпчЦел(нвхотдисп)
        | мПост:
            понД.родп:=пПост;
            ЕСЛИ вид.родв = вЦепь ТО
              Обмен.ОпчПЦепь(понД.цепьД)
            ИНАЧЕ
              Обмен.ОпчЦел(понД.адр)
            КОН
        | мПер:
            понД.родп:=пПер;
            Обмен.ОпчМнож(понД.признаки);
            Обмен.ОпчЦел(понД.адр)
        | мЗадача:
            понД.родп:=пЗадача;
            понД.первпон:=Перевернуть(послПриёмник[урПриёмников]);
            УМЕНЬШИТЬ(урПриёмников)
        КОН;
        Обмен.ОпчЦепь(понД.имя);
        обл:=вхотдисп[нвхотдисп].обл;
        понД.обл:=обл;
                          (* добавляем в конец области видимости новое понятие или исправляем вид *)
             былоД:=обл.первпон;
        ЕСЛИ былоД = ПУСТО ТО
          обл.первпон:=понД
        ИНАЧЕ
          КОЛЬЦО
            ЕСЛИ  былоД = ПУСТО ТО       (* добавляем в конец новое понятие *)
              преД.слеД:=понД;
              ВЫХОД
            АЕСЛИ былоД.имя = понД.имя ТО
              ЕСЛИ понД.родп = пВид ТО   (* этот вид уже был заведён через другой отдел *)
                виды[номв]:=былоД.вид
              КОН;
              ВЫХОД
            КОН;
             преД:=былоД;
            былоД:=былоД.слеД
          КОН
        КОН
    | мНабор,мРяд,мЦепь,мДоступ,мБегунок,мВидЗадача: (* виды *)
        вид:=СоздатьВид(вНеопр);
        Обмен.ОпчЦел(номв);
        вид.овид:=виды[номв];
        Обмен.ОпчЦел(нвхотдисп);         (* входной номер отдела в исп. отделе *)
        вид.нвхотд:=вхотдисп[нвхотдисп].нвхотд;
        ВЫБРАТЬ метка ИЗ
        | мДоступ:
            вид.родв:=вДоступ;
            вид.размер:=Настрой.рДоступ
        | мВидЗадача:
            вид.родв:=вЗадача;
            вид.размер:=Настрой.рЗадача;
            вид.первпон:=Перевернуть(послПриёмник[урПриёмников]);
            УМЕНЬШИТЬ(урПриёмников)
        | мБегунок:
            вид.родв:=вБегунок;
            вид.размер:=Настрой.рБегунок;
            Обмен.ОпчЦел(вид.шаг)
        | мРяд:
            вид.родв:=вРяд;
            Обмен.ОпчЦел(вид.размер)
        | мЦепь:
            вид.родв:=вЦепь;
            Обмен.ОпчЦел(вид.размер)
        | мНабор:
            вид.родв:=вНабор;
            Обмен.ОпчЦел(вид.размер);
            вид.первпон:=Перевернуть(послСвойство[урСвойств]);
            УМЕНЬШИТЬ(урСвойств);
            ЕСЛИ вид.овид = нетвид ТО
              вид.овид:=неопрвид
            КОН
        КОН;
        виды[следномв]:=вид;
        УВЕЛИЧИТЬ(следномв)
    | мПриёмники:                              (* начало списка приёмников *)
        ЕСЛИ урПриёмников >= 5 ТО
          Ошибка.Отметить(Ошибка.МНОГО_ВЛОЖЕННЫХ)
        КОН;
        УВЕЛИЧИТЬ(урПриёмников);
        послПриёмник[урПриёмников]:=ПУСТО
    | мСвойства:                               (* начало списка свойств набора *)  
        ЕСЛИ урСвойств >= 5 ТО
          Ошибка.Отметить(Ошибка.МНОГО_ВЛОЖЕННЫХ)
        КОН;
        УВЕЛИЧИТЬ(урСвойств);
        послСвойство[урСвойств]:=ПУСТО
    | мПриёмник,мСсылка:                       (* приёмник *)
        понД:=СоздатьПонятие();
        ЕСЛИ метка = мПриёмник ТО
          понД.родп:=пПер
        ИНАЧЕ
          понД.родп:=пСсылка
        КОН;
        Обмен.ОпчМнож(понД.признаки);
        Обмен.ОпчЦел(номв);
        понД.вид:=виды[номв];
        Обмен.ОпчЦел(понД.адр);
        Обмен.ОпчЦепь(понД.имя);
        понД.слеД:=послПриёмник[урПриёмников];
        послПриёмник[урПриёмников]:=понД
    | мСвойство:
        понД:=СоздатьПонятие();
        понД.родп:=пСвойство;
        Обмен.ОпчМнож(понД.признаки);
        Обмен.ОпчЦел(номв);
        понД.вид:=виды[номв];
        Обмен.ОпчЦел(понД.адр);
        Обмен.ОпчЦепь(понД.имя);
        понД.слеД:=послСвойство[урСвойств];
        послСвойство[урСвойств]:=понД
    | мСкрепка:
        Обмен.ОпчЦел(номв);
        вид:=виды[номв];
        Обмен.ОпчЦел(номв);
        ЕСЛИ вид.овид = неопрвид ТО
          вид.овид:=виды[номв]
        КОН
    КОН
  КОН;
  Обмен.ОпчЗакрыть;
  понД:=Вставить(опчИмя);
  понД.родп:=пОтдел;
  понД.первпон:=вхотдисп[0].обл.первпон;
  понД.адр:=вхотдисп[0].нвхотд;
  понД.вид:=нетвид
КОН Использовать;


(*-оооооооооооооо- опережающие определения/заготовки задач -ооооооооооооооооо-*)

ЗАДАЧА^ ВыводВида(вид:ДкВидуВид);
ЗАДАЧА^ ВыводПонятия(понД:ДкВидуПонятие);


(*----------------------------------------------------------------------------*)
ЗАДАЧА ВыводПриёмников(понД:ДкВидуПонятие);
УКАЗ
  Обмен.ОпзЦел(мПриёмники);
  ПОКА ЭтоПриёмник(понД) ВЫП
    ВыводВида(понД.вид);
    ЕСЛИ понД.родп = пПер ТО
      Обмен.ОпзЦел(мПриёмник)
    ИНАЧЕ
      Обмен.ОпзЦел(мСсылка)
    КОН;
    Обмен.ОпзМнож(понД.признаки);
    Обмен.ОпзЦел(понД.вид.номв);
    Обмен.ОпзЦел(понД.адр);
    Обмен.ОпзЦепь(понД.имя);
    понД:=понД.слеД
  КОН
КОН ВыводПриёмников;

(*----------------------------------------------------------------------------*)
ЗАДАЧА ВыводСвойств(понД:ДкВидуПонятие);
УКАЗ
  Обмен.ОпзЦел(мСвойства);
  ПОКА понД # ПУСТО ВЫП
    ВыводВида(понД.вид);
    Обмен.ОпзЦел(мСвойство);
    Обмен.ОпзМнож(понД.признаки);
    Обмен.ОпзЦел(понД.вид.номв);
    Обмен.ОпзЦел(понД.адр);
    Обмен.ОпзЦепь(понД.имя);
    понД:=понД.слеД
  КОН
КОН ВыводСвойств;

(*----------------------------------------------------------------------------*)
ЗАДАЧА ВыводВида(вид:ДкВидуВид);
ПЕР
       нвхотд,
      номвидо:ЦЕЛ;
         овид:ДкВидуВид;
УКАЗ
  ЕСЛИ вид.номв > 0 ТО (* обработан *)
    ВОЗВРАТ
  КОН;
       нвхотд:=вид.нвхотд;
         овид:=вид.овид;
  ВЫБРАТЬ
          вид.родв
  ИЗ
  | вДоступ:
      Обмен.ОпзЦел(мДоступ);
      ЕСЛИ овид.номв > 0 ТО
        Обмен.ОпзЦел(овид.номв)
      ИНАЧЕ
        Обмен.ОпзЦел(вНеопр);

        ЧэргаСлеД.ДобавитьНовЗвеноВконСписка(неоДоступы,вид)
      КОН;
      Обмен.ОпзЦел(нвхотд)
  | вЗадача:
      ВыводВида(овид);
      ВыводПриёмников(вид.первпон);
      Обмен.ОпзЦел(мВидЗадача);
      Обмен.ОпзЦел(овид.номв);
      Обмен.ОпзЦел(нвхотд)
  | вБегунок:
      Обмен.ОпзЦел(мБегунок);
      Обмен.ОпзЦел(овид.номв);
      Обмен.ОпзЦел(нвхотд);
      Обмен.ОпзЦел(вид.шаг)
  | вРяд:
      ВыводВида(овид);
      Обмен.ОпзЦел(мРяд);
      Обмен.ОпзЦел(овид.номв);
      Обмен.ОпзЦел(нвхотд);
      Обмен.ОпзЦел(вид.размер)
  | вЦепь:
      Обмен.ОпзЦел(мЦепь);
      Обмен.ОпзЦел(овид.номв);
      Обмен.ОпзЦел(нвхотд);
      Обмен.ОпзЦел(вид.размер)
  | вНабор:
      ЕСЛИ овид = неопрвид ТО
        номвидо:=вНет
      ИНАЧЕ
        ВыводВида(овид);
        номвидо:=овид.номв
      КОН;
      ВыводСвойств(вид.первпон);
      Обмен.ОпзЦел(мНабор);
      Обмен.ОпзЦел(номвидо);
      Обмен.ОпзЦел(нвхотд);
      Обмен.ОпзЦел(вид.размер)
  КОН;
  вид.номв:=следномв;
  УВЕЛИЧИТЬ(следномв);
  ЕСЛИ следномв >= ВсегоВидов ТО
    Ошибка.Отметить(Ошибка.МНОГО_ОБЩЕДОСТУПНЫХ)
  КОН;
  ЕСЛИ вид.понвида # ПУСТО ТО (* это именованный вид *)
    ВыводПонятия(вид.понвида)
  КОН
КОН ВыводВида;

(*----------------------------------------------------------------------------*)
ЗАДАЧА ВыводПонятия(понД:ДкВидуПонятие);
УКАЗ
  ВЫБРАТЬ понД.родп ИЗ
  | пВид:
      ВыводВида(понД.вид);
      Обмен.ОпзЦел(мВид);
      Обмен.ОпзЦел(понД.вид.номв);
      Обмен.ОпзМнож(понД.признаки);
      (* "ВИД в2=О1.в1;" *)
      ЕСЛИ (понД.вид.понвида # понД) ТО
        Обмен.ОпзЦел(0) (* нвхотд для в2 *)
      ИНАЧЕ
        Обмен.ОпзЦел(понД.вид.нвхотд) (* нвхотд для в1 *)
      КОН;
      Обмен.ОпзЦепь(понД.имя)
  | пПер:
      ВыводВида(понД.вид);
      Обмен.ОпзЦел(мПер);
      Обмен.ОпзЦел(понД.вид.номв);
      Обмен.ОпзМнож(понД.признаки);
      Обмен.ОпзЦел(понД.адр);
      Обмен.ОпзЦепь(понД.имя)
  | пПост:
      Обмен.ОпзЦел(мПост);
      ЕСЛИ понД.вид.родв = вЦепь ТО
        ВыводВида(понД.вид);
        Обмен.ОпзПЦепь(понД.цепьД^)
      ИНАЧЕ
        Обмен.ОпзЦел(понД.вид.номв);
        Обмен.ОпзЦел(понД.адр)
      КОН;
      Обмен.ОпзЦепь(понД.имя)
  | пЗадача:
      ВыводВида(понД.вид);
      ВыводПриёмников(понД.первпон);
      Обмен.ОпзЦел(мЗадача);
      Обмен.ОпзЦел(понД.вид.номв);
      Обмен.ОпзЦепь(понД.имя)
  | пОтдел:
  КОН
КОН ВыводПонятия;

(*----------------------------------------------------------------------------*)
ЗАДАЧА ВыводПонятий(понД:ДкВидуПонятие);
УКАЗ
  ПОКА понД # ПУСТО ВЫП
    ЕСЛИ прОбщедоступное В понД.признаки ТО
      понД.признаки:=понД.признаки-{прТекущийОтд};
      ВыводПонятия(понД)
    КОН;
    понД:=понД.слеД
  КОН
КОН ВыводПонятий;

(*----------------------------------------------------------------------------*)
ЗАДАЧА ВыводНеоДост;
ПЕР
  звеноД:ЧэргаСлеД.ДкЗвену_телоД;
    вид:ДкВидуВид;
УКАЗ
(*
   Обход списка с 1-го звена до N-го, т.е. пока звеноД.слеД # ПУСТО
 *)
         звеноД:=ЧэргаСлеД.Дк1муЗвену(неоДоступы);
  ПОКА
         звеноД # ПУСТО
  ВЫП                                           (* преобразование полиморфное  
                телоД           из ЧэргаСлеД.ДкПустомуНабору в
                      ДкВидуВид <- ЧэргаСлеД.ДкПустомуНабору                  *)
    вид:=звеноД.телоД(ДкВидуВид);

    ВыводВида(вид.овид);
    Обмен.ОпзЦел(мСкрепка);
    Обмен.ОпзЦел(вид.номв);
    Обмен.ОпзЦел(вид.овид.номв);

         звеноД:=звеноД.слеД
  КОН;
  ЧэргаСлеД.ОчиститьСписок(неоДоступы)
КОН ВыводНеоДост;

(*----------------------------------------------------------------------------*)
ЗАДАЧА ВыводИспОтделов;
ПЕР
     но:ЦЕЛ;
УКАЗ
    Обмен.ОпзЦел(чвхотд);
  ОТ но:=0 ДО чвхотд-1 ВЫП
    Обмен.ОпзЦепь(вхотд[но].имя);
    Обмен.ОпзЦепь(вхотд[но].имяФ^)
  КОН
КОН ВыводИспОтделов;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Сохранить-;
УКАЗ
  Обмен.ОпзОткрыть;

  ВыводИспОтделов;

  следномв:=вНабор+1;
  ВыводПонятий(текОбласть.первпон);

  ВыводНеоДост;

  Обмен.ОпзЗакрыть
КОН Сохранить;

(*----------------------------------------------------------------------------*)
ЗАДАЧА ПодготовитьВстрВид(вид+:ДкВидуВид; родв:ЦЕЛ);
УКАЗ
  СОЗДАТЬ(вид);
          вид.родв:=родв;
          вид.номв:=родв;
          вид.размер:=1
КОН ПодготовитьВстрВид;

(*----------------------------------------------------------------------------*)
ЗАДАЧА ДобКлючПост(имя-:ЦЕПЬ; значение:ЦЕЛ);
ПЕР
  понД:ДкВидуПонятие;
УКАЗ 
  понД:=Вставить(имя);
  понД.родп:=пПост; 
  понД.вид:=ключвид; 
  понД.адр:=значение
КОН ДобКлючПост;

(*----------------------------------------------------------------------------*)
ЗАДАЧА ДобВстрВид(имя-:ЦЕПЬ; родв,размер:ЦЕЛ; вид+:ДкВидуВид);
ПЕР
  понД:ДкВидуПонятие;
УКАЗ 
  понД:=Вставить(имя);
  СОЗДАТЬ(вид);
          вид.родв:=родв;
          вид.понвида:=понД;
          вид.размер:=размер;
          вид.номв:=родв;

  понД.родп:=пВид;
  понД.признаки:={прОбщедоступное};
  понД.вид:=вид
КОН ДобВстрВид;

(*----------------------------------------------------------------------------*)
ЗАДАЧА ДобВстрЗадачу(имя-:ЦЕПЬ; ном:ЦЕЛ);
ПЕР
  понД:ДкВидуПонятие;
УКАЗ 
  понД:=Вставить(имя);
  понД.родп:=пВстрЗадача; 
  понД.вид:=нетвид; 
  понД.адр:=ном
КОН ДобВстрЗадачу;

(*----------------------------------------------------------------------------*)
ЗАДАЧА Обновить-;
УКАЗ
  ПОКА чвхотд > 0 ВЫП
    УМЕНЬШИТЬ(чвхотд);
    вхотд[чвхотд]:=ПУСТО
  КОН;
  ЧэргаСлеД.ОчиститьСписок(неоДоступы);
  чвхотд:=1
КОН Обновить;


(*-ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss-*)
УКАЗ
  чвхотд:=0; 
  ПодготовитьВстрВид(неопрвид,вНеопр);
  неопрвид.овид:=неопрвид;
  ПодготовитьВстрВид(нетвид,  вНет);
  ПодготовитьВстрВид(пустовид,вПусто);
  текОбласть:=ПУСТО;
                                           (* подготовка области отдела ОБХОД *)
  ОткрытьОбласть("ОБХОД");
  ДобВстрВид("Доступ",вДоступ,Настрой.рДоступ,одоствид);
  ДобВстрВид("Ячейка",вЯчейка,Настрой.рЯчейка,оячейкавид);
  ДобВстрВид("Ячейки",вЯчейки,              0,оячейкивид);
  оячейкивид.овид:=оячейкавид;
  ДобВстрЗадачу("Адрес",   зАдрес);
  ДобВстрЗадачу("ИзПамяти",зИзПамяти);
  ДобВстрЗадачу("ВПамять", зВПамять);
  ДобВстрЗадачу("Значение",зЗначение);
  ДобВстрЗадачу("Образ",   зОбраз);
  обхОбласть:=текОбласть;
  ЗакрытьОбласть;
                                             (* подготовка встроенной области *)
  ОткрытьОбласть("");
  ДобВстрВид("КЛЮЧ",  вКлюч,Настрой.рКлюч,ключвид);
  ДобВстрВид("ЗНАК",  вЗнак,Настрой.рЗнак,знаквид);
  ДобВстрВид("Цел16",вЦел16,Настрой.рУЦел,цел16вид);
  ДобВстрВид("ЦЕЛ",   вЦел32, Настрой.рЦел32, цел32вид);
  ДобВстрВид("МНОЖ",  вМнож,Настрой.рМнож,множвид);
  ДобКлючПост("ОТКЛ",0);
  ДобКлючПост("ВКЛ", 1);
  ДобВстрЗадачу("УВЕЛИЧИТЬ", зУвеличить);
  ДобВстрЗадачу("УМЕНЬШИТЬ", зУменьшить);
  ДобВстрЗадачу("СОЗДАТЬ",   зСоздать);
  ДобВстрЗадачу("МОДУЛЬ",    зМодуль);
  ДобВстрЗадачу("ВЦЕЛ",      зВЦел);
  ДобВстрЗадачу("ЧЕТ",       зЧет);
  ДобВстрЗадачу("МИН",       зМин);
  ДобВстрЗадачу("МАКС",      зМакс);
  ДобВстрЗадачу("ВЗНАК",     зВЗнак);
  ДобВстрЗадачу("УЗК",       зУзк);
  ДобВстрЗадачу("СПИСАТЬ",   зСписать);
  ДобВстрЗадачу("РАЗМЕР",    зРазмер);
  ДобВстрЗадачу("ДЛИНА",     зДлина);
  ДобВстрЗадачу("ЗАДАНО",    зЗадано);
  ДобВстрЗадачу("ПОСТАВИТЬ", зПоставить);
  ДобВстрЗадачу("СМЕСТИТЬ",  зСместить);
  ДобВстрЗадачу("ОБНУЛИТЬ",  зОбнулить);
  глаОбласть:=текОбласть;
КОН Данные.
