Subject: Re: [SWIPL] Performance!

From: "Richard A. O'Keefe" <[email-masked]>
Date: Mon, 5 Nov 2001 14:53:02 +1300 (NZDT)

Mehmet E. Donderler <[email-masked]> wrote:
	/* WEST, EAST, RIGHT, LEFT */
	
	p-west(X, Y, F) :- p1-west(X, Y, F); p2-west(X, Y, F);
	             p3-west(X, Y, F).
	
	p1-west(X, Y, F) :- west(X, Y, F).
	
(1) The hyphen-minus character ('-') is not allowed in Prolog identifiers
    unless you quote them.  What you have here is the same as
    p(west(X, Y, F)) :- ...
    pl(west(X, Y, F)) :- ...

    It is far from clear to me that this is what you intended.

(2) The semicolon character looks so much like the comma character that
    people often mistake one for the other; the incidence of errors can
    be greatly reduced if you make it your practice NEVER to put a
    semicolon at the end of a line, but always to lay your code out
    like

    p_west(X, Y, F) :-
        (   p1_west(X, Y, F)
        ;   p2_west(X, Y, F)
        ;   p3_west(W, Y, F)
        ).
        
    p1_west(X, Y, F) :-
        west(X, Z, F),	
        (   Y = Z
        ;   p1_west(Z, Y, F)
        ).

(3) I have factorised p1_west/3; this may make the program faster
    (because calls to west(X, _, F) will not be repeated) or slower
    (because the search order is changed).

(4) You can easily cache p1_west/3 like this (assuming that the F
    argument is always ground on entry):

    :- dynamic
        p1_west_cache/3,
        p1_west_cached/1.

    p1_west(X, Y, F) :-
        (  p1_west_cached(F) -> true
	;  p1_west_rule(A, B, F),
           assert(p1_west_cache(A, B, F)),
           fail
	;  assert(p1_west_cached(F))
	),
	p1_west_cache(X, Y, F).

    p1_west_rule(X, Y, F) :-
        west(X, Z, F),	
        (   Y = Z
        ;   p1_west_rule(Z, Y, F)
        ).

    Of course, if you change west/3, you will have to clear the cache.