From ok@atlas.otago.ac.nz Mon Nov  5 02:53:33 2001
Received: from atlas.otago.ac.nz (atlas.otago.ac.nz [139.80.32.250])
	by swi.psy.uva.nl (8.11.2/8.11.2) with ESMTP id fA51rWt14006
	for <prolog@swi.psy.uva.nl>; Mon, 5 Nov 2001 02:53:32 +0100 (MET)
Received: (from ok@localhost)
	by atlas.otago.ac.nz (8.9.3/8.9.3) id OAA234373;
	Mon, 5 Nov 2001 14:53:02 +1300 (NZDT)
Date: Mon, 5 Nov 2001 14:53:02 +1300 (NZDT)
From: "Richard A. O'Keefe" <ok@atlas.otago.ac.nz>
Message-Id: <200111050153.OAA234373@atlas.otago.ac.nz>
To: mdonder@cs.bilkent.edu.tr, prolog@swi.psy.uva.nl
Subject: Re:  [SWIPL] Performance!

Mehmet E. Donderler <mdonder@cs.bilkent.edu.tr> 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.

