(*~\Глагол\Отделы\Иное\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                             ОТДЕЛ Чэрга;
(*============================================================================*)
(* НАЗНАЧЕНИЕ:                                    ДЕК/DEQ                     *
//            обработка двуконцевого лин.цепного списка-набора (очередь)      *
//                               вида  Чэрга.нСписок                          *
//      из двусвязных звеньев-наборов  Чэрга.ДкЗвену_телоД                    *
// с доступами <слеД> и                                                       *
//             <преД> и полиморфным доступом <телоД:Чэрга.ДкПустомуНабору>    *
//                                                                            *
//  FIFO/LIFO        ПУСТО <-      1  <=> 2 <=> ... <=> N       -> ПУСТО      *
//                           начЗвенД =ВхВых    ВхВых= конЗвенД               *
//                                                                            *
//               Опорные вид НАБОР и вид ДОСТУП К 'имя набора'                *
//             при Предметно-Описательном Подходе (ПоП) на Глаголе            *
//                                                                            *
//       Абстрактные Виды Данных (АВД) и многоформие                          *
//                при Предметно-описательном Подходе (ПоП) на Глаголе         *
//                                                     или на Обероне         *
//     [ Абстрактные Типы Данных (АТД) и полиморфизм                          *
//                при традиционном ООП               ]                        *)
(*============================================================================*)
ВИД
                           (*--- опорный вид для <телоД> в звене ---*)

  ДкПустомуНабору- = ДОСТУП К нПустой;
                              нПустой- = НАБОР КОН;  (* пустой набор "Чэрга.нПустой" - расширяемый
                                                        для конкретных тел у звеньев списка, т.е. это опорный вид *)
(*----------------------------------------------------------------------------*
//
//     Отдел Чэрга содержит конструкцию для работы с очередью из звеньев, 
// связанных через <слеД> - по доступу к следующему звену и
// связанных через <преД> - по доступу к предыдующему звену
//                  (цепной список двусвязанных звеньев или связанный список).
//
 * Скрытый реальный вид-НАБОР: 'нЗвено'    - двусвязное звено-телоД_СлеД_ПреД *
 *     Реальный  вид-ДОСТУП: "ДкЗвену_телоД" - доступ к звену-телоД_СлеД_ПреД *
//                                                                            *
//  LIFO/FIFO        ПУСТО <-  1 <=> 2 <=> ... <=> N  <=>  N+1  -> ПУСТО      *
//             ВхВых <=> начЗвенД                 конЗвенД <=> ВхВых          *
//                                                                            *
//  LIFO/FIFO ПУСТО <- N+1 <=> N <=> ... <=> 2 <=> 1 -> ПУСТО                 *
//             ВхВых <=> начЗвенД                 конЗвенД <=> ВхВых          *
//                                                                            *
 *----------------------------------------------------------------------------*)
(*-
    Описание экспортируемого/общедоступного/
                                 публичного/видимого НАБОРа-предмета -
             <нЗвено>
  с доступом <телоД+> к набору пока пустому - опорному (будущие данные звена) и
  с доступом  <слеД+> к следующему  звену связанного списка стэк-СлеД-ПреД.
  с доступом  <преД+> к предыдущему звену связанного списка стэк-СлеД-ПреД.
-*)
  ДкЗвену_телоД- = ДОСТУП К нЗвено;
                            нЗвено- =  (* двусвязное звено-СлеД-ПреД цепного списка *)
  НАБОР
    телоД+ :ДкПустомуНабору;  (* доступ к пустому набору, описанному именно в этом отделе! - опорный вид *)
     слеД+ :ДкЗвену_телоД;    (* доступ к  следующему звену-телоД-СлеД-ПреД *)
     преД+ :ДкЗвену_телоД     (* доступ к предыдущему звену-телоД-СлеД-ПреД *)
  КОН;

ВИД
(*----------------------------------------------------------------------------*
 *    Реальный вид-НАБОР:  'нЧэрга' - очередь (ДЕК/DEQ) с головой (ВхВых) -   *
 *       FIFO -    1-вым  вошёл, 1-вым вышел                 [Втолкнуть/push, *
 *                                                              Забрать/pop]  *
 *                                                      и хвостом (ВхВых) -   *
 *       LIFO - последним вошёл, 1-вым вышел                 [Втолкнуть/push, *
 *                                                              Забрать/pop]  *
 *            вид-ДОСТУП: 'ДкЧэрга' - доступ к списку чэрга/очередь           *
//                                                                            *
//  LIFO/FIFO        ПУСТО <-  1 <=> 2 <=> ... <=> N  <=>  N+1  -> ПУСТО      *
//             ВхВых <=> начЗвенД                 конЗвенД <=> ВхВых          *
//                                                                            *
 *  Двуконцевой цепной список 'нЧэрга'(ДЕК/DEQ) - очередь с головой и хвостом *
 *    из двусвязных звеньев с доступом к следующему и предыдущему звену.      *
 *                                                                            *
 *  Добавление нового звена происходит в начало-голову списка - <начЗвенД+>   *
 *                                  и  в  конец-хвост  списка - <конЗвенД+>,  *
 *    (а также и внутри списка).                                              *
 *        Удаление звена возможно как из начала-головы списка - <начЗвенД+>,  *
 *                              так и из  конца-хвоста списка - <конЗвенД+>   *
 *    (а также и внутри списка).                                              *
 *----------------------------------------------------------------------------*)
(*-
    Описание экспортируемого/общедоступного/
                                 публичного/видимого НАБОРа-предмета -
               <нСписок>
  со счётчиком <всехЗвен+> входящих в цепной список и
     с доступом <начЗвенД+>  к    1-му    звену двусвязного списка 'нСписок',
     с доступом <конЗвенД+>  к последнему звену двусвязного списка 'нСписок'.
-*)
  ДкСписку- = ДОСТУП К нСписок;
                       нСписок- =
  НАБОР
    всехЗвен+ :ЦЕЛ;
     начЗвенД+:ДкЗвену_телоД;           (* ссылка на голову списка 'нСписок'  *)
     конЗвенД+:ДкЗвену_телоД            (* ссылка на  хвост списка 'нСписок'  *)
  КОН;

(*------------------------------------------------*
//
//       Таким образом, вся навигация по списку звеньев (содержащих полиморфный доступ к телу звена <телоД>)
// происходит внутри отдела, в котором собственно и описан вид набор-список    - Чэрга.нСписок
//                                                    или  вид доступ к набору - Чэрга.ДкСписку 
//
 *------------------------------------------------*)


(*=рррррррррррррррррррррррр= реализация задач =рррррррррррррррррррррррррррррр=*)



(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА                                                                       (* (Чэрга.нСписок) *)
       ОчиститьСписок-(список+:нСписок);
    (* ОчиститьСписок-(чэргаД+:ДкСписку); *)
УКАЗ
              ОБНУЛИТЬ(список)   
           (* ОБНУЛИТЬ(чэргаД^) *)   
               (*
                       список.всехЗвен :=0;
                        список.начЗвенД:=ПУСТО;
                        список.конЗвенД:=ПУСТО
                *)
КОН ОчиститьСписок;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА                                                                       (* (Чэрга.нСписок) *)
       ДобавитьНовЗвеноВконСписка-(
                                     список+:нСписок;
                                (*   чэргаД+:ДкСписку;  *)
                                    данныеД :ДкПустомуНабору (* приёмник <- источник = расширению приёмника! *)
                                  );
(*
 * Цель: создать и присоединить новое (N+1)-е <звеноД> в конец очереди <список+> по <слеД>
 *                                    а в поле звена <телоД+> заслать <данныеД>
//
//       FIFO                  1 -> 2 -> ... -> N ->  N+1 -> ПУСТО
//               Вых <=  начЗвенД              конЗвенД <=  Вх (N+1)-го
 *)
ПЕР
          звено:ДкЗвену_телоД;
УКАЗ
  СОЗДАТЬ(звено);
          звено.телоД:=данныеД;
  ЕСЛИ
       список.начЗвенД = ПУСТО
  ТО                                 (* очередь ещё пуста - выставляем оба доступа на 1-е звено *)
          звено.слеД
                      := ПУСТО;       (* 1 -> ПУСТО *)

       список.начЗвенД     :=звено;
                          (* звено.слеД    =  ПУСТО *)
   (*  список.начЗвенД.слеД:=ПУСТО; *)(* 1 -> ПУСТО *)
       список.конЗвенД     :=звено;
                          (* звено.слеД    =  ПУСТО *)
   (*  список.конЗвенД.слеД:=ПУСТО; *)(* 1 -> ПУСТО *)

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

КОН ДобавитьНовЗвеноВконСписка;

   (*=-
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА                                                                       (* (Чэрга.нСписок) *)
       ДобавитьНовЗвеноВначСписка-(
                                     список+:нСписок;
                                (*   чэргаД+:ДкСписку;  *)
                                    данныеД :ДкПустомуНабору (* приёмник <- источник = расширению приёмника! *)
                                  );
(*
 * Цель: создать и присоединить новое (N+1)-е <звеноД> в начало очереди <список+> по <слеД>
 *                                    а в поле звена <телоД+>  заслать <данныеД>
//
//       LIFO           N+1 -> N -> ... -> 2 -> 1 -> ПУСТО
//             ВхВых <=> начЗвенД              конЗвенД
 *)
ПЕР
          звено:ДкЗвену_телоД;
УКАЗ
  СОЗДАТЬ(звено);
          звено.телоД:=данныеД;
  ЕСЛИ
       список.конЗвенД = ПУСТО
  ТО                                 (* очередь ещё пуста - выставляем оба доступа на 1-е звено *)
          звено.слеД
                      := ПУСТО;       (* 1 -> ПУСТО *)

       список.начЗвенД     :=звено;
                          (* звено.слеД    =  ПУСТО *)
   (*  список.начЗвенД.слеД:=ПУСТО; *)(* 1 -> ПУСТО *)
       список.конЗвенД     :=звено;
                          (* звено.слеД    =  ПУСТО *)
   (*  список.конЗвенД.слеД:=ПУСТО; *)(* 1 -> ПУСТО *)

  ИНАЧЕ                              (* добавляем не 1-е звено - выставляем начЗвенД на новое (N+1)-е звено *)
(*
                    при добавлении не нач.(1-го) звена, а только при удалении 1-го и единственного
       список.конЗвенД - хвост очереди не изменяем
 *)
                 звено.слеД:=список.начЗвеноД; (*        N-е *) (* старая голова следует за новой головой (=новому звену)  N+1 -> N *)
                                               (* N+1 -> N   *)
       список.начЗвенД     :=звено;            (* N+1        *) (* новое звено стало головным - первым *)
    (* список.начЗвенД.слеД:= N-е; *)          (* N+1 -> N   *)
  КОН;
  УВЕЛИЧИТЬ(список.всехЗвен)

КОН ДобавитьНовЗвеноВначСписка;
  -=*)

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА                                                                       (* (Чэрга.нСписок) *)
       Дк1муЗвену-(список+:нСписок):ДкЗвену_телоД;
(*
   Цель:  получить доступ к первому (1-му) звену списка для обхода всех его звеньев по <слеД>
//                                                            (без удаления звена)
//
//       FIFO                  1 -> 2 -> ... -> N ->  N+1 -> ПУСТО
//                Вых <=  начЗвенД             конЗвенД <=  Вх (N+1)-го
 *)
УКАЗ
           ВОЗВРАТ список.начЗвенД    (* для обхода списка по ссылке <слеД> в звене *)
        (* ВОЗВРАТ чэргаД.начЗвенД *)
КОН Дк1муЗвену;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА                                                                       (* (Чэрга.нСписок) *)
       ДкNмуЗвену-(список+:нСписок):ДкЗвену_телоД;
(*
   Цель:  получить доступ к последнему (N-му) добавленному звену списка для обхода всех его звеньев по <слеД>
//                                                                            (без удаления звена)
//
//       LIFO           N+1 -> N -> ... -> 2 -> 1 -> ПУСТО
//              ВхВых <=> начЗвенД             конЗвенД
 *)
УКАЗ
           ВОЗВРАТ список.начЗвенД    (* для обхода списка по ссылке <слеД> в звене *)
КОН ДкNмуЗвену;

КОН Чэрга.
