Annexe D Ajout de règles externes (méthode des parasites). PrologIA HERITAGE II+
A!ociation
Prolog
HERITAGE
Annexe D ajout de règles externes
(méthode des parasites)
D.1. Description générale
D.2. Règle Prolog réalisant l'interface
D.3. Appel du programme externe
D.4. Comment provoquer un backtracking ou renvoyer une erreur
Ce chapitre montre comment ajouter de nouvelles règles faisant référence à des fonctions externes écrites en C ou tout autre langage compatible avec C, et décrit les procédures d'interface. La méthode décrite ici est la seule qui fonctionne en mode 16 bits sur PC. Sinon, une méthode plus simple utilisant des descripteurs peut être utilisée avec le compilateur (voir le chapitre 7. du Manuel de Référence).
La fonction externe peut provoquer un backtracking, renvoyer une erreur qui sera traitée par le mécanisme block, ou afficher un message défini par l'utilisateur.
Le module utilisateur prouser sert de relais entre Prolog et les routines utilisateur
écrites en C, de même le module utilisateur fprouser sert de relais entre Prolog et les routines utilisateur écrites en Fortran. De cette manière il est possible d'avoir simultanément des règles prédéfinies dans les deux langages. Les fichiers sources sont inclus dans le volume de distribution.
D.1. Description générale
Nous rappelons que l'appel depuis Prolog d'une fonction externe définie en C peut se faire de deux manières:
1.
Par la méthode des descripteurs (voir § R 7.6). C'est une méthode d'appel direct avec génération automatique de la règle d'appel Prolog.
2.
En utilisant un parasite via une procédure relais définie dans un module utilisateur fourni dans le kit. C'est la méthode décrite dans ce chapitre.
Quand Prolog est lancé sans spécifier d'état initial, l'état initial standard (fichier
initial.po) est chargé. Ajouter de nouvelles règles écrites dans un autre langage, par la méthode des parasites décrite ici, consiste à:
1.
Définir en Prolog l'appel à ces règles par Prolog, et l'inclure dans un état initial
(cette étape se fait automatiquement dans la méthode des descripteurs).
©PrologIA
D - 2
Annexe D
-
2.
Définir l'implantation externe en C (ou Fortran ou tout autre langage externe compatible), et l'inclure dans la Machine prolog.
-
Cette méthode nécessite deux relais d'appels : l'un entre le programme Prolog et le module utilisateur prouser l'autre entre ce module et la fonction externe.
A!ociation
Prolog
HERITAGE prolog prouser.c
my_rule(...) -> /?300; switch(nb) {
...
case 300:
my_rule(...);
break;
...} autre module C my_rule(...)
{
...
}
Prenons un exemple. Pour ajouter une nouvelle règle, il faut d'abord choisir le module dans lequel on désire la définir. On peut utiliser un module réservé à cet usage, par exemple "Interface". Nous nous placerons dans ce cas pour l'exemple cidessous.
Les deux étapes de la méthode sont :
1.
Définir la règle d'appel dans le module "Interface".
module("Interface"); my_rule(x,y,z) -> /?300; end_module("Interface");
Ceci peut se faire dans un module source séparé, ou directement sur la ligne de commande de Prolog. Vous pouvez sauver ce module par la commande :
save( ["Interface"], "Interface.mo");
Il peut alors être rechargé dans n'importe quel état initial avec la commande
load. Vous pouvez aussi créer directement un nouvel état initial par la commande:
exit("nouvel_etat.po");.
Nous nous placerons dans ce dernier cas pour la suite : nouvel_etat.po est alors un fichier contenant l'état initial augmenté de la règle d'appel compilée par Prolog.
©PrologIA
A!ociation
Prolog
HERITAGE
Ajout de règles externes (méthode des parasites)
D - 3
2.
Créer une nouvelle Machine prolog contenant le programme externe :
Ecrire le programme externe en utilisant les fonctions de communication décrites au § R 7.1 et le compiler avec le compilateur approprié.
Mettre à jour le module utilisateur prouser correspondant (voir § D.3.) et le compiler.
Refaire l'édition de liens entre les nouveaux modules et ceux qui constituent Prolog (se référer au § U 2.7 pour les commandes exactes pour votre machine)
Il suffit ensuite d'utiliser la nouvelle Machine Prolog avec l'état initial augmenté.
D.2. Règle Prolog réalisant l'interface
L'appel sous Prolog d'une fonction externe se fait au moyen d'une règle satisfaisant les conditions suivantes:
- la tête de la règle est un identificateur suivi par des arguments qui sont des variables libres.
- la queue de la règle contient un parasite, représenté par un nombre précédé de /?.
Exemple: la règle relais pour find_pattern est: sys:find_pattern(s1,s2,n) -> /?201;
Le nombre sélectionne la fonction externe adéquate (voir la fonction user_rule dans le module prouser). Pour chaque nombre, il y a un appel de fonction externe correspondant dans la fonction C user_rule ou la fonction Fortran fuserrule.
Note inportante:
Les nombres inférieurs à 250 sont réservés au système (mais aucune vérification n'est faite). Les nombres supérieurs à 250 sont disponibles pour l'utilisateur. Il est conseillé d'utiliser les nombres compris entre 250 et 9999 pour les routines C dont l'appel se trouve dans le module prouser, les nombres compris entre 10000 et
20000 pour les routines Fortran (ou d'autres langages de type Fortran) dont l'appel se trouve dans le module fprouser, et les nombres supérieurs à 20000 pour les routines du mode 16 bits sous DOS/WINDOWS3 dont l'appel se trouve dans le module prowuser.
D.3. Appel du programme externe
Un programme externe ne peut être appelé depuis Prolog par la méthode des parasites, que si le nombre associé et l'instruction d'appel ont été ajoutés dans la fonction user_rule du module C prouser (respectivement fuserrule du module
Fortarn fprouser).
©PrologIA
D - 4
Annexe D
Voici un extrait du texte de la fonction C user_rule: user_rule(nb, err, err_nb) int nb, *err, *err_nb;
{
*err_nb = 0; if (num >10000)
fuserrule(&nb, err, err_nb);
else if (num >20000)
real_mode_user_rule(nb, err, err_nb);
else
switch (nb)
{ case 201: find_pattern(err, err_nb); break;
...
/* add procedure calls here */ default:
*err_nb = 500;
}
}
La terminaison normale du programme externe (qui se traduit par un succès en
Prolog) intervient quand le paramètre err_nb de la fonction C user_rule vaut zéro.
Selon la nature de votre programme externe, vous pouvez choisir de l'insérer directement dans le module prouser ou bien de l'écrire dans un fichier séparé.
Si vous avez écrit vos règles externes dans un ou plusieurs modules différents des modules prouser et fprouser, alors vous devez compiler ce(s) module(s) puis donner le(s) nom(s) au programme prolink pour l'édition de liens.
Tel qu'il est livré, le module prouser établit les relais d'appel entre le compilateur
Prolog et la fonction externe find_pattern, qui constitue pour vous un exemple d'écriture de règles externes.
Attention: Le programme externe find_pattern donné en exemple met en
œuvre la règle prédéfinie find-pattern(s1,s2,n). Sa modification
inconsidérée peut introduire un mauvais fonctionnement de cette règle.
A!ociation
Prolog
HERITAGE
©PrologIA
A!ociation
Prolog
HERITAGE
Ajout de règles externes (méthode des parasites)
D - 5
D.4. Comment provoquer un backtracking ou renvoyer une erreur
Pour renvoyer une erreur depuis une fonction externe, celle-ci doit positionner le paramètre err_nb de la fonction user_rule.
Note importante :
A parir de la version 4.1, le paramètre err n'est plus significatif, il est ignoré par
Prolog. La compatibilité ascendante des versions est toujours assurée.
Si err_nb est positionné à une valeur strictement positive, alors une commande
équivalente à la commande Prolog block_exit(err_nb) est exécutée. Pour y associer un message, ajoutez la ligne correspondante dans le fichier err.txt, sous la forme:
Numéro Texte_décrivant_l'erreur
La règle prédéfinie ms_err permet d'accéder au message associé à un numéro donné. Les numéros d'erreurs inférieurs à 1000 sont réservés pour Prolog, les nombres supérieurs à 1000 sont disponibles pour l'utilisateur. Quelques définitions actuelles de messages d'erreur concernant les modules externes, sont:
500 ERREUR DANS UNE REGLE PREDEFINIE
501 ARGUMENT ERRONE DANS LE MODULE UTILISATEUR
502 VALEUR HORS LIMITES DANS LE MODULE UTILISATEUR
503 CHAINE TROP LONGUE DANS LE MODULE UTILISATEUR
520 get_term: TABLEAU TROP PETIT POUR CODER LE TERME
521 get_term: TABLEAU DES CHAINES TROP PETIT
522 get_term: TABLEAU DES REELS TROP PETIT
523 put_term: INDEX ERRONE DANS LE TABLEAU DES TERMES
!
indique qu'à un tag de type 'T' ou 'D', correspond une valeur en dehors des index possibles pour le tableau val_tab.
524 put_term: INDEX ERRONE DANS LE TABLEAU DES CHAINES
!
indique qu'à un tag de type 'S' correspond une valeur en dehors des index possibles pour le tableau des chaînes.
525 put_term: INDEX ERRONE DANS LE TABLEAU DES REELS
!
indique qu'à un tag de type 'R', correspond une valeur en dehors des index possibles pour le tableau des réels.
526 put_term: CODAGE DE TUPLE ERRONE
!
un index de tuple référence une suite dont le premier élément n'est pas de type entier.
527 put_term: TAG NON VALIDE
528 put_term: L'ARGUMENT PROLOG N'EST PAS UNE VARIABLE LIBRE
Un backtracking est provoqué quand on retourne à Prolog avec err_nb égal à un entier strictement négatif.
©PrologIA
D - 6
Annexe D
A!ociation
Prolog
HERITAGE
©PrologIA

Enlace público actualizado
El enlace público a tu chat ha sido actualizado.