Программирование на языке Пролог на Андроиде

Изменения связанные с версией 2.3:

  1. Имя предиката functor_chars/2 изменено на chars/2. Где первый аргумент теперь должен быть строго атомарным;
  2. Добавлены предикаты:
    а) fchar/3, где 1-ый аргумент - это первый символ от атомарного терма 3-го аргумента, а 2-ой аргумент - это остаток;
    б) string/3, который истинен, если первые 2-а атомарные аргумента, при слиянии имён равны имени 3-го атомарного аргумента;
    в) name/2, который истинен, если 1-ый аргумент атомарен и его имя распадается на список кодов его символов;
    г) tell/1, который истинен, если его аргумент - это атом, в котором указан путь и имя существующего файла. Предикат устанавливает данный файл как поток вывода. Если аргумент равен user потоком вывода будет консоль. Если аргументом является свободная переменная, тогда мы просто получаем путь (оно же его имя) файла текущего потока вывода;
    д) told/0, который является истинным, если текущий поток вывода является файлом, который и закрывается;
    е) delete_file/1, который истинен, если возможно удалить файл указанный в аргументе, что и делает предикат;
    ё) create_file/1, который истинен, если возможно создать файл;
    ж) инфиксный оператор =:, который истинен, если справа у нас список, у которого первый элемент - это имя терма стоящего слева от оператора, а остальные элементы (если они есть) - его аргументы.

Изменения в приложении с версией 2.4:

  1. При запуске приложения вместе с окном появляется сервисное уведомление в шторке уведомлений. Оно нужно для того, чтобы во первых, после закрытия окна его можно было восстановить с текущими данными (на андроид 8 это не работает; на 9 и 10 не проверял), тоесть даже если вы закроете окно, например, при работе программы, все данные которые программа будет выводить в консоль, после восстановления окна, появятся на экран. Во вторых, теперь из шторки уведомлений можно прервать работу программы, например при случайном зацикливании. Приложение, теперь, полностью закрывается только из шторки уведомлений;
  2. Запущенная программа, теперь будет работать и при выключенном экране (Внимание: андроид на xiaomi так устроен, что приложение сильно потребляющее ресурсы, тоесть при работе сложной программы, может быть убито, если окно свёрнуто: не закрыто, не видимо, а именно свёрнуто; имейте ввиду!);
  3. Добавлен поиск в тексте;
  4. Добавлено окно со списком всех операторов, тоесть встроенные и те, которые написаны в программе;
  5. Добавлен предикат ucase/2, у которого второй аргумент это строка с возведёнными символами в верхний регистр строки первого аргумента. Первый аргумент должен быть обязательно определён;
  6. Приложение, призапуске неправильной программы, более подробно показывает ошибку;
  7. Минимаeльные требования: андроид 8.0.

Изменения в приложении с версией 2.5:

  1. Ускорена работа редактора и интерпретатора;
  2. Переменные окрашиваются зелёным цветом;
  3. Добавлен встроенный предикат consult(F), где F - это путь и имя файла. При чтении с консоли (consult(user)), end_of_consult является меткой завершения чтения, после которой должна сразу стоять точка;
  4. Добавлен встроенный предикат lcase(A1,A2), где A2 - это строка A1 превидённая к нижнему регистру;
  5. Добавлен встроенный предикат e(E), Где E - это число e;
  6. Добавлен оператор exp (A1 exp A2), число A1 возводится в степень A2.
  7. Подобие: ?- X. - теперь работает всегда. Например:
    а) ?- X = (Y=5+3), X. Результат: X = ( 8 = 5 + 3 ), Y = 8.
    Или
    б) ?- X = not(7=5+3), X. Результат: X = not ( 7 = 5 + 3 ), потому что, предикат в переменной истинен.

Почему мы должны изучать этот prolog, а не haskell? Пролог отличается тем, что в нем есть жручая “машина логического вывода”, которую надо императивно ограничивать отсечениями перебора, иначе всё будет безбожно тормозить. Вот просто почему сразу не писать хорошо? Да ещё распараллеливаемо для современных многоядерных процессоров (которые, да, в смартфонах).

Не понимаю, что можно распараллелить в логической программе. Это не нейронные сети же, чтобы их параллелить?!

очень обидно смотреть на то, как в процессоре задействовано одно ядро из 32-х, а процесс работы при этом длится днями.

Согласен. Я в таких случаях запускаю ещё клон приложения. (Приложение, для тяжёлой программы, обязательно должно работать или в фоне, или в переднем окне, или в виде плавающего окна, потому что тяжёлое свёрнутое приложение miui от ксиаоми обязательно зарубит).
Так что, когда работают несколько приложений, вероятность получить стих раньше возрастает. :thinking:

Изменения в приложении с версией 3.0:

  1. Параллельное программирование:
    С новой версией приложения появился предикат ‘::-’, который является тем же правилом, но с той разницей, что его предикаты в теле правила выполняются параллельно. Для удобства, назовём его правилом П.
    Например:
    ПравилоП(X)::- предикат1(X), предикат2(X), предикат3(X).
    Здесь, все три предиката будут выполняться одновременно. Что касается переменных, если, к примеру, они есть в голове правила и далее, используются, скажем, во всех предикатах, то на момент запуска предикатов, будут использоваться переменные из заголовка тела, в каждом предикате, такими какими являются в голове правила (включая свободные переменные). И что важно, конкретизация переменных, из головы правила, в одном предикате, не повлияет на те же переменные из другого предиката (считайте их разными копиями). Но, после удачного выполнения эти копии между собой унифицируются. И только после этого, такое правило может быть удачным (декларативно - «истинным»).
    В таком правиле тоже есть механизм возврата с поиском новых решений. С декларативной стороны он выдаст, при необходимости, все возможные решения для каждого предиката, и нам не важно как он их будет искать. Но с технической стороны, это будет происходить следующим образом. Скажем, такое правило, после первого запуска, выдаст первые решения для своих предикатов. Если нужно искать следующий результат, для правила, то сначала делается откат последнего предиката (крайний справа или снизу). Если последний предикат всё равно будет ложным, тогда откатывается предпоследний предикат и т.д. Похоже на обычное правило, не так ли? Но дальше вы узнаете, что есть и разница. Если, скажем, при выполнении правила ПравилоП(Х) (см. выше), после первого решения для правила, неудачным стал предикат предикат2(X), тогда он отправляется в конец списка (после последнего удачного предиката):
    ПравилоП(X)::- предикат1(X), предикат3(X), предикат2(X).
    И если после этого, неудачными будут предикаты: предикат1(X), предикат2(X), тогда, теперь первый предикат отправится перед предикатом предикат2(X) (то-есть, после последнего удачного предиката):
    ПравилоП(X)::- предикат3(X), предикат1(X), предикат2(X).
    А если бы, с самого начала после первого удачного решения, неудачными стали бы оба предиката предикат1(X), предикат2(X), тогда они бы оба отправились в конец списка (после последнего удачного предиката предикат3(X)):
    ПравилоП(X)::- предикат3(X), предикат1(X), предикат2(X).
    Как видите, порядок отправляющихся одновременно предикатов сохраняется: слева на право.
    Все эти перемещения и порядок нужны для того, чтобы получить ВСЕ решения, как если бы они выполнялись последовательно.
    Теперь поговорим ещё об одном виде параллельного программирования - это параллельные вопросы (операторы: ‘!-’ и ‘?-’).
    Параллельные вопросы бывают двух видов:
  1. У первых предикаты выполняются точно также - последовательно, - как и у главного вопроса, за исключением, что эти параллельные вопросы выполняются одновременно с главным и параллельными вопросами. Например:
    cons(вопрос2) ?- предикат1, предикат2.
    Левая часть предиката должна обязательно состоять из функтора cons и одного атомарного аргумента, который не может быть переменной (идентификатор вопроса).
  2. У вторых предикаты выполняются параллельно, как в правилах П, ну и конечно, сами вопросы выполняются одновременно с главным и параллельными вопросами. Например:
    par(вопрос2) ?- предикат1, предикат2.
    Левая часть предиката должна обязательно состоять из функтора par и одного атомарного аргумента, который не может быть переменной (идентификатор вопроса).
    Теперь, поговорим немножко о том что будет, если нехватит ОЗУ при выполнении параллельных правил П.
    Допустим, у вас, выполняется параллельное правило правП1 с предикатами: предикат1, предикат2. Итак, предикат1 и предикат2 выполняются параллельно. Что же будет, если во время их выполнения не хватит оперативной памяти? А будет то, что в какой-то момент, один предикат будет выполняться дальше, а другой будет ждать, пока не выполнится первый. А если быть точнее, пока не освободится достаточно памяти. А поскольку надо, чтобы не просто выполнился один из предикатов, а после выполнения одного снова освободилась память, - я советую делать следующее. Допустим, вам известно, что с правиломП может такое случиться. Тогда, с каждым его предикатом (предикат1, предикат2 и т.д.) нужно сделать следующую трансформацию:
    предикат1_(M,X):- предикат1(X), assertA (p(M,X)), false; retractA (p(M,X)).
    Мы создали новый предикат предикат1_(M,X), в котором при удачном выполнении предиката предикат1(X), сохраняется результат его выполнения в факт p(M,X), где М - это уникальный идентификатор предиката (чтобы не путался факт одного предиката с фактом другого). Таким образом, после выполнения предиката предикат1(X), весь стэк освобождается до момента его выполнения, что позволяет дальше выполняться другим параллельным предикатам.
  1. Добавлены предикаты:
    а) lock_up_writeread/0. Предоставляет текущему вопросу выводить на экран или в файл или читать аналогично, не позволяя другим параллельно выполняющимся вопросам делать в этот момент тоже самое;
    б) unlock_writeread/0. Разблокировка ввода-вывода, если в вопросе, из которого он вызван, была использована блокировка (lock_up_writeread);
    в) mark/1. Используется для получения заголовка вопроса являющийся индивидуальным идентификатором. Например:
  • par(1)!- mark(M).
    M = par(1).
  • cons(2)?- mark(M).
    M = cons(2).
  • Но: ?- mark(M).
    M = ?.
    г) synchronize/1. Синхронизирует код с другими потоками (параллельными вопросами или правилами), у которого аргумент должен быть атомарным, являющийся меткой для синхронизации с другим таким же кодом. Работа его такова: когда два или несколько вопросов или параллельных предикатов доходят до этого предиката с одной и той же меткой, у одного код выполнятся дальше, остальные ждут;
    д) unsynchronize/1. Завершает синхронизацию кода с определённой меткой.

Это как-нибудь согласуется с какими-нибудь стандартами на пролог, или теперь получился несовместимый язык?

Это просто добавление. Всё что должно быть в прологе - здесь есть. Это просто добавление.
Хотите пользуйтесь - хотите нет.

Ну вообще, PrologClassic похож на SWI-Prolog. Его приемущество в том, что он работает на Андроиде.

приемущество

Это не аргумент. На андроиде надо программировать на том, на чём программируют для андроида максимальное количество людей, то есть на Java.

Аргумент изучать пролог должен крыться в каких-то уникальных возможностях, даруемых самим прологом. Но их не существует.

Но я и не думал выставлять его для создания коммерческих приложений. Не зря же он работает в консоли. Для обучения прологу разве не сгодится? SWI-Prolog , вроде, на андроиде не работает. А этот - да. Разве не удобно иметь корманное приложение, которое всегда с тобой?
Может я в статье, написал что-то лишнее, прошу прощения.

Изменения в версии 3.2:
С новой версией добавлен умный помощник (его зовут Ванечка). Этот помощник основан на базе генеративной языковой модели.


Для того, чтобы этот помощник появился нужно при первом запуске приложения или в настройках выбрать желаемую GPT на базе которой помощник будет работать (YandexGPT или GigaChat) и ввести авторизационные данные (после подключения в облаке, например Yandex Cloud) услуги работы с API генеративной модели (как это сделать - читайте документацию для соответствующей «сетки»).

Возможности помощника:

  1. может предоставить общую справочную информацию по PrologClassic и вообще по прологу, например:

  2. может предоставить справочную информацию по встроенным операторам и встроенным предикатам, например:

  3. может написать небольшой программный код (в запросе должны обязательно присутствовать ключевые слова: «программный код»), например:

Некоторые рекомендации:

  1. Касательно GigaChat Lite (в приложении обозначена как GigaChat);
  2. В чате, после запроса на написание программного кода, если нужно получить справочную информацию - нужно очистить чат, т.к. после написания кода сетка ещё будет думать об этом коде и не поймёт что вы от неё хотите.

Отличный маркетинговый материал. Жаль, что я не покупатель.

Изменения в приложении с версией 3.4:

  1. возможность использовать в функторе терма одинарную ковычку добавив её двумя одинарными ковычками, например:
'Вася ''лентяй'''(двоечник) или 'минералка ''боржоми'''
  1. добавлен предикат speak/3 позволяющий синтезировать речь средствами ОС Андроид, например:
speak ('Привет. Меня зовут Вася',1,1)

Второй параметр указывает тембр голоса, третий - скорость произношения. Предикат произносит предложения на русском языке, голос же, например мужской или женский, выбирается в настройках Андроид. В качестве примера его работы, можно скачать и запустить файл с программой “Крестики и нолики 1.5.txt” (файл находится здесь ). Это написанная мной программа игры в крестики и нолики с компьютером, каждый ход озвучивается компьютером.

Изменения в приложении с обновлением 3.41:
• добавлен предикат sleep/1 , заставляющий вопрос остановиться на столько, сколько указано мелисикунд в аргументе, например:

sleep (1000)

Изменения в приложении с версией 4.0:

  1. Новые типы данных.
    Теперь атомарный терм может быть не только атомом, числом и переменной, но ещё и изображением, и аудиозаписью.

  2. Появились новые предикаты:
    image/1 - является ли терм изображением;
    sound/1 - является ли терм аудиозаписью;
    img_width/2 - изменить ширину картинки, а вместе с ней и высоту пропорционально ширине. Первый аргумент - это само изображение, а второй - величина новой ширины в пикселях;
    connection/2 - задаёт авторизационные данные для работы с нейросетями. Для Яндекса - это Oauth яндекс-аккаунта и Id папки. Для Сбера - это Авторизационные данные и Client Secret (RqUID);
    chat_YandexGPT/5 - генерирует текст нейросетью YandexGPT. Аргументы: 1-ый - это атом представляющий из себя системный текст запроса; 2-ой - список атомов представляющих из себя пользовательский текст с ответами нейросети; 3-ий - тип нейросети: YandexGPT Lite, YandexGPT Pro и YandexGPT Pro 32k; 4-ый - температура; 5-ый - это атом: ответ нейронной сети;
    chat_GigaChat/5 - генерирует текст нейросетью GigaChat. Аргументы: 1-ый - это атом представляющий из себя системный текст запроса; 2-ой - список атомов представляющих из себя пользовательский текст с ответами нейросети; 3-ий - тип нейросети: GigaChat Lite, GigaChat Pro и GigaChat Max; 4-ый - температура; 5-ый - это атом: ответ нейронной сети;
    chat_YandexART/6 - генерирует изображение нейросетью YandexART. Аргументы: 1-ый - это атом представляющий из себя текст запроса; 2-ой и 3-ий - соотношение сторон изображения; 4-ый - зерно генерации, по умолчанию ставим 0; 5-ый - вес текстового описания, по умолчанию ставим 1; 6-ой - это атомарный терм - изображение: ответ нейронной сети;
    chat_GigaChat_image/4 - генерирует изображение нейросетью Гигачатом (если быть точным - это Кандински в оболочке Гигачата). Аргументы: 1-ый - атом представляющий из себя системный текст запроса; 2-ой - атом представляющий из себя обычный текст запроса; 3-ий - тип нейросети: GigaChat Lite, GigaChat Pro и GigaChat Max; 4-ый - ответ нейронной сети ввиде изображения;
    chat_YandexSpeechKitv1/6 - синтез речи нейросетью Яндекса. Аргументы: 1-ый - текст для синтеза; 2-ой - атом представляющий из себя тип языка (например русский: ‘ru-Ru’); 3-ий - задать голос, например: filipp; 4-ый - амплуа голоса, например: neutral; 5-ый - скорость речи; 6-ой - ответ нейронной сети ввиде аудиозаписи.

Примером использования данных предикатов является программа Сочинитель сказки.


Технология отличная. Сказка плохая. У нас в стране демографический кризис как раз из-за сказок с подобным содержимым. Политики, воспитанные на подобных сказках, не в состоянии принять правильные законы (как, например, недавно приняли в Китае).

Изменения а приложении с версией 4.03:
chat_SberSaluteSpeech/3 - Синтез речи нейросетью Сбера. Аргументы: 1-ый - текст для синтеза; 2-ий - голос, например: Pon_24000; 3-ой - ответ нейронной сети ввиде аудиозаписи.

Изменения в приложении с версией 4.04:

  1. chat_GigaChat/6 (замена старому chat_GigaChat/5)- генерирует текст нейросетью GigaChat. Аргументы: 1-ый - это атом представляющий из себя системный текст запроса; 2-ой - список атомов представляющих из себя пользовательский текст с ответами нейросети; 3-ий - список изображений использующиеся в текущем запросе к нейросети; 4-ый - тип нейросети: GigaChat Lite, GigaChat Pro и т. д. записывающиеся теперь по внутреннему наименованию: GigaChat, GigaChat-Pro, GigaChat-2-Max и т.д.; 5-ый - температура; 6-ой - это атом: ответ нейронной сети;
  2. chat_GigaChat_image/4 - генерирует изображение нейросетью Гигачатом (если быть точным - это Кандински в оболочке Гигачата; замена этому же предикату). Аргументы: 1-ый - атом представляющий из себя системный текст запроса; 2-ой - атом представляющий из себя обычный текст запроса; 3-ий - тип нейросети: GigaChat Lite, GigaChat Pro и т. д. записывающиеся теперь по внутреннему наименованию: GigaChat, GigaChat-Pro, GigaChat-2-Max и т.д.; 4-ый - ответ нейронной сети ввиде изображения;
  3. В окне, где выбирается нейросеть для помощника, теперь для GigaChat модель нейросети пишется вручную и таким образом: GigaChat, GigaChat-Pro, GigaChat-2-Max и т.д.;
    Модели нейросетей GigaChat можно посмотреть здесь.
  4. Исправлена работа помощника касательно запросов: “написать предикат” и “написать программу”.