使用Prolog将csv文件中的数据解析为给定格式
我有包含以下数据的csv文件:使用Prolog将csv文件中的数据解析为给定格式,csv,prolog,swi-prolog,Csv,Prolog,Swi Prolog,我有包含以下数据的csv文件: A B C A - 4 5 B 8 - 6 C 2 3 - 我希望得到以下形式的事实: num(a,b,4). num(a,c,5). num(b,a,8). num(b,c,6). num(c,a,2). num(c,b,3). 类似于num(a,a,-)这样的字母表不应该存在事实 我使用prolog的csv_read_文件作为: csv_read_file(Path, Rows, [functor(num), arity(4)]), m
A B C
A - 4 5
B 8 - 6
C 2 3 -
我希望得到以下形式的事实:
num(a,b,4).
num(a,c,5).
num(b,a,8).
num(b,c,6).
num(c,a,2).
num(c,b,3).
类似于num(a,a,-)这样的字母表不应该存在事实
我使用prolog的csv_read_文件作为:
csv_read_file(Path, Rows, [functor(num), arity(4)]), maplist(assert, Rows).
它给我的输出是:
Rows = [num('', 'A', 'B', 'C'), num('A', -, 4, 5), num('B', 8, -, 6), num('C', 2, 3, -)]
这似乎是一个基本问题,但我无法考虑执行此操作的条件。我们将非常感谢您的帮助
根据伊莎贝尔新手回答:
Open :- csv_read_file('Path', Rows, [functor(num), arity(4)]), table_entry(Rows, Row).
header_row_entry(Header,Row,Entry):-
arg(1, Row, RowName),
functor(Header, _, Arity),
between(2,Arity,ArgIndex),
arg(ArgIndex, Header, ColumnName),
arg(ArgIndex, Row, Value),
Entry = num(RowName, ColumnName, Value),
writeln(Entry).
table_entry(Entries, Entry):-
Entries = [Header | Rows],
member(Row, Rows),
header_row_entry(Header, Row, Entry).
现在,谁能解释一下我应该如何以及在哪里使用maplist以事实的形式转换行(现在忽略过滤“-”和小写),以便在我查询时:
?-num(A,B,X).
我应该得到:
X=4
下一个任务是,我想在它上面实现深度优先搜索算法。非常感谢您提供与此相关的任何详细信息。考虑一个表头
num(''a','B','C')
和表中的一行num('B',8,-,6)
。从这里,您需要计算一个由行名(此处为'B'
)和列名标识的表条目:第一个值(8
)的列名为'a'
,第二个值(-
)的列名为'B'
),第三个值(6
)的列名为'C'
)
下面是一个简单的方法,包括一些键入和强制复制粘贴错误:
header\u row\u条目(header,row,entry):-
Header=num(“”,ColumnName,u,u),
Row=num(RowName,Value,u,u),
Entry=num(行名、列名、值)。
标题\行\条目(标题、行、条目):-
Header=num(“”,u,ColumnName,u),
Row=num(RowName,u,Value,u),
Entry=num(行名、列名、值)。
标题\行\条目(标题、行、条目):-
Header=num(“”,,,ColumnName),
Row=num(RowName,u,u,Value),
Entry=num(行名、列名、值)。
这将枚举回溯时一行中的所有条目:
?-Header=num(''A','B','C'),Row=num('B',8,-,6),
标题\行\条目(标题、行、条目)。
Header=num(''A','B','C'),
行=num('B',8,-6),
条目=num('B','A',8);
Header=num(''A','B','C'),
行=num('B',8,-6),
Entry=num('B','B',-);
Header=num(''A','B','C'),
行=num('B',8,-6),
Entry=num('B','C',6)。
要枚举整个表中的所有条目,仍然需要枚举所有行,然后如上所述枚举行条目。这是:
table_条目(条目,条目):-
条目=[标题|行],
成员(行,行),
标题\行\条目(标题、行、条目)。
现在,考虑到你的桌子:
?-Table=[num('A','B','C'),num('A',-,4,5),num('B',8,-,6),num('C',2,3,-)],Table_entry(Table,entry)。
表=[num('A','B','C'),num('A',-,4,5),num('B',8,-,6),num('C',2,3,-)],
Entry=num('A','A',-);
表=[num('A','B','C'),num('A',-,4,5),num('B',8,-,6),num('C',2,3,-)],
条目=num('A','B',4);
表=[num('A','B','C'),num('A',-,4,5),num('B',8,-,6),num('C',2,3,-)],
条目=num('A','C',5);
表=[num('A','B','C'),num('A',-,4,5),num('B',8,-,6),num('C',2,3,-)],
条目=num('B','A',8);
表=[num('A','B','C'),num('A',-,4,5),num('B',8,-,6),num('C',2,3,-)],
条目=num('B','B',-)。%等
根据您的具体需要,仍然需要将行名和列名(例如,SWI Prolog中令人恼火的名称downcase_atom
)小写,并过滤掉-
条目。然后,您可以使用故障驱动循环断言条目,或者使用findall
收集所有条目,并使用maplist
进行断言
现在我们已经有了一个有效的解决方案,我们可能希望标题\行\条目
稍微好一点。我们可以使用arg/3
更明确地捕捉到,我们正在尝试将列名和值配对,它们在各自的标题和行术语中位于相同的参数位置:
header\u row\u条目(header,row,entry):-
arg(1,行,行名称),
函子(头、数、数),
在(2,Arity,ArgIndex)之间,
arg(ArgIndex、标题、列名称),
arg(ArgIndex,行,值),
Entry=num(行名、列名、值)。
这比上面的要短,并且适用于表中任何数量的列。这不是CSV文件。很明显,对于答案@IsabelleNewbie,您可以在@GuycoderTank之间假设逗号。正如您所说,我可以使用maplist将条目作为事实。我在上面添加了我所完成的工作。请您解释一下,我应该如何以及在哪里使用maplist生成事实(现在忽略过滤-和小写)。那么,当我询问时?-num(A,B,X)。我应该得到输出。