A
Android
Original poster
“Мне нравится программировать в Picat, потому что это очень хорошо подходит для моего мышления.” - Хакан Кьеллерстранд
Язык Picat действительно классный; это очень полезное сочетание логики, функциональности, ограничений и императивного программирования. Скрипты могут быть сделаны довольно короткими, но также легко читаемыми. А встроенный таблинг действительно хорош для ускорения рекурсивных программ. «Я думаю, что Пикат похож на идеальный швейцарский армейский нож, с которым можно делать все что угодно» - Лоренц Шиффманн.
Picat - это простой и в то же время мощный, основанный на логике язык программирования с множеством парадигм, предназначенный для приложений общего назначения. Picat - это язык на основе правил, в котором предикаты, функции и акторы определяются с помощью правил сопоставления с образцом. Picat включает в себя множество функций декларативного языка для повышения производительности разработки программного обеспечения, в том числе явный недетерминизм, явное объединение, функции, списки, ограничения и табулирование. Picat также предоставляет обязательные языковые конструкции, такие как назначения и циклы, для программирования повседневных вещей. Реализация Picat, которая основана на хорошо спроектированной виртуальной машине и включает диспетчер памяти, который собирает мусор и расширяет стеки и области данных, когда это необходимо, является эффективной и масштабируемой. Picat можно использовать не только для символьных вычислений, которые являются традиционной областью применения декларативных языков, но также для задач сценариев и моделирования.
Пример 1. Следующий предикат input_data (Tri) считывает строки целых чисел из текстового файла triangle.txt в массив. Это первая часть решения Picat для проекта Эйлера, проблема № 67.
импорт утилит
input_data (Tri) =>
Lines = read_file_lines ("triangle.txt"),
Tri = new_array (Lines.length),
Я = 1,
foreach (линия в строках)
Tri = Line.split (). Map (to_integer) .to_array (),
Я: = Я + 1
конец.
Функция read_file_lines / 1, которая по умолчанию импортируется из модуля io, считывает все строки из файла в виде списка строк. Для каждой строки в строках цикл foreach разбивает строку на токены (с помощью функции split / 1, импортированной из модуля util), отображает токены в целые числа (map (to_integer)) и преобразует список в массив ( to_array). Как показано в этом примере, Picat, как язык сценариев, так же мощен, как Python и Ruby.
Пример 2: следующая функция perms (L) возвращает список всех перестановок L.
Пермс ([]) = [[]].
perms (Lst) = [[E | P]: E в Lst, P в перми (Lst.delete (E))].
Picat предоставляет функции «функционального программирования», такие как сопоставление с образцом, рекурсия и понимание списка, для составления функций.
Пример 3: учитывая треугольник, хранящийся в массиве, следующий табличный предикат находит максимальную общую сумму сверху вниз. Это вторая часть решения Picat для проекта Эйлера, проблема № 67.
таблица (+, +, max, nt)
путь (Row, Col, Sum, Tri), Row == Tri.length => Sum = Tri [Row, Col].
путь (Row, Col, Sum, Tri)? =>
Путь (строка + 1, Col, sum1, Tri),
Sum = Sum1 + Tri [Row, Col].
путь (Row, Col, Sum, Tri) =>
Путь (строка + 1, Col + 1, sum1, Tri),
Sum = Sum1 + Tri [Row, Col].
Первая строка - это объявление режима таблицы, которое инструктирует систему о том, как составить таблицу вызовов и ответов: + означает, что аргумент является табличным, max означает, что аргумент должен быть развернут, а nt означает, что аргумент не представлен. Этот предикат ищет путь с максимальной общей суммой. Если текущая строка находится внизу треугольника, то возвращается значение листа. В противном случае он делает недетерминированный выбор между двумя ветвями, одна идет прямо вниз, а другая - вниз к соседнему числу. Эта программа не только компактна, но и работает быстро. Для 100-рядного треугольника, предоставленного проектом Эйлера, эта программа находит ответ всего за 0,01 секунды.
Модуль планировщика основан на табулировании. Для задачи планирования пользователям нужно только указать условия для конечных состояний и набор действий и вызвать плановика в начальном состоянии, чтобы найти подходящий план.
Пример 4: Ниже приведена часть программы по проблеме Фермера.
планировщик импорта.
идти =>
S0 = [S, S, S, S],
best_plan (S0, план),
WriteLn (план).
final ([n, n, n, n]) => true.
действие ([F, F, G, C], S1, Action, ActionCost)? =>
Действие = farmer_wolf,
ActionCost = 1,
напротив (F, F1),
S1 = [F1, F1, G, C],
небезопасно (S1).
...
Показано, что включение, когда оно расширено с помощью методов совместного использования терминов, досрочного прекращения и ограниченного по ресурсам поиска, является лучшей альтернативой планированию, чем планировщики PDDL на основе ASP и SAT.
В настоящее время Picat предоставляет два модуля с именами cp и sat для решения проблем удовлетворения и оптимизации. Оба модуля используют один и тот же интерфейс. Это позволяет плавно переключаться с одного решателя на другой. Функции языка, такие как массивы, карты, циклы и списки, делают Picat мощным языком моделирования для задач с ограничениями.
Пример 5: В следующем примере моделируется проблема N-ферзей с использованием трех ограничений all_different.
импортная цена
Queens(N, Q) =>
Q = new_list (N),
Q :: 1..N,
all_different (Q)
all_different ([$ Q -I: I в 1..N]),
all_different ([$ Q + I: I в 1..N]),
решения ([далее], Q).
Как показали приведенные выше примеры, Picat предлагает много преимуществ перед другими языками. По сравнению с функциональными языками и языками сценариев поддержка явной унификации, явного недетерминизма, табуляции и ограничений делает Picat более подходящим для символьных вычислений. По сравнению с Prolog, Picat, возможно, более выразителен и масштабируем: нередко можно найти проблемы, для которых Picat требует на порядок меньше строк кода для описания, чем Prolog. Picat может быть значительно быстрее, чем Prolog, потому что сопоставление с образцом облегчает индексирование правила.
Надеемся эта информация была вам полезна!