Мне нужно создать список из базы знаний, который может выглядеть следующим образом:
fact1(3,3).
fact1(2,3).
fact1(3,5).
fact1(2,2).
fact1(2,10).
fact1(3,1).
fact1(1,1).
fact1(1,6).
fact2(3,a,b)
fact2(2,c,d)
fact2(1,e,f)
Этот список должен содержать кортежи, каждый из которых содержит второе и третье значение факта 2 и добавленные номера факта 2, всякий раз, когда совпадают первые значения факта 1 и факта 2.
Может быть, станет яснее, когда я покажу, что у меня есть.
Вот мой предикат с утверждением findall, которое, как мне кажется, дает мне самое близкое место, куда мне нужно попасть:
collect_items(List):-
findall((Out1,Out2,Nr),
(fact2(Val1,Out1,Out2),
fact1(Val1,Nr)),
List).
Список, который я получаю от этого, выглядит следующим образом:
List = [(a,b,3),(a,b,5),(a,b,1),(c,d,3),(c,d,2),(c,d,10),(e,f,1),(e,f,6)]
Но мне действительно нужно, чтобы список выглядел так:
List = [(a,b,9),(c,d,15),(e,f,7)]
Это означает, что всякий раз, когда совпадают первые два элемента кортежа, числа, являющиеся третьим элементом кортежа, должны складываться вместе.
Однако я не знаю, как даже приблизиться к чему-то подобному, как я всегда читал, что, как только список задан, его нельзя изменить, поскольку пролог функционален и декларативен.
Так что я думаю, что мне нужно как-то сопоставить каждый элемент с элементом до или после него (поскольку список всегда будет отсортирован по переменным Out1 и Out2), и, если они совпадают, добавьте третье значение в кортеж вместе. Проблема в том, что я понятия не имею, как.
Мне кажется, что это не может быть сделано в самом самом findal, но должно быть сделано после findall
Я настоящий новичок и буду признателен за любую помощь. В этом случае было бы лучше, если бы решение было все в одном предикате.