SWI Prolog中如何将publication列表转为连字符分隔原子列表
问题:将Prolog publication列表转换为连字符分隔的项列表
我有一个函数返回如下SWI Prolog列表:
S = [ publication(12, stout, call), publication(19, jones, wendalissa), publication(26, olson, dessert), publication(33, hansen, away) ]
我希望将其转换为如下形式的列表:
S = [ 19-olson-wendalissa, 7-author-away, 22-jackson-book, 33-anotherauthor-anotherbook ].
参考相关方法无法解决我的问题,我尝试了如下代码:
custom_print(L2) :- sol(S), S = [ publication(12,A1,B1), publication(19,A2,B2), publication(26,A3,B3), publication(33,A4,B4) ], L = [ [12,A1,B1], [12,A2,B2], [26,A3,B3], [33,A4,B4] ], maplist(term_to_atom, L, L1), atomic_list_concat(L1,'-',L2).
我是SWI Prolog新手,正在尝试理解并解决该问题。
解决方案
你的代码存在两个核心问题:
- 硬编码了列表长度与元素结构,无法适配任意长度的
publication列表 atomic_list_concat/3会把整个列表拼接成单个原子,而非生成每个元素都是连字符格式的列表
可以通过以下步骤实现需求:
- 定义单元素转换规则,将
publication(Num, Author, Book)转为Num-Author-Book格式的原子 - 用
maplist/3将规则批量应用到整个列表
基础转换代码
% 单个publication项的转换逻辑 pub_to_atom(publication(Num, Author, Book), Atom) :- atomic_list_concat([Num, Author, Book], '-', Atom). % 处理整个列表的入口函数 convert_publications(PubList, ResultList) :- maplist(pub_to_atom, PubList, ResultList). % 测试用的sol/1函数(模拟你的原始列表来源) sol(S) :- S = [ publication(12, stout, call), publication(19, jones, wendalissa), publication(26, olson, dessert), publication(33, hansen, away) ].
调用示例:
?- sol(S), convert_publications(S, Result). S = [publication(12, stout, call), publication(19, jones, wendalissa), publication(26, olson, dessert), publication(33, hansen, away)], Result = ['12-stout-call', '19-jones-wendalissa', '26-olson-dessert', '33-hansen-away'].
自定义数字/内容的转换
如果需要像示例中那样替换特定项的数字或内容,可以在转换规则里添加匹配逻辑:
% 匹配特定项做自定义替换 pub_to_atom(publication(12, _, _), '7-author-away') :- !. pub_to_atom(publication(19, _, _), '22-jackson-book') :- !. pub_to_atom(publication(26, _, _), '19-olson-wendalissa') :- !. % 默认转换规则 pub_to_atom(publication(Num, Author, Book), Atom) :- atomic_list_concat([Num, Author, Book], '-', Atom).
调用后即可得到你示例中的目标格式。
内容的提问来源于stack exchange,提问作者user17221096
相关产品推荐
相关产品推荐

