Path: utzoo!utgpu!attcan!uunet!mcvax!ukc!dcl-cs!nott-cs!abc
From: abc@cs.nott.ac.uk (Andy Cheese)
Newsgroups: comp.lang.prolog
Subject: Re: Parallel: lists or trees ?
Message-ID: <2939@robin.cs.nott.ac.uk>
Date: 5 Aug 88 10:41:31 GMT
Reply-To: abc@cs.nott.ac.uk (Andy Cheese)
Organization: Computer Science, Nottingham Univ., UK.
Lines: 98


This is a response to richard o'keefe's message of some time ago, i meant
to follow it up ages ago but have only just got around to it.

the reason lists are so prevalent in FCP, parlog, FGHC etc is that they are
all concurrent logic programming languages ( i do wish people wouldn't use
the term logic language, this has a clear definition i understand from my
mathematics days and doesn't have a lot of relation to what people mean when
they use the term, please use logic programming language). this paradigm more
or less forces you to think in terms of communicating processes and hence
streams, hence lists.

> make_list(0, []).
> make_list(N, [N|Rest]) :- N > 0, M := N-1 |
>         make_list(M, Rest).

i don't understand why you have the unification "M := N-1" in the guard,
if N is an integer this will always succeed, surely the clause should be

make_list(N, [N|Rest) :- N > 0 | 
        M := N-1,
        make_list(M?, Rest).

you want as little computation in the guard as possible, only what is necessary
to decide that this is the clause you want, the same as cut in Prolog, but you
know this anyway.

> remainder_list([], []).
> remainder_list([N|Ns], [R|Rs]) :- R := N \ 3 |
>       remainder_list(Ns?, Rs).

looking at the code for make_list/2, you can see that the second argument of
a call to remainder list will always be an unbound variable. 
remainder_list/2 is constructing its second argument so you want the
ouput unification "R := N \ 3" in the body of the second clause, the fact
that you've got non-overlapping constructor functions for first argument
is good enough to ensure the correct clause is chosen. The second clause
should be

remainder_list([N|Ns], [R|Rs]) :-
      R : = N \ 3,
      remainder_list(Ns?, Rs).

This same argument also holds for the second clause of zero_count_list/3,
put output unification in the body of clauses.

Exactly the same for the tree version, tests in the guard, output unification
in the body. The correct code is (i think because i don't have logix online
at the moment so i can't test it, i have been known to bungle things before).

three_tree(N, Count) :-
	make_tree(1, N, Numbers),  % Numbers guaranteed unbound at call
	remainder_tree(Numbers?, Remainders), % Remainders guaranteed unbound
	zero_count_tree(Remainders?, Count).

make_tree(N, N, {N}).
make_tree(L, U, [LM|NU]) :- L < U |
	M := (L+U)/2, make_tree(L, M?, LM),
        N := (L+U)/2 + 1, make_tree(N?, U, NU).

remainder_tree({N}, {R}) :- R := N \ 3.
remainder_tree([N1|N2], [R1|R2]) :-
	remainder_tree(N1?, R1),
	remainder_tree(N2?, R2).

zero_count_tree({R}, C) :- C := (3-R)/3.
zero_count_tree([T1|T2], C) :-
	zero_count_tree(T1?, C1),
	zero_count_tree(T2?, C2),
        plus(C1?, C2?, C).
    
what we really need is a system which knows about the underlying architecture
and can transform a program to use the most appropriate data structures to
give the right grain of parallelism and which allows me to debug it as if it
were still my original program.
---------------------------------------------------------------------

JANET : abc@uk.ac.nott.cs              Andy Cheese
ARPA  : abc%nott.cs@ucl-cs.arpa        Department of Computer Science,
                                       University of Nottingham,
Functional vs. Logic Programming       University Park,
If You Can't Decide Between Em,        Nottingham.
-- Join Em                             NG7 2RD.
                                       England.
 
                                       Tel. No. : (0602) 484848 ext. 2765

From October 1988 :-

ECRC
European Computer-Industry Research Centre GMBH
(Forschungszentrum)
Arabellastrasse 17
D-8000 Muenchen 81
West Germany

-- 
Andy Cheese