使用Prolog将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

我有包含以下数据的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)]), 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)。我应该得到输出。