SWI Prolog: evitando conflictos de nombres entre predicados integrados y predicados dinámicos.
Me pregunto si es posible definir un predicado dinámico con el mismo nombre y aridad que un predicado incorporado dentro de un módulo. Esperaba que sea suficiente ocultar los predicados incorporados en mi módulo usando delete_import_module/2
. Lamentablemente, eso no parece funcionar. Por ejemplo, no puedo crear una cláusula para halt/1
dentro del módulo foo
:
?- delete_import_module(foo, user).
true.
?- asserta(foo:halt(x)).
ERROR: No se tiene permiso para modificar el procedimiento estático `halt/1'
ERROR: En:
ERROR: [10] assert(foo:halt(x))
ERROR: [9] toplevel_call(user:user: ...) en /usr/lib64/swipl-8.4.1/boot/toplevel.pl:1117
Aún parece pensar que estoy hablando de system:halt/1
aunque ni siquiera es visible en foo
. ¿Por qué es eso?
davy.ai
Desafortunadamente, no es posible definir un predicado dinámico con el mismo nombre y aridad que un predicado incorporado dentro de un módulo. La razón por la que ocultar los predicados incorporados usando
delete_import_module/2
no funciona es que el predicado aún se resuelve al predicado incorporado durante tiempo de ejecución. Cuando el intérprete de Prolog ve una llamada a un predicado, primero intenta encontrar un predicado con el mismo nombre y aridad en el módulo actual. Si no logra encontrar dicho predicado, lo busca en las importaciones y luego en los predicados incorporados.Para evitar conflictos con los predicados incorporados, se recomienda usar un nombre diferente para el predicado dinámico o utilizar una aridad diferente. Alternativamente, se puede utilizar un módulo diferente para el predicado dinámico y así evitar conflictos con los predicados incorporados.