Крестики-нолики на платформе Гедымин. Игровой движок реализован на Prolog. Исходный код тут.
Клонируйте проект gedemin-prolog. Устанавливайте пространство имен GS.Пролог.Учебный пример.Игра крестики-нолики.yml. Получайте удовольствие!
PS: получится обыграть машину на максимальном поле и уровне сложности -- обязательно пишите сюда.
Показаны сообщения с ярлыком prolog. Показать все сообщения
Показаны сообщения с ярлыком prolog. Показать все сообщения
8 мая 2015 г.
4 апр. 2014 г.
Пролог
Аналогов в Беларуси просто нет. Ниже приведен фрагмент кода программы расчета заработной платы на языке Prolog . Работает в режиме промышленной эксплуатации на двух крупных предприятиях (более 1000 работников на каждом).
% среднедневной заработок по сотруднику (по среднечасовому) % - для отпусков calc_avg_wage(Scope, PK, AvgWage, Rule) :- Rule = by_avg_houre, % правило действительно is_valid_rule(Scope, PK, _, Rule), % подготовка временных данных для расчета prep_avg_wage(Scope, PK, Periods), % взять заработок findall( Wage, % за каждый период проверки ( member(Y1-M1, Periods), % взять данные по заработку get_month_wage(Scope, PK, Y1, M1, _, Wage) ), % в список заработков Wages ), % итоговый заработок sum_list(Wages, Amount), % взять часы findall( THoures, % за период проверки ( member(Y2-M2, Periods), % взять данные по часам за месяц get_month_norm_tab(Scope, PK, Y2-M2, _, _, _, THoures) ), % в список часов Durations), % всего часов по табелю sum_list(Durations, TotalTab), % среднечасовой заработок catch( AvgHoureWage is Amount / TotalTab, _, fail ), % разложить первичный ключ PK = [pEmplKey-EmplKey, pFirstMoveKey-FirstMoveKey], % всего часов по графику за расчетный год get_data(Scope, in, usr_wg_TblYearNorm, [ fEmplKey-EmplKey, fFirstMoveKey-FirstMoveKey, fWHoures-TotalNorm]), % среднемесячное количество расчетных рабочих часов AvgMonthNorm is TotalNorm / 12, % среднемесячное количество календарных дней get_param(Scope, in, pAvgDays-AvgDays), % среднедневной заработок catch( AvgWage0 is AvgHoureWage * AvgMonthNorm / AvgDays, _, fail ), AvgWage is round(AvgWage0), !.
13 нояб. 2013 г.
Обработка результата Пролог вычислений
Результат выполнения Пролога нужен разработчику для дальнейшей обработки.
Насколько я понимаю, предлагается вариант с созданием клиент датасета и ручной перегонкой в него данных. Это долго и не удобно (хотя возможность ручного перебора результата обязательно следует оставить). Необходимо предложить структуру таблицы для хранения результата и реализовать метод, который находит решения и сразу помещает их в указанную таблицу.
Почему таблица?
-
Можно использовать в запросах.
Можно подключать все существующие контролы.
5 нояб. 2013 г.
Задача на Прологе для платформы Гедымин
Поскольку это первый пример в книге Ивана Братко (классиков нужно чтить!) задача будет такой:
-
В стандартный справочник людей (GD_PEOPLE) добавить два поля -- отец и мать. Необязательные для заполнения ссылки на этот же справочник.
Реализовать на Прологе правила: предок, потомок, сын, дочь, внук, внучка, дедушка, бабушка, родственник, близкий родственник, член семьи, брат, сестра, сводный брат, сводная сестра.
Реализовать диалоговое окно в котором можно:
-
Выбрать человека, степень родства и получить список удовлетворяющих лиц.
Выбрать двух людей и получить список степеней родства между ними.
Выбрать двух людей, степень родства и получить ответ Да или Нет.
29 авг. 2013 г.
Подключение Embedded SWI-Prolog в Гедымин
Есть два варианта подключения Пролога. Первый -- мы обращаемся к embedded SWI-Prolog из кода на VBScript через глобальный объект (назовем его PL). Второй -- алгоритм пишется непосредственно на Прологе, а доступ к функционалу платформы происходит через Foreign Predicates.
Обращение к Прологу через глобальный объект мы рассмотрим на сравнительном примере доступа к реляционным данным из макроса на Гедымине. Пусть данные находятся в двух таблицах: GD_CONTACT(ID, CITYKEY, NAME) и GD_PLACE(ID, NAME):
ID CITYKEY NAME ====================== 1 1 Company A 2 1 Company B 3 2 Company C ID NAME ====================== 1 Minsk 2 BeriozaДля извлечения cписка компаний по заданному наименованию города мы пишем SQL запрос, который выполняем через объект класса TIBSQL:
... Dim q Set q = Creator.GetObject(nil, "TIBSQL", "") Set q.Transaction = gdcBaseManager.ReadTransaction q.SQL.Text = _ "SELECT c.name " & _ "FROM gd_contact c JOIN gd_place p " & _ " ON p.id = c.citykey " & _ "WHERE p.name = 'Minsk' " q.ExecQuery While Not q.EOF ... q.Next WEnd ...Теперь изобразим тоже самое на Prolog. Исходные данные в виде предикатов Prolog выглядят так:
gd_contact(1, 1, 'Company A'). gd_contact(2, 1, 'Company B'). gd_contact(3, 2, 'Company C'). gd_place(1, 'Minsk'). gd_place(2, 'Berioza').Правило связи компании с городом через ключи:
bycity(City, Name) :- gd_place(CityID, City), gd_contact(_, CityID, Name).Тогда запрос на извлечение всех минских компаний будет выглядеть следующим образом:
? bycity('Minsk', Name).
Что мы видим из данного примера?
-
Необходим класс для доступа к Прологу из макросов. Далее по тексту будем называть его PL. Экземпляр данного класса создается стандартным образом через глобальный объект Designer/Creator. Каждый экземпляр может иметь свое имя.
PL должен иметь метод для формирования предикатов на основании заданной SQL выборки. Пример кода:
... Call PL.MakePredicates(_ "SELECT id, citykey, name FROM gd_contact", _ gdcBaseManager.ReadTransaction, _ "gd_contact", "name") ...Последний параметр -- имя выборки, которое будет использоваться для формирования имени .pl файла в режиме отладки. Пусть это и не касается непосредственно сопряжения Пролога с Гедымином, но здесь стоит вспомнить об идее изоляции разработчика от работы с SQL запросами и инкапсуляции последних внутрь т.н. SQL объекта. SQL объект -- это заранее написанный, проверенный и оптимизированный SQL запрос, загружаемый на базу стандартным образом через настройки или пространства имен. Для выполнения, программист обращается к нужному SQL объекту по его РУИДу. PL должен иметь метод для формирования предикатов на основании бизнес-класса. На вход передается класс-подтип, подмножество, дополнительные условия выборки. Сразу следует договориться о стандартном механизме (способе) загрузки данных мастер-дитэйл (например, документ накладная с позициями).
... Call PL.MakePredicates2(_ "TgdcCompany", "", "ByID", Array(777777), "", _ gdcBaseManager.ReadTransaction, _ "gd_contact", "name") ...PL должен иметь метод для формирования предикатов на основании существующего набора данных (дата-сета). PL должен иметь метод для ручного формирования произвольных предикатов. PL должен иметь метод для вычисления цели. Результат вычисления может быть как одиночное значение, так и выборка. Для работы с последней предусмотрены методы итерации (EOF, First, Next) и методы для обращения к параметрам по имени. С помощью соответствующих методов результат вычисления может быть напрямую помещен в указанную таблицу в базе, клиент-датасет в оперативной памяти, или на его основе могут быть созданы новые бизнес-объекты в БД. Предикаты, которые создает разработчик, должны храниться в базе данных аналогично тому, как сейчас хранится код VBScript. В дереве Проводника Редактора скрипт-объектов следует добавить корневой раздел для кода на Прологе. Внутри раздела пролог-скрипты могут размещаться в папках. Минимальная единица для загрузки в объект PL -- один пролог-скрипт. Каждый скрипт имеет уникальное имя и РУИД. Загрузка осуществляется по РУИДу. Внутри скрипта могут встречаться директивы %#INCLUDE для загрузки других пролог-скриптов (аналогично директиве '#INCLUDE для VBScript). Стандартные библиотеки SWI-Prolog, которые в дистрибутиве занимают 8 Мб в 377 файлах, будут храниться в базе данных точно так же, как и обычные пролог-скрипты. Отладка:
-
Для отладки на компьютере должен быть установлен полный вариант SWI-Prolog и, возможно, SWI-Prolog Editor.
Местоположение SWI-Prolog и каталога для временных файлов задается в параметрах платформы.
Режим отладки активизируется в параметрах редактора скрипт-объектов для списка конкретных экземпляров PL, заданных их именами. Если список пуст, то режим активируется для всех PL объектов.
Когда активирован режим дебаггера предикаты записываются в текстовые файлы .pl программ во временном каталоге. При этом файлы формируются следующим образом:
-
Для каждого пролог-скрипта отдельный файл.
Результаты вызова MakePredicatesX помещаются в файлы в соответствии с заданными именами.
Labels:
архитектура,
идеи,
prolog,
SQL
8 авг. 2013 г.
Первые шаги в функциональном программировании
Двадцать лет назад я собирался изучить Prolog. Купил даже книгу Ивана Братко "Программирование на языке Пролог для искусственного интеллекта". Так бы она и пылилась на полке, если бы не Гедымин и очередной наш технологический прорыв на стыке пост-реляционных технологий и функционального программирования.
А вот и собственноручно написанный код. Решение первой задачи Проекта Ойлера:
my_sum(From, To, C, C2, S) :- From < To, ( From mod C =:= 0; From mod C2 =:= 0 ), Next is From + 1, my_sum(Next, To, C, C2, T), S is T + From. my_sum(From, To, C, C2, S) :- From < To, From mod C =\= 0, From mod C2 =\= 0, Next is From + 1, my_sum(Next, To, C, C2, T), S is T. my_sum(From, To, _, _, S) :- From = To, S is 0.PS: Надо же: Леонард Ойлер оказывается родился в Базеле ))
Labels:
идеи,
исходный код,
prolog
Подписаться на:
Сообщения (Atom)
