问题描述
我有这个模块:
:- module(data_db,[ attach_data_db/1,% +File
current_user_role/2,% ?User,?Role
add_user/2,% +User,+Role
set_user_role/2 % +User,+Role
]).
:- use_module(library(persistency)).
:- persistent
user_role(name:atom,role:oneof([user,administrator])).
attach_data_db(File) :-
db_attach(File,[]).
%% current_user_role(+Name,-Role) is semidet.
current_user_role(Name,Role) :-
with_mutex(data_db,user_role(Name,Role)).
add_user(Name,Role) :-
assert_user_role(Name,Role).
set_user_role(Name,Role) :-
user_role(Name,Role),!.
set_user_role(Name,( retractall_user_role(Name,_),assert_user_role(Name,Role))).
这是官方文档中的示例。因此,我可以使用db_attach
将数据添加到文件中,但是我不知道如何从文件中获取数据。该文件包含:
created(1603178081.6254506).
assert(user_role('John',user)).
assert(user_role('John',user)).
assert(user_role(han,user)).
解决方法
首先,您真的应该在SWI-Prolog forum中问这个问题,因为很多人都不知道如何使用library(persistency)。
关于库(持久性)的好处之一是,一旦配置正确,它就可以管理数据(事实和谓词)的保存和加载。
由于您给出了由library(persistency)创建的文件的示例,因此我认为它可以正常工作。
您的问题与我第一次使用library(persistency)时遇到的问题相同,因为我希望将事实存储在文件中,就像我手动输入它们一样。这不是您应该考虑的库(持久性),而是将其视为创建命令日志,并且在打开日志时将回放这些命令。
由于它是命令日志,所以这就是为什么看到assert(user_role('John',user)).
而不是user_role('John',user).
的原因。当文件由库(持久性)打开并播放时,该命令将事实断言到内存中的Prolog数据库中,这由库(持久性)自动完成。
所以回答你的问题
如何从SWI-Prolog中的库(持久性)中获取数据?
只需访问事实,就好像它们在Prolog数据库中一样
?- user_role('John',Role).
Role = user.
在SWI-Prolog论坛上使用库(持久性)创建Wiki时,却排在我的长名单上,这是最新的完整post,其中包含我编写的工作代码。
您需要单击三角形以展开详细信息以查看代码。
根据您的问题,这是一个完整的工作示例。有两个Prolog源文件,一个用于将某些事实保留到日志中,然后暂停Prolog顶层,以证明数据不是通过Prolog数据库传递的,而是通过日志文件传递的。然后,第二个Prolog来源将访问日志文件,使事实在顶层可用。
文件:create_facts.pl
:- module(create_facts,[]).
:- use_module(library(persistency)).
:- persistent
user_role(name:atom,role:oneof([user,developer,administrator])).
:- db_attach('user.journal',[]).
:- initialization(main).
add_user(Name,Role) :-
(
user_role(Name,Role),!
;
assert_user_role(Name,Role)
).
main :-
add_user('John',user),add_user('Mary',add_user('Ellen',developer),add_user('Stan',add_user('Eric',administrator).
文件:load_facts.pl
:- module(load_facts,[
user_role/2
]).
:- use_module(library(persistency)).
:- persistent
user_role(name:atom,[]).
示范
- 咨询create_facts.pl,它将自动运行
main
在日记文件中创建事实。
?- ['create_facts'].
true.
- 暂停Prolog顶层,以显示事实仅在日志文件中传递。同样,在执行
halt
之前,日记文件可能不完整,并且仍将由SWI-Prolog顶层保持锁定。
?- halt.
在步骤1中创建的日记文件
文件:user.joural
created(1603198849.086677).
assert(user_role('John',user)).
assert(user_role('Mary',user)).
assert(user_role('Ellen',developer)).
assert(user_role('Stan',user)).
assert(user_role('Eric',administrator)).
如果您愿意,可以一次又一次地执行步骤1和2,并且不会重复日记中的事实,因为
(
user_role(Name,Role)
).
检查事实是否存在,如果不存在,则将事实断言到日记中。
- 咨询
load_facts.pl
,将事实从日志文件加载到Prolog数据库中。
?- ['load_facts'].
true.
- 就像访问普通事实一样访问事实
?- user_role(Name,Role).
Name = 'John',Role = user ;
Name = 'Mary',Role = user ;
Name = 'Ellen',Role = developer ;
Name = 'Stan',Role = user ;
Name = 'Eric',Role = administrator.
享受!