如何读取创建列表的文件

时间:2018-03-23 06:33:29

标签: list prolog

我有一些代码,看起来像这样:

main :-
    open('input.txt', read, Input),
    repeat,
    read_line_to_codes(Input, Line),
    maplist(my_representation, Line, FinalLine),
    ( Line \= end_of_file -> writeln(FinalLine), fail ; true ),
    close(Input).

FinalLine是一个整数列表,包括一些下划线(基于输入文件)。由于这循环,我想知道如何动态地,循环的每次迭代,将FinalLine列表添加到另一个列表。基本上这将创建一个列表列表。

由于我知道输入文件的规格,我知道它循环了16次,因此我想要一个包含16个列表的列表。因此,虽然我不知道如何做到这一点,但我确信最好的方法是创建一个我调用的谓词,而不是我现在正在做的输出(writeln(FinalLine)),以动态创建此列表列表。

希望这是有道理的。非常感谢任何帮助,谢谢!

2 个答案:

答案 0 :(得分:2)

虽然历史上Prolog中的I / O通常以def a(): return 2 + 3 def b(): return 3 - 2 def c(): return 2*3 dic = {} dic['a'] = a dic['b'] = b dic['c'] = c funcs = str(input("which functions would you like to use?: ")) funcs = funcs.split(',') result = 0 for i in funcs: result += dic[i]() print (result) / repeat循环的形式呈现,但递归通常(几乎总是?)是实现迭代的最佳方式。特别是如果你需要记住从一次迭代到下一次迭代的数据;失败会导致回溯,从而将您的变量与先前计算的数据解除绑定。在回溯时,你会丢失任何你没有使用更多不纯的结构而保存的数据。递归更简单。

递归会强制您将程序分解为多个谓词,但无论如何这都是个好主意。例如,将流打开与读取分开会使您的程序更具可重用性和可测试性,因为流可以使用除文件之外的其他内容构建。

fail

测试输入文件:

% dummy
my_representation(Codes, Result) :-
    atom_codes(Result, Codes).

stream_representations(Input, Lines) :-
    read_line_to_codes(Input, Line),
    (   Line == end_of_file
    ->  Lines = []
    ;   my_representation(Line, FinalLine),
        Lines = [FinalLine | FurtherLines],
        stream_representations(Input, FurtherLines) ).

main :-
    open('input.txt', read, Input),
    stream_representations(Input, Lines),
    close(Input),
    writeln(Lines).

试运行:

hello
world
hello, world!
this file ends here

答案 1 :(得分:-1)

列表的二维列表是一个矩阵,在头脑中可视化它的最简单方法是由行和列组成的表。这是一段澄清概念的示例代码。

此代码根据您希望的最大列数MaxX生成矩阵,并根据MaxY生成所需的最大行数。矩阵中的每个位置都有一个cell(point(X,Y))坐标,可以更容易地显示输出。

%If the MaxY has been reached for the Y axis, step back
generate_matrix([],_,_,MaxY,MaxY) :- !.
%If MaxX has been reached, new row
generate_matrix([Row|Tp],X,MaxX,Y,MaxY):-
    generate_row(Row, X, MaxX, Y),
    Y1 is Y+1,
    generate_matrix(Tp,0,MaxX,Y1,MaxY).

%If the MaxX has been reached for the X axis, step back
generate_row([], MaxX,MaxX,_) :- !.
generate_row([cell(point(X,Y))|T], X, MaxX, Y) :-
    XNew is X + 1,
    generate_row(T, XNew, MaxX, Y).

您可以轻松地将cell(point(X,Y)替换为您要放置的内容。我希望这能为您澄清这个概念,如果没有,请务必要求澄清。

Testquery生成10×10矩阵/网格/表/ 2维列表:

%generate_matrix(Matrix, 0, MaxX, 0, MaxY)
generate_matrix(Matrix, 0, 10, 0, 10).

您可以添加尺寸来表示更复杂的结构。添加Z轴可以为您提供3D立方体。