Подтвердить что ты не робот

Хэш-таблицы в прологе

Я решил головоломку в прологе на днях и понял, что если я использую другой язык программирования, я бы использовал хэш-таблицу/словарь, но насколько я знаю, это невозможно в прологе.

Итак, мой первый вопрос: есть ли прологи, которые поддерживают подобную словарю структуру данных с характеристиками производительности хеш-таблицы?

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

4b9b3361

Ответ 1

Я только что узнал, что:

Версия 7 SWI-Prolog представляет диктовки как абстрактный объект с конкретным современным синтаксисом и функциональной нотацией для доступа к членам, а также к функциям доступа, определенным пользователем.

Синтаксис выглядит следующим образом:

Tag{Key1:Value1, Key2:Value2,...}

См. Dicts: структуры с именованными аргументами для деталей.

Обратите внимание, что:

Временная сложность операций настоящей реализации (2019) приведена в руководстве по SWI Prolog в разделе "5.4.5: Замечания по реализации о диктантах":

Dicts в настоящее время представлены как составной термин, используя dict. Первый аргумент - это тег. Оставшиеся аргументы создают массив отсортированных пар ключ-значение. Это представление компактно и гарантирует хорошее месторасположение. Поиск - это журнал порядка (N), в то время как добавление значений, удаление значений и слияние с другими диктовками имеет порядок N. Основной недостаток состоит в том, что изменение значений в больших диктовках является дорогостоящим как с точки зрения памяти, так и времени.

Будущие версии могут совместно использовать ключи в отдельной структуре или использовать двоичные деревья для более дешевых обновлений. Одна из проблем заключается в том, что представление должно быть либо каноническим, либо унификация должна быть расширена для компенсации альтернативных представлений.

Ответ 2

В некоторых средах Prolog есть списки Ассоциации, которые можно использовать для создания и редактирования словаря:

Edit:

Возможно, вы сможете повысить производительность за счет реализации предикатов на иностранных языках, например:

Ответ 3

Я не парень Пролога (только внешний наблюдатель), но я нашел это:

http://www.sics.se/sicstus/docs/4.0.7/html/sicstus/lib_002davl.html

когда я искал "сбалансированные деревья с простыми конечными картами". Он говорит об альтернативной реализации списков ассоциаций.

(Почему я подумал об этом: в Haskell, чисто функциональном языке, вместо списков ассоциаций или хеш-таблиц, обычно используют деревья для (постоянных) словарей или конечных карт. Lookups также O (log (N)). См. Data.Map для некоторых ссылок на реализацию карт со сбалансированными деревьями.)

Ответ 4

В SICStus Prolog используйте assoc или avl.

Ответ 5

Следующие комментарии касаются вашего вопроса в порядке, грубо говоря, от "более конкретного" до "более общего".

Сначала, обращаясь к вашему конкретному комментарию:

Я бы использовал хэш-таблицу/словарь, но насколько я знаю, это невозможно в Прологе.

Все серьезные реализации Prolog позволяют деструктивно изменять термины Prolog, используя, например, setarg/3. Использование arg/3 и setarg/3 дает вам O (1) доступ к каждому аргументу термина, чего достаточно для реализации хэш-таблицы точно так же, как и на других языках, если ваша система не устанавливает произвольные ограничения на атрибуты терминов.

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

Какие библиотеки? Я второй, что другие написал: вместо хэширующих библиотек используйте древовидные библиотеки, такие как library(assoc), library(avl) и т.д. Они не так эффективны, как хэши в среднем случае, но:

  • они часто достаточно эффективны
  • они масштабируются очень предсказуемо: наиболее важные операции всегда в O (log (n)).

Также, как и другие, деструктивные модификации несовместимы с логическим программированием, а библиотеки деревьев имеют огромное преимущество в том, что они могут быть реализованы в ISO Prolog и в чистом   с асимптотически оптимальной эффективностью.

Наконец, расшифровки расширений SWI-Prolog не соответствуют ISO, даже синтаксически и, следовательно, не переносятся в совместимые системы Prolog! См. Ulrich Neumerkel комментарии о том, как добавить инфиксную точку в ISO-совместимый способ.