Логические акторы

Что такое логические акторы, лучше всего показать на примере. Давайте рассмотрим программу Actors.A, которую я обычно демонстрирую в начале лекций по Акторному Прологу.

Эта программа создаёт несколько логических акторов, каждый из которых печатает сообщения в отдельном текстовом окне. Все текстовые окна раскрашены в разные цвета. Акторы связаны между собой двумя общими переменными i и j. При изменении значений этих переменных, акторы доказываются повторно и выводят на экран новые сообщения. Кроме того, переменные i и j "присоединены" к полям редактирования экранного диалога. Поэтому пользователь может взаимодействовать с акторами напрямую, изменяя значения полей редактирования.

Загрузите программу и нажмите кнопку .



Рис.1. Пример работы логических акторов (программа Actors.A).

Введите любой текст в поля редактирования I и J. Программа будет реагировать на каждое изменение этих переменных. Обратите внимание, что для реализации такого поведения программы в Акторном Прологе не нужно программировать обработку событий, как это делается в языках более низкого уровня. Изменения переменных i и j напрямую передаются логическим акторам и вызывают их повторные доказательства.

Теперь давайте рассмотрим текст программы, и разберёмся, как всё это работает.

Пример. Принцип работы логических акторов.

-------------------------------------------
-- An example of Actor Prolog program.   --
-- (c) 2002, Alexei A. Morozov, IRE RAS. --
-- The principle of logical actors.      --
-------------------------------------------
project: (('Main'))
-------------------------------------------
class 'Main' specializing 'Dialog':
--
identifier      = "input";
x               = 27;
y               = 8;
--
i;
j;
--
w1      = ('TextPage',
                value_1=i,
                value_2=j,
                text_color='White',
                background_color='Red',
                x=9,
                y=4);

Основной класс программы 'Main' является потомком предопределённого класса 'Dialog', предназначенного для управления диалоговыми окнами. В составе класса 'Main' определено несколько слотов, имеющих различное назначение. Слоты identifier, x, y определяют формат и координаты диалогового окна на экране (соответствующий формат диалогового окна определён в отдельном файле, который будет рассмотрен ниже). Слоты i и j это те самые общие переменные, которые связывают акторы программы с внешним миром.

Слоты w1 - w7 (часть из них см. ниже) содержат экземпляры класса 'TextPage', в которых "живут" логические акторы. Обратите внимание, что для каждого конструктора экземпляра класса 'TextPage' заданы свои цвета и координаты на экране. Кроме того, в миры w1 - w7 передаются значения i и j. При этом в некоторые из них значение j не передаётся. Это значит, что слоты value_2 в мирах w2, w4 и w6 останутся несвязанными переменными, не присоединёнными к слоту j экземпляра класса 'Main'.

w2      = ('TextPage',
                value_1=i,
                text_color='White',
                background_color='Orange',
                x=27,
                y=1);
w3      = ('TextPage',
                value_1=i,
                value_2=j,
                text_color='Black',
                background_color='Yellow',
                x=45,
                y=4);
w4      = ('TextPage',
                value_1=i,
                text_color='Black',
                background_color='Green',
                x=47,
                y=9);
w5      = ('TextPage',
                value_1=i,
                value_2=j,
                text_color='Black',
                background_color='Cyan',
                x=41,
                y=12);
w6      = ('TextPage',
                value_1=i,
                text_color='White',
                background_color='Blue',
                x=13,
                y=12);
w7      = ('TextPage',
                value_1=i,
                value_2=j,
                text_color='White',
                background_color='Violet',
                x=7,
                y=9);
--
[

Предикат goal вызывает метод show предопределённого класса 'Dialog'. В результате этого на экране создаётся соответствующее диалоговое окно.

goal:-
        show.
--

Предикат action это обычный обработчик события. Событие "stop" возникает при нажатии на кнопку диалогового окна. При нажатии на эту кнопку предикат action просто закрывает диалоговое окно 'Main', а также текстовые окна w1 - w7. После закрытия диалогового окна исполнение программы автоматически прекращается. Обратите внимание на использование разделителя ? в операциях посылки сообщения экземпляру класса.

action("stop"):-
        hide,
        w1 ? hide,
        w2 ? hide,
        w3 ? hide,
        w4 ? hide,
        w5 ? hide,
        w6 ? hide,
        w7 ? hide.
]
-------------------------------------------

Класс 'TextPage' является потомком предопределённого класса 'Report', реализующего работу с текстовыми окнами. В классе 'Report' реализованы предикаты вывода 'write', 'writeln' и др. (чтобы получить подробный список предопределённых классов и предикатов, нажмите кнопку и найдите раздел "Methods"). Слоты width и height определяют размеры соответствующего текстового окна. Слоты value_1 и value_2 содержат общие переменные, соединяющие акторы с внешним миром.

class 'TextPage' specializing 'Report':
--
width   = 27;
height  = 10;
--
value_1;
value_2;
--
[
goal:-
        write_value("i",value_1),
        write_value("j",value_2).
--
write_value(_,#):-!.
write_value(Name,V):-
        writeln(Name,"= ",V).
]
-------------------------------------------

Теперь о том, откуда в экземпляре класса 'TextPage' появляется актор? В соответствии с правилами языка, каждый автоматический вызов предиката goal во время построения нового экземпляра класса автоматически создаёт новый актор. Таким образом, в каждом экземпляре класса программы автоматически создаётся свой собственный актор goal, который проверяет заданные логические условия и автоматически доказывается повторно в случае изменения каких-либо общих переменных. В рассматриваемом примере актор goal просто печатает в соответствующем окне значения слотов value_1 и value_2. Заметим, что программа сделана так, чтобы неопределённые значения переменных (то есть такие, которые могут быть унифицированы с константой #) не печатались.

Обратите внимание, что изменение переменной i вызывает реакцию акторов во всех мирах w1 - w7, в то время как изменение переменной j вызывает повторные доказательства только акторов в отдельных мирах w1, w3, w5 и w7. Это достигается за счёт того, что миры w2, w4 и w6 не подсоединены к переменной j. Таким образом, стратегия управления Акторного Пролога обеспечивает повторное доказательство только тех акторов, общие переменные которых подверглись изменениям, оставляя результаты доказательства всех остальных акторов нетронутыми.

Как видим, средства Акторного Пролога не исключают использование обычного событийного стиля программирования (как это было в случае с обработкой нажатия на кнопку диалогового окна). Но при этом язык реализует принципы программирования человеко-машинного интерфейса более высокого уровня.

В том, что повторные доказательства акторов принципиально отличаются от обработки событий, можно убедиться, если запустить рассмотренный пример на очень медленной машине. В этом случае акторы не будут успевать печатать все промежуточные значения общих переменных, если пользователь будет достаточно быстро изменять значения полей редактирования. На экран будут выведены только некоторые промежуточные значения полей, а также окончательные значения. Такая операционная семантика программы в точности соответствует её декларативной семантике. Задача Акторного Пролога состоит в том, чтобы привести логическое доказательство в точное соответствие с последними данными, поступившими извне. Поэтому Акторный Пролог может пропускать обработку событий, не нужных для получения конечного результата.

В заключение рассмотрим файл с определением формата диалогового окна программы (Actors.DLG). Конечно, синтаксис этого файла не имеет никакого отношения к синтаксису Акторного Пролога и является особенностью данной реализации языка. В настоящее время реализовано автоматическое подключение файлов с определениями диалоговых окон. Для этого определения диалоговых окон должны храниться в файле с таким же именем, как у исходного файла программы и в том же каталоге. При этом расширение имени файла должно быть DLG.

Файл определения диалоговых окон.

grid(80,25)
window_font("Arial",17,[bold])
dialog_font("Arial",12,[])
dialog "input" (
     "Title",default,default,default,
     centered,centered,default)
vbox(center)
     table
          row
               column
                    "I= "
               end_of_column
               column
                    edittext(i,10,1,"")
               end_of_column
          end_of_row
          row
               column
                    "J= "
               end_of_column
               column
                    edittext(j,10,1,"")
               end_of_column
          end_of_row
     end_of_table
     button("stop","&Exit")
end_of_vbox
end_of_dialog

Определения, заданные в этом файле, имеют следующий смысл:

  • grid(80,25) - количество колонок и строк координатной сетки, относительно которой будут располагаться различные элементы пользовательского интерфейса.
  • window_font ("Arial",17,[bold]) - имя, размер и атрибуты фонта, который следует по умолчанию использовать в текстовых окнах программы.
  • dialog_font ("Arial",12,[]) - имя, размер и атрибуты фонта, который следует по умолчанию использовать в диалоговых окнах программы.
  • dialog "input" ("Title", default, default, default, centered, centered, default) - начало определения немодального диалога "input". Параметры диалога, заданные здесь, будут использоваться, только если задать значение 'default' соответствующего слота экземпляра класса. Значения параметров по порядку:
    1. Заголовок диалогового окна.
    2. Цвет текстовых надписей.
    3. Цвет фона текстовых надписей.
    4. Размер букв текстовых надписей.
    5. Расположение окна по горизонтали.
    6. Расположение окна по вертикали.
    7. Цвет фона диалогового окна.
  • Скобки vbox(center) ... end_of_vbox - вертикальное расположение элементов диалога с выравниванием по центру.
  • Скобки table ... end_of_table - таблица элементов экранного диалога.
  • Скобки row ... end_of_row - строка таблицы элементов экранного диалога.
  • Скобки column ... end_of_column - колонка таблицы элементов экранного диалога.
  • "Text..." - текстовая надпись в составе экранного диалога.
  • edittext(i,10,1,"") - поле редактирования текста. Поле редактирования присоединено непосредственно к слоту i соответствующего экземпляра класса. Имеет размеры 10 букв в ширину и 1 букву в высоту. Начальное значение равно пустой строке "".
  • button("stop","&Exit") - кнопка, вызывающая действие "stop". Текстовая надпись на кнопке .

Оглавление