微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用Prolog将csv文件中的数据解析为给定格式

如何解决使用Prolog将csv文件中的数据解析为给定格式

我的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,6).
num(c,2).
num(c,3).

类似num(a,a,-)这样的字母应该没有事实。

我将prolog的csv_read_file用作:

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,-)]

这似乎是一个基本问题,但我无法考虑执行此操作的条件。任何帮助将不胜感激。

根据Isabelle Newbie的答案:

Open :- csv_read_file('Path',table_entry(Rows,Row).


header_row_entry(Header,Row,Entry):-
    arg(1,RowName),functor(Header,_,Arity),between(2,Arity,ArgIndex),arg(ArgIndex,Header,ColumnName),Value),Entry = num(RowName,ColumnName,writeln(Entry).

table_entry(Entries,Entry):-
    Entries = [Header | Rows],member(Row,Rows),header_row_entry(Header,Entry).

现在,任何人都可以解释一下我应该如何以及在何处使用maplist以事实的形式转换行(暂时忽略'-'和小写字母的过滤),以便在查询时使用:

?-num(A,B,X).

我应该得到:

X=4

一个任务是,我想在其上实现深度优先搜索算法。对此的任何细节将不胜感激。

解决方法

考虑表头num('','A','B','C')和表num('B',8,-,6)中的一行。由此,您想要计算一个表条目,该表条目由行名(这里是'B')和列名标识:第一个值('A'的列名是8'B'代表第二个(-'C'代表第三个(6)。

这是一种简单的方法,涉及一些键入和强制性的复制和粘贴错误:

header_row_entry(Header,Row,Entry) :-
    Header = num('',ColumnName,_,_),Row = num(RowName,Value,Entry = num(RowName,Value).
header_row_entry(Header,ColumnName),Value),Value).

这枚举了回溯中连续的所有条目:

?- Header = num('','C'),Row = num('B',6),header_row_entry(Header,Entry).
Header = num('',Entry = num('B',8) ;
Header = num('',-) ;
Header = num('','C',6).

要枚举整个表中的所有条目,保留枚举所有行,然后如上所述枚举行条目。这是:

table_entry(Entries,Entry) :-
    Entries = [Header | Rows],member(Row,Rows),Entry).

现在,给定您的桌子:

?- Table = [num('',num('A',4,5),num('B',num('C',2,3,-)],table_entry(Table,Entry).
Table = [num('',Entry = num('A',-) ;
Table = [num('',4) ;
Table = [num('',5) ;
Table = [num('',8) ;
Table = [num('',-) .  % etc.

根据您的确切要求,保留小写的行和列名称(例如,在SWI-Prolog中令人讨厌的名称为downcase_atom)并过滤掉-条目。然后,您可以使用故障驱动的循环来声明条目,或者使用findall收集所有条目并使用maplist声明条目。

现在我们有了一个可行的解决方案,我们可能希望header_row_entry更好一些。我们可以使用arg/3来更明确地捕获我们正在尝试将在各自的标题和行术语中位于相同参数位置的列名和值配对:

header_row_entry(Header,Entry) :-
    arg(1,RowName),functor(Header,Arity),between(2,Arity,ArgIndex),arg(ArgIndex,Header,Value).

这比上面的短,并且适用于表中任意数量的列。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。