N00b question : Capturing new information and saving part of the database

Hi everyone,

I’m just starting a small (but real) application to try to get my head around Prolog (and logic programming in general).

In the application I’m developing, I want part of the database to be fixed. It’s generated by a separate program and just imported into Prolog.

Then the idea is that user adds to this database, giving some extra information, by “filling in the blanks” through a web-form.

The question is how I handle this.

Should I be using asserts to capture the extra information? And is there a way of saving just the extra data asserted in the run-session?

For the data which is generated elsewhere, that is the official version. I don’t want to do a listing. from my application and dump everything, because that external generated data might be more up-to-date.

At the same time, I want to capture the extra data that the user has filled in, as a kind of extra annotation of the knowledge available.

How do I typically handle this kind of requirement?

Hi interstar and welcome to the discourse group.

What you need is library(persistency), which has a pretty good example in the docs I’ve linked to.

Best of luck learning Prolog, any questions feel free to ask.

Hi Paul,

thanks for this.

I’m still pretty new at this so not fully understanding that code example.

Should I assume that, assert_user_role(U,R). is an automatically generated wrapper for something like assert(user_role(U,R)). ?

I’m assuming that inside this module, facts are bound to being in a user_db namespace. But only the user_role predicate is actually being persisted?

Presumably because of the line beginning “:- persistent user_role…”?

What is the File argument passed to attach_user ? A filename or a File object I have to make elsewhere?

What if I have some facts which use the same predicate which come from elsewhere, and I want to just append a few more here? Can I have some user_role statements elsewhere or are they only in scope in this module?

cheers

Phil

Should I assume that, assert_user_role(U,R). is an automatically generated wrapper for something like assert(user_role(U,R)). ?

When you call assert_user_role/2 it will assert user_role/2 into working memory. It will also update the persistent file, “sensibly”, you can modify how this works through the options for dbsync/2 like dbsync(gc(always)).

I’m assuming that inside this module, facts are bound to being in a user_db namespace. But only the user_role predicate is actually being persisted?

Within the module all predicates are within the module namespace unless explicitly exported, which in the example is all of them except user_role/2. There’s nothing stopping user_role/2 from also being exported except conventional design wisdom. And yes, only user_role/2 is persisted in the database file, the other predicates are persisted in the module and not updated.

Presumably because of the line beginning “:- persistent user_role…”?

Yes, this declares your predicates to be persisted in the database file.

What is the File argument passed to attach_user ? A filename or a File object I have to make elsewhere?

It can be just a filename, in which case it will be made in the local directory. It can also be a full path to a file, so it can be anywhere you choose.

What if I have some facts which use the same predicate which come from elsewhere, and I want to just append a few more here? Can I have some user_role statements elsewhere or are they only in scope in this module?

If you don’t use modules you can, but it’s wiser to use modules and create a shared interface:

user_role(A, B) :-
    always_user_role(A, B).
user_role(A, B) :-
    current_user_role(A, B).

Thanks Paul

I think this is enough for me to go and have a play and see if I can do what I want.

Many thanks again.

1 Like