Setting global variable within engine - why does it work

Hi,

To try to avoid assert as much as possible, i adapted the engine heap example to set and get a global variable. To keep the engine alive at the top level i asserted the engine reference, and an retrieving it, prior to an engine post.

I don’t understand why the b_setval/2 / b_getval/2 work – how is their storage associated with the engine and why do they persist.

Here is my slightly amended sample code:

The code

:-dynamic eng/1.

create_heap(E) :-
empty_heap(H),
engine_create(_, update_heap(H), E),
assert(eng(E)).

update_heap(H) :-
engine_fetch(Command),
( update_heap(Command, Reply, H, H1)
→ true
; H1 = H,
Reply = false
),
engine_yield(Reply),
update_heap(H1).

update_heap(add(Priority, Key), true, H0, H) :-
> b_setval(global_var, 123),
add_to_heap(H0, Priority, Key, H).

update_heap(get(Priority, Key), Priority-Key, H0, H) :-
> b_getval(global_var, X),
get_from_heap(H0, Priority, Key, H).

heap_add(Priority, Key) :-
eng(E),
engine_post(E, add(Priority, Key), true).

heap_get(Priority, Key) :-
eng(E),
engine_post(E, get(Priority, Key), Priority-Key).

I then call it from the top level as so:

?- create_heap(E).
E = (7,0000017244E9FC50).

?- heap_add(1, key1).
true

?- heap_get(1, K).
K = key1 .

When running a trace, i can see that X is correctly bound to 123 in the “get” routine …

Global variables live on the Prolog stacks and an engine has its own stacks. The docs do not say much about engines. They are in 99.9% the same as threads, so everything written about things being local to a thread also applies to engines.