Шаг 11.
Динамические структуры данных в языке Prolog.
Реализация основных операций над деком

    На этом шаге мы рассмотрим программу, в которой реализованы основные операции над деком. В ней для наглядности создано меню.

    Текст этой программы приведен ниже:

domains
/* содержит объявления типов объектов (доменов), используемых в программе */
     list = integer*
     /* домен типа списка целых чисел */
predicates
/* содержит объявление предикатов */
     vvod(integer, list)
     /* предикат, реализующий формирование дека */
     add_in_begin (integer, list, list)
     /* предикат, реализующий добавление компоненты в начало дека */
     add_in_end (list, list, list)
     /* предикат, реализующий добавление компоненты в конец дека */
     delete_with_end (integer, list, list)
     /* предикат, реализующий удаление последней компоненты дека */
     del (integer, list)
     /* предикат, с помощью которого добираемся до последней компоненты дека */
     write_dek (list, integer)
     /* предикат, реализующий вывод дека */
     process (integer, list, list)
     /* предикат, выполняющий действия, описанные в меню */
     show_menu (list, list)
     /* предикат, реализующий вывод меню на экран */
     run_file
     /* предикат, позволяющий повторять вывод меню до тех пор,
      пока пользователь не выйдет из программы */
goal 
/* целевое утверждение */
     run_file.
clauses
 /* содержит утверждения */
     run_file:-
          show_menu ([], _), nl,
          write ("Нажмите любую клавишу."),
          readchar (_),
          exit.
     show_menu (Spisok, S1):-
          makewindow (1, 7, 7, "Главное меню", 0, 0, 25, 80), nl,
          /* номер окна - 1, символы в нем белые, а фон черный (7),
          рамка белая (7), название окна, верхний левый угол окна на строке 0,
          столбце 0, а само окно имеет 25 строк и 80 столбцов */
          write ("Выберите действие:"), nl, nl,
          write ("  1  Заполнение дека."), nl,
          write ("  2  Добавление элемента в начало дека."), nl,
          write ("  3  Добавление элемента в конец дека."), nl,
          write ("  4  Удаление первого элемента из дека."), nl,
          write ("  5  Удаление последнего элемента из дека."), nl,
          write ("  6  Печать дека."), nl,
          write ("******************************************"),nl,
          write ("  0  Выход из программы."), nl, nl,
          write ("Укажите номер: (0-6) "),
          readint (G),
          G<7,
          process (G, Spisok, S1),
          /* Spisok - исходный дек, S1 - результирующий дек */
          show_menu (S1, _),!.
          /* посылаем в качестве исходного результирующий дек */
     process (0, _, []):- !,
     /* выход из программы */
          exit.
     process (1, _, S1):-
     /* заполнение дека */
          makewindow (2, 7, 7, "Заполнение дека", 0, 0, 25, 80), nl,
          write ("Введите количество элементов дека:"), nl, nl,
          readint (Kol), nl,
          write ("Вводите элементы:"), nl, nl,
          vvod (Kol, S1), nl, nl,
          write ("Дек заполнен."),
          nl, nl,
          write ("Для продолжения нажмите любую клавишу."),
          readchar (_),
          removewindow,!.
          /* удаляет текущее окно с экрана */
     process (2, Spisok, S1):-
     /* добавление элемента в начало дека */
          makewindow(3, 7, 7, "Добавление элемента в начало дека",
          0, 0, 25, 80), nl,
          write ("Введите добавляемый в начало элемент: "), nl, nl,
          readint (B), nl,
          add_in_begin (B, Spisok, S1),
          nl, nl,
          write ("Элемент в начало добавлен."),
          nl, nl,
          write ("Для продолжения нажмите любую клавишу."),
          readchar (_),
          removewindow,!.
     process (3, Spisok, S1):-
     /* добавление элемента в конец дека */
          makewindow (3, 7, 7, "Добавление элемента в конец дека",
          0, 0, 25, 80), nl,
          write ("Введите добавляемый в конец элемент: "), nl, nl,
          readint (X), nl,
          add_in_end (Spisok, [X], S1),
          nl, nl,
          write ("Элемент в конец добавлен."),
          nl, nl,
          write ("Для продолжения нажмите любую клавишу."),
          readchar (_),
          removewindow,!.
     process (4, Spisok, S1):-
     /* удаление первого элемента из дека */
          makewindow (4, 7, 7, "Удаление первого элемента из дека",
          0, 0, 25, 80), nl,
          write ("Элемент из начала дека удален."), nl, nl,
          Spisok = [_|S1],
          write ("Для продолжения нажмите любую клавишу."),
          readchar (_),
          removewindow,!.
     process (5, Spisok, S1):-
     /* удаление последнего элемента из дека */
          makewindow (4, 7, 7, "Удаление последнего элемента из дека",
          0, 0, 25, 80), nl,
          write ("Элемент с конца дека удален."), nl, nl,
          del (Y, Spisok),
          delete_with_end (Y, Spisok, S1),
          write ("Для продолжения нажмите любую клавишу."),
          readchar (_),
          removewindow,!.
     process (6, Spisok, S1):-
     /* печать дека */
          nl, nl,
          write ("Полученный дек:"), nl, nl,
          write_dek (Spisok, 0),
          S1 = Spisok,
          nl, nl,
          write ("Для продолжения нажмите любую клавишу."),
          readchar (_),
          removewindow,!.

     vvod (0, []):- !.
     vvod (N, L):-
          readint (X),
          N1 = N-1,
          vvod (N1, LL),
          L = [X|LL].

     add_in_end ([], S, S).
     add_in_end ([X|S1], S2, [X|S3]):-
          add_in_end (S1, S2, S3).

     add_in_begin (X, L, [X|L]):- !.

     delete_with_end (X, [X|L1], L1).
     delete_with_end (X, [Z|Y], [Z|Y1]):-
          delete_with_end (X, Y, Y1).

     del (F, [F]).
     del (F, [_|S]):-
          del (F, S).

     write_dek ([], 1):- !.
     write_dek ([], 0):- 
          write ("Дек пуст!!!").
     write_dek ([H|T], _):- 
          write (H, "  "),
          write_dek (T, 1).
Текст этой программы можно взять здесь.

    В данной программе также описан предикат, который позволяет выводить последовательно все элементы списка.

    На следующем шаге мы рассмотрим этот предикат.




Предыдущий шаг Содержание Следующий шаг