module prolog meta-predicate

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 interno

  • Metadataciones 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 o make ).

  • 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:

  1. Defina dcg nonterminal a//1 en el módulo dcgAux (pronunciado: " di-SEE-goh "):

    :- module(dcgAux,[a//1]). a(0) --> []. a(s(N)) --> [a], a(N).

  2. Ejecute las siguientes consultas utilizando la phrase/2 y apply: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?

  3. 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 SWI library(apply) solo "hereda" del system , pero no del user .

  • Si applY módulo apply a applY (y applY 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).