Significant speed difference in predicate usage?

I’m using: SWI-Prolog version 8.0.2.

I like adorning individual arguments in predicates I use as facts. For example:

explain(item_id(dog), event_name(barked), explanation('The dog barked)).

I prefer this to relying alone on the position of an argument in a predicate to know what that argument is for. In that style, the above fact would look like this:

explain(dog, barked, 'The dog barked).

Is there a significant difference in speed between the two predicate clauses shown above when SWI-Prolog does a look-up across a large number of predicate clauses? I am not familiar with how SWI-Prolog does its indexing to know what choice to make here.

The reason I’m concerned is this. I will have hundreds if not thousands of these “facts” and I’m worried that if I use my normal style of adorning each predicate argument with its own functor, it will be a lot slower than if I don’t because SWI-Prolog can’t do whatever optimizations it does to make predicate clause scanning fast.

What is the reality here?

1 Like

Most of the indexing is described in https://www.swi-prolog.org/pldoc/man?section=jitindex

I would typically advice against this usage though. It makes the clauses bigger, the indexes bigger and the whole thing slower. Measure to see by how much.

If you want to have some access by name create two predicates: one holding the plain facts and a wrapper that provides the friendly interface you want. Just wrapping in a functor gives you very little extra IMO, except some readability which you can also provide using comments. You could do

explain(Dict) :-
     _{item_id:ID, event_name:Event, explanation:Explanation} :< Dict,
     explain(ID, Event, Explanation).

Now you can make efficient and readable queries with the bonus that you can simply omit arguments in which you are not interested and your code will keep working if at some point you extend the data with an additional column.

?- explain(_{item_id:ID, explanation:Explanation}).
2 Likes

Interesting! I 've never seen that colon prefixing idiom to and then access arguments in a Prolog term. Is that a SWI-Prolog enhancement? Can you tell me what the official name is for that feature and if there’s a manual page on it?

See:
Dicts: structures with named arguments
library(dicts): Dict utilities

1 Like