Joshua Levy writes:
However, I've run into a problem in using the data predicates. Can you tell me if it is a bug, or what I'm doing wrong? I made a file foo.pl containing:
:- module(foo,[main/0]).
blah(1).
main :- assertz_fact(blah(2)), blah(2).
You should declare blah/1 as a data predicate by inserting
:- data blah/1.
after the module declaration (it can go anywhere, but respecting certain order makes programs easier to read for other people). This tells the compiler that blah/1 is dynamic, and can be changed during program execution. These predicates are compiled specially, and the compiler must be aware of that. The main/0 call fails (silently) at the point of doing assertz_fact. Note that assertz_fact/1 is a Ciao Prolog extension for asserting facts. If you use the ISO Prolog assertz/1 (slightly less efficient in the case of facts) a runtime error is raised. Note that it is not necessary that a blah/1 fact appears in the source code: the predicate still exists even if it has no clauses.
Now if I trace the source, it behaves as I would expect -- blah(2) is satified. But if I compile it, it ends with failure. Any insight would be appreciated.
Programs debugged in the toplevel are also loaded in a special interpreted mode, which happens to be the same as a dynamic predicate. That's why the clause assertion does not fail. However assertz_fact gives an error. assert{a,z}_fact make less tests than the assert{a,z} primitive, which, in part, explains their faster execution. Your program could have been classified as "wrong" (quotes intended) by simple ocular inspection, but other cases, such as
main:- ... assertz_fact(G), ...
are not so straightforward, and would need a non-trivial amount of analysis. It is our hope to plug other analysis tools we are developing into Ciao Prolog to catch these errors at compile time, without overloading the execution.
Note that I quoted "wrong" on purpose: it may be the intention of the program author that the program fails (in Prolog sense) if the fact to be asserted is not among those declared as data/1.
(Also, while I'm asking, is there a way to avoid the 'undefined predicate' error that results if I delete the blah(1) assertion?)
blah(1) is not an assertion, but a predicate definition --- more exactly, a clause of a predicate definition. If you take it out, the compiler finds a explicit call to blah/1 which cannot be resolved a compile time, since no module exporting it is being loaded.
Thanks very much for you help, and for making an excellent prolog system freely available.
Thanks for you kind words!
MCL
__________________________________________________________________ Anything is possible if you don't know what you are talking about.