Как превратить выходные данные функции в список? - PullRequest
1 голос
/ 03 декабря 2011

У меня есть функция, которая выводит имена, которые соответствуют определенному ограничению. Эта функция в порядке.

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

Моя проблема в том, что я не знаю, как перебирать выходы, чтобы добавить их в аккумулятор. Функция, которая выводит имена, делает это, затем я нажимаю «;» или ПРОБЕЛ, и он выводит следующий ответ, пока он не из ответов. Я полагаю, это означает, что я должен сделать несколько вызовов функции, а затем добавить ее. Но я не знаю, сколько раз мне нужно вызывать его, поскольку я не могу перебрать его, как список с [Head | Tail].

Вот что у меня есть (хотя, вероятно, это неправильно):

%p1(L,X) determines if chemicals in List X are in any of the products and stores those        products in L
p1(L,X) :- p1_helper(L,X,[]).
p1_helper(L,X,Acc) :- has_chemicals(A,X),append(Acc,[A],K),L=K, p1_helper(L,X,K).

функция, которая выводит имена с запросом has_chemicals (X, [Список химических веществ]).:

%has_chemicals(X,Is) determines if the chemicals in List Is are in the chemical list of X.
has_chemicals(X,Is) :- chemicals(X,Y), hc(Y,Is).
%hc(X,Y) determines if elements of Y are in elements of X.
hc(Y,[]).
hc(Y,[C|D]) :- isin(C,Y), hc(Y,D).

Любая помощь приветствуется.

Ответы [ 3 ]

3 голосов
/ 03 декабря 2011

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

findall(+Template, :Goal, -Bag): Создает список экземпляров, которые Template последовательно получает при возврате через Goal и объединяет результат с Bag.

Например, как собрать все нечетные числа от 1 до 15:

odd( X ) :-
    X rem 2 =:= 1.

Мы можем получить все эти коэффициенты один за другимодин.

?- between( 1, 15, X ), odd( X ).
X = 1 ;
X = 3 ;
X = 5 ;
X = 7 ;
X = 9 ;
X = 11 ;
X = 13 ;
X = 15.

И мы можем собрать их в список:

?- findall(X, (between( 1, 15, X ), odd( X )), List).
List = [1, 3, 5, 7, 9, 11, 13, 15].
2 голосов
/ 03 декабря 2011

Я думаю, что вы ищете способ получить выходные данные isin / 2. Затем вы можете использовать встроенный with_output_to / 2 и объединить его с findall / 3, как это предлагают другие ответы.

0 голосов
/ 03 декабря 2011

Я рекомендую вам посетить эту страницу , особенно если вы используете swi-prolog.

Существует 4 предиката, которые делают то, что вы хотите: findall/3, findall/4, bagof/3 и setof/3.

Подводя итог, вот предикат теста, с которым я буду работать:

test(0, 3).
test(1, 3).
test(2, 5).
test(3, 4).

Сначала самое простое - findall / 3 и findall / 4:

?- findall(C, test(X, C), Cs).
Cs = [3, 3, 5, 4].

?- findall(C, test(X, C), Cs, TailCs).
Cs = [3, 3, 5, 4|TailCs].

Они просто возвращают все альтернативы, с дубликатами, без сортировки, без привязки других свободных переменных, как обычный список для findall/3 и список различий для findall/4.оба предиката findall s успешно завершаются, когда список пуст.

Затем bagof.По сути, bagof/3 работает как findall/3, но связывает свободные переменные.Это означает, что тот же запрос, что и выше, но с bagof/3 возвращает:

?- bagof(C, test(X, C), Cs).
X = 0,
Cs = [3] ;
X = 1,
Cs = [3] ;
X = 2,
Cs = [5] ;
X = 3,
Cs = [4].

Говоря bagof/3 не связывать все свободные переменные, вы получаете findall/3:

?- bagof(C, X^test(X, C), Cs).
Cs = [3, 3, 5, 4].

Тем не менее, вы должны заметить, что bagof/3 терпит неудачу, когда результат пустой, где findall/3 нет.

Наконец, setof/3.Это в основном bagof/3, но с отсортированными результатами и без дубликатов:

?- setof(C, X^test(X, C), Cs).
Cs = [3, 4, 5].
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...