Extracting facts as a matrix in Prolog

Suppose we have:

edge(a, 1, 10).
edge(b, 2, 20).
edge(c, 3, 30).
edge(d, 4, 40).

I want to extract the matrix representation ( M) of these facts, so that

M = [[a,b,c,d],[1,2,3,4],[10,20,30,40]]

There are no problems here:

edgeMatrix(M) :-
  findall(A, edge(A, _, _), As),
  findall(B, edge(_, B, _), Bs),
  findall(C, edge(_, _, C), Cs),
  M = [As, Bs, Cs].

There are some problems for this approach, namely:

  • we go through the database n times, where n is the number of arguments; and
  • this does not generalize well to arbitrary n.

So the question is: what is the most idiomatic way to achieve this in Prolog?

+4
source share
2 answers

What about:

edgeMatrix(M) :-
    findall([A,B,C],edge(A,B,C),Trans),
    transpose(Trans,M).

transpose/2 clpfd (, , , ?).

swipl, :

?- edgeMatrix(M).
M = [[a, b, c, d], [1, 2, 3, 4], [10, 20, 30, 40]].

, .

, , transpose/2 , ( , ), , , , , , , .

+5

, , . N = 3:

edges(Edges) :-
    Goal = edge(_A, _B, _C),
    findall(Goal, Goal, Edges).

edges_abcs_([], [], [], []).
edges_abcs_([edge(A,B,C)|Edges], [A|As], [B|Bs], [C|Cs]) :-
    edges_abcs_(Edges, As, Bs, Cs).

edges_abcs([As, Bs, Cs]) :-
    edges(Edges),
    edges_abcs_(Edges, As, Bs, Cs).

100 000 edge/3 :

?- time(edges_abcs(M)).
% 200,021 inferences, 0.063 CPU in 0.065 seconds (97% CPU, 3176913 Lips)
M = [[a, b, c, d, 1, 2, 3, 4|...], [1, 2, 3, 4, 1, 2, 3|...], [10, 20, 30, 40, 1, 2|...]].

, :

?- time(edgeMatrix_orig(M)).
% 300,043 inferences, 0.061 CPU in 0.061 seconds (100% CPU, 4896149 Lips)
M = [[a, b, c, d, 1, 2, 3, 4|...], [1, 2, 3, 4, 1, 2, 3|...], [10, 20, 30, 40, 1, 2|...]].

, transpose/2 :

?- time(edgeMatrix_transpose(M)).
% 700,051 inferences, 0.098 CPU in 0.098 seconds (100% CPU, 7142196 Lips)
M = [[a, b, c, d, 1, 2, 3, 4|...], [1, 2, 3, 4, 1, 2, 3|...], [10, 20, 30, 40, 1, 2|...]].

, : 100 000 findall/3 100 000 . 100 000 findall/3, . , , , : , , , 100 000 edge/3 , . ( SWI-Prolog , / GC.)

, , N, , - .

: "" , edge SWI-Prolog. findall/3 .

+2

Source: https://habr.com/ru/post/1665932/


All Articles