4
votes

In the book "Expert systems in prolog" I've hit a roadblock. The book defines a simple shell as follows:

solve :-
   abolish(known, 3),
   define(known, 3),
   top_goal(X),
   write('The answer is '),
   write(X),
   nl.
solve :-
   write('No answer found.'),
   nl. 

However, the predicate define doesn't seem to be a built-in predicate in SWI-Prolog. The purpose of define is to ensure the predicate known/3 is defined in the system after abolish is called to remove any previous definitions of known/3. known/3 itself is used to mark if an attribute/value pair is in the database or not. I've tried using assert/1:

assert(known(Y,A,V)).

But I'm not sure if that's correct.

Also, in

write('The answer is '), write(X), nl.

The listener reports that there's a syntax error and that an operator was expected. Yet, in the second definition of solve, there's no issue.

What would be the equivalent for SWI-Prolog, and how can I fix my syntax error? Thanks for your help!

1
You might consider a more introductory Prolog textbook before this one. This book has some quite special code shown in it, some of it also a bit outdated in its style.user1812457
I'm familiar with the basics: facts, rules, predicates, clauses, variables, atoms, and unification. google_predicate_with_arity(X) :- do_not_know_definition(X). ;)OrangeCalx01

1 Answers

3
votes

I think that in SWI-Prolog you should be able to use dynamic(known/3) to achieve the same as what define(known, 3) is supposed to be doing. I guess that for your needs instead of abolish(known, 3), define(known, 3), you should be using retractall(known(_,_,_)).

Say, you have a predicate that should succeed if a condition is satisfied, and fail otherwise, and you query:

?- a(7).

At this point, either you have somewhere in your database a a(7)., then the query succeeds. Or you don't have a a(7)., but Prolog knows about the predicate a/1, so the query fails. Or, a/1 is not defined at all, and you get an error (exception).

What abolish does is to completely erase any knowledge of a predicate, so that it is not defined at all, and you get an error if you try to evaluate it. What retractall does is that it removes all clauses of a predicate, and makes sure that the system knows about the predicate. What dynamic does is that it declares a predicate to the system at compile time or at run time (!) so that a call to the predicate is not an error, even if the predicate itself has no clauses.

?- a(7).
ERROR: toplevel: Undefined procedure: a/1 (DWIM could not correct goal)
?- dynamic(a/1).
true.

?- a(7).
false.

?- abolish(a/1).
true.

?- a(7).
ERROR: toplevel: Undefined procedure: a/1 (DWIM could not correct goal)
?- retractall(a(_)).
true.

?- a(7).
false.

?- assertz(a(7)).
true.

?- a(7).
true.