Is there a way to determine whether a call has been tabled?

View: New views
3 Messages — Rating Filter:   Alert me  

Is there a way to determine whether a call has been tabled?

by Brian DeVries :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Howdy all,

I'm using tabling in my Prolog program, and when calling a tabled predicate, I would like to determine whether the call I'm about to make has been tabled already or not. Is there a way to query the predicate's table before (or after) making the call so I can determine whether the call will succeed via a tabled answer or because the predicate itself was executed?

My situation is more complex than this example, but it will suffice to describe the behavior I would like:

:- table fib/2.

fib(1, 1) :- write('Base case'), nl.
fib(X, Y) :- X1 is X - 1, X2 is X - 2, fib(X1, Y1), fib(X2, Y2), Y is Y1 + Y2, write('Inductive case'), nl.

call_fib(X, Y) :- fib(X, Y), (was_tabled(fib(X, Y)) -> write('Tabled success'), nl ; true /* do nothing */).


Regardless of whether fib is actually executed, I still need to execute the call to write, so I would like a way to determine whether a call succeeds / succeeded because it was already in the table or because the predicate was actually executed.

I do realize that the general principle is "actions taken inside tabled predicates can't be expected to always be executed, so actions that must always be taken should not be placed in tabled predicates." Unfortunately, in my case, the required actions are essentially (non-I/O) data processing instructions that cannot be removed from the tabled predicate but nevertheless must be executed every time the tabled predicate is called, regardless of whether it succeeds or not.

Is there a way to do this?

Thanks,
~Brian W. DeVries

------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
Yap-users mailing list
Yap-users@...
https://lists.sourceforge.net/lists/listinfo/yap-users

Re: Is there a way to determine whether a call has been tabled?

by Ricardo Rocha-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Brian,

Currently, from the user point of view, there is no way to check if a
tabled call is already tabled or not. The tabling engine automatically
detects when a call is already completed and in such cases simply
consumes answers from the table space without executing the clauses.

For what I understand, the behaviour you want to implement, can be
solved, for instance, by using a global variable in the tabled code.
Something like that:

fib(_,_) :- set_value(fib_executing_clauses,1).
fib(1, 1) :- ...
fib(X, Y) :- ...

call_fib(X, Y) :- set_value(fib_executing_clauses,0),
                  fib(X, Y),
                  get_value(fib_executing_clauses,T),
                  (T = 0 -> write('Tabled success'), nl ; true).

Ricardo Rocha

> Howdy all,
>
> I'm using tabling in my Prolog program, and when calling a tabled
> predicate, I would like to determine whether the call I'm about to
> make has been tabled already or not. Is there a way to query the
> predicate's table before (or after) making the call so I can determine
> whether the call will succeed via a tabled answer or because the
> predicate itself was executed?
>
> My situation is more complex than this example, but it will suffice to
> describe the behavior I would like:
>
> :- table fib/2.
>
> fib(1, 1) :- write('Base case'), nl.
> fib(X, Y) :- X1 is X - 1, X2 is X - 2, fib(X1, Y1), fib(X2, Y2), Y is
> Y1 + Y2, write('Inductive case'), nl.
>
> call_fib(X, Y) :- fib(X, Y), (was_tabled(fib(X, Y)) -> write('Tabled
> success'), nl ; true /* do nothing */).
>
>
> Regardless of whether fib is actually executed, I still need to
> execute the call to write, so I would like a way to determine whether
> a call succeeds / succeeded because it was already in the table or
> because the predicate was actually executed.
>
> I do realize that the general principle is "actions taken inside
> tabled predicates can't be expected to always be executed, so actions
> that must always be taken should not be placed in tabled predicates."
> Unfortunately, in my case, the required actions are essentially
> (non-I/O) data processing instructions that cannot be removed from the
> tabled predicate but nevertheless must be executed every time the
> tabled predicate is called, regardless of whether it succeeds or not.
>
> Is there a way to do this?
>
> Thanks,
> ~Brian W. DeVries
> ------------------------------------------------------------------------------
> Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
> -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
> -Strategies to boost innovation and cut costs with open source participation
> -Receive a $600 discount off the registration fee with the source code: SFAD
> http://p.sf.net/sfu/XcvMzF8H
> _______________________________________________ Yap-users mailing list Yap-users@... https://lists.sourceforge.net/lists/listinfo/yap-users


------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
Yap-users mailing list
Yap-users@...
https://lists.sourceforge.net/lists/listinfo/yap-users

Re: Is there a way to determine whether a call has been tabled?

by Brian DeVries :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Ricardo,

Thanks for the reply. I am doing it like this already and it works fine, but it just seemed too C-like to be used in a logic program.

Also, I ran across Call Cleanup recently (http://www.dcc.fc.up.pt/~vsc/Yap/documentation.html#SEC94). Would this also work?

Thanks,
~Brian W. DeVries

On Sat, Feb 28, 2009 at 12:54 PM, Ricardo Rocha <ricroc@...> wrote:
Hi Brian,

Currently, from the user point of view, there is no way to check if a
tabled call is already tabled or not. The tabling engine automatically
detects when a call is already completed and in such cases simply
consumes answers from the table space without executing the clauses.

For what I understand, the behaviour you want to implement, can be
solved, for instance, by using a global variable in the tabled code.
Something like that:

fib(_,_) :- set_value(fib_executing_clauses,1).
fib(1, 1) :- ...
fib(X, Y) :- ...

call_fib(X, Y) :- set_value(fib_executing_clauses,0),
                 fib(X, Y),
                 get_value(fib_executing_clauses,T),
                 (T = 0 -> write('Tabled success'), nl ; true).

Ricardo Rocha

> Howdy all,
>
> I'm using tabling in my Prolog program, and when calling a tabled
> predicate, I would like to determine whether the call I'm about to
> make has been tabled already or not. Is there a way to query the
> predicate's table before (or after) making the call so I can determine
> whether the call will succeed via a tabled answer or because the
> predicate itself was executed?
>
> My situation is more complex than this example, but it will suffice to
> describe the behavior I would like:
>
> :- table fib/2.
>
> fib(1, 1) :- write('Base case'), nl.
> fib(X, Y) :- X1 is X - 1, X2 is X - 2, fib(X1, Y1), fib(X2, Y2), Y is
> Y1 + Y2, write('Inductive case'), nl.
>
> call_fib(X, Y) :- fib(X, Y), (was_tabled(fib(X, Y)) -> write('Tabled
> success'), nl ; true /* do nothing */).
>
>
> Regardless of whether fib is actually executed, I still need to
> execute the call to write, so I would like a way to determine whether
> a call succeeds / succeeded because it was already in the table or
> because the predicate was actually executed.
>
> I do realize that the general principle is "actions taken inside
> tabled predicates can't be expected to always be executed, so actions
> that must always be taken should not be placed in tabled predicates."
> Unfortunately, in my case, the required actions are essentially
> (non-I/O) data processing instructions that cannot be removed from the
> tabled predicate but nevertheless must be executed every time the
> tabled predicate is called, regardless of whether it succeeds or not.
>
> Is there a way to do this?
>
> Thanks,
> ~Brian W. DeVries
> ------------------------------------------------------------------------------
> Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
> -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
> -Strategies to boost innovation and cut costs with open source participation
> -Receive a $600 discount off the registration fee with the source code: SFAD
> http://p.sf.net/sfu/XcvMzF8H
> _______________________________________________ Yap-users mailing list Yap-users@... https://lists.sourceforge.net/lists/listinfo/yap-users



------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
Yap-users mailing list
Yap-users@...
https://lists.sourceforge.net/lists/listinfo/yap-users