Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

First argument indexing

I want to know how smart first argument indexing is implemented on various Prolog implementations.

In particular, simple type-test goals like integer/1 right after a clause "neck" could contribute to better indexing. Consider:

foo(h(X),X).
foo([],nil).
foo([_|_],cons).
foo(X,Y) :- integer(X), Y = n(X).

With this clause ordering I would like the goal foo([],_) to succeed without leaving any useless choicepoints.

Unfortunately, SWI Prolog does not figure it out:

?- length(Xs,10),
   maplist(=([]),Xs),
   statistics(trailused,T1),
   maplist(foo,Xs,Ys),
   statistics(trailused,T2).

T1 = 5792,
T2 = 5968,
Xs = [[], [], [], [], [], [], [], [], [], []],
Ys = [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil] ...

Do other Prolog implementations do better?

like image 600
repeat Avatar asked Apr 13 '15 12:04

repeat


People also ask

What is indexing in Prolog?

In SICStus Prolog, predicates are indexed on their first arguments. This means that when a predicate is called with an instantiated first argument, a hash table is used to gain fast access to only those clauses having a first argument with the same primary functor as the one in the predicate call.

What is argument in Prolog?

A : argument is a meta-argument, i.e., it is a goal to be called by the predicate (as in setof/3 , for example). In the example of http_server(:Goal, +Options) , you are supposed to call this predicate with the first argument bound to a goal, probably a predicate name.


2 Answers

Yes, the ECLiPSe system does this.

As you suggest, it takes into account a number of simple built-in predicates (such as integer/1, =/2, !/0) for indexing purposes. Your example then executes deterministically, without choicepoints, for all calls of foo/2 with the first argument instantiated. Moreover, ECLiPSe would do this on any argument, not just the first.

You can find a little more detail in the paper ECLiPSe - from LP to CLP.

To answer your followup question: No extra VM features are necessary, the generated VM code looks like this:

foo / 2:
    switch_on_type           a(1) 
            list:           ref(L5)
            structure:      ref(L1)
            bignum:         ref(L7)
            []:             ref(L4)
            integer:        ref(L7)
            meta:           ref(L0)
label(L0):
    try                      0     2     ref(L1) 
    retry                    0     ref(L3) 
    trust                    0     ref(L5) 
label(L1):
    get_structure            a(1)     h / 1     ref(L2) 
    write_value              a(2) 
    ret                  
label(L2):
    read_value               a(2) 
    ret                  
label(L3):
    get_nil                  a(1) 
label(L4):
    get_atom                 a(2)     nil 
    ret                  
label(L5):
    get_list                 a(1)     ref(L6) 
    write_void               2 
label(L6):
    get_atom                 a(2)     cons 
    ret                  
label(L7):
    get_structure            a(2)     n / 1     ref(L8) 
    write_value              a(1) 
    ret                  
label(L8):
    read_value               a(1) 
    ret  
like image 73
jschimpf Avatar answered Oct 23 '22 21:10

jschimpf


YAP is another Prolog system providing extending indexing of predicate clauses:

$ yap
YAP 6.3.4 (x86_64-darwin14.3.0): Wed Apr 22 22:26:34 WEST 2015
 ?- [user].
 % consulting user_input...
foo(h(X),X).
|     foo([],nil).
|     foo([_|_],cons).
|     foo(X,Y) :- integer(X), Y = n(X).
|      % consulted user_input in module user, 1 msec 0 bytes
true.
 ?- foo([],_).
true.

Some relevant papers on YAP indexing features are:

  • Demand-Driven Indexing of Prolog Clauses
  • On Just in Time Indexing of Dynamic Predicates in Prolog
like image 23
Paulo Moura Avatar answered Oct 23 '22 23:10

Paulo Moura