收回并断言到Prolog中的另一个文件



我正试图收回并断言另一个文件中的一个事实。一个(fruit1.pl)包含两个事实,另一个(fruit.pl)包含一个谓词start,该谓词指定另一谓词insert_fruit将更新哪个事实:

fruit1.pl

fruit(apple, [[2, yellow], [1, brown]]).
fruit(orange, [[3, orange], [2, orange]]).

水果.pl

:- dynamic fruit/2.
start :-
    consult('fruit1.pl'),
    File = 'fruit1.pl',
    Name = apple,
    Price = 2,
    Color = red,
    insert_fruit(File, Name, Price, Color). 
insert_fruit(File, Name, Price, Color) :-
   open(File, update, Stream),
   retract(fruit(Name, Information)),
   assert(fruit(Name, [[Price, Color]|Information])),
   close(Stream). 

然而,insert_fruit并没有按预期工作,因为我认为它需要包含Stream来修改另一个文件,尽管我不知道如何(retract(Stream, ...)不工作)。是否有一些我可以让retract和assert谓词在另一个文件中发挥作用?

在SWI Prolog中,您可以使用库persistency:从用作持久事实存储的文件中断言/收回事实

  1. 您将fruit/3声明为持久性。(可选):使用类型对参数进行注释,以进行自动类型检查
  2. 您附加一个文件,该文件将在初始化fruit模块(在本例中为fruit1.pl)时用作持久事实存储
  3. 您添加了用于插入(即add_fruit/3)和查询(即current_fruit/3)水果事实的谓词。收回的处理方式类似
  4. 请注意,您可以通过使用with_mutex/2在多线程环境中使用事实存储(当您开始收回事实时也特别有用)

代码

:- module(
  fruit,
  [
    add_fruit/3, % +Name:atom, +Price:float, +Color:atom
    current_fruit/3 % ?Name:atom, ?Price:float, ?Color:atom
  ]
).
:- use_module(library(persistency)).
:- persistent(fruit(name:atom, price:float, color:atom)).
:- initialization(db_attach('fruit1.pl', [])).
add_fruit(Name, Price, Color):-
  with_mutex(fruit_db, assert_fruit(Name, Price, Color)).
current_fruit(Name, Price, Color):-
  with_mutex(fruit_db, fruit(Name, Price, Color)).

使用说明

启动Prolog,加载fruit.pl,执行:

?- add_fruit(apple, 1.10, red).

关闭Prolog,再次启动Prolog,执行:

?- current_fruit(X, Y, Z).
X = apple,
Y = 1.1,
Z = red

您现在正在阅读fruit1.pl中的事实!

自动型式检查示意图

如前所述,库还为您执行类型检查,例如:

?- add_fruit(pear, expensive, green).
ERROR: Type error: `float' expected, found `expensive' (an atom)

最新更新