在Prolog中撤回并断言到另一个文件

时间:2014-10-26 12:29:36

标签: prolog

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

fruit1.pl

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

fruit.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, ...)如何不起作用)。是否有一些我能够得到撤回并断言谓词在另一个文件中起作用?

1 个答案:

答案 0 :(得分:4)

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

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

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