Home > Net >  Prolog: How to switch negative indexes of dictionary into positive successors of the maximal index?
Prolog: How to switch negative indexes of dictionary into positive successors of the maximal index?

Time:04-17

I have some SWI-Prolog dictionary of following form:

dict_label{-N: a(-N), -N 1: a(-N 1), ..., -1: a(-1), 1: a(1), ..., M: a(M)}.

whereby:

  • a(j), -N≤j≤M are the values of the dictionary with keys in the integer interval [-N, M]\{0}.

My aim now is to convert this dictionary into some dictionary of form:

dict_label{1: a(1), ..., M: a(M), M 1: a(-N), ..., M N: a(-1) }.

as example:

P = test_label{-5: e, -4: f, -3: g, -2: h, -1: i, 1: a, 2:b, 3: c, 4: d} 

should be converted into:

Q = test_label{1: a, 2: b, 3: c, 4: d, 5: e, 6: f, 7: g, 8: h, 9: i}

I hope you can help me to find some good way to solve the problem and find some predicate to switch negative index in that form.

CodePudding user response:

The problem seems very specific, so I will share an ad-hoc solution to solve it.

The solution requires the transformation of the dict into a list of ordered pairs to work on the keys of such pairs.

The positive keys will remain unchanged while the negative keys will be modified: by using the fact that the list of keys is ordered this can be done by keeping a counter starting at M 1 and gradually updating the list of keys.

Finally the keys are put together with the original values and the list of pairs is transformed again into a dictionary.

This is the code:

dict_normalize(DictIn, DictOut) :-
        dict_pairs(DictIn, Tag, Pairs), % transform dict into ordered list of pairs
        pairs_normalize(Pairs, NewPairs), % work on the pairs to get the new dict
        dict_pairs(DictOut, Tag, NewPairs).

pairs_normalize(PairsIn, PairsOut) :-
        pairs_values(PairsIn, Values), % extract values
        pairs_keys(PairsIn, Keys), % extract keys
        keys_normalize(Keys, NewKeys), % work on the keys to get the new list of pairs
        pairs_keys_values(PairsOut, NewKeys, Values).

keys_normalize(KeysIn, KeysOut) :-
        max_list(KeysIn, Max),
        Start is Max   1, % determine the starting index for negative values
        keys_normalize(KeysIn, Start, KeysOut). % this predicate works because keys are known to be ordered

keys_normalize([], _, []).
keys_normalize([H|T], N, [N|NewT]) :- % negative key
        H < 0,
        !,
        NewN is N   1,
        keys_normalize(T, NewN, NewT).
keys_normalize([H|T], N, [H|NewT]) :- % positive key (unchanged)
        keys_normalize(T, N, NewT).

Example:

?- P = test_label{-5: e, -4: f, -3: g, -2: h, -1: i, 1: a, 2:b, 3: c, 4: d},
dict_normalize(P, Q).

P = test_label{-5:e, -4:f, -3:g, -2:h, -1:i, 1:a, 2:b, 3:c, 4:d},
Q = test_label{1:a, 2:b, 3:c, 4:d, 5:e, 6:f, 7:g, 8:h, 9:i}.
  • Related