Search code examples
prologgraph-theoryeclipse-clp

Constructing an array of ground data from list of integers in ECLiPSe


I'm trying to use the make_graph_symbolic/3 from the graph_algorithms library, which requires for the Nodes to be an array of ground data.

As I'm constructing this graph from a matrix, the nodenames are XY, where X is the row and Y the column of a specific element. A different predicate that I've written, nodeNames/2 generates a list of all names (which are integer values).

However, when I try to provide this list to the make_graph_symbolic predicate, it throws the following error for one of the predicates it's using:

out of range in graph_set_nodenames(graph(_1089, _1090, _1091, _1092, _1093, _1094, _1095, _1096), [22, 12, 21, 11])

When I try to do it manually by providing [](11, 12, 21, 22), it works fine. This indicates that my array is wrong, but I can't really see why because integer values are ground.

Now for the actual question: is it possible to transform a list of integers to an array of ground data, containing the same integers?

I'm not that experienced in prolog and ECLiPSe, so I'm not sure if this is possible. I've been looking around for a solution for a couple of days now. The closest that I've come is using the apply([], [list of ints]) predicate, but that does not have the desired effect (as it then tries to evaluate the list).

Edit: I forgot to mention: linearizing the matrix and using the make_graph/2 instead of the make_graph_symbolic-predicate is not really an option since, eventually, not every element from the matrix is going to be used in the graph.

Edit2: example: Let's say I want to extract the nodenames from the following matrix:

[[1, 2],
 [3, 4]].

Desired nodenames are 11, 12, 21 and 22 (where the first number is the row, the second the column). I do this by providing each row to the following predicate:

addNode([], N, _, _, N).
addNode([_| Rest], N, X, Y, NewNodes) :-
    term_string(X, Xs), term_string(Y, Ys), 
    string_concat(Xs, Ys, ID1s),
    term_string(ID1, ID1s),
    addColEdge(Rest, [ID1 | N], X, NewY, NewNodes).

It basically just goes through the list and adds each node to the list until it hits the basecase. For the above graph, this would result in the following list:

Nodes = [22, 21, 12, 11]

Which I then try to feed into the make_graph_symbolic-predicate as its nodelist.

make_graph_symbolic(Nodes, [], Graph).

This results in the error posted above. However, when I hardcode it like this:

make_graph_symbolic([](22, 21, 12, 11), [], Graph).

it works fine. So basically what I'm after is for a way to transform [22, 21, 12, 11] to [](22, 21, 12, 11).


Solution

  • So basically what I'm after is for a way to transform [22, 21, 12, 11] to [](22, 21, 12, 11).

    It looks like you are looking for ECLiPSe's array_list/2 predicate:

    ?- array_list([](a,b,c,d,e,f), L).
    L = [a,b,c,d,e,f]
    
    ?- array_list(A, [a,b,c,d,e,f]),
    A = [](a,b,c,d,e,f)