4

我有一个包含很多事实的 prolog 数据库文件knowledge.pl。例如:

father_of(joe,paul).
father_of(joe,mary).
mother_of(jane,paul).
mother_of(jane,mary).
male(paul).
male(joe).
female(mary).
female(jane). % and so on.

每次我的程序再次执行时,都会查阅这个文件 (consult/1)。

我希望能够通过直接在这个数据库文本文件中写入或删除来插入、修改和删除我想要的事实(其中一些是直接的,另一些是满足某些特定条件的)。

类似assertz、retract 和retractall 之类的东西,但要修改此文本文件,以便更改永久保留在那里。

我该怎么做?

4

2 回答 2

3

您可以创建所需的事实并将它们写入(相同)文件或修改数据库,然后将其保存在文件中。

不同之处在于,第一种方法将加载旧文件的数据库,而第二种方法将在执行期间更改它。

从你提出问题的方式来看,我假设你想做第二个;为此,您应该:

1)将所有要更改的谓词声明为动态 2)在执行期间断言、撤回等 3)将新数据库写入文件。你可以使用Listing/1

要编写,您可以执行以下操作:

tell(knowledge),
.....
told.

或者您可以使用其他一些io 谓词。也许使用set_prolog_IO/3将是最简单的方法。

现在,如果您想要第一个,您应该构造谓词(可能使用univ 运算符)或其他字符串操作谓词,然后将它们写入文件

编辑:

有 listing/0 但会列出所有加载的谓词(你可能不想要的东西)。经过一番搜索,我找到了source_file/2;所以你可以做类似的事情

findall(X,source_file(X,FileName),L).

请注意, source_file/2 需要绝对文件名。您可以使用absolute_file_name/2来获取它的方式 source_file/2 格式化谓词有点奇怪(我期待像 foo/1 这样的东西)但看起来您可以将它提供给 Listing/1 并且它工作正常所以你可以做类似的事情:

save(FileName):-
    absolute_file_name(FileName,Abs),
    findall(X,source_file(X,Abs),L),
    tell(FileName),
    maplist(listing,L),
    told.

另一方面,您始终可以拥有一个包含要存储在文件中某处的谓词的列表

于 2012-06-01T21:23:23.483 回答
3

如果您使用的是 SWI-Prolog,则有多种选择:

在寻找prolog 持久性时,我陷入了持久性:一个乍一看可能有用的模块。

然后是'外部表'的库,即存储在文件中并建立索引。如果您有不适合内存的数据,或者加载/保存整个数据集需要太长时间,您应该使用它。

否则,thanosQR 的答案建议使用“老式”处理持久性的方法。

于 2012-06-01T22:27:50.723 回答