Hybrid dynamic asserted and backtrackable predicate arguments


In the system I am developing there are performance critical parts. Every additional hash lookup adds time I look at avoiding.

In one part of my program i am asserting facts such as node(X) and link(link_ID, X,Y). In another part of the program I associate a value with each node (and link) using an assoc.

So, when I want to read a current value on a node(X) i do something like so:

create_node(X) :-

get_val(X, Assoc, Val) :-
   get_assoc(X, Assoc, Val). 

put_val(X, Assoc1, Val, Assoc2) :-
    put_assoc(X, Assoc1, Val, Assoc2).

(in truth, the get_val doesn’t look up the node(X), this is done elsewhere and has to be done beforehand, and then passed to get_val/3).

This however, means two hash lookups, one for node/1 and one for get_assoc/3 / put_assoc/4.

Ideally, i would have liked to associate a dynamic value with the asserted node as so:

assert_node_with_dynamic_value(X, Val) :-
    assert(node(X, Var)),
    Var << Val.

% assume  >> is a read value operator
get_b_val(X, Val) :-
   node(X, Var), 
   Var >> Val. 

put_b_val(X, Val) :-
   node(X, Var), 
   Var << Val.

In a way this seems like attribute variables, but over dynamically asserted facts.

One can, btw, approximately simulate such a thing with global variables.

For example, to generate a unique global variable name and and assert as so:

node(X, uniqu_var_name).

and to get the value to look up the global name – just that

get_val(X, Val) :-
    node(X, Var_name),
   b_get_val(VarName, Val).

put_val(X, Val) :-
   node(X, Var_name),
  b_put_val(Var_name, X).

Just that the latter solution (needlessly?) adds the second hash lookup. Also, global variables have trouble with multi threading – so the assoc solution would be better.

But, what if dynamic facts could support such dynamic structure directly?

any thoughts are much appreciated,