10. Extensions Edinburgh. PrologIA HERITAGE II+
Ci-dessous, vous trouverez de brèves informations concernant II+ Prolog. Ce manuel de référence décrit en détail le langage Prolog II+, son utilisation, ainsi que ses caractéristiques, comme la compilation incrémentale, la modularité, l'ouverture vers d'autres langages et l'environnement de programmation.
A!ociation
Prolog
HERITAGE
10.
Extensions Edinburgh
10.1. Syntaxe
10.2. Le contrôle
10.3. Manipulation des règles
10.4. Opérations prédéfinies sur les données
10.5. Les entrées / sorties
10.6. L'environnement
10.7. Traduction de DCG
Ce chapitre décrit les possibilités supplémentaires présentes lorsque le module de compatibilité Edinburgh est chargé.
Le plan de ce document suit le plan du manuel de référence en décrivant pour chaque rubrique les spécificités du mode Edinburgh.
Un certain nombre de règles prédéfinies dupliquent sous un autre nom les règles prédéfinies Prolog II+.
Toutes les fonctionnalités Prolog II+ sont également disponibles en syntaxe
Edinburgh.
IMPORTANT: Dans ce chapitre, tous les atomes donnés en position d'argument ont le préfixe vide (""). Dans l'écriture des exemples, il est supposé que l'option permettant que "tous les atomes en position d'argument non préfixés explicitement ont le préfixe vide" est activée. Cette option est décrite en annexe A. Si cette option n'est pas activée, il faut avoir à l'esprit que les atomes dont la représentation abrégée est déjà connue du système doivent être explicitement préfixés avec le préfixe vide, sinon c'est le préfixe sys qui sera pris par défaut (du moins dans le contexte user).
C'est notamment le cas des atomes debug, string, fail (utilisés dans le prédicat
set_prolog_flag/2), true, false (utilisés par exemple dans le prédicat write_term/2) et
input , output, read, write (pour stream_property/2 ou open/4).
10.1. Syntaxe
10.1.1. Généralités
La syntaxe Edinburgh est acceptée en entrée dans l'un des cas suivants:
1) à l'activation de Prolog II + a) si l'on utilise l'option -E (équivalent de -m edinburg.mo) b) si l'on utilise un état binaire sauvé alors que la syntaxe Edinburgh était active,
2) sur la ligne de commande Prolog II+
©PrologIA
R 10 - 2
Manuel de Référence
a) si le fichier edinburg.mo est chargé (par le prédicat load ou reload).
b) si le but edinburgh est tapé,
La syntaxe exacte est décrite au chapitre 1 en utilisant la variante E des règles syntaxiques. Les principales différences avec la syntaxe Edinburgh définie dans la norme ISO/IEC sont décrites en annexe A.
Sur la ligne de commande ou dans une directive, lorsque le premier terme rencontré est une liste, celle-ci est interprétée comme une liste de fichiers à consulter. user est
équivalent à "console".
A!ociation
Prolog
HERITAGE
10.1.2. Les opérateurs
En syntaxe Edinburgh , les opérateurs suivants sont prédéfinis:
-
/\
=:=
+
\/
mod
rem
@>
@>=
@=<
\=
==
=\=
\==
=..
\+
is
=
<
>
>=
=<
@<
-->
;
->
, opérateur
:-
:-
?-
700
500
500
500
500
400
400
700
700
700
700
700
700
700
700
700
700
700
700
900
700
700
700 précédence
1200
1200
1200
1200
1100
1050
1001 xfx yfx yfx yfx yfx yfx yfx xfx xfx xfx xfx xfx xfx xfx xfx xfx xfx xfx xfx fy xfx xfx xfx xfx xfy xfy xfy fx fx type xfx terme construit sys:':-'(T1,T2) sys:':-'(T1) sys:'?-'(T1) sys:'-->'(T1,T2) sys:';'(T1,T2) sys:'->'(T1,T2) sys:','(T1,T2) sys:not(T1) sys:is(T1,T2) sys:'='(T1,T2) sys:'<'(T1,T2) sys:'>'(T1,T2) sys:'>='(T1,T2) sys:'=<'(T1,T2) sys:'@<'(T1,T2) sys:'@>'(T1,T2) sys:'@>='(T1,T2) sys:'@=<'(T1,T2) sys:'\='(T1,T2) sys:'=='(T1,T2) sys:'=\='(T1,T2) sys:'\=='(T1,T2) sys:'=..'(T1,T2) sys:'=:='(t1,t2) sys:'+'(t1,t2) sys:'-'(t1,t2) sys:'/\'(T1,T2) sys:'\/'(T1,T2) sys:mod(t1,t2) sys:rem(t1,t2)
©PrologIA
A!ociation
Prolog
HERITAGE
+
-
^
>>
//
\
** opérateur
*
/
<<
400
400
200
200 précédence
400
400
400
200
200
200 yfx yfx fy xfx type yfx yfx yfx fy fy xfy
Extensions Edinburgh
terme construit sys:'*'(t1,t2) sys:'/'(t1,t2) sys:'<<'(T1,T2) sys:'>>'(T1,T2) sys:'//'(T1,T2) sys:'\'(t1,t2) sys:'**'(t1,t2) sys:'+'(t1) sys:'-'(t1) sys:'^'(T1,T2)
R 10 - 3
current_op(P,M,O)
Unifie respectivement les arguments P, M et O avec la précédence, le type de parenthèsage et l'opérateur. Exemple:
?- current_op(1200,M,O).
{M=fx,O=?-}
{M=fx,O=:-}
{M=xfx,O=:-}
{M=xfx,O=-->}
10.2. Le contrôle
\+ X ou \+(X)
Equivalent à not(X).
X =Y ou =(X,Y)
Succès si X est unifiable avec Y, sinon échec. Est défini par la règle:
X = X.
X \= Y ou \=(X,Y)
Succès si X n'est pas unifiable avec Y, sinon échec. Exemples:
?- 1 \= 1.
?- X \= 1.
?- X \= Y.
?- 1 \= 1.0.
{}
X -> Y ou ->(X,Y)
Si-alors. Est défini par la règle (les parenthèses ne servent qu'à améliorer la lisibilité):
(X -> Y) :- X,!,Y.
X , Y ou ,(X,Y)
"Et" propositionnel. X est exécuté puis Y.
X ; Y ou ;(X,Y)
"Ou" propositionnel. Est défini par les règles suivantes (Note: en Prolog II la coupure est transparente):
©PrologIA
R 10 - 4
Manuel de Référence
X;Y :- X.
X;Y :- Y.
call(X)
Est défini par la règle: call(X) :- X.
catch(G,C,R)
Lance l'exécution du but G. Fait un succès dans deux cas:
- l'exécution de G réussit sans interruption de type "throw"
- une interruption de type "throw" dont l'argument s'unifie avec l'argument C se produit et l'exécution du but R réussit. Si l'unification échoue, l'interruption est propagée selon le mécanisme de block/block_exit. Exemples:
?- reconsult(user).
foo(X) :- Y is X*2, throw(test(Y)).
bar(X) :- X=Y, throw(Y).
coo(X) :- throw(X).
car(X) :- X=1, throw(X).
g :- catch(p, B, write(h2)), coo(c).
p.
p :- throw(b). .
{}
?- catch(foo(5),test(Y),true).
{Y=10}
?- catch(bar(3),Z,true).
{Z=3}
?- catch(true,C,write(foo)), throw(bla).
-> bla([]) 'block_exit' SANS 'block' CORRESPONDANT
?- catch(coo(X),Y,true).
{}
?- catch(car(X),Y,true).
{X=1,Y=1}
?- catch(g, C, write(h1)). h1{C=c}
fail_if(X)
Est équivalent à l'appel de not(call(X)).
?- fail_if(true).
?- fail_if(4=5).
{}
once(G)
Efface le but G de la première manière possible. Est défini par la règle: once(G) :- G, ! .
throw(X)
Est équivalent à un appel de block_exit(X1) , X1 étant une copie du terme X
(renommage des variables).
true
S'efface toujours avec succès.
A!ociation
Prolog
HERITAGE
©PrologIA
A!ociation
Prolog
HERITAGE
Extensions Edinburgh
R 10 - 5
unify_with_occurs_check(X, Y)
Tente l'unification des termes X et Y avec une vérification de non production d'arbres infinis. Echoue si l'unification échoue ou si elle génère un arbre infini. Exemples:
?- unify_with_occurs_check(1,1).
{}
?- unify_with_occurs_check(1,2).
?- unify_with_occurs_check(X,1).
{X=1}
?- unify_with_occurs_check(X,a(X)).
?- unify_with_occurs_check(X,[1|X]).
?- unify_with_occurs_check(X,[X|1]).
?-
10.3. Manipulation des règles
abolish(P)
Se comporte comme suppress(P) où P est un identificateur ou un terme de la forme identificateur/arité.
assert(X) assertz(X)
Ajoute en queue de paquet la règle ou le fait X. Voir assert décrit pour
Prolog II. Attention, en syntaxe Edinburgh, la virgule est à la fois un séparateur et un opérateur, il faut donc parenthéser l'argument dans le cas des règles:
?- assert(a).
{}
?- assert((a :- b,c)).
{}
asserta(X)
Ajoute en tête de paquet la règle ou le fait X. Voir asserta décrit pour
Prolog II. Même remarque sur la virgule que ci dessus.
clause(T,Q)
T ne doit pas être une variable libre. Unifie T et Q respectivement avec la tête et la queue de toutes les clauses dont l'accès est défini par T. Se comporte comme rule avec la différence qu'une queue vide est représentée par true, et qu'une queue d'au moins deux littéraux est représentée par une structure avec le noeud ','.
consult(F) reconsult(F)
Est équivalent respectivement à insert et reinsert. Si F est un identificateur, c'est la chaîne correspondant à son abréviation qui est prise en compte comme nom de fichier (c.à.d. le préfixe est ignoré). Si F vaut user ou "user" lit sur l'unité courante de lecture.
©PrologIA
R 10 - 6
Manuel de Référence listing listing(X)
Est équivalent respectivement à list et list(X).
retract(X)
Même comportement que retract à deux arguments. X doit être un fait ou une règle dont le prédicat de tête est instancié.
retract((T:- true)) est équivalent à retract(T),
retract(T) est équivalent à retract(T,[]), si T ne s'unifie pas avec :- (T1,T2),
retract((T :- Q)) est équivalent à retract(T,Q).
retractall(X)
Toutes les règles dont la tête s'unifie avec X sont supprimées (sans unification de X ni backtracking). X doit avoir la forme d'une tête de règle, sinon, le prédicat n'aura aucun effet. Fait toujours un succès.
A!ociation
Prolog
HERITAGE
10.4. Opérations prédéfinies sur les données
10.4.1. Les tests de type
atom(X)
Succès si X est un identificateur, sinon échec. Equivalent à ident(X).
atomic(X)
Succès si X est une constante, sinon échec.
compound(X)
Succès si X est une liste ou un n-uplet, sinon échec.
float(X)
Est équivalent à real(X).
nonvar(X)
Est équivalent à bound(X).
number(X)
Succès si X est un entier ou un réel, sinon échec.
var(X)
Succès si X est une variable libre, sinon échec. Est équivalent à free(X).
©PrologIA
A!ociation
Prolog
HERITAGE
Extensions Edinburgh
R 10 - 7
10.4.2. Les opérations arithmétiques
L'évaluation d'une expression est faite au moyen de la règle prédéfinie val. Certaines expressions peuvent être utilisées en syntaxe Edinburgh directement comme des termes à effacer.
Les termes suivants peuvent être effacés, sans l'intermédiaire du prédicat val.
X =:= Y ou =:=(X,Y)
Est équivalent à val(eql(X,Y),1).
X =\= Y ou =\= (X,Y)
Est équivalent à val('=\='(X,Y),1).
X < Y ou <(X,Y)
X =< Y ou =<(X,Y)
X > Y ou >(X,Y)
X >= Y ou >=(X,Y)
Sont respectivement équivalents à:
val('<'(X,Y),1) val('=<'(X,Y),1) val('>'(X,Y),1) val('>='(X,Y),1)
X is Y ou is(X,Y)
Est équivalent à val(Y,X).
Les fonctions suivantes sont spécifiques au mode Edinburgh. Elles sont évaluables par les règles prédéfinies val, tval ou is. Elles doivent être appliquées à des arguments de type entier ou réel.
\X ou \(X) valeur (\X) = valeur('~'(X)) = complément bit à bit de X.
La valeur de X doit être de type entier. Le résultat est de type entier.
X // Y ou //(X,Y) valeur(//(X, Y)) = division entière de valeur(X) par valeur(Y).
Le résultat est de type entier.
log(t)
valeur(log(t)) = valeur(ln(t)) = logarithme népérien(valeur(t)).
Le résultat est de type réel.
truncate(t)
valeur(truncate(t)) = valeur(trunc(t)) = conversion en entier de la valeur de t.
Le résultat est de type entier.
©PrologIA
R 10 - 8
Manuel de Référence
10.4.3. Composition et décomposition d'objets
X =.. Y ou =..(X,Y)
Si X est instancié, Y est unifié avec une liste dont le premier élément est le foncteur de X, et les éléments suivants les éventuels arguments dans l'ordre. Si
X est libre, Y doit être instancié avec une liste; X est alors unifié avec le n-uplet construit avec le premier élément de la liste comme foncteur, et les autres
éléments comme arguments. A un élément atomique correspond une liste constituée de ce seul élément. Exemples:
?- '=..'(foo(a,b),[foo,a,b]).
{}
?- '=..'(X,[foo,a,b]).
{X=foo(a,b)}
?- '=..'(foo(a,b),L).
{L=[foo,a,b]}
?- '=..'(foo(X,b),[foo,a,Y]).
{X=a,Y=b}
?- '=..'(1,[1]).
{}
?- '=..'(foo(a,b),[foo,b,a]).
?- '=..'(f(X),[f,u(X)]).
{X=_714, _714=u(_714)}
arg(N,T,X)
S'efface si X est le Nième élément du terme T. N entier et T tuple ou paire pointée, doivent être connus au moment de l'appel.
Si T est une paire pointée alors si
N=1, X est unifié avec le premier élément de la paire.
N=2, X est unifié avec le deuxième élément de la paire.
Si N est un entier et T est un n-uplet de taille M>1, alors si
0<N<M, X est unifié avec l' argument N+1 du n-uplet T.
(c.à.d. avec l'argument N de T=f(a
1
,...,a n
,...,a
M-1
)).
Sinon échec.
Exemple :
?- arg(1,eq(john,fred), X).
{X=john}
?- arg(0,eq(john,fred), Y).
?-
atom_chars(A,L)
Associe à un identificateur A la liste L des caractères qui le constituent et viceversa. Le préfixe de l'identificateur A est ignoré (en entrée) ou égal à "" (en sortie). Exemples:
?- atom_chars('',L).
{L=[]}
?- atom_chars('''', L).
{L=['''']}
?- atom_chars('ant',L).
{L=[a,n,t]}
?- atom_chars(Str, ['s', 'o', 'p']).
{Str=sop}
A!ociation
Prolog
HERITAGE
©PrologIA
A!ociation
Prolog
HERITAGE
Extensions Edinburgh
R 10 - 9
atom_codes(A,L)
Associe à un identificateur A la liste L des codes internes (codes ISO ou codes de la machine hôte) qui le constituent et vice-versa. Le préfixe de l'identificateur A est ignoré (en entrée) ou égal à "" (en sortie).
atom_concat(A1,A2,A3)
Fonctionne sur les identificateurs de la même manière que conc_string sur les chaînes de caractères. Le préfixe des identificateurs A1, A2, A3 sont ignorés
(en entrée) ou égaux à "" (en sortie). Exemples:
?- atom_concat('hello',' world',S3).
{S3='hello world'}
?- atom_concat(T,' world','small world').
{T=small}
?- atom_concat(T1,T2,'hello').
{T1='',T2=hello}
{T1=h,T2=ello}
{T1=he,T2=llo}
{T1=hel,T2=lo}
{T1=hell,T2=o}
{T1=hello,T2=''}
atom_length(A,N)
Unifie N avec la longueur de l'identificateur A . Le préfixe de l'identificateur A est ignoré. Exemples:
?- atom_length('enchanted evening',N).
{N=17}
?- atom_length('',N).
{N=0}
functor(T,F,N)
Associe à un arbre T son foncteur F et son arité N, et vice-versa.
?- functor(foo(a,b,c),X,Y).
{X=foo,Y=3}
?- functor(X,foo,3).
{X=foo(_515,_516,_517)}
?- functor(X,foo,0).
{X=foo}
?- functor(foo(a),foo,2).
?- functor(foo(a),fo,1).
?- functor(1,X,Y).
{X=1,Y=0}
?- functor(X,1.1,0).
{X=1.1}
?- functor([_|_],'.',2).
{}
?- functor([],[],0).
{}
name(X,L)
Si X est un identificateur ou un nombre, L est unifié avec la liste des codes internes (codes ISO ou codes de la machine hôte) des caractères constituant la représentation de l'identificateur X.
Si L est une liste de codes internes des lettres d'un identificateur, X est instancié avec l'identificateur déterminé par les conventions courantes de préfixage.
?- name(abc:def,L).
©PrologIA
R 10 - 10
Manuel de Référence
{L=[97,98,99,58,100,101,102]}
?- name(123,L).
{L=[49,50,51]}
?- name(X,[65,66|4]).
?- name("asd",X).
?- name(Y,X).
?- name(ab:'cd',L).
{L=[97,98,58,99,100]}
?- name(ab:' %',L).
{L=[97,98,58,39,32,37,39]}
?- name(I,[97,98,58,99,100]).
{I=ab:cd}
?- name(M,[97,98,58,39,32,37,39]).
{M=ab:' %'}
?-
number_chars(N,L)
Associe à un nombre N la liste L des caractères qui le constituent.
Réciproquement, considère la liste L des caractères comme une entrée et y associe le nombre N (imprimé sous sa forme décimale). Exemples:
?- number_chars(33, L).
{L=['3','3']}
?- number_chars(33.0, L).
{L=['3','3','.','0']}
?- number_chars(X, ['3', '.', '3', 'E', '+', '0']).
{X=3.3}
?- number_chars(3.3, ['3', '.', '3', 'E', '+', '0']).
{}
?- number_chars(A, ['-', '2', '5']).
{A=-25}
?- number_chars(A, [' ', '3']).
{A=3}
?- number_chars(A, ['0', 'x', 'f']).
{A=15}
?- number_chars(A, ['0', '''', 'a']).
{A=97}
?- number_chars(A, ['4', '.', '2']).
{A=4.2}
?- number_chars(A, ['4', '2', '.', '0', 'e', '-', '1']).
{A=4.2}
number_codes(N,L)
Même description que number_chars/2 mais L est une liste de codes internes
(codes ISO ou codes de la machine hôte).
phrase(X,Y) phrase(X,Y,Z)
Essaie de décomposer la liste Y en une phrase de la grammaire et un reste. X doit être une tête de règle de grammaire, Y et Z peuvent être des variables libres ou des listes. Enumère les solutions possibles en unifiant le reste avec
Z. La forme à deux arguments phrase(X,Y) équivaut à phrase(X,Y,[]).
Note: Si Y ou Z sont des chaînes de caractères, celles-ci sont d'abord transformées en listes de caractères avant de réaliser l'appel :
phrase(somme(X),"1+2+3") est transformé automatiquement dans l'appel
phrase(somme(X), ["1","+","2","+","3"]).
A!ociation
Prolog
HERITAGE
©PrologIA
A!ociation
Prolog
HERITAGE
Extensions Edinburgh
R 10 - 11
sub_atom(A1,N1,N2,N3,A2)
Fait un succès si l'identificateur A1, qui doit être connu lors de l'appel, peut
être vu comme la concaténation de trois parties telles que N1 soit la longueur de la première partie, N2 la longueur de la seconde partie qui n'est rien d'autre que l'identificateur A2, et N3 la longueur de la troisième partie. Les préfixes des identificateurs A1 et A2 sont ignorés (en entrée) ou égaux à "" (en sortie).
Exemples:
?- sub_atom(abracadabra, 0, 5, A, S2).
{A=6,S2=abrac}
?- sub_atom(abracadabra, _, 5, 0, S2).
{S2=dabra}
?- sub_atom(abracadabra, 3, L, 3, S2).
{L=5,S2=acada}
?- sub_atom(abracadabra, B, 2, A, ab).
{B=0,A=9}
{B=7,A=2}
?- sub_atom('Banana', 3, 2, A, S2).
{A=1,S2=an}
?- sub_atom('charity', B, 3, A, S2).
{B=0,A=4,S2=cha}
{B=1,A=3,S2=har}
{B=2,A=2,S2=ari}
{B=3,A=1,S2=rit}
{B=4,A=0,S2=ity}
?- sub_atom('ab', Start, Length, A, Sub_atom).
{Start=0,Length=0,A=2,Sub_atom=''}
{Start=0,Length=1,A=1,Sub_atom=a}
{Start=0,Length=2,A=0,Sub_atom=ab}
{Start=1,Length=0,A=1,Sub_atom=''}
{Start=1,Length=1,A=0,Sub_atom=b}
{Start=2,Length=0,A=0,Sub_atom=''}
10.4.3. Comparaison de termes quelconques
X == Y ou ==(X,Y)
Succès si X est formellement égal à Y, sinon échec. Exemples:
?- 1 == 1.
{}
?- X == X.
{}
?- 1 == 2.
?- X == 1.
?- X == Y.
?- _ == 1.
?- _ == _.
?-
X \== Y ou \== (X,Y)
Succès si X n'est pas formellement égal à Y, sinon échec. Exemples:
?- 1 \== 1.
?- 1 \== 2.
{}
?- X \== 1.
{}
?- _ \== _.
{}
?-
©PrologIA
R 10 - 12
Manuel de Référence
X @< Y
Compare les termes X et Y, fait un succès si X précède Y, échoue sinon.
X @> Y
Compare les termes X et Y, fait un succès si Y précède X, échoue sinon.
X @>= Y
Compare les termes X et Y, fait un succès si Y précède ou est formellement
égal à X, échoue sinon.
X @=< Y
Compare les termes X et Y, fait un succès si X précède ou est formellement
égal à Y, échoue sinon. Quelques exemples:
?- 1.0 @< 1.
{}
?- @<(aardvark,zebra).
{}
?- @<(short,short).
?- short @< shorter.
{}
?- @<(foo(a),foo(b)).
{}
?- @<(foo(a,b),north(a)).
?- @<(X,X).
?- Y @< X.
{}
?- @<(_,_).
{}
?- @<(foo(X,a),foo(Y,b)).
{}
?- "foo" @> foo.
{}
?- [1,2,3] @> [1,1,3,4].
{}
?- [1,2] @> <>(1,2).
?- [1,2] @> <>(X).
{}
A!ociation
Prolog
HERITAGE
10.5. Les entrées / sorties
10.5.1. Généralités
A l'ouverture d'une unité d'entrée/sortie (prédicats open/3 et open/4), un argument de sortie, qui doit obligatoirement être une variable libre lors de l'appel, est unifié avec une constante (en l'occurence un entier négatif). Cette constante permettra dans les prédicats de désigner de manière unique le canal d'accès à l'unité. Une option d'ouverture permet d'associer à l'unité un identificateur, appelé "alias", qui sera dans les sources de programmes un moyen plus clair et plus global de désigner ce numéro de canal.
©PrologIA
A!ociation
Prolog
HERITAGE
Extensions Edinburgh
R 10 - 13
close(C,O), close(C)
Ferme l'unité associée au canal C. L'argument O, s'il existe, doit être une liste d'options prises parmi:
force(true): une erreur sur la fermeture de l'unité sera remontée.
force(false): une erreur sur la fermeture de l'unité sera ignorée.
open(S,M,C,O), open(S,M,C)
Ouvre selon le mode M, l'unité ayant pour nom l'atome S et renvoie le canal associé C. L'argument O, s'il existe, doit être une liste d'options prises parmi:
- alias(A) où A doit être un identificateur et indiquera un alias par lequel l'unité pourra être nommée dans les prédicats.
- eof_action(A) qui indique l'action à accomplir sur une fin de fichier suivant la valeur de A:
- error: une erreur est générée (c'est le défaut).
- eof_code: un code spécial, dépendant du prédicat de lecture, est rendu à chaque tentative d'accès au fichier (Voir les prédicats de lecture).
- reset: le même code que dans le cas de eof_code est rendu et la lecture de la fin de fichier est annulée. La valeur de la propriété end_of_stream reste at. Ceci est utile pour des terminaux.
- lg_buffer(L) où L doit être un entier et indiquera la taille du buffer associé à l'unité.
- reposition(B) où B peut prendre la valeur :true ou :false et indique si l'index de lecture (ou d'écriture) peut être repositionné (appel à la primitive set_stream_position/2). Défaut: true.
- type(T) où T désignera le type de l'unité.
Le canal C associé à l'unité doit être une variable libre lors de l'appel et est unifié avec une valeur entière négative (transparent pour l'utilisateur).
Exemple:
?- open(bfile,write,X,[alias(bfile),type(binary)]).
{X=-7}
set_stream_position(C,N)
Positionne au Nième octet le pointeur de lecture ou d'écriture de l'unité associée au canal C. N doit être un entier et l'unité doit être un fichier disque.
stream_property(C,P)
Réussit si l'unité associée au canal C a la propriété P. C peut être une variable libre, auquel cas tous les canaux ayant la propriété P seront unifiés successivement avec C. P peut soit être libre, soit indiquer une propriété prise parmi:
- alias(A) où A sera unifié avec l'alias de l'unité.
- file_name(S) où S sera unifié avec le nom de l'unité.
- input qui sera vrai si l'unité est une unité d'entrée.
- mode(M) où M sera unifié avec le mode d'ouverture de l'unité.
- output qui sera vrai si l'unité est une unité de sortie.
- position(P) où P sera unifié avec la position du pointeur de l'unité.
- type(T) où T sera unifié avec le type de l'unité.
©PrologIA
R 10 - 14
Manuel de Référence
- reposition(B) où B sera unifié avec la valeur true ou false suivant l'option choisie à l'ouverture de l'unité.
- eof_action(A) où A sera unifié avec l'action à accomplir sur une fin de fichier.
- end_of_stream(E) où E sera unifié avec:
- not si l'on n'est pas sur une fin de fichier.
- at si l'on se trouve sur une fin de fichier.
- past si l'on a dépassé la fin de fichier (une lecture a encore été tentée après une fin de fichier signalée).
C ne peut pas être un alias car il peut aussi être utilisé en sortie.
Exemples
?- stream_property(S,P).
{S=-6,P=file_name(foo)}
{S=-7,P=file_name(bfoo)}
{S=-6,P=mode(append)}
{S=-7,P=mode(read)}
{S=-6,P=alias(momo)}
{S=-7,P=alias(bfile)}
{S=-6,P=type(text)}
{S=-7,P=type(binary)}
{S=-7,P=input}
{S=-6,P=output}
{S=-6,P=position(69)}
{S=-7,P=position(4)}
{S=-6,P=reposition(:true)}
{S=-7,P=reposition(false)}
{S=-6,P=eof_action(error)}
{S=-7,P=eof_action(eof_code)}
{S=-6,P=end_of_stream(:not)}
{S=-7,P=end_of_stream(:not)}
?- stream_property(S,type(text)).
{S=-6}
?- stream_property(-7,type(B)).
{B=binary}
A!ociation
Prolog
HERITAGE
10.5.2. Entrées
10.5.2.1. Interprétation des chaînes de caractères
Un texte en position d'argument noté entre doubles quotes peut être interprété par l'analyseur syntaxique de différentes manières suivant l'option choisie (sur la ligne de commande ou par exécution du prédicat set_prolog_flag/2):
- Soit comme une vraie chaîne de caractères (type à part entière).
- Soit comme un atome: il y aura alors une équivalence avec l'écriture entre simples quotes.
- Soit comme une liste composée des caractères (atomes préfixés par le préfixe vide) constituant la chaîne.
- Soit comme une liste composée des codes des caractères constituant la chaîne.
Exemples:
?- set_prolog_flag(double_quotes,string), read(R).
"hello world".
{R="hello world"}
?- set_prolog_flag(double_quotes,chars), read(R).
©PrologIA
A!ociation
Prolog
HERITAGE
Extensions Edinburgh
R 10 - 15
"hello world".
{R=[h,e,l,l,o,' ',w,o,r,l,d]}
?- set_prolog_flag(double_quotes,codes), read(R).
"hello world".
{R=[104,101,108,108,111,32,119,111,114,108,100]}
?- set_prolog_flag(double_quotes,atom), read(R).
"hello world".
{R='hello world'}
?-
10.5.2.2. Prédicats
Si l'argument désignant l'unité d'entrée est un argument en entrée, on pourra utiliser indifféremment le n° de canal ou bien l'alias associé à cette l'unité. Dans le cas contraire (cas du prédicat current_input/1), c'est le n° de canal qui sera rendu.
La plupart des prédicats d'entrée peuvent s'utiliser soit sur l'unité spécifiée en argument (n° de canal, alias), soit sur l'unité courante d'entrée, auquel cas l'argument indiquant l'unité est absent.
Le comportement des prédicats de lecture, quand une fin de fichier est rencontrée, est conforme à l'option eof_action choisie à l'ouverture de l'unité sur laquelle se fait la lecture.
at_end_of_stream(C), at_end_of_stream
Réussit si une lecture sur le canal C a déjà signalé une fin de fichier, échoue sinon. Contrairement au prédicat eof, ce prédicat n'essaie pas d'effectuer une nouvelle lecture sur le canal C mais se contente d'examiner le status de la lecture précédente.
current_input(C)
C est unifié avec le canal associé à l'unité d'entrée courante. Attention: C ne sera pas un alias.
get(C,X), get(X)
X est unifié avec l'entier égal au code interne (code ISO ou code de la machine hôte) du premier caractère non blanc lu sur l'unité d'entrée associée au canal
C. Si une fin de fichier est rencontrée et que l'unité a été ouverte avec l'option
eof_action(eof_code), X est unifié avec la valeur -1.
get_byte(C,X), get_byte(B)
X est unifié avec le premier octet (entier >= 0) lu sur l'unité d'entrée associée au canal C. Cette unité doit être de type :binary. Si une fin de fichier est rencontrée et que l'unité a été ouverte avec l'option eof_action(eof_code), X est unifié avec la valeur -1.
get_char(C,X), get_char(X)
X est unifié avec le premier caractère lu sur l'unité d'entrée associée au canal C.
Si une fin de fichier est rencontrée et que l'unité a été ouverte avec l'option
eof_action(eof_code), X est unifié avec la valeur end_of_file.
©PrologIA
R 10 - 16
Manuel de Référence get_code(C,X), get_code(X)
X est unifié avec l'entier égal au code interne (code ISO ou code de la machine hôte) du premier caractère lu sur l'unité d'entrée associée au canal C. Si une fin de fichier est rencontrée et que l'unité a été ouverte avec l'option
eof_action(eof_code), X est unifié avec la valeur -1.
A!ociation
Prolog
HERITAGE
get0(X)
Identique à get_code/1.
peek_byte(C,X), peek_byte(X)
Essaie d'unifier X avec le premier octet (entier >= 0) en entrée sur l'unité associée au canal C. Cette unité doit être de type :binary. L'octet n'est pas lu.
Ce prédicat ne modifie donc pas les propriétés position et end_of_stream de l'unité. Si une fin de fichier est rencontrée et que l'unité a été ouverte avec l'option eof_action(eof_code), X est unifié avec la valeur -1.
peek_char(C,X), peek_char(X)
Essaie d'unifier X avec le premier caractère en entrée sur l'unité associée au canal C. Le caractère n'est pas lu. Ce prédicat ne modifie donc pas les propriétés position et end_of_stream de l'unité. Si une fin de fichier est rencontrée et que l'unité a été ouverte avec l'option eof_action(eof_code), X est unifié avec la valeur end_of_file.
peek_code(C,X), peek_code(X)
Essaie d'unifier X avec l'entier égal au code interne (code ISO ou code de la machine hôte) du premier caractère en entrée sur l'unité associée au canal C.
Le caractère n'est pas lu. Ce prédicat ne modifie donc pas les propriétés
position et end_of_stream de l'unité. Si une fin de fichier est rencontrée et que l'unité a été ouverte avec l'option eof_action(eof_code), X est unifié avec la valeur -1.
read(C,X), read(X)
Lit le prochain terme se trouvant sur l'unité associée au canal C, plus le premier caractère non blanc qui le suit. Equivalent à in(X,_) sur l'unité C. Si une fin de fichier est rencontrée et que l'unité a été ouverte avec l'option
eof_action(eof_code), X est unifié avec la valeur end_of_file.
Exemple:
?- read(X).
[1,2].
{X=[1,2]}
read_line(C,S,N), read_line(S,N), read_line(S)
Equivalent au prédicat inl(S,N) sur l'unité associée au canal C.
read_term(C,X,O), read_term(X,O)
Même chose que le prédicat read, mais l'on peut en plus obtenir une liste d'options prises parmi:
- variables(L_V) où L_V sera la liste des variables du terme X.
©PrologIA
A!ociation
Prolog
HERITAGE
Extensions Edinburgh
R 10 - 17
- variable_names(L_VN) où L_VN sera le dictionnaire des variables du terme X. Ce dictionnaire sera composé d'éléments de la forme:
"nom de la variable" = variable.
- singletons(L_S) où L_S sera le dictionnaire des variables qui n'apparaissent qu'une seule fois dans le terme X. Ce dictionnaire sera composé d'éléments de la forme: "nom de la variable" = variable.
Exemple:
?- read_term(T,[variables(L_V),variable_names(L_VN),
singletons(S)]).
aa(X,[Y,X,Y,Z],<>(Z,U)).
{T=aa(_940,[_969,_940,_969,_1042],_1042(_1208)),
L_V=[_940,_969,_1042,_1208],
L_VN=["X" = _940,"Y" = _969,"Z" = _1042,
"U" = _1208],
S=["U" = _1208]}
see(F)
Est équivalent à input(F). Si F est un identificateur, c'est la chaîne correspondant à son abréviation qui est prise en compte comme nom d'unité
(c.à.d. le préfixe est ignoré).
seeing(F)
Est équivalent à input_is(F). Si F est un identificateur, c'est la chaîne correspondant à son abréviation qui est prise en compte comme nom d'unité
(c.à.d. le préfixe est ignoré).
seen
Est équivalent à close_input.
set_input(C)
Redirige l'entrée courante vers l'unité associée au canal C.
10.5.3. Sorties
Si l'argument désignant l'unité de sortie est un argument en entrée, on pourra utiliser indifféremment le n° de canal ou bien l'alias associé à cette l'unité. Dans le cas contraire (cas du prédicat current_output/1), c'est le n° de canal qui sera rendu.
La plupart des prédicats de sortie peuvent s'utiliser soit sur l'unité spécifiée en argument (n° de canal, alias), soit sur l'unité courante de sortie, auquel cas l'argument indiquant l'unité est absent.
current_output(C)
C est unifié avec le canal associé à l'unité de sortie courante. Attention: C ne sera pas un alias.
flush_output(C), flush_output
Equivalent au prédicat flush/0 pour l'unité de sortie associée au canal C.
©PrologIA
R 10 - 18
Manuel de Référence nl(C), nl
Est équivalent à line/0 pour l'unité de sortie associée au canal C.
put(X)
Equivalent à put_code/1.
put_byte(C,X), put_byte(X)
L'octet X (entier >= 0) est envoyé sur l'unité de sortie associée au canal C.
Cette unité doit être de type :binary.
A!ociation
Prolog
HERITAGE
put_char(C,X), put_char(X)
Le caractère X est envoyé sur l'unité de sortie associée au canal C.
put_code(C,X), put_code(X)
Le code interne de caractère X est envoyé sur l'unité de sortie associée au canal
C.
set_output(C)
Redirige la sortie courante vers l'unité associée au canal C.
tab(N)
Envoie N blancs sur l'unité courante de sortie.
tell(F)
Est équivalent à output(F). Si F est un identificateur, c'est la chaîne correspondant à son abréviation qui est prise en compte comme nom d'unité
(c.à.d. le préfixe est ignoré).
telling(F)
Est équivalent à output_is(F). Si F est un identificateur, c'est la chaîne correspondant à son abréviation qui est prise en compte comme nom d'unité
(c.à.d. le préfixe est ignoré).
told
Est équivalent à close_output.
write(C,X), write(X)
Est équivalent à write_term avec les options [quoted(false),
numbervars(true), ignore_ops(false)].
writeq(C,X), writeq(X)
Est équivalent à write_term avec les options [quoted(true), numbervars(true),
ignore_ops(false)].
write_canonical(C,X), write_canonical(X)
Est équivalent à write_term avec les options [quoted(true),
numbervars(false), ignore_ops(true)].
©PrologIA
A!ociation
Prolog
HERITAGE
Extensions Edinburgh
R 10 - 19
write_term(C,X,O), write_term(X,O)
Ecrit le terme X sur l'unité de sortie associée au canal C, en tenant compte de la liste d'options O, options prises parmi:
- quoted(true) ou quoted(false): indique si les constantes chaînes et les identificateurs contenus dans X doivent être écrits sous forme quotée.
- ignore_ops(true) ou ignore_ops(false): indique si les déclarations courantes d'opérateurs doivent être ignorées.
- numbervars(true) ou numbervars(false): indique si les termes de la forme '$VAR'(N), N étant un entier positif doivent être écrits comme une variable constituée d'une lettre majuscule suivie d'un entier. La lettre est la (i+1)ième lettre de l'alphabet et l'entier est j, tels que:
i = N modulo 26
j = N / 26 (division entière).
Si une option n'est pas spécifiée, elle a pour valeur par défaut :false.
Exemples:
?- write_term(['quoted atom', "string", 1+2,
'$VAR'(35)],[]).
[quoted atom,string,1 + 2,'$VAR'(35)]{}
?- write_term(['quoted atom', "string", 1+2,
'$VAR'(35)],[quoted(:true),numbervars(true), ignore_ops(true)]).
['quoted atom',"string",+(1,2),J1]{}
?-
10.6. L'environnement
Un certain nombre de paramètres globaux appelés "variables d'état" peuvent être modifiés ou consultés. Ce sont:
- l'état du débogueur: nom de la variable d'état: debug valeurs possibles: on (actif) ou off (inactif).
- le comportement de Prolog sur une règle appelée et non définie: nom de la variable d'état: unknown valeurs possibles: error (génération d'une erreur), warning (génération d'un avertissement) ou fail (échec).
- l'interprétation des doubles quotes en position d'argument: nom de la variable d'état: double_quotes valeurs possibles: chars (liste de caractères), codes (liste des codes des caractères), atom (atome) ou string (vraies chaînes).
- la possibilité de convertir des caractères en d'autres: nom de la variable d'état: char_conversion
Seule valeur possible actuellement: off (inactif).
- l'affirmation que l'arithmétique entière n'est pas limitée: nom de la variable d'état: bounded valeur non modifiable: false.
- l'arité maximale (nombre d'arguments) d'une règle ou d'une structure: nom de la variable d'état: max_arity valeur non modifiable: 8388607.
- la définition de la division entière et du reste de celle-ci:
©PrologIA
R 10 - 20
Manuel de Référence
nom de la variable d'état: integer_rounding_function valeur non modifiable: toward_zero.
current_prolog_flag(X,Y)
Renseigne sur l'état courant des variables d'état de l'environnement. Les variables d'état: max_integer et min_integer provoquent toujours un échec car l'arithmétique entière n'est pas bornée. Exemple: On veut connaître la valeur de toutes les variables d'état:
?- current_prolog_flag(F, V).
{F=bounded,V=false}
{F=integer_rounding_function,V=toward_zero}
{F=char_conversion,V=off}
{F=max_arity,V=8388607}
{F=:debug,V=off}
{F=unknown,V=warning}
{F=double_quotes,V=:string}
halt(X), halt
Sont respectivement équivalents à quit(X) et quit.
set_prolog_flag(X,Y)
Positionne la variable d'état X de l'environnement à la valeur Y. Ce prédicat est aussi une directive de compilation, c'est à dire que les variables d'environnement peuvent être modifiées au milieu d'un source que l'on compile. Exemples:
?- consult.
set_prolog_flag(double_quotes, codes).
foo :- myrule("abc").
.
{}
?- set_prolog_flag(debug, on).
{}
A!ociation
Prolog
HERITAGE
10.7. Traduction de DCG
1
En mode insertion, Prolog transforme en règles Prolog II+ les règles de grammaire de la forme
A --> B.
où A est un terme et B est une suite de termes. Pour chaque terme de la suite de termes B :
- Si c'est une liste, il est interprété comme une suite de symboles terminaux.
1Definite Clause Grammar, extension des grammaires hors-contexte et sous-ensemble des grammaires de métamorphose.
©PrologIA
A!ociation
Prolog
HERITAGE
Extensions Edinburgh
R 10 - 21
- Si c'est une chaîne de caractères, celle-ci est transformée en une liste de caractères qui est donc ensuite considérée également comme une liste de symboles terminaux.
- Si c'est un terme entre accolades, il est interprété comme un appel à une règle à effectuer tel quel.
- Sinon le terme est considéré comme un non-terminal représentant une règle de réécriture.
La règle prédéfinie phrase/2 ou phrase/3 permet d'analyser ou de synthétiser les chaînes grammaticales définies par cette grammaire (voir § 10.2).
Pour traduire la règle de grammaire en règle Prolog, Prolog appellera le prédicat
:term_expansion/2 s'il a été défini, sinon il utilisera son propre programme de transformation. Il est ainsi possible de réaliser automatiquement des transformations sur les termes de la forme (A --> B). Si l'on désire définir un programme de transformation, il doit définir la règle suivante :
:term_expansion(X,Y)
Lors de l'appel, X est le terme que Prolog vient de lire et Y est une variable libre. X est de la forme (A --> B).
Après appel, Y doit représenter la règle Prolog qui doit être associée à la règle de réécriture X (c'est à dire la règle Prolog qui sera assertée).
Voici deux exemples de compilation et d'interrogation d'une grammaire DCG :
?- [user].
somme(Z) --> chiffre(Z).
somme(X+Y) --> chiffre(X), "+", somme(Y).
chiffre(1) --> "1".
...
chiffre(9) --> "9".
.
{}
?- list.
somme(_53,_54,_55) :-
chiffre(_53,_54,_55).
somme(_57 + _58,_54,_55) :-
chiffre(_57,_54,["+" | _59]),
somme(_58,_59,_55).
chiffre(1,["1"|_54],_54).
...
chiffre(9,["9"|_54],_54).
{}
?- phrase(somme(Z),"1+2+3").
{Z=1 + (2 + 3)}
?- phrase(somme(1+(2+9)),L).
{L=["1","+","2","+","9"]}
©PrologIA
R 10 - 22
Manuel de Référence
Exemple 2 :
?- [user].
somme(Z) --> chiffre(Z).
somme(Z) --> chiffre(X), "+", somme(Y),{Z is X+Y}.
chiffre(N) --> [C],{string_integer(C,N)}.
liste3 --> elt, elt, elt.
elt --> [a].
elt --> [b].
elt --> [c]. .
{}
?- phrase(somme(Z),"1+2+3").
{Z=6}
?- phrase(liste3,L).
{L=[a,a,a]}
{L=[a,a,b]}
{L=[a,a,c]}
...
{L=[c,c,c]
A!ociation
Prolog
HERITAGE
©PrologIA
A!ociation
Prolog
HERITAGE
Extensions Edinburgh
R 10 - 23
©PrologIA
A!ociation
Prolog
HERITAGE

Lien public mis à jour
Le lien public vers votre chat a été mis à jour.
Caractéristiques clés
- Compilation incrémentale pour une vitesse optimisée.
- Modularité pour l'écriture de gros programmes.
- Ouverture vers d'autres langages (C, etc.).
- Récupération dynamique de mémoire (garbage collector).
- Débogueur de haut niveau intégré.
- Bibliothèque portable d'interface graphique.