PROLOG-REQUEST@SUSHI.STANFORD.EDU (Chuck Restivo, The Moderator) (07/17/87)
PROLOG Digest Friday, 17 Jul 1987 Volume 5 : Issue 46 Today's Topics: Query - Retry, Implementation - Assert & Retract, Puzzle - Riddle ---------------------------------------------------------------------- Date: 16-Jul-1987 1846 From: spa%hara.DEC@decwrl.dec.com Subject: C-Prolog: retry option in trace menu We are trying to implement, on top of C-Prolog 1.5b.edai, a built-in predicate called 'retry' with the same semantics of the retry option on trace mode. In the following examples the trace option 'r 2' (retry goal 2) in response to "call: true ?" behaves differently. Example1: trace,a(X),write(X),nl,true. % 'r 2' jumps erroneously back to "call: true" trace,a(X),write(X),true. % 'r 2' jumps correctly back to "call: a(X)" Example2: trace,a(X),b(Y),eq(X,Y),true. % 'r 2' jumps erroneously back to "call: true" trace,a(X),b(Y),true. % 'r 2' jumps correctly back to "call: a(X)" The database is comprised by the following clauses: a(1). b(1). This behaviour occurs not only when 'nl' or 'eq' are present but also with other predicates defined in init.pl (e.g. retract, lt ). As this is crucial for our Delta-Prolog implementation, does anyone know how to get around this? Thank you. -- Luis Moniz Pereira ------------------------------ Date: 14 Jul 87 17:39:10 GMT From: Wayne Citrin <ji.Berkeley.EDU!citrin@ucbvax.Berkeley.EDU> Subject: Behavior of assert and retract >I have just had a brief introduction to Quintus Prolog 2.0 after >having used version 1.5 for several years. The behavior of retract >has changed between these two releases. > >Basically, I have a small program that traverses a set of grammar >rules (stored in the clause database) that is implemented in a fail >loop: > >traverse_grammar :- > retract(needs_visiting(Nonterminal)), > visit_node(Nonterminal), > fail. > >The idea is that visit_node/1 will assert new clauses of >needs_visiting/1 as it finds new nonterminals that havent been >visited yet. What you describe boils down to the problem of what is supposed to happen when the program modifies procedures referred to in active choice points. Should the changes be visible to the active choice points or not? My feeling is that they should not, although this behavior is more difficult to implement, since it requires somehow recording the state of a given procedure at various points in the program. It should be obvious that the fragment listed above will behave differently when the active retract cannot 'see' the clauses of needs_visiting/1 than when it can. I favor fixing the visible clauses at the time that the choice point is created since this seems to make it easier to make informal 'assertions' about the behavior of the code (in other words, to understand what's going on). I stumbled on this problem a while ago when comparing two versions of C-Prolog. I had a short correspondence with Fernando Pereira and he agreed that fixing the visible clauses was appropriate behavior in this case, although implementation is more difficult. -- Wayne Citrin ------------------------------ Date: 16 Jul 87 11:29:49 GMT From: mcvax!philmds!philtis!debruyn@seismo.css.gov Subject: Behavior of assert and retract I don't think this should be used as an argument in favour of fixing the set of branch destinations in a choice point at the moment of calling. Facilities for hypothetical reasoning (that's what's being asked for) should be implemented through a partitioned clause-base (in other words: modularity). It would be interesting to learn from Fernando Perreira (C-Prolog) and Richard O'Keefe what arguments pro and con they weighed when opting for this route. -- Frank W.G.M. de Bruyn ------------------------------ Date: Wed 15 Jul 87 15:38:47-EDT From: Paul G. Weiss <PGW@XX.LCS.MIT.EDU> Subject: Prolog Riddle Unless I am missing something, this program solves the Prolog Riddle. nat(X) :- nats_from(1, X). nats_from(N, N). nats_from(N, X) :- N1 is N+1, nats_from(N1, X). This is a special case of the well known for/3 predicate: for(I, I, I) :- !. for(I, J, I). for(I, J, K) :- I1 is I+1, for(I1, J, K). without the second argument or termination condition. Also, note that the time is indeed linear, notwithstanding the submitter's remarks about exits and redos, because of TRO. ------------------------------ Date: 14 Jul 87 11:45:06 GMT From: Lars-Henrik Eriksson <mcvax!enea!ttds!draken!sics!lhe@seismo.css.gov> Subject: Prolog riddle - (nf) If you want the predicate to generate successive integers each time it is called, then it is impossible to do without side effects. Suppose the predicate foo/1 would do what you want. Then different calls foo(X) would instantiate X to different integers. In Prolog, as in any other language, this can only be done with side effects. If no side effects were involved, the program would have no way of knowing that it had been called before. In logic programming, it is conceivable that you could write a predicate foo/1 such that foo(N) holds for ANY natural number N, but some complex control information make sure that successive calls with N uninstantiated instantiates it to successive natural numbers, but I guess that is not really what you want. (It couldn't be done in Prolog anyway). -- Lars-Henrik Eriksson ------------------------------ Date: 16 Jul 87 08:31:06 GMT From: J. A. Durieux <mcvax!botter!klipper!biep@seismo.css.gov> Subject:: Prolog riddle - (nf) I believe this may be useful. numbers(X) :- count(0, X). ; or whatever number you want to start with count(X, X). count(X, Y) :- Z = X+1, count(Z, Y). In this way, *on backtracking*, all natural numbers are generated. (Thanks to Hans Weigand, who once helped me out of a similar problem). I think this program meets the three specified criteria, except perhaps that due to interpreter inefficiencies time might exceed O(n). -- Biep ------------------------------ End of PROLOG Digest ********************