Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I want to create dynamic facts in prolog

I wrote the following simple code, and I expect that when I write 'male.', this code ask me once "is it male?" and if i input 'No' it write on screen "she is female".

male :- ( print('is it male ? '),read(yes)) -> true; asserta( not(male)),female.
female:- not(male),print('she is female').
not(P) :- (call(P) -> fail ; true) .

but this code has following error:

uncaught exception: error(permission_error(modify,static_procedure,not/1),asserta/1);

the error in swi-prolog is :

ERROR: asserta/1: No permission to modify static_procedure `not/1'
like image 737
vakarami Avatar asked Dec 29 '11 14:12

vakarami


1 Answers

As gusbro said, not/1 is a predefined static procedure (and therefore it is not a good idea to use the same name). However, this is not the reason you get the error in swi-prolog as you can overwrite the standard definition:

?- assert(not(42)).
true.

?- not(42).
true.

the problem is that you have already defined not/1 in your code and, when you do not declare a predicate explicitly as dynamic, swi-prolog will assume that it's static and will not allow you to change it.

You can declare it as dynamic by inserting this line in your code:

:-dynamic(not/1).

I think that this will not solve the problem in other prolog implementations (eg gnu-prolog) as the error message says permission_error(modify,static_procedure,not/1); in any case it is highly recommended to change the name.

By the way, it would be simpler and cleaner to simply test what the argument is and print the corresponding message. If, however, you want to create something more complex (using a state maybe) you could use global variables since they are more efficient that assert/retract.

like image 179
Thanos Tintinidis Avatar answered Sep 19 '22 19:09

Thanos Tintinidis