Pattern matching dicts in head terms?

Can dicts be used effectively match on the heads of rules?

Suppose I have a number of pattern transformations of structured data:

A ---> B:-
    % token(tokendata{tag:tagdata{kind:str, ... }   },    [<token>]  )
    A = token(AData, AChildren),
    AData.tag.kind = 'number',
    ... 

A ---> B:- ...
A ---> B:- ...
A ---> B:- ...
... many

… which I expect will have a very negative impact on performance with more rules. (I assume no indexing happening on the contents of A or B, or does the prolog JIT look inside the rule?).

Is there a way to benefit from indexing here?

Perhaps something like this:

token(tokendata{tag:tagdata{kind:number | TagDatas  } | TokenDatas  },    Children ) --> B :-

where TagDatas means “the remaining key-value pairs”.

I understand that I could flatten tok and tag to be plain-old-structure, but ideally, for my sanity, I’d like to preserve the naming of attributes that dict provides. (If it helps, the dicts for have a fixed set of keys and are easily mapped to structures).

Related: Missing a way for partial dict unification in clause header?

If all dicts have the same set of keys the system may use deep indexing. Run the code and use jiti_list/1 to see what indexes it created.

(I really love the auto-linking as it avoids the need to lookup the exact name and arity in the manual :slight_smile: Thanks @jamesnvc)

In other cases, you may use term_expansion/2 to extract the indexable keys from the dict and (also) pass it as an additional argument.

3 Likes