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.