如何在写入 .pl 文件的 pyswip 中进行断言
How to make assertion in pyswip written to .pl file
我有一个包含事实和规则的预填充“.pl”文件。我使用 pyswip 的 consult() 方法打开文件。例如,关于对象的可拾取性有两个事实:
pickable_object(pen).
pickable_object(paper).
现在,在我使用 pyswip 添加新事实后:
prolog.assertz('pickable_object(light)')
查询
for result in prolog.query('pickable_object(X)'):
print(result)
完美运行并打印:
{'X': 'pen'}
{'X': 'paper'}
{'X': 'light'}
但是,断言不会写入“.pl”文件。我该如何启用它?
作为一种解决方法,我只是将新的子句字符串附加为一个新行,将其视为一个文本文件。
如果您只对在 Prolog 运行 之间保存和恢复动态谓词的状态感兴趣,最简单的方法可能是使用 persistency library。对于您的示例,您可以拥有以下文件 myfacts_db.pl
:
:- module(myfacts_db,
[ attach_myfacts_db/1, % +File
get_myfact/1, % ?Fact
set_myfact/1 % +Fact
]).
:- use_module(library(persistency)).
:- persistent
myfact(fact:any).
attach_myfacts_db(File) :-
db_attach(File, []).
get_myfact(pickable_object(pen)).
get_myfact(pickable_object(paper)).
get_myfact(Fact) :-
myfact(Fact).
set_myfact(Fact) :-
assert_myfact(Fact).
如果我们 运行 Prolog 第一次使用新模块,我们得到:
$ swipl
?- use_module(myfacts_db).
true.
?- attach_myfacts_db('test.pl').
true.
?- findall(X,get_myfact(pickable_object(X)),Objects).
Objects = [pen, paper].
?- set_myfact(pickable_object(light)).
true.
?- findall(X,get_myfact(pickable_object(X)),Objects).
Objects = [pen, paper, light].
?- halt.
如果数据库文件 test.pl
不存在,将创建它。如果我们再次启动 Prolog,我们有:
$ swipl
?- use_module(myfacts_db).
true.
?- attach_myfacts_db('test.pl').
true.
?- findall(X,get_myfact(pickable_object(X)),Objects).
Objects = [pen, paper, light].
请注意,这样创建的数据库并不是简单的事实列表,而是看起来像这样(额外的东西用于处理同步):
$ cat test.pl
created(1565656419.9478514).
assert(myfact(pickable_object(light))).
如果你真的想要一个只列出 "pure" 事实 pickable_object(light)).
等的文件,我不知道 SWI-Prolog 的任何内置方法会支持这一点,所以在那种情况下,您确实必须通过文件 I/O 写入和读取文件(或相应地修改数据库文件)。然而,一旦您还想支持删除事实、共享访问等,这将变得棘手。
我有一个包含事实和规则的预填充“.pl”文件。我使用 pyswip 的 consult() 方法打开文件。例如,关于对象的可拾取性有两个事实:
pickable_object(pen).
pickable_object(paper).
现在,在我使用 pyswip 添加新事实后:
prolog.assertz('pickable_object(light)')
查询
for result in prolog.query('pickable_object(X)'):
print(result)
完美运行并打印:
{'X': 'pen'} {'X': 'paper'} {'X': 'light'}
但是,断言不会写入“.pl”文件。我该如何启用它?
作为一种解决方法,我只是将新的子句字符串附加为一个新行,将其视为一个文本文件。
如果您只对在 Prolog 运行 之间保存和恢复动态谓词的状态感兴趣,最简单的方法可能是使用 persistency library。对于您的示例,您可以拥有以下文件 myfacts_db.pl
:
:- module(myfacts_db,
[ attach_myfacts_db/1, % +File
get_myfact/1, % ?Fact
set_myfact/1 % +Fact
]).
:- use_module(library(persistency)).
:- persistent
myfact(fact:any).
attach_myfacts_db(File) :-
db_attach(File, []).
get_myfact(pickable_object(pen)).
get_myfact(pickable_object(paper)).
get_myfact(Fact) :-
myfact(Fact).
set_myfact(Fact) :-
assert_myfact(Fact).
如果我们 运行 Prolog 第一次使用新模块,我们得到:
$ swipl
?- use_module(myfacts_db).
true.
?- attach_myfacts_db('test.pl').
true.
?- findall(X,get_myfact(pickable_object(X)),Objects).
Objects = [pen, paper].
?- set_myfact(pickable_object(light)).
true.
?- findall(X,get_myfact(pickable_object(X)),Objects).
Objects = [pen, paper, light].
?- halt.
如果数据库文件 test.pl
不存在,将创建它。如果我们再次启动 Prolog,我们有:
$ swipl
?- use_module(myfacts_db).
true.
?- attach_myfacts_db('test.pl').
true.
?- findall(X,get_myfact(pickable_object(X)),Objects).
Objects = [pen, paper, light].
请注意,这样创建的数据库并不是简单的事实列表,而是看起来像这样(额外的东西用于处理同步):
$ cat test.pl
created(1565656419.9478514).
assert(myfact(pickable_object(light))).
如果你真的想要一个只列出 "pure" 事实 pickable_object(light)).
等的文件,我不知道 SWI-Prolog 的任何内置方法会支持这一点,所以在那种情况下,您确实必须通过文件 I/O 写入和读取文件(或相应地修改数据库文件)。然而,一旦您还想支持删除事实、共享访问等,这将变得棘手。