pere(cesar,
adrienne).
pere(marc, enza).
pere(cesar, marc).
pere(marc, mara).
mere(silvia, cesar).
mere(julie, lea).
mere(lea, adrienne).
mere(adrienne, enza).
true.
masc(X) :- pere(X, Y).
fem(X) :- mere(X, Y).
ancetre(X, X).
ancetre(A, D) :- pere(A, G), ancetre(G, D).
ancetre(A, D) :- mere(A, G), ancetre(G, D).
) ?- fem(adrienne).
true.
?- fem(enza).
false.
?- fem(mara).
false.
?- masc(cesar).
true
; true.
?- ancetre(silvia, adrienne).
true
; false.
?- ancetre(X, adrienne).
X = adrienne
; X = cesar
;X = silvia
;X = julie
;X = lea
;false.
?- ancetre(X, enza),
ancetre(julie, X).
X = enza
; X = julie
;X = lea
;X = adrienne
;false.
:-
"
dans les définitions s'interprète comme une implication de droite à
gauche : X, Y
)
- plus
généralement leur initiale est une majuscule.pere, mere, masc,...
)enza, julie,
marc,...
). ?- fem(masc).
false.
false
.id(le_pere(X), P) :- pere(P, X).
id(la_fille(X, Y), F) :- pere(X, F), mere(Y, F), fem(F).
?- id(X,Y).
X = le_pere(adrienne),
Y = cesar
;
X = le_pere(enza),
Y = marc
;
X = le_pere(marc),
Y = cesar
;
X = le_pere(mara),
Y = marc
;
X = la_fille(cesar, lea),
Y = adrienne
;
false.
fonction(arg1, arg2, ..., argk)
. lea, adrienne, marc
,...)append(X, iReverse(Y, nil))
|
long([], 0).
long([A | S], N) :- long(S, P), N is P+1.
+
',
'-
', '*
', '/
')
sont des symboles fonctionnels prédéfinis,+(3,
/(5,2))
' qu'en notation traditionnelle '3+5/2
'.:- op(préc, assoc, [nom])
nom
comme opérateur binaire ou
unaire infixé, préc
comme précédence (plus préc
est petit, plus elle est forte : celle de '+
' est 500,
celle de '*
' est 400) assoc
régissant
l'arité et l'association à gauche ou à droiteyfx
binaire associe à gauchexfy
binaire associe à droitefx
unaire préfixéxf
unaire postfixénon a ou (b imp c) imp a et non b ou (a imp c)
:- op(900, yfx, [imp]) .
:- op(800, yfx, [ou]) .
:- op(700, yfx, [et]) .
:- op(600, fx, [non]) .
nom(femme(X), marie)
<==> X a une femme nommée Marie
(c'est vrai ou faux, suivant la valeur de X)nom
est un prédicat, mais pas femme
qui est un symbole fonctionnel.pere, mere, ancetre
et id
sont des prédicats,le_pere
et la_fille
sont des symbole fonctionnels.pere,
mere, ancetre
et id
), write(terme)
a pour effet
d'envoyer en sortie l'écriture canoniqe du terme-argument nl
(sans argument)
provoque un saut de ligne tab(terme à valeur numérique)
provoque autant de tabulations is
,
prend deux arguments dont le premier doit être une variable et le
second une expression arithmétique;?- X is 3+5/2, write(X).
5.5
X = 5.5.
?- is(X, +(3, /(5,2))), write(X).
5.5
X = 5.5.
c :-
p1, p2,
... , pk
.
<==> p1
⋀ p2
⋀
...
⋀ pk
⊃ c
]p1, p2, ... , pk
<--- les prémisses
----------------
c
<--- la conclusion
:-
"
est le symbole fonctionnel. /* Arbre généalogique, première manière */
ecrire(X, N) :- tab(N), write(X), nl. /* N doit etre entier */
arbgen1(X) :- ecrire(X, 0), genarb1(X, 10).
genarb1(X, N) :- genp1(X, N). /* p comme pere */
genarb1(X, N) :- genm1(X, N). /* m comme mere */
genp1(X, N) :- pere(Y, X), ecrire(Y, N), sgenarb1(Y, N).
genm1(X, N) :- mere(Y, X), ecrire(Y, N), sgenarb1(Y, N).
sgenarb1(X, N) :- M is N + 10 , genarb1(X, M).
pere(jules, cesar). pere(andre, lea).
pere(cesar, adrienne). pere(otto, enza).
pere(cesar, marc). pere(otto, mara). pere(marc, antoine).
pere(marc, paul).
mere(silvia, cesar). mere(julie, lea). mere(lea, adrienne). mere(pippa,
enza).
mere(lea, marc). mere(enza, antoine). mere(enza,
paul).
?- arbgen1(paul).
paul
marc
cesar
jules
silvia
lea
andre
julie
enza
otto
pippa
false.
p
le
prédicat du but visé [c-à-d. but = p(....)
] p
dans l'ordre (de haut en bas) zig(X)
,
avec : zig(a)
:-
write('un '),
write('deux '), write('trois'), nl. |
?- zig(X).
un deux trois
X = a
;quatre cinq six
X = b
;sept
fini_pour_zig
X = c.
Le fonctionnement normal de Prolog lui fait
chercher toutes les démonstrations possibles du but visé. Ceci le conduit à revenir en arrière après un échec, pour essayer la clause suivante du paquet. Ce mécanisme de retour-arrière (backtrack), superposé au "zig-zag" induit un séquencement complexe : Exemple : résolution du littéral zigzag(X,
Y) , avec zigzag(X, Y) :- On observe que le littéral le plus à droite zig(Y)
a été résolu 9 fois, et zig(X) 3 fois seulement [sorte de boucle intérieure sur zig(Y) ,
extérieure sur zig(X) ] |
fail
fail
?- zigzag(X,Y), fail.
un deux trois
X = a
un deux trois
Y = a
quatre cinq six
Y = b
sept
fini_pour_zig
Y = c
quatre cinq six
X = b
un deux trois
Y = a
quatre cinq six
Y = b
sept
fini_pour_zig
Y = c
sept
fini_pour_zig
X = c
un deux trois
Y = a
quatre cinq six
Y = b
sept
fini_pour_zig
Y = c
false.
!
"(point
d'exclamation), dit en anglais "cut" et en français "coupe-choix",write
") et le
calcul se poursuit normalement ;!
". parentc(E, P, M) :- pere(P, E), !, mere(M, E).
parentc
(adrienne, P, M)
avec la base de données
ci-dessus, P = cesar
et M = lea
, pere
"
s'arrêtera à la première, mere
"
seront successivement essayées. parents(E, P, M) :- pere(P, E), mere(M, E) , !.
/* Arbre genealogique,
deuxieme maniere */
arbgen2(X) :- ecrire(X, 0), genarb2(X, 10).
genarb2(X, N) :- genp2(X, N), genm2(X, N).
genp2(X, N) :- pere(Y, X), !, ecrire(Y, N), sgenarb2(Y, N).
genp2(X, N) :- name(C, "Pere inconnu"), ecrire(C, N).
genm2(X, N) :- mere(Y, X), !, ecrire(Y, N), sgenarb2(Y, N).
genm2(X, N) :- name(C, "Mere inconnue"), ecrire(C, N).
sgenarb2(X, N) :- M is N + 10 , genarb2(X, M).
?- arbgen2(paul).
paul
marc
cesar
jules
Pere inconnu
Mere inconnue
silvia
Pere inconnu
Mere inconnue
lea
andre
Pere inconnu
Mere inconnue
julie
Pere inconnu
Mere inconnue
enza
otto
Pere inconnu
Mere inconnue
pippa
Pere inconnu
Mere inconnue
true.
fac(0, 1) :- !.
fac(N, F) :- P is N-1, fac(P, G), F is N*G.
bin(P, 0, 1):- !.
bin(Q, Q, 1):- !.
bin(P, Q, R) :- P1 is P-1, Q1 is Q-1, bin(P1, Q1, R1), bin(P1, Q, R2),
R is R1+R2.
liliste([X|S]):- read(X), not X='F', !,
liliste(S).
liliste([]).
not
", voir le prochain cours.?-
liliste(X).
|: a.
|: b.
|: c.
|: $.
X = [a,b,c]
element1(E, [E|S]) .
element1(E, [X|S]) :- element1(E, S).
element1(a, [b,a,d,a,c])
---> true
(2 fois) element1(X, [b,a,d])
---> X=b,
X=a,
X=d
enlever1(E, [E|S], S).
enlever1(E, [X|S], [X|T]) :- enlever1(E, S, T).
enlever1(a, [b,a,c],
[b,c]) ---> true
enlever1(a, [b,a,c,a], X)-->
X=[b,c,a], X=[b,a,c]
enlever1(a, X, [b,c])--> X=[a,b,c],
X=[b,a,c],X=[b,c,a]
enlever1(X, [b,a,d,a,c], [b,d,a,c])
---> X=a
permut([], []).
permut([A|S], P) :- permut(S, R), enlever1(A, P, R).
?- permut1([a, b, c], X).
X = [a,b,c]
;X = [b,a,c]
;X = [b,c,a]
;X = [a,c,b]
;X = [c,a,b]
;X = [c,b,a]
;false.
permutation
.concat([], L, L).
concat([A|S], L, [A|R]) :- concat(S, L, R).
concat([a,b,c], [d,e],
[a,b,c,d,e]) ---> true
concat([a,b,c], [d,e], X)
---> X = [a,b,c,d,e]
concat(X, [d,e], [a,b,c,d,e] ---> X
= [a,b,c]
concat(([a,b], X, [a,b,c,d]) ---> X
= [c, d]
concat(X, Y, [a, b, c]) ---> X=[] Y=
[a,b,c], X=[a] Y=[b,c], X=[a,b] Y=[c], X=[a,b,c] Y=[]
concat
boucle si son premier
et son troisième paramètres sont des variables libres ! concat(X, [a, b, c], Y)
!append
. renverser([], []).
renverser([A|S], R) :- renverser(S,T), concat(T, [A], R).
renverser([a,b,c], X) ---> X=[c,b,a]
renverser(X, [a,b,c])
boucle !
par rappel à renverser(S,T)
renverser([A|S], R) :- concat(T,
[A], R),
renverser(S,T).
reverse
. element2(E, L) :- concat(_, [E|_], L).
enlever2(E, L, R) :- concat(D, [E|F], L), concat(D, F, R).
enlever2(a, X, [b,d,c])
boucle
! par appel à concat(D,
[a|F], L)
enlever1
(cf. ci-dessus) : enleverp(E, [E|S], S) :- !.
enleverp(E, [X|S], [X|T]) :- enleverp(E, S, T).
enleverp(a, [b,a,d,a,c], X). --> X = [b,d,a,c]
enlever1
: enlever toutes les occurrences "d'un seul coup" enlevertout(E, L, R) :- enlever1(E, L, T), !,
enlevertout(E, T, R).
enlevertout(E, L, L).
enlevertout(a, [b,a,c,a,d], X). --> X = [b,c,d]
name(chaine, liste)
. /* nonvide(L) vrai si la liste L contient
au moins un élément */
nonvide([ _ | _ ]).
/* pour mémoire :
concat([], L, L).
concat([A|S], L, [A|R]) :- concat(S, L,
R).
*/
/* mutant(S) où S est le symbole obtenu
par mutation, p.ex. chevalapin */
mutant(S) :-
animal(D), animal(F),
/* les
deux noms qui vont se chevaucher*/
concat(Debut, Milieu, D),
nonvide(Debut), nonvide(Milieu),
/*
décomposition non-triviale de D */
concat(Milieu, _, F),
/*
chevauchement avec F */
concat(Debut, F, M),
/*
composition du mutant */
name(S, M). /* pour visualiser */
/* la ménagerie
*/
animal("ALLIGATOR").
animal("TORTUE"). animal("LAPIN").
animal("CHEVAL").
animal("CARIBOU"). animal("OURS").
animal("PINTADE").
animal("VACHE"). animal("BOUC").
?- mutant(X), write(X),nl, fail.
ALLIGATORTUE
LAPINTADE
CHEVALLIGATOR
CHEVALAPIN
CARIBOURS
CARIBOUC
VACHEVAL
BOUCHEVAL
BOUCARIBOU
false.