
store_test_and_set(+StoreHandle, ++Key, ++OldValue, ?NewValue)

   Update an existing entry in a store object

Arguments
   StoreHandle         A store handle or store name
   Key                 A ground term
   OldValue            An arbitrary term (should be ground)
   NewValue            An arbitrary term

Type
   Non-logical Variables, Arrays, Bags, Shelves and Stores

Description
	Looks up a store entry under the given key.  If one exists and
	its value is identical to OldValue, it is replaced with New Value.
	Otherwise the predicate fails.  It could be defined as:

        store_test_and_set(Store, Key, OldValue, NewValue) :-
            with_mutex(Store, (
                    store_get(Store, Key, Entry),
                    OldValue == Entry,
                    store_set(Store, Key, NewValue)
            )).

	Note that the old value is compared for identity, which implies
	that only ground terms can possibly be identical to the stored value
	(because the stored term has different variables).

	The key can be arbitrarily complex, but must be a ground term.
	The value can be an arbitrary term, and may contain uninstantiated
	variables. Note that values are copied when being stored or
	retrieved, therefore a retrieved nonground value will contain
	fresh variables rather than the original ones (this is similar
	to the behaviour of bags, shelves and global variables).

	The complexity of the update operation is linear in the size
	of the key and both values.  NewValue is copied.  For indexing
	purposes, a hash value is computed from the key, and the full depth
	of the key is taken into account.

	Note: If StoreHandle is not a handle, then it must be an atom or a
	compound term, and the store is identified by this term's toplevel
	functor together with the context module.

    

Modes and Determinism
   store_test_and_set(+, ++, ++, ?) is semidet

Modules
   This predicate is sensitive to its module context (tool predicate, see @/2).

Fail Conditions
   Fails is there is no previous entry, or it is not identical to OldValue

Exceptions
     4 --- StoreHandle is uninstantiated
     4 --- Key is not ground
     5 --- StoreHandle is neither atom nor compound term nor store handle
    45 --- StoreHandle is not the name of a store

Examples
   
    ?- store_create(Handle),
       store_test_and_set(Handle, tom, Old, first).	% no entry yet

    No (0.00s cpu)


    ?- store_create(Handle),
       store_set(Handle, tom, first),
       store_test_and_set(Handle, tom, first, second),
       store_get(Handle, tom, New).
    
    Handle = $&(store,"17h3")
    Old = first
    New = second
    Yes (0.00s cpu)


    ?- store_create(Handle),
       store_set(Handle, tom, first),
       store_test_and_set(Handle, tom, premier, second).
    
    No (0.00s cpu)
    

See Also
   store / 1, store_create / 1, store_contains / 2, store_count / 2, store_get / 3, store_inc / 2, store_insert / 3, store_set / 3, store_update / 4
