【问题标题】:Prolog - Consult actually cleans current state?Prolog - 咨询实际上清除了当前状态?
【发布时间】:2015-09-24 21:47:39
【问题描述】:

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

:-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').

这是一种好/坏的做法吗?我不太明白这里发生了什么或为什么这能解决问题。

【问题讨论】:

  • 这是一个很棘手的问题:见reconsult/1
  • 您确定您必须为这个程序使用 Prolog 数据库吗?如果您可以重新设计它,您将避免一整类问题,这样您就不必使用consultassertretract 等。
  • 无论哪种方式,单独的动态数据库的更好解决方案可能是使用像 library(persistency) 这样的库。
  • 我强烈支持 Boris 写的:避免使用assertz/1 等。对于您的用例,您可以简单地使用include/1 来包含外部数据库,并且在您重新咨询时也会再次读取它。 (SWI-Prolog:试试make/0。)
  • 感谢大家的建议.. 遗憾的是我正在上课,这就是应该解决的方式

标签: prolog prolog-directive-dynamic


【解决方案1】:

咨询谓词,如文档中的一个相当模糊的地方所述,引用了已弃用的reconsult 子句,声明它将重新加载从文件中加载的子句。 p>

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

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

添加新条目时会出现问题。让我们用一个例子来检查一下,让事情变得更清楚:

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 reload 子句从文件中加载的位置

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

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').

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-15
    • 1970-01-01
    • 2020-03-27
    • 1970-01-01
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多