0

我怀疑这个从文件中读取字符并将这些字符放入列表的简单 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 中读取一个字符并将其放在列表的头部(作为列表的第一个元素)......所以......为什么列表不包含相反的文件内容?

IE

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

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

文本列表 = [一个]

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

文本列表 = [b,a]

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

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

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

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

4

1 回答 1

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

So you have your Stream, you get a character from it and unify it with Char. You have a yet-to-be initialized list in Tail. You then pass Stream (with one character now gone) and Tail to a recursive call of readCharacter. Rinse and repeat until Stream is at end of file.

The point is that this: [Char|Tail] means that Char is the head of the resulting list, or in other words, before everything else in the list.

If you trace this, you will see how Char gets unified with the codes of the characters you have in your file, in the order they are in the file, on calling get0(Char), but disappear as you call readCharacter recursively.

Then, as you go out of the recursion, the character codes you got from get0 magically reappear in the second argument of readCharacter, on the exit from the call in which they were read, each Char before everything in Tail (as should be, according to [Char|Tail].

Basically, what is wrong with your reasoning (here and in other questions) is that you try too hard to impose your expectations on what you see instead of accepting and trying to recognize the logic in what you observe. Prolog, as all other man-made things, follows a certain logic, most of the time.

于 2013-04-23T15:20:33.433 回答