Пролог нескольких объединений в одну переменную

#prolog #prolog-findall

#пролог #пролог-поиск

Вопрос:

Мне нужно объединить все термины в базе данных в одну переменную.

Для данного кода:

 man('a').
man('b').

main :-
        prompt(_, ''),
        man(X),
        write(X),
        nl,
        halt.
  

Я получаю вывод:

 a
  

Мне нужно получить что-то вроде:

 ['a','b']
  

Возможно ли это? Я знаю о retract/1 , который удаляет термин из базы данных, я мог бы перебрать все эти факты и удалить их из базы данных один за другим, но это похоже на выстрел в ногу. Любой данный совет приветствуется.

Комментарии:

1. Вы можете использовать findall/3 для получения списка результатов, поэтому findall(X, man(X), L) будет создан список L = ['a', 'b'] .

2. Большое спасибо, именно то, что мне было нужно.

Ответ №1:

Если у вас есть набор фактов, таких как:

 man(a).
man(b).
  

Как было указано в комментариях, вы можете найти все решения с помощью findall :

 | ?- findall(X, man(X), Solutions).
Solutions = [a, b]
  

Вы также можете изменить свою исходную программу, чтобы использовать цикл, управляемый сбоями. fail in Prolog делает именно это: он терпит неудачу, и поэтому он заставляет Prolog возвращаться. После man(X) того, как не удастся найти больше решений, тогда первое предложение main окончательно завершит Пролог до второго предложения, которое просто завершится успехом без дальнейших действий:

 main :-
    man(X),
    write(X),
    nl,
    fail.
main.
  

Теперь, если вы запросите main , вы получите:

 | ?- main.
a
b

yes
| ?-
  

В контексте более широкой программы findall/3 может быть предпочтительнее, поскольку она фиксирует решения для вас, тогда как приведенное выше просто «распечатывает» их, не собирая их. Хотя бывают случаи, когда это все, что требуется.