Мне нужно получить некоторые значения фактов. Эта часть, кажется, работает.
fact1(A, _, Val1, _, _),
fact2(_, B, Val2, _, _),
A = B,
Но как только я пытаюсь добавить эти значения [(Val1,Val2)]
в список (OutList) с помощью предиката append/3, я получаю обратно только одно возможное решение вместо списка со всеми.
Добавление вот так: append(OutList, [(Val1,Val2)], OutList)
тоже не работает. Я чувствую, что мне здесь не хватает чего-то фундаментального.
Вот как выглядит мой предикат до сих пор.
buildList(OutList):-
fact1(A, _, Val1, _, _),
fact2(_, B, Val2, _, _),
A = B,
append([], [(Val1,Val2)], OutList).
Может ли кто-нибудь указать мне на некоторые ошибки, которые я сделал. Я знаю, что проблему, вероятно, довольно легко найти, но я только начинаю с Пролога/функционального программирования.
Редактировать: Если бы у меня были fact1(a,b,c,d,e).
и fact2(f,a,g,h,i)
, то я бы хотел, чтобы мой предикат давал мне список всех значений fact2
3-го места и fact1
значений третьего места в виде кортежа, где a
совпадает с fact1
. Мне трудно объяснить, извините.
Я пробовал findall/3, но он никогда не работал так, как мне нужно. У меня есть база знаний с двумя разными типами фактов. И мне нужно добавить все факты одного типа в список, если он соответствует определенному значению из другого набора фактов. Хотя я не уверен, что это имеет смысл.
Вы были правы, рассматривая использование найтивсе/3, и должны были придерживаться его. Ваша проблема в том, что вы ушли с верного пути. Не волнуйтесь, Эйнштейн сделал то же самое с общей теорией относительности, позже он понял свою ошибку и вернулся на правильный путь.
Первая часть — найти отдельные элементы, вторая — собрать их в список.
Учитывая следующие факты
fact1(1, _, a, _, _).
fact1(2, _, c, _, _).
fact1(3, _, d, _, _).
fact1(4, _, f, _, _).
fact2(_, 1, b, _, _).
fact2(_, 2, c, _, _).
fact2(_, 4, e, _, _).
Найдите отдельные элементы:
find_item((Val1,Val2)):-
fact1(A, _, Val1, _, _),
fact2(_, A, Val2, _, _).
Затем соберите их в список:
findall(Item,find_item(Item),Items).
Теперь, чтобы упростить использование, поместите его в предикат:
test(Items) :-
findall(Item,find_item(Item),Items).
Пример запуска:
?- test(Items).
Items = [(a, b), (c, c), (f, e)].
См. продолжение вопрос для более простого ответа.
Большое спасибо! Это действительно сработало. Вы знаете способ сделать это одним предикатом? Я пытался сделать это некоторое время. Я знаю, что это, вероятно, не самый оптимальный способ, но это было бы очень полезно. Спасибо большое в любом случае.
Да, это имеет смысл. Напишу новый.
Вам что-то нужно от Поиск всех решений цели