Path: utzoo!utgpu!water!watmath!clyde!att-cb!att-ih!alberta!ubc-cs!voda From: voda@ubc-cs (Paul Voda) Newsgroups: comp.lang.prolog Subject: Re: Programming Quickie Message-ID: <1922@ubc-cs.UUCP> Date: 1 Apr 88 07:16:33 GMT References: <1600011@otter.hple.hp.com> <2644@mulga.oz> <839@cresswell.quintus.UUCP> Sender: nobody@ubc-cs.UUCP Reply-To: voda@ubc-cs.UUCP (Paul Voda) Organization: UBC Department of Computer Science, Vancouver, B.C., Canada Lines: 95 In article <839@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >: > exactly_one( +X, ?Y ) >: > is true if X contains Y, Y satisfies p/1 and all of the other >: > Y' contained by X satisfy q/1. >: >: % NU-Prolog solution (will generate X or Y or both) >: exactly_one(X, Y) :- >: setof(Y0, X contains Y0, YList), % >: select(Y, YList, Remainder), % >: p(Y), >: forall(member(Y1, Remainder), q(Y1)). % > The code of Naish as edited by O'Keefe contains three list constructions/traversals: setof, forall, and select. One list operation is sufficient provided that your Prolog has a LOGICAL "all solutions" predicate ( i.e. the one looking for an ORDERED list with no repetitions of values satisfying a formula). Since I do not have such a Prolog and anyway I program mostly in Trilogy here is the solution in Trilogy: Aux = Some_notP1Q | P1_of(B) | Some_Q proc Exactly_one(x:B) iff all aux in listaux Contains(x,z) & if P1(z) then aux = P1_of(z) elsif Q(z) then aux = Some_Q else aux = Some_notP1Q end end & listaux = P1_of(y),w & ( w = Nil | w = Some_Q,Nil ) Assumptions: For simplicity sake (without compromising the generality of the solution) I assume the following about the predicates Contains, P, and Q. Actually I use P1 since P is a predefined identifier in Trilogy.: P1 and Q may hold for the same x. The declarations are as follows: pred Contains(x:B) {output B's are contained in input (given)A} proc P1(x: