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