Updating a knowledge base in SWI-Prolog

457 views
Skip to first unread message

Matthew McNally

unread,
Jun 20, 2017, 7:51:36 PM6/20/17
to swi-p...@googlegroups.com
Hi there,

Coming from a more imperative programming background, I am probably looking at this problem the wrong way, however I have not found much information to suggest the 'right' way to do this.

Here is my problem:

Let's say I have a predicate in my Prolog knowledge base, position(X, Y). This stores the position of some entity at any given point in time. Consider that the initial position of any entity is (0, 0), and so in my .pl file the knowledge base is initialised to have the fact position(0, 0).

My question is: how can this be 'updated'? For example, say my entity moves to position (3, 2). How can I 'update' my knowledge base such that the position fact is now listed as position(3, 2)? I need to be able to query this fact at some time in the future and it be correct to the position at the current time (i.e. return (3, 2)), so it needs to be stored in the knowledge base.

From searching, all I have really found to be able to provide this functionality is the various database paradigms described at this page. That page lists two main ideas which seem like they would get the job done:
  1. Using dynamic predicates - Modifying the clause database at runtime using assert and retract variants. However I have read that this is slow, and also as the page I linked states, backtracking changes is not supported.
  2. Using global variables - This feels like a sin, should I really be using global variables to realise state? It feels like there should be issues with modularity or whatnot (again, coming from an imperative programming background, global variables are generally avoided). I am obviously not an expert however.
Regardless of their individual problems, the page I linked quite clearly states that 'Typically it is a bad idea to use any of the predicates in this section for realising global variables that can be assigned to'. That leads me to ask, what options do I have to get the functionality I want, if not for the alternatives already listed?

I appreciate any help you can give me.

Regards,
Matthew McNally

Boris Vassilev

unread,
Jun 21, 2017, 2:17:43 AM6/21/17
to Matthew McNally, SWI-Prolog
Hello Matthew,

if your question is, "how do I keep state", you have two more choices.

  - You can use an extra argument that represents the state;
  - If you have a state machine, you can have a predicate for each state.

Both approaches are used also in functional programming, if this would make it easier to search for examples. I would like to give you an example with code but it would be much easier if you had a specific problem in mind.

Cheers,
Boris


Save our in-boxes! http://emailcharter.org

On Wed, Jun 21, 2017 at 2:51 AM, Matthew McNally <matthew...@gmail.com> wrote:
Hi there,

Coming from a more imperative programming background, I am probably looking at this problem the wrong way, however I have not found much information to suggest the 'right' way to do this.

Here is my problem:

Let's say I have a predicate in my Prolog knowledge base, position(X, Y). This stores the position of some entity at any given point in time. Consider that the initial position of any entity is (0, 0), and so in my .pl file the knowledge base is initialised to have the fact position(0, 0).

My question is: how can this be 'updated'? For example, say my entity moves to position (3, 2). How can I 'update' my knowledge base such that the position fact is now listed as position(3, 2)? I need to be able to query this fact at some time in the future and it be correct to the position at the current time (i.e. return (3, 2)), so it needs to be stored in the knowledge base.

From searching, all I have really found to be able to provide this functionality is the various database paradigms described at this page. That page lists two main ideas which seem like they would get the job done:
  1. Using dynamic predicates - Modifying the clause database at runtime using assert and retract variants. However I have read that this is slow, and also as the page I linked states, backtracking is not supported.
  1. Using global variables - This feels like a sin, should I really be using global variables to realise state? It feels like there should be issues with modularity or whatnot (again, coming from an imperative programming background, global variables are generally avoided). I am obviously not an expert however.
Regardless of their individual problems, the page I linked quite clearly states that 'Typically it is a bad idea to use any of the predicates in this section for realising global variables that can be assigned to'. That leads me to ask, what options do I have to get the functionality I want, if not for the alternatives already listed?

I appreciate any help you can give me.

Regards,
Matthew McNally

--
You received this message because you are subscribed to the Google Groups "SWI-Prolog" group.
To unsubscribe from this group and stop receiving emails from it, send an email to swi-prolog+unsubscribe@googlegroups.com.
Visit this group at https://groups.google.com/group/swi-prolog.
For more options, visit https://groups.google.com/d/optout.

Samer Abdallah

unread,
Jun 21, 2017, 5:13:14 AM6/21/17
to Boris Vassilev, Matthew McNally, SWI-Prolog
Hi Matthew,

On 21 Jun 2017, at 07:17, Boris Vassilev <boris.v...@gmail.com> wrote:

Hello Matthew,

if your question is, "how do I keep state", you have two more choices.

  - You can use an extra argument that represents the state;

If some operations need to update the state, then you can have two
extra arguments on each predicate, one for the ‘input’ state and one
for the ‘output'. It can be convenient to use DCG notation (using
—>instead of :-), which automatically adds two extra arguments
at the end and threads the state through all the calls.

Another option which became available recently is to use delimited
continuations to manage state. From inside the delimited context,
it looks like you have a piece of mutable state as you would in an 
imperative language, but the apparent mutability  is carefully managed
by context’s effect handler, and from the outside looks pure and
declarative. You can simulate backtrackable or non-backtrackable
state using different handlers. Have a a look at the ccstate module
in the add-on pack called ‘genutils’.

Samer


To unsubscribe from this group and stop receiving emails from it, send an email to swi-prolog+...@googlegroups.com.
signature.asc
Reply all
Reply to author
Forward
0 new messages