module - Expansión del módulo de objetivos pasados a los meta-predicados de la biblioteca
prolog meta-predicate (1)
Esta es una característica / error inherente de los sistemas de módulos basados en predicados en la tradición de Quintus. Es decir, este sistema de módulos se desarrolló por primera vez para Quintus Prolog. Fue adoptado posteriormente por SICStus (después de 0.7 1 ), luego (más o menos) por 13211-2, luego por YAP y (con algunas modificaciones) por SWI.
El problema aquí es qué significa exactamente una calificación explícita. Mientras el objetivo no sea un meta-predicado, las cosas se resuelven trivialmente: tome el módulo de la calificación más interna. Sin embargo, una vez que tiene meta-predicados, los meta-argumentos deben ser informados de ese módulo; o no. Si se informan los meta-argumentos, decimos que el dos puntos establece el contexto de la llamada , si no, entonces se necesitan otros medios para ese fin.
En la tradición de Quintus, los meta-argumentos se toman en cuenta. Con el resultado que ves. Como consecuencia, no puede comparar dos implementaciones del mismo meta-predicado directamente en el mismo módulo. Hay otros enfoques, especialmente IF y ECLiPSe que no cambian el contexto de la llamada a través de los dos puntos. Tiene sus ventajas y desventajas. Lo mejor es compararlos caso por caso.
Aquí hay un caso reciente. Tome lambdas y cómo se colocan en un módulo en SICStus, en SWI y en ECLiPSe .
En cuanto al sistema de módulos Quintus / SICStus / YAP / SWI, prefiero usarlo de la manera más conservadora posible. Es decir:
sin calificación explícita, considere el infijo
:
como algo internoMetadataciones limpias y comprobables: inserte a propósito un predicado indefinido solo para ver si las referencias cruzadas son capaces de detectar el problema (en SWI eso es
check
omake
).use el subconjunto común, evite las muchas campanas y silbatos; hay muchas extensiones bien intencionadas ...
haga cosas más versátiles a la manera peatonal: vuelva a exportar agregando un módulo apropiado y agregue una definición ficticia. Del mismo modo, en lugar de cambiar el nombre, importa cosas desde un módulo de interfaz.
tenga siempre en cuenta que los sistemas de módulos tienen intrínsecamente algunos límites. No importa cómo lo tuerza o gire. No existe un sistema de módulos completamente integrado, ya que el propósito de los módulos es separar el código y las preocupaciones.
1: para ser precisos, la adaptación de SICStus de los módulos Quintus solo incluía :
para argumentos sensibles al módulo en declaraciones meta_predicate
. Los enteros 0..9
, que son tan importantes para la programación de orden superior basada en call/N
, solo se introdujeron unos 20 años más tarde en la versión 4.2.0 lanzada el 2011-03-08 .
Usando SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.5), procedemos paso a paso:
Defina dcg nonterminal
a//1
en el módulodcgAux
(pronunciado: " di-SEE-goh ")::- module(dcgAux,[a//1]). a(0) --> []. a(s(N)) --> [a], a(N).
Ejecute las siguientes consultas utilizando la
phrase/2
yapply:foldl/4
:?- use_module([library(apply),dcgAux]). true. ?- phrase( foldl( a,[s(0),s(s(0))]),[a,a,a]). true. ?- phrase( foldl(dcgAux:a,[s(0),s(s(0))]),[a,a,a]). true. ?- phrase(apply:foldl(dcgAux:a,[s(0),s(s(0))]),[a,a,a]). true. ?- phrase(apply:foldl( a,[s(0),s(s(0))]),[a,a,a]). ERROR: apply:foldl_/4: Undefined procedure: apply:a/3
нет! Una gran sorpresa, y no una buena. ¿Nos hemos perdido algunas incógnitas desconocidas?
Para deshacerse de la conducta irritante anterior, primero debemos averiguar la (s) razón (es) que la causan:
?- import_module(apply,M), M=user. false. ?- phrase(apply:foldl(a,[s(0),s(s(0))]),[a,a,a]). ERROR: apply:foldl_/4: Undefined procedure: apply:a/3 ?- add_import_module(apply,user,end). true. ?- import_module(apply,M), M=user. % sic! M = user. % `?- import_module(apply,user).` fails! ?- phrase(apply:foldl(a,[s(0),s(s(0))]),[a,a,a]). true.
¿Que esta pasando? La forma en que lo veo es esta:
- La expansión del módulo de la meta pasada a
foldl/4
es limitada. Citando de la página de manual de SWI-Prolog en
import_module/2
:Todos los módulos normales solo importan desde el usuario, que importa desde el sistema.
La
library(apply)
de SWIlibrary(apply)
solo "hereda" delsystem
, pero no deluser
.Si
applY
móduloapply
aapplY
(yapplY
el nuevo nombre del módulo), observamos:?- use_module(applY). true. ?- phrase(applY:foldl(a,[s(0),s(s(0))]),[a,a,a]). % was: ERROR true. % now: OK!
¡Por favor comparte tus ideas sobre cómo podría / debería proceder!
(Todavía no he realizado un experimento similar con otros procesadores Prolog).