Prolog:如何将字典的负索引转换为最大索引的正后继?

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

我有一些如下形式的 SWI-Prolog dictionary

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

由此:

我现在的目标是将这本词典转换成某种形式的词典:

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

例如:

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}

我希望你能帮我找到一些解决问题的好方法,并找到一些谓词来切换那种形式的负索引。

这个问题看起来很具体,所以我将分享一个ad-hoc解决方案。

该解决方案需要将 dict 转换为有序对列表以处理此类对的键。

正键将保持不变,而负键将被修改:利用键列表已排序的事实,这可以通过保持从 M+1 开始的计数器并逐渐更新列表来完成键数。

最后将键与原始值放在一起,并将对列表再次转换为字典。

这是代码:

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).

示例:

?- 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}.