1:- module(persist,
    2         [find_term/2,
    3          add_term/2,
    4          replace_term/3,
    5          remove_term/2]).    6:- use_module(library(reif), [if_/3, (=)/3]).    7:- use_module(library(settings), [set_setting/2, setting/4]).

Persists facts into a file

/

   18:- setting(separator_fn, callable, nl, "The separator function to use between terms").   19
   20internal:noop(_).
   21
   22internal:remove_term(Term, InputStream, OutputStream, SeparatorFn) :-
   23    read(InputStream, InputTerm),
   24    setting(separator_fn, NewSeparatorFn),
   25    if_(InputTerm = Term, true,
   26        (InputTerm = end_of_file ->
   27         true ;
   28         (call(SeparatorFn, OutputStream), portray_clause(OutputStream, InputTerm)))),
   29    if_(InputTerm = end_of_file, true,
   30        internal:remove_term(Term, InputStream, OutputStream, NewSeparatorFn)).
   31
   32internal:remove_term(Term, File) :-
   33    setup_call_cleanup(
   34        (open(File, read, InputStream), open(File, write, OutputStream)),
   35        internal:remove_term(Term, InputStream, OutputStream, internal:noop),
   36        (close(InputStream), close(OutputStream))
   37    ).
 remove_term(+Term, +ModuleName) is semidet
Removes a Term from the module
   42remove_term(Term, ModuleName) :-
   43    module_property(ModuleName, file(File)),
   44    internal:remove_term(Term, File).
   45
   46
   47
   48internal:replace_term(OldTerm, NewTerm, InputStream, OutputStream, SeparatorFn) :-
   49    read(InputStream, InputTerm),
   50    setting(separator_fn, NewSeparatorFn),
   51    if_(InputTerm = OldTerm,
   52        (call(SeparatorFn, OutputStream), portray_clause(OutputStream, NewTerm)),
   53        (InputTerm = end_of_file ->
   54         true ;
   55         (call(SeparatorFn, OutputStream), portray_clause(OutputStream, InputTerm)))),
   56    if_(InputTerm = end_of_file, true,
   57        internal:replace_term(OldTerm, NewTerm, InputStream, OutputStream, NewSeparatorFn)).
   58
   59internal:replace_term(OldTerm, NewTerm, File) :-
   60    setup_call_cleanup(
   61        (open(File, read, InputStream), open(File, write, OutputStream)),
   62        internal:replace_term(OldTerm, NewTerm, InputStream, OutputStream, internal:noop),
   63        (close(InputStream), close(OutputStream))
   64    ).
 replace_term(+OldTerm, +NewTerm, +ModuleName) is semidet
Replace a term in the module. This will replace all instances of OldTerm with NewTerm in place.
   70replace_term(OldTerm, NewTerm, ModuleName) :-
   71    module_property(ModuleName, file(File)),
   72    internal:replace_term(OldTerm, NewTerm, File).
   73
   74
   75
   76internal:find_in_stream(Term, InputStream) :-
   77    read(InputStream, InputTerm),
   78    if_(InputTerm = Term,
   79        true,
   80        if_(InputTerm = end_of_file, false, internal:find_in_stream(Term, InputStream))
   81    ).
   82
   83internal:find_term(Term, File) :-
   84    setup_call_cleanup(
   85        open(File, read, InputStream),
   86        internal:find_in_stream(Term, InputStream),
   87        close(InputStream)
   88    ).
 find_term(+Term, +ModuleName) is semidet
Finds the Term in the module, returning true if found.
   93find_term(Term, ModuleName) :-
   94    module_property(ModuleName, file(File)),
   95    internal:find_term(Term, File).
   96
   97
   98
   99internal:add_term(Term, File) :-
  100    setup_call_cleanup(
  101        open(File, append, OutputStream),
  102        (internal:find_term(Term, File) -> false ;
  103         (nl(OutputStream), portray_clause(OutputStream, Term))),
  104        close(OutputStream)
  105    ).
 add_term(+Term, +ModuleName) is semidet
Adds a Term to the module
  110add_term(Term, ModuleName) :-
  111    module_property(ModuleName, file(File)),
  112    internal:add_term(Term, File)