Organization of data and code through modules in Prolog

I am developing a simple web service that will add data provided by the user to my Prolog database (using assert). I thought it was better to keep these dynamic facts (“data”) separate from my service rules that work with these facts (“code”), and therefore separate them into two different modules. The main reason was that I wanted to periodically save dynamic facts to disk, being able to develop code without problems and regardless of user data. I used assert(my_store:fact(...))to add user data to the module my_store, and then in the code module I started coding rules such as

:- module (my_code, [a_rule/1, ...]).

a_rule(Term) :-
   my_store:fact(...), ...

Everything looks fine, but with this approach it is my_storehardcoded in the code module, which is a bit worrying. For example, what if, after some time, I decide to change the name of the data module, or maybe I need two separate data modules with frequent persistence, the other with constancy, performed only sporadically?

Can anyone advise what are the best practices in organizing code and data? Perhaps the separation of code and data is contrary to the "prologue"? Are there any good books that cover these issues in depth?

Cheers, Jacek

+4
source share
3 answers

This is a good question, addressing several very important topics.

, , , , , , , .

  • -, , . SWI-Prolog safe_goal/1, . , , .

  • SWI-Prolog (). , , , , .

  • , :

    • . .
    • , . use_module/1 , . , , .

: Prolog .

Prolog - Prolog.

! !

+3

@mat , . ; , persistency, , .

, assert(my_store:fact(...)). , my_store , use_module. import/1 , , :

:- module(my_code, [a_rule/1, ...]).

:- initialization import_my_store.

import_my_store :-
   import(my_store:fact/1),
   import(my_store:another_fact/1),
   ...

a_rule(Term) :-
   fact(...), ...

, fact/1 my_store. .

save_db(File) :-
   tell(File),
   my_store:listing,
   told.

, import/1 , : import/1: my_store:fact/1 is not exported (still imported into my_code). , my_code, .

. Cheers,

+2

Logtalk, . :

:- object(my_code).

    :- public([a_rule/1, ...]).

    :- private([fact/1, another_fact/1, ...]).
    :- dynamic([fact/1, another_fact/1, ...]).

    a_rule(Term) :-
        ::fact(...), ...

    ...

:- end_object.

, ( ) my_code:

?- create_object(my_store, [extends(my_code)], [], []).

, :

?- my_store::a_rule(Term).

create_object/4 ( , ):

?- create_object(my_store, [extends(my_code)], [include('my_store.pl'))], []).

, :

?- my_store::assertz(fact(...)).

, my_code. :

:- public(dump/0).
dump :-
    self(Self),
    atom_concat(Self, '.pl', File),
    tell(File),
    dump_dynamic_predicates,
    told.

dump_dynamic_predicates :-
    current_predicate(Functor/Arity),
    functor(Template, Functor, Arity),
    predicate_property(Template, (dynamic)),
    ::Template,
    write_canonical(Template), write('.\n'),
    fail.
dump_dynamic_predicates.

, :

?- my_store::dump.

Note that with this solution it is trivial to have any number of data stores at the same time. If the data warehouse requires a specialized version of the code, you can simply expand the code object and then create a specialized data warehouse as an extension of this specialized object.

+2
source

Source: https://habr.com/ru/post/1648571/


All Articles