合并Prolog列表中的元组元素

时间:2019-04-14 11:51:56

标签: list prolog tuples findall

我需要从一个看起来像这样的知识库中创建一个列表:

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)

该列表需要包含元组,并且每当事实1和事实2的第一个值匹配时,每个元组都包含事实2的第二个和第三个值,以及事实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变量进行排序),并且如果它们匹配,则将元组中的第三个值加在一起。问题是,我不知道如何。

在我看来,这似乎无法在findall本身内完成,但需要在findall之后完成 我是一个真正的初学者,将不胜感激。在这种情况下,最好是将解决方案全部放在一个谓词中。

3 个答案:

答案 0 :(得分:0)

这不是最终解决方案,因为这是家庭作业。

transformation(fact2(N,A,B),values(Values,A,B)) :-
    bagof(Value,fact1(N,Value),Values).

sum_values(values(Values,A,B),values(Sum,A,B)) :-
    sum_list(Values,Sum).

items(Items) :-
    bagof(fact2(N,A,B), fact2(N,A,B),Facts2),
    maplist(transformation,Facts2,Items1),
    maplist(sum_values,Items1,Items).

示例运行:

?- items(Result).
Result = [values(9, a, b), values(15, c, d), values(7, e, f)].

答案 1 :(得分:0)

这是另一个使用多个谓词的解决方案:

collect_items(Result):-
    findall([Out1,Out2,Nr],(fact2(Val1,Out1,Out2),fact1(Val1,Nr)),[[OutA, OutB, N]|B]), 
    sumElements([[OutA, OutB, N]|B], Result).

sumElements([],[]).
sumElements([[Out, Outt, N]|B], [[Out, Outt, SumLocal]|RestOfList]):-
    findall([Out, Outt, X], member([Out, Outt, X], [[Out, Outt, N]|B]), SubList),
    sumLocal(SubList, SumLocal),
    subtract([[Out, Outt, N]|B], SubList, New),
    sumElements(New, RestOfList).

sumLocal([],0).
sumLocal([[_,_,S]|B], T):-
    sumLocal(B, R),
    T is S + R.

输出:

?- collect_items(Result).
Result = [[a, b, 9], [c, d, 15], [e, f, 7]].

答案 2 :(得分:0)

具有库聚合:

collect_items(L) :-
    setof((U,V,S),
          K^aggregate((set(X/Y),sum(N)), (
                          fact2(K,X,Y),
                          fact1(K,N)
                      ), ([U/V],S)), L).

我们得到

?- collect_items(L).
L = [(a, b, 9),  (c, d, 15),  (e, f, 7)].

您不在这里

  

因为序言是功能性和声明性的

序言是关系和声明性的