Ответ в теме: Пример работы с базами данных в Prolog

      Комментарии к записи Ответ в теме: Пример работы с базами данных в Prolog отключены
#2522

За исключением небольших деталей, реализация для Visual Prolog не будет отличаться от других реализаций (например на SWI Prolog).

Для начала в Visual Prolog нужно описать используемые в программе домены (типы данных), а для диалектов с динамической типизацией эту часть можно пропустить:

domains
  d_continent = string
  d_state = string
  d_square = real
  d_population = real
  d_capital = string
  
  d_continents = d_continent*
  d_populations = d_population*
  d_states = d_state*

Затем, нужно объявить тип записей базы данных — в SWI Prolog для этого используется ключевое слово dynamic (вы читали про нее в теме про функции для работы с БД), а в Visual Prolog — секция database:

database -states_db
  nondeterm state(d_continent, d_state, d_square, d_population, d_capital)

База данных в Visual Prolog должна быть или глобальной (global database) или иметь свое имя (БД в примере имеет имя states_db). При этом глобальная БД может использовать только глобальные домены. Факты (записи) базы данных могут быть описаны в секции clauses — при этом они будут загружаться каждый раз при запуске программы или находиться во внешнем файле, подключаемом стандартной функцией consult — такой подход используется если возникает необходимость хранить изменения базы данных между запусками программы. Факты могут быть описаны следующим образом:

  state ("Europe", "United Kingdom", 244.0, 57077.0, "London").
  state ("Europe", "Italy", 301.0, 57441.0, "Rome").
  state ("Asia", "Indonesia", 1905.0, 179140.0, "Jakarta").
  state ("Asia", "Iraq", 435.0, 17655.0, "Baghdad").
  state ("Asia", "Iran", 1648.0, 52522.0, "Tehran").
  state ("Asia", "Kuwait", 18.0, 2050.0, "Kuwait").
  state ("Asia", "Oman", 212.0, 1377.0, "Muscat").
  state ("Asia", "Saudi Arabia", 2150.0, 14430.0, "Al-Riyadh").
  state ("Africa", "Libya", 1760.0, 4232.0, "Tripoli").
  state ("North America", "USA", 9373.0, 248251.0, "Washington").
  state ("South America", "Argentina", 2767.0, 31930.0, "Buenos Aires").

Пусть наша программа умеет: выводить всю информацию из базы; печатать информацию о странах заданного континента; выводить информацию о странах, упорядоченных по населению; добавлять и удалять записи базы данных. В диалектах prolog с динамической типизацией мы сразу можем приступить к написанию предикатов, но в SWI Prolog — сначала необходимо описать количество и типы их входных аргументов в секции predicates:

predicates
  menu(integer)
  
  print_state_information(d_continent, d_state, d_square, d_population, d_capital)
  print_states_by_continent_information(d_continent)
  print_sorted_by_populations(d_states, d_populations)
  
  list_to_set(d_continents, d_continents, d_continents)
  nondeterm member(d_continent, d_continents)
  nondeterm member(d_state, d_states)
  
  qsort(d_populations, d_populations)
  divide(d_populations, d_population, d_populations, d_populations)
  append(d_populations, d_populations, d_populations)
  
  print_states(d_states)
  filter_states_by_population(d_states, d_population, d_population, d_states)
  
  print_continents

Большая часть описанных предикатов уже описаны на блоге или являются стандартными: для сортировки записей нам пригодится функция qsort, которая использует функцию divide для разделения списка на элементы большие и меньшие заданного значения и встроенную функцию append для соединения списков. Кроме того, при сортировке нам потребуется удалять из списка один элемент списка с заданным значением, для этого напишем функцию delete_single_element, которую можно построить на базе стандартного select.

Чтобы вывести все имеющиеся в базе данных континенты без повторений нам потребуется преобразовывать список во множество (удалять из него повторы) — для этого можно применить функцию list_to_set, которая использует встроенный предикат member для поиска элемента в списке.