2011-12-29 12 views
6

Escribí el siguiente código simple, y espero que cuando escribo 'masculino', este código me pregunte una vez "¿es masculino?" y si ingreso 'No' escriba en la pantalla "ella es mujer".Quiero crear hechos dinámicos en prolog

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) . 

pero este código ha error siguiente:

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

el error en swi-prolog es:

ERROR: asserta/1: No permission to modify static_procedure `not/1' 
+1

not/1 es un procedimiento estático predefinido. Considera cambiar el nombre a otra cosa. Además, no parece muy correcto lo que estás haciendo. – gusbro

Respuesta

7

Como dijo gusbro, no/1 es un procedimiento estático predefinido (y por lo tanto, no es una buena idea usar el mismo nombre). Sin embargo, esta no es la razón por la que sale el error en SWI-Prolog como se puede sobrescribir la definición estándar:

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

?- not(42). 
true. 

el problema es que tienes ya no/1 definido en el código y, cuando no lo hacen declara un predicado explícitamente como dinámico, swi-prolog asumirá que es estático y no le permitirá cambiarlo.

Se puede declarar como dinámica mediante la inserción de esta línea en su código:

:-dynamic(not/1). 

creo que esto no va a resolver el problema en otras implementaciones de prólogo (por ejemplo GNU-Prolog) como el mensaje de error dice permission_error(modify,static_procedure,not/1) ; en cualquier caso, es muy recomendable cambiar el nombre.

Por cierto, sería más simple y más limpio simplemente probar cuál es el argumento e imprimir el mensaje correspondiente. Sin embargo, si desea crear algo más complejo (utilizando un estado tal vez), podría usar variables globales ya que son más eficientes que afirman/retraen.