Prolog - 咨询实际上清除了当前状态?

Prolog - Consult actually cleans current state?

我有以下用于客户创建和列表的代码:

:-dynamic customer/2.

load:-consult('C:\customers.txt').

save:-tell('C:\customers.txt'), listing(customer), told.

%New customer
new_customer:-write("Name: "), read(Name), 
customer_code(Code), asserta(customer(Code, Name)), save.

customer_code(Code):- customer(C, _, _, _), Code is C + 1.
customer_code(1).

到目前为止,还不错。问题是,当尝试进行更复杂的搜索、过滤和一般报告时,我不得不使用 retract 来清理客户的当前内存状态。

所以,在任何列表之前,我倾向于再次查阅文件(调用load):

list_customers:- load, listing(customer).

这里出了问题的是,这个新负载往往会导致 listing 重复上次添加到数据库中的客户。

例如:

C:\customers.txt:

:-dynamic customers/2
(2, 'John')
(1, 'Alicia')

列表(客户):

(2, 'John')
(2, 'John')
(1, 'Alicia')

我在咨询之前使用 retractall 可以避免这种情况:

load:- reatractall(customer(_,_)), consult('C:\customers.txt').

这是good/bad的做法吗?我不太明白这是怎么回事,也不太明白为什么这样可以解决问题。

咨询谓词,如文档中引用已弃用的 reconsult 子句的相当晦涩的地方所述,指出它将重新加载 从文件中加载的子句.

在这种情况下这是什么意思?

当您第一次在文本文件中创建条目时,从文件加载的子句和您创建的子句是相同的。

添加新条目时出现问题。让我们用一个例子来说明这一点:

1) 你加载文件 consult:

现在您的数据库和文件将包含相同的子句:

customers.txt:

:- dynamic customer/2.

customer(4, 'Juan').
customer(3, 'Juan').
customer(2, 'Juan').
customer(1, 'Juan').

您的 Prolog 数据库:

:- dynamic customer/2.

customer(4, 'Juan').
customer(3, 'Juan').
customer(2, 'Juan').
customer(1, 'Juan').

到目前为止,还不错。

2) 您添加一个新客户并使用 tell / told:

将其保存到文件中

customers.txt:

:- dynamic customer/2.

customer(5, 'Juan').
customer(4, 'Juan').
customer(3, 'Juan').
customer(2, 'Juan').
customer(1, 'Juan').

您的 Prolog 数据库:

:- dynamic customer/2.

customer(5, 'Juan').
customer(4, 'Juan').
customer(3, 'Juan').
customer(2, 'Juan').
customer(1, 'Juan').

仍然没有问题。真正的问题来了:

3) 你重新加载文件:

customers.txt:

:- dynamic customer/2.

customer(5, 'Juan').
customer(4, 'Juan').
customer(3, 'Juan').
customer(2, 'Juan').
customer(1, 'Juan').

您的 Prolog 数据库:

:- dynamic customer/2.

customer(5, 'Juan').
customer(5, 'Juan').
customer(4, 'Juan').
customer(3, 'Juan').
customer(2, 'Juan').
customer(1, 'Juan').

好的,这里发生了什么?如果您还记得的话,我们之前看到 从文件 .

加载的 consult 重新加载子句

所以,我们重新加载的子句是:

customer(4, 'Juan').
customer(3, 'Juan').
customer(2, 'Juan').
customer(1, 'Juan').

这给我们留下了一个子句,customer(5, 'Juan'),它不是第一次从文件中加载的。所以现在我们必须将它添加到我们的数据库中,从而导致:

customer(5, 'Juan').
customer(5, 'Juan').
customer(4, 'Juan').
customer(3, 'Juan').
customer(2, 'Juan').
customer(1, 'Juan').