【问题标题】:Some doubts about the reading of a file in Prolog using a StreamProlog中使用Stream读取文件的一些疑惑
【发布时间】:2023-03-28 06:45:01
【问题描述】:

我对这个从文件中读取字符并将这些字符放入列表的简单 Prolog 程序如何工作表示怀疑。

代码运行良好,如下:

readFile(FileInput, TextList):- open(FileInput, read, Stream),
                                readCharacter(Stream, TextList),
                                close(Stream),
                                !.


readCharacter(Stream,[]):- at_end_of_stream(Stream).    % Exit condition


readCharacter(Stream,[Char|Tail]):- get0(Stream,Char),
                                    readCharacter(Stream,Tail).

当调用 readFile/2 谓词时,会发生:输入传递的文件以读取模式打开并且该文件与流相关联。

然后调用 readCharacter/2 谓词,将 Stream 关​​联到我的输入文件(要读取的文件)和 TextList 即放置文件的列表内容。

readCharacter/2 谓词分为两种情况:

1) 使用 at_end_of_stream(Stream) 谓词的退出条件,在读取 Stream 的最后一个字符(即文件中的最后一个字符)后成功。在这种情况下,什么都不做,readCharacter 谓词结束

2) 第二种情况是添加读取字符并将其添加到我的 TextList 的规则:

readCharacter(Stream,[Char|Tail]):- get0(Stream,Char),
                                    readCharacter(Stream,Tail).

在这里我有一个疑问:它使用 get0 从 Stream 中读取一个字符并将其放在列表的头部(作为列表的第一个元素)......所以......为什么列表不包含文件内容的反面?

我有一个名为 myFile.txt 的文件,其中包含以下文本:abc

所以 readCharacter 首先从 Stream 中读取 a 字符并将其放在列表的头部,所以我有:

文本列表 = [a]

然后 readCharacter 从 Stream 中读取 b 字符并将其放在我拥有的列表的头部:

文本列表 = [b,a]

然后 readCharacter 从 Stream 中读取 c 字符并将其放在我拥有的列表的头部:

文本列表 = [c,b,a]

如果是这样,TextList 应该包含 myFile.txt 文件的相反内容,但在我看来,TextList 以相同的顺序包含 myFile.txt 文件的相同内容。

为什么?我错过了什么?我的推理有什么问题?

【问题讨论】:

    标签: prolog


    【解决方案1】:
    readCharacter(Stream,[Char|Tail]):-
        get0(Stream,Char),
        readCharacter(Stream,Tail).
    

    所以你有你的Stream,你可以从中得到一个字符,并用Char统一它。 Tail 中有一个尚未初始化的列表。然后,您将 Stream(一个字符现在消失了)和 Tail 传递给 readCharacter 的递归调用。冲洗并重复,直到 Stream 位于文件末尾。

    重点在于:[Char|Tail] 表示 Char 是结果列表的头部,或者换句话说,列表中的所有其他内容之前。

    如果你跟踪这个,你会看到 Char 是如何与你文件中的字符代码统一起来的,按照它们在文件中的顺序,调用get0(Char),但是当你递归调用readCharacter 时消失。

    然后,当您退出递归时,您从 get0 获得的字符代码神奇地重新出现在 readCharacter 的第二个参数中,在读取它们的调用退出时,每个 Char Tail 中的所有内容之前(应该是,根据[Char|Tail]

    基本上,您的推理(此处和其他问题)的错误在于您过于努力地将您的期望强加于您所看到的而不是接受和试图识别你观察到的逻辑。与所有其他人造事物一样,Prolog 大部分时间都遵循一定的逻辑。

    【讨论】:

    • 你是对的,这并不难。不幸的是,我今天在办公室度过了一整夜,我非常融化
    • @false 这是一个相当愚蠢的问题,然后是我不必要的愚蠢的答案。原始问题使用get0/1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-20
    • 1970-01-01
    • 1970-01-01
    • 2013-02-13
    • 1970-01-01
    • 2022-01-21
    相关资源
    最近更新 更多