Thanks.
It looks like i wasn’t able to explain what i am looking for.
Let me make up an artificial example, just to illustrate.
Consider the following code. It essentially, it’s aim is to associate with each item(a), item(b) a calculated value. Due to backtracking, the calculated value for each item(a) and item(b) can change.
In the code below an assoc is used to map between item(a) and item(b) and respective calculated values, simulated here by the long_calculation/2 predicate. During backtracking, the assoc backtracks as well, and gets the next calculated values for each item(a) and item(b), respectively (one each, for each next backtrack request).
Now, the mapping is assoc based – so any time one wants to retrieve the current calculated value of an item, you have an assoc lookup – which can become expensive for a very large number of items – say, in the millions or tens of millions or more.
However, in C you wouldn’t use an assoc to map between an item and a calculated value – you would use a pointer (or simply another adjacent memory cell, in such a simple case of one value) to where item(a) is stored.
If you have a reference to a in the item table, then you can immediately retrieve the calculated value, say, via the pointer to its memory cell.
In Prolog, you have to take atom ‘a’ as key and look it up in the assoc to get the value. There is actually no other way to associate any item(a), item(b) to a backtrackable value, but use some kind of key-value data structure – and this is due to the dichotomy in Prolog between the fact store and the stack for terms bound to goal variables.
(one can implement it with backtrackable assert, but that is even more expensive, with all the indexing going on in the background, or one can read all items into a term on the stack, and use attributed variables (somehow) to associate via a pointer each item with its calculated value – which, however, replicates all items in stack memory – which is not feasible).
However, what if, in prolog along with item(a) that is stored in the fact base, one can store a pointer to an (backtrackable) attribute Value (or Term) as well, via a & operator, then a lookup item(a)&Attr would immediately bind the calculated value to Attr – and thereby save an assoc lookup, as in the code below.
For a very large list of items (and hence assoc) the saving can be substantial during lookup and during put – in particular when a put and get attribute is performed in a core area of the system that gets called a lot.
Dan
item(a).
item(b).
long_calculation(X, Count) :-
item_result(X, Count).
item_result(a, 5).
item_result(a, 6).
item_result(b, 2).
item_result(b, 3).
found_items(Items, Assoc) :-
empty_assoc(Assoc0),
aux_found_items(Items, Assoc0, Assoc).
aux_found_items([], Assoc, Assoc).
aux_found_items([First | Rest ], Assoc0, Assoc) :-
item(First),
long_calculation(First, N),
put_assoc(First, Assoc0, N, Assoc1),
aux_found_items(Rest, Assoc1, Assoc).
top_level_process(Items, Result) :-
found_items(Items, Assoc),
process_found(Assoc, Result).
?- top_level_process([a,b], Result).