Search code examples
prologmeta-predicate

Relying on rule order


To calculate the hamming distance between two lists of the same length, I use foldl(hamm, A, B, 0, R). with this definition of hamm/4:

hamm(A, A, V, V) :- !.
hamm(A, B, V0, V1) :- A \= B, V1 is V0 + 1.

The cut in the first rule prevents the unnecessary backtracking. The second rule, however, could have been written differently:

hamm2(A, A, V, V) :- !.
hamm2(_, _, V0, V1) :- V1 is V0 + 1.

and hamm2/4 will still be correct together with foldl/5 or for queries where both A and B are ground.

So is there a really good reason to prefer the one over the other? Or is there a reason to keep the rules in that order or switch them around?

I know that the query

hamm(a, B, 0, 1).

is false, while

hamm2(a, B, 0, 1).

is true, but I can't quite decide which one makes more sense . . .


Solution

  • You already spotted the differences between those definitions: efficiency apart, you should decide about your requirements. Are you going to accept variables in your data structures? Such programming style introduces some of advanced Prolog features (incomplete data structures).

    Anyway, I think the first form is more accurate (not really sure about, I would say steadfast on 4° argument)

    ?- hamm(a, B, 0, 1).
    false.
    
    ?- hamm(a, B, 0, 0).
    B = a.
    

    while hamm2 is

    ?- hamm2(a, B, 0, 1).
    true.
    
    ?- hamm2(a, B, 0, 0).
    B = a.