Path: utzoo!attcan!uunet!munnari.oz.au!cs.mu.oz.au!ok From: ok@cs.mu.oz.au (Richard O'Keefe) Newsgroups: comp.lang.prolog Subject: Re: Dynamic Properties Message-ID: <2644@munnari.oz.au> Date: 6 Nov 89 05:44:52 GMT References: <5500@ubc-cs.UUCP> Sender: news@cs.mu.oz.au Distribution: comp.lang.prolog Lines: 78 In article <5500@ubc-cs.UUCP>, kean@faculty.cs.ubc.ca (Alex Kean) writes: > 1) solve(true). > 2) solve((A,B)) :- solve(A), solve(B). > 3) solve(X) :- clause(X,Y), solve(Y). That's a pretty awful interpreter. (Yes, I know it's common.) > I guess I was surprised when the above program would not run in Quintus > Prolog upon any backtracking. You haven't got a copy of my tutorial notes, then! > 1) As I understand, the dynamic/static property is useful for compiler > optimization. If the default is static, then the compiler can optimize > without fear since the predicate cannot be altered. Am I correct? No. A static predicate cannot be *altered* (by assert or retract) but it can be *replaced* (by abolishing it and then adding a new predicate, or by compiling a file which redefines the predicate). The point of predicates being static by default is to ensure that you don't change anything *accidentally*. (Also, a :- dynamic declaration is used to tell the system "it is ok for this predicate to have no clauses.") One of the things which commonly went wrong in DEC-10 Prolog programs was that you would do p :- q. % these two lines r, % were switched s. and this would quietly be taken as a definition of (r,s) and that definition would be as quietly forgotten. (It was even worse in a Prolog interpreter I used once which would take it as a definition of (r,s) and redefine (',')/2...) This is just one of the reasons why any attempt to treat a built-in predicate inappropriately is reported. In this case, there is a built-in predicate called (',')/2. As it happens, there *IS* a clause for that predicate in the system, and you *really* do not want to get a copy of it. > 2) Is there an obvious solution to my problem that I am missing ? Yes. /*1*/ solve(true) :- !. /*2*/ solve((A,B)) :- !, solve(A), solve(B). /*3*/ solve(X) :- predicate_property(X, built_in), !, call(X). /*4*/ solve(X) :- clause(X, Y), solve(Y). I've added clause /*3*/ so that your interpreter can do arithmetic and such. The point is, once your clause 1) or clause 2) has been selected, there really is no point at all in ever considering any of the other clauses, so a cut is appropriate. Even if it was not needed to prevent calling solve(true) or solve((_,_)), you would still want it for efficiency. > 3) As I am not a Prolog expert, I am speaking from a user point of > view. I use high level programming languages because I want fast > prototyping capability to test out my theorems and lemmata. > In this situation, I find myself *not* testing my result but rather > combating with different systems specific capabilities and drawbacks. > Is my experience unwarranted? Yes. You *were* testing your code, which was broken to start with. What you wrote does NOT mean what you thought it meant, and some Prolog systems report that and some don't. Just to re-emphasize that the code was broken: one of the Prologs around here has a clause true. in it, which would show up in clause/2 as ?- clause(true, true). if the call clause(true, Y) were not blocked somehow. Then 'true' would have infinitely many proofs, which is not a very good idea. Quintus Prolog and NU Prolog both have clauses for (',')/2 as well. (There is much more to say about this, but I've got to leave something for the book.)