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)}.
由此:
a(j), -N≤j≤M
是字典的值,键在整数区间[-N, M]\{0}.
我现在的目标是将这本词典转换成某种形式的词典:
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}.
我有一些如下形式的 SWI-Prolog dictionary:
dict_label{-N: a(-N), -N+1: a(-N+1), ..., -1: a(-1), 1: a(1), ..., M: a(M)}.
由此:
a(j), -N≤j≤M
是字典的值,键在整数区间[-N, M]\{0}.
我现在的目标是将这本词典转换成某种形式的词典:
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}.