Re: handling state the database way

"Abdallah, Samer" <[email protected]>
Newsgroups gmane.comp.ai.prolog.swi
Message-ID <[email protected]>
I agree, the Logtalk way is fine if the decision to use Logtalk for
scoping and encapsulation has been made (sorry, that's almost
tautological), but for plain Prolog, the module system already provides
a relatively standardised way of providing separate namespaces.

For the sake of completeness, this is my current state module.
I got the impression from the documentation that the recorded
database is more efficient than assert/retract when updates are
relatively common compared to reads. For a module aware version,
the recorded item schema could be changed to, e.g.
	record(Module, Key=Value)
but then, of course, there may be multiple items under one key
instead of exactly one in my schema below.

----------------------------
:- module(state,
   [  remove_state/2
   ,  insert_state/2
   ,  get_state/2
   ,  set_state/2
   ,  apply_to_state/2
   ,  call_with_state/4
   ]).

:- meta_predicate apply_to_state(+,2).
:- meta_predicate with_state(+,0,+,-).
   
insert_state(Key,Value) :- check(\+recorded(Key,_)), recorda(Key,Value).
remove_state(Key,Value) :- 
   nofail(recorded(Key,V,Ref), no_state(Key)), 
   erase(Ref), 
   Value=V. % failure here does not affect removal

get_state(Key,Value) :- nofail(recorded(Key,Value), no_state(Key)).
set_state(Key,Value) :- 
   nofail(recorded(Key,_,Ref), no_state(Key)), 
   erase(Ref), recorda(Key,Value).

apply_to_state(Key,Pred) :-
   nofail(recorded(Key,V1,Ref), no_state(Key)),
   call(Pred,V1,V2), % exception here leaves state unchanged
   erase(Ref), recorda(Key,V2).

% guarantees no leak.
call_with_state(Key,Goal,V1,V2) :-
   setup_call_cleanup( 
      insert_state(Key,V1),
      call(Goal),
      remove_state(Key,V2)). % what if removal fails?

nofail(G,Ex) :- G -> true; throw(Ex).
check(G) :-  call(G) -> true; debug(state,'State assertion failed: ~w.',[G]).

/* goal expansion versions of the above omitted here … */
----------------------------

Samer.


On 18 Feb 2014, at 10:05, Jan Wielemaker <[email protected]>
 wrote:

> On 02/18/2014 10:36 AM, Paulo Moura wrote:
>> The design idea behind the "single_fact" module centralizes (for an
>> application) the handling of mutable data.  This can be both an
>> advantage (a single place to hold the mutable data) and a
>> disadvantage (multiple modules using this module must be careful to
>> use different keys). This makes "single_fact" more like a *prototype*
>> solution than an ideal *library* solution. As a library solution it
>> comes with a bias towards a single central, global store.
>> 
>> Logtalk provides a bit more flexible library solution by using a
>> category instead. A Logtalk category is a fine-grined unit of code
>> reuse that can be (virtually) imported by any object. Using the
>> "single_fact" module suggested predicates, we can define:
> 
> Logtalk's abstracting has a cleaner design than classical Prolog
> modules, but that doesn't mean we can't realise module local
> storage with Prolog modules:
> 
> :- meta_predicate
> 	initialize(:, +),
> 	...
> 
> initialize(Module:Key, Value) :-
> 	asserta(Module:store(Key, Value)).
> 
> ...
> 
> And the central store is just
> 
> 	initialize(central:size, 42).
> 
> 	Cheers --- Jan
> _______________________________________________
> SWI-Prolog mailing list
> [email protected]
> https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
> 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 495 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <https://lists.iai.uni-bonn.de/pipermail/swi-prolog/attachments/20140218/4ab75360/attachment.bin>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.