Exemple 3 : Cet exemple montre comment utiliser une variable pour contrôler un programme de l'extérieur La règle liste_de_un qui a été donnée
7. Extensions de Prolog avec des langages externes.
7.2. Fonctions de communication de données simples
Les fonctions décrites ici conviennent dans les cas simples où le type des données à transférer est connu au moment de l'appel et correspond à un type du langage externe, typiquement les entiers, les réels et les chaînes de caractères. Pour les autres cas, d'autres fonctions de communication plus générales existent, elles sont décrites au § 7.3.
Chaque type de données a une fonction1 qui lui est associée pour transférer cette
donnée depuis Prolog vers le programme externe, et une autre pour la transférer depuis la fonction externe vers Prolog.
7.2.1. Test du type d'un argument
La fonction get_arg_type permet de tester le type d'un argument Prolog, afin de pouvoir choisir la procédure de communication appropriée pour récupérer sa valeur. Cette fonction permet également de connaître la taille en octets qu'occuperait l'argument. Ceci est très utile en particulier pour connaître la taille à allouer pour récupérer une chaîne. La fonction renvoie une erreur uniquement lorsqu'il n'existe pas d'argument du rang demandé.
get_arg_type(no_arg, value, lgPtr, err) int no_arg;
char *value; int *lgPtr; int *err;
integer*4 function fgetargtype(no_arg, value, lgPtr, err) integer*4 no_arg,lgPtr,err;
character** value; no_arg
Entier donnant le rang de l'argument choisi dans le prédicat Prolog. Le premier argument a le rang 1, le second a le rang 2 et ainsi de suite.
value
Adresse d'une variable de type caractère dans laquelle sera écrit le "code" du type de l'argument. La signification des caractères retournés est la suivante:
"code" type 'I' entier 'R' réel 'S' chaîne 'N' identificateur 'E' nil 'V' variable libre 'D' liste 'T' n-uplet
Le codage des types est le même que celui choisi pour les procédures get_term, put_term (cf. §7.2.1.), excepté pour l'identificateur nil qui est repéré par le 'E'.
lgPtr
Adresse d'une variable entière dans laquelle sera écrite la taille en octets occupée par l'argument. Lorsque l'argument n'est pas un terme simple, autrement dit lorsque c'est une liste ou un n-uplet, la taille est non spécifiée. err
La variable pointée est différente de 0 si une erreur s'est produite, égale à 0 sinon.
La fonction retourne la valeur correspondant à *err.
7.2.2. Transfert de données simples de Prolog vers un autre langage.
Ces fonctions sont appelées par le programme externe pour obtenir les valeurs effectives des arguments du prédicat Prolog.
Si le type de l'argument effectif n'est pas celui attendu, ou bien s'il n'existe pas d'argument du rang demandé, la fonction de communication notifie une erreur en affectant à l'indicateur err une valeur non nulle. Si, pour un argument de type entier, la valeur ne peut être représentée dans le type externe associé, une erreur est notifiée de la même manière.
Attention: Pour un comportement correct du système de gestion des
erreurs, on doit immédiatement sortir du programme externe si la variable représentée par err est non nulle.
Voici les fonctions disponibles pour les types simples: Interface C:
int get_integer(no_arg, value, err) int no_arg;
long *value; int *err;
int get_real(no_arg, value, err) int no_arg;
float *value; int *err;
int get_double(no_arg, value, err) int no_arg;
double *value; int *err;
int get_string(no_arg, value, err) int no_arg;
char *value; int *err;
int get_max_string(no_arg, lg_max, value, in_external_code, err) int no_arg; int lg_max; char *value; int in_external_code; int *err; Interface Fortran:
integer*4 function fgetinteger(no_arg, value, err) integer*4 no_arg,value,err
integer*4 function fgetreal(no_arg, value, err) integer*4 no_arg,err
real*4 value
integer*4 function fgetdouble(no_arg, value, err) integer*4 no_arg,err
real*8 value
integer*4 function fgetstring(no_arg, lg, value, err) integer*4 no_arg,lg,err
character** value
integer*4 function fgetmaxstring(no_arg, lg_max, lg, value, in_external_code, err)
integer*4 no_arg,lg_max,lg,in_external_code,err character** value
no_arg
Entier donnant le rang de l'argument choisi dans le prédicat Prolog. Le premier argument a le rang 1, le second a le rang 2 et ainsi de suite.
value
Adresse de la donnée qui doit recevoir la valeur de l'argument de rang no_arg dans le prédicat Prolog.
lg
Entier, utilisé dans les fonctions Fortran qui manipulent des chaînes, qui doit recevoir la longueur effective de la chaîne de caractères.
lg_max
est la taille de la zone de caractères. in_external_code
est un booléen qui indique si la chaîne doit être en code caractère externe (ceci est utile lorsque l'option caractères ISO est activée et que l'on utilise des caractères non présents dans la première moitié du jeu ISO; voir Annexe E). Si la valeur est 0 aucune transformation n'est faite sur la chaîne Prolog.
err
La variable pointée est différente de 0 si une erreur ou un backtracking a été demandé.
Ces fonctions retournent zéro lorsqu'une erreur s'est produite ou une valeur non nulle lorsqu'il n'y a pas eu d'erreur.
get_max_string copie la chaîne de caractères originale (depuis la mémoire de travail de Prolog) dans une zone définie dans le programme externe, pointée par value, d'une taille de lg_max caractères. Un caractère nul indique la fin de la chaîne. Une erreur est provoquée si la taille de la zone de caractères définie par lg_max est insuffisante pour la chaîne à récupérer.
get_string fait la même chose que get_max_string mais ne fait pas de test de débordement. Le tableau pointé par value doit donc avoir une taille suffisante pour contenir la chaîne. Pour éviter les risques d'écrasement mémoire, il est préférable d'utiliser get_max_string.
7.2.3. Transfert de données simples d'un langage externe vers Prolog
Ces fonctions sont appelées par le programme externe pour unifier une valeur avec un argument du prédicat Prolog associé. Si l'unification échoue, un backtracking est annoncé par la fonction de communication.
Si le type de l'argument effectif n'est pas celui attendu, ou bien s'il n'existe pas d'argument du rang demandé, la fonction de communication notifie une erreur en affectant à l'indicateur err une valeur non nulle.
Attention: Pour un comportement correct du système de gestion des
erreurs, on doit immédiatement sortir du programme externe si la variable représentée par err est non nulle.
Voici les fonctions disponibles pour les types simples: Interface C:
int put_integer(no_arg, value, err) int no_arg;
long value; int *err;
int put_real(no_arg, value, err) int no_arg;
float value; int *err;
int put_double(no_arg, value, err) int no_arg;
double value; int *err;
int put_string(no_arg, value, err) int no_arg;
char *value; int *err;
Interface Fortran:
integer*4 function fputinteger(no_arg, value, err) integer*4 no_arg,value,err
integer*4 function fputreal(no_arg, value, err) integer*4 no_arg,err
real*4 value
integer*4 function fputdouble(no_arg, value, err) integer*4 no_arg,err
real*8 value
integer*4 function fputstring(no_arg, lg, value, err) integer*4 no_arg,lg,err
character** value
no_arg
Entier donnant le rang de l'argument choisi dans le prédicat Prolog. Le premier argument a le rang 1, le second a le rang 2 et ainsi de suite.
value
Valeur qui sera unifiée sur l'argument de rang no_arg dans le prédicat Prolog associé. Pour le transfert de données de type chaîne de caractères, value est l'adresse d'une chaîne de caractères terminée par zéro, définie dans le programme externe. La fonction put_string copie alors cette chaîne de caractères dans la mémoire de travail de Prolog avant d'unifier la valeur avec l'argument du prédicat associé.
err
La variable pointée est différente de 0 si une erreur ou un backtracking a été demandé.
Ces fonctions retournent zéro lorsqu'une erreur s'est produite ou une valeur non nulle lorsqu'il n'y a pas eu d'erreur.