|\^/| Maple 8 (IBM INTEL LINUX) ._|\| |/|_. Copyright (c) 2002 by Waterloo Maple Inc. \ MAPLE / All rights reserved. Maple is a registered trademark of <____ ____> Waterloo Maple Inc. | Type ? for help. # (gH) -- rapm.prm ; TimeStamp (unix) : le 24 Septembre 03 à 13:36 ################################################################################### # # # ceci est le fichier rapm.prm qui évite de retaper les expressions et # # instructions Maple présentées dans le cours # # # # "Rappels mathématiques pour la licence informatique". # # # # l'url de la page web de ce fichier est : # # # # http://www.info.univ-angers.fr/pub/gh/cours_gH/rapm.prm # # # # # # Références : Gilles HUNAULT, Université d'Angers. # # Email : gilles.hunault@univ-angers.fr # # Site web : http://www.info.univ-angers.fr/pub/gh/ # # # ################################################################################### # # # - en ligne de commande, il faut taper # # # # maple < rapm.prm # # # # pour éxécuter ce fichier. # # (avec peut-être le chemin d'accés au fichier à maple) # # # # - à l'intérieur d'une session il faut taper : # # # # interface(echo=4) ; # # read "rapm.prm" ; # # # # pour éxécuter ce fichier. # # (avec peut-être le chemin d'accés au fichier rapm.prm) # # # ################################################################################### # comme vous l'avez surement compris, un commentaire commence par le symbole dièse # et il peut être mis apres une instruction ; # Maple ignore donc ces lignes... # le symbole > est le prompt de Maple qui attend une ligne # (même une ligne vide) > print( interface(version) ) ; # <-- ceci donne la version de Maple utilisée TTY Iris, Maple 8.00, IBM INTEL LINUX, Apr 22 2002 Build ID 110847 > interface(errorbreak=0) ; # <-- s'il y a une erreur de fichier, on continue ################################################################################### # # # pot-pourri d'expressions pour une prise de contact avec Maple # # # ################################################################################### # une expression formelle : le développement de (1+x) au cube, # sans que x n'ait de valeur > expand((1+x)^3) ; 2 3 1 + 3 x + 3 x + x # utilisation du pont-virgule et du symbole deux-points # avec le point virgule on calcule et on affiche > x:= 0 ; y := x + 1; x := 0 y := 1 # avec le deux-points on calcule mais on n'affiche pas > x:= 0 : y := x + 1; y := 1 # si on décommente la ligne suivante, on sort de Maple #quit ; # Maple utilise une très grande précision pour les calculs en nombres entiers > 2^1996 ; 7175816845464090776455207507360512400139485638054345002985267105161039133702\ 314461604121789478164186990287278993671642334044493505394095821412070976\ 041582408695624321582017500043048696765002804464307936878967890298850966\ 477899272746707314127529147123181562284885149925559039350351456978096010\ 263873145792584010556811528656600148717800494628681308423531276812669794\ 164114407625508264767580735079242707325412437212276132938861241150252634\ 990823953221305589618880745034684861474354502447505122326039411422211276\ 598982875970521799151214503406807204736492664073464720550051427673176122\ 840860136553196814336 # les fonctions ont en général des noms anglais > 2^3, 3**2 ,(7 mod 5)=irem(17,8), iquo(35, 8), gcd(1250,500); 8, 9, 2 = 1, 4, 250 # il y a plusieurs types de nombres ; # (décommenter pour avoir le détail) # help (number) ; # Maple interprète les expressions directement > 1.23456^1.3 ; 1.315121453 # on peut forcer le nombre de décimales avec evalf > evalf(1.23456^1.3,2) ; 1.3 # et l'affichage cadré avec printf > printf(`%20.15f`,1.23456^1.3) ; 1.315121453000000 # la variable Digits gère la précision par défaut > 1/3.0 ; 0.3333333333 > Digits := 40 ; Digits := 40 > 1/3.0 ; 0.3333333333333333333333333333333333333333 # la précision n'est pas infinie > 1996^(1996^1996) ; # incorrect volontairement : cela déborde Error, numeric exception: overflow # a propos, qui est plus grand : a^(b^c) ou (a^b)^c ? # les affectations avec := sont (presque) classiques > x := 2 ; y := x+2 ; x := 3 ; x := 2 y := 4 x := 3 # mais la "transparence référentielle" complique un peu > b := a ; a := 1 ; b ; a := 2 : b ; b := a a := 1 1 2 > restart ; # <-- pour effacer toutes la session, y compris les variables > a := 1 ; b := a ; b ; a := 2 : b ; a := 1 b := 1 1 1 # les structures de base sont les ensembles ("sets"), les listes, les vecteurs, # (décommenter pour avoir le détail) # ? set # ? list # ? vector # ? matrix # ? seq # voici la liste des constantes reconnues par Maple > constants ; false, gamma, infinity, true, Catalan, FAIL, Pi # quand Maple "ne sait pas", il ne dit rien # et se contente de "répéter betement" > factor(x^4+1) ; 4 x + 1 # pour suivre en détail, il faut utiliser infolevel > restart ; # <-- car Maple garde en mémoire ses essais de factorisation > infolevel[factor] := 4 ; infolevel[factor] := 4 > factor(x^4+1) ; factor/polynom: polynomial factorization: number of terms 2 4 x + 1 # une séquence d'expressions, ce sont des expressions séparées par # des virgules, comme > a , 1+2, 3=6, evalb(3=9), Int(t/2,t) = int(t/2,t) ; / 2 | t a, 3, 3 = 6, false, | t/2 dt = ---- | 4 / # avec des accolades, cela devient un ensemble et avec des crochets, une liste > s := a , b , c ; s := a, b, c > whattype( { s } ) ; set > whattype( [ s ] ) ; list # la fonction seq produit des suites de valeurs numérique ou formelles > seq(i*i,i=1..3) ; 1, 4, 9 > seq(h(i),i=[a,b,c]) ; h(a), h(b), h(c) # pour convertir, il faut rajouter une structure à seq > convert( seq(`i`,i=1..10) ,`+` ) ; # incorrect volontairement : manque les crochets Error, wrong number (or type) of parameters in function convert > convert( [seq(`i`,i=1..10)],`+` ) ; 55 # essais calcul de la somme formelle des n premiers entiers > n := 'n' ; n := n > i := 'i' ; i := i > convert(seq(i,i=1..n),`+`) ; # incorrect volontairement : pas de seq formel Error, unable to execute seq > add(i,i=1..n) ; # incorrect volontairement : pas de add formel Error, unable to execute add > sum(i,i=1..n) ; 2 (n + 1) -------- - n/2 - 1/2 2 # une forme factorisée, c'est "plus propre" > factor( sum(i,i=1..n) ) ; factor/polynom: polynomial factorization: number of terms 2 n (n + 1) --------- 2 # les formes inertes permettent d'écrire de jolies expressions > Sum(i,i=1..n) = factor( sum(i,i=1..n) ) ; n ----- \ n (n + 1) ) i = --------- / 2 ----- i = 1 # quand on a plusieurs expressions qui donnent le même résultats, # on peut utiliser time pour comparer la vitesse d'exécution > n := 200 : > i:='i':deb:=time():sum(`i`,`i`=1..n):time()-deb ; 0. > convert([seq(`i`,`i`=1..n)],`+`):time() -deb; 0. > product(`i`,`i`=1..n) :time() -deb ; 0. > convert([seq(`i`,`i`=1..n)],`*`):time() -deb ; 0. # exemples de boucles pour traditionnelles > i :='i':deb := time() : > for j from 1 to 200 do : > sum(`i`,`i`=1..n) : > od : time() -deb ; i := 'i' : 0.039 > deb := time() : > for j from 1 to 200 do : > product(`i`,`i`=1..n) : > od : time() -deb ; i := 'i' : bytes used=4002560, alloc=3734868, time=0.09 bytes used=8007024, alloc=4521156, time=0.13 0.101 > deb := time() : > for j from 1 to 200 do : > s:=0 : > for i from 1 to n do : s := s + i : od : > od : time() -deb ; i := 'i' : 0.019 > deb := time() : > for j from 1 to 200 do : fact(n) : od : > time() -deb ; 0.011 # le nombre d'éléments d'une liste est donné par nops, # on accède aux éléments via l'indice entre crochets > L:=[seq(i*i,i=1..10)] ; nops(L); L[2] ; L := [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] 10 4 # la notation [$a..b] génére la liste-intervalle de a à b > L := [\$1..10] ;L := [\$1..10] ; L := [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] L := [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # reverse retourne une liste mais on peut aussi faire > n := nops(L) ; L := [seq(L[n+1-i],i=1..n)] ; n := 10 L := [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] # mais attention à length pour une liste > length(L) ; 24 # map applique une fonction à chacun des éléments de la liste > map(x->x+1,[1,2,4]) ; map(x->x-1,\{1,2,4\}) ; [2, 3, 5] {0, 1, 3} # mais attention à la vitesse d'exécution > deb := time() : > for j from 1 to 300 do convert(map(i->i,{$1..500}),`+`):od: bytes used=12007232, alloc=4521156, time=0.21 bytes used=16007456, alloc=4521156, time=0.29 bytes used=20007648, alloc=4521156, time=0.36 bytes used=24010156, alloc=4521156, time=0.45 > time() -deb ; 0.279 # pour appliquer un opérateur binaire à une liste, on utilise foldl > foldl( `and`, true, op(map(isprime,[$1..3]))) ; false # les fonctions classiques connaissent les listes > L := [$1..5] : > S := map( x->x+1, L ) : > A := L + S ; A := [3, 5, 7, 9, 11] > sommeListe := (x,y) -> x+ y : > Z := sommeListe(L,S) ; Z := [3, 5, 7, 9, 11] # la même choe avec les vecteurs > V := vector(5,[$1..5]) : > W := vector(5,[ seq(V[i]+1,i=1..5) ]) : > sommeVecteur := (x,y) -> > vector(5,[ seq(x[i]+y[i],i=1..5) ]): > U := sommeVecteur(V,W) ; U := [3, 5, 7, 9, 11] # on peut calculer la longueur d'un vecteur par > nops( convert(V,list) ) ; 5 > nops( [ entries(V) ] ) ; 5 # mais le mieux est sans doute d'utiliser la fonction "ad hoc" de Maple > linalg[vectdim](V) ; 5 # on définit rapidement une fonction par la correspondance fonctionnelle # noté -> soit les touches "tiret" et "supérieur" > f := x -> x**2 = 1 ; 2 f := x -> x = 1 > f(5) ; 25 = 1 # le test avec si permet de gérer les différents cas # et elif signifie else if (en français sinon si) > f := x ->if x<3 then x+1 elif x <5 then x-1 else x*x :fi: > map(f,[$1..10]) ; [2, 3, 2, 3, 25, 36, 49, 64, 81, 100] # nombres aléatoires > y := map(1+rand(100),[$1..1000]) : # un test élémentaire pour voir la qualité du générateur aléatoire > z := map(x-> if x>50 then 1 : fi , y ) : convert(z,`+`) ; 510 # ceci est sans doute mieux mais plus illisible > convert( map(x-> if x>50 then 1 : fi , > map(1+rand(100),[$1..1000]) ),`+`) ; 489 # détail des expressions gérées par Maple comme des arbres > f := x**2*exp(3/2)*sin(Pi/3-1/x) ; 2 Pi f := x exp(3/2) sin(---- - 1/x) 3 > nops(f),[op(f) ],length(f),op(3,f) ; 2 Pi Pi 3, [x , exp(3/2), sin(---- - 1/x)], 50, sin(---- - 1/x) 3 3 > op(1,op(op(3,f))) ; Pi ---- 3 # quand on sait ce qu'on fait, on peut modifier une # sous-expression avec subsop : > subsop(3=cos(x),f) ; 2 x exp(3/2) cos(x) > f ; 2 Pi x exp(3/2) sin(---- - 1/x) 3 # subs, quant à lui remplace dans l'expression > g := 2*(x-1) + 3**(x**2+1); 2 (x + 1) g := 2 x - 2 + 3 > subs(x=a,g) ; 2 (a + 1) 2 a - 2 + 3 # mais seulement au niveau le plus haut ; > subs(n=2,1+n) ; 11 > subs(a+b=2,1+a+b) ; 1 + a + b # pour descendre dans l'arbre, il faut utiliser simplify > simplify(1+a+b,{a+b=2}) ; 3 # la boucle while permet de sortir d'une boucle en fonction d'un test > i:=2; s := 0 ; while (i*i-35<0) do i := i +1 ; s := s + cos(i)**2 ; od : print(s) ; i := 2 s := 0 2 2 2 2 cos(3) + cos(4) + cos(5) + cos(6) # il vaut mieux écrire "proprement" > i:=2; i := 2 > s := 0 ; s := 0 > while (i*i<35) do > i := i +1 ; > s := s + cos(i*1.0)**2 ; > od : > print(s) ; 2.409726340 # select effectue une boucle implicite > select(isprime,[$1..100]) ; [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97] # utilisé avec convert, c'est illisible mais puissant > convert([seq(1/2^p,p=select(isprime,[$1..1000]))],`+`); 5554198481938377907850558291786122081247094133911048363204704074186492596269\ 018919949037019985713276932497362044695072958574306663481117626238020118\ 815668949296772234274506032629762802377904501140672912769089311544651110\ 735958727397629248407652614894370968806622231216577846546855520887401858\ / 06749761 / 13393857589828341511855313113250022632017560146319170093046\ / 879854629388139061701531164979735196198226594933411469414335314839316071\ 153925544980721968373218504918209718530288731776343256327963927347442727\ 691308093729477426584248459448956929932596328643213995597108177709575537\ 28956578048354650708508672 # si on ne veut que la durée : > deb := time() ; deb := 0.599 > convert([seq(1/2^p,p=select(isprime,[$1..1000]))],`+`): bytes used=28010936, alloc=4521156, time=0.62 > time()-deb; 0.081 # pour programmer les fonctions, nargs donne le nombre d'arguments # et on peut donner explicitement les paramètres ou uitliser args[...] # la fonction renvoie la dernière valeur calculée # sauf si on trouve return avant > f := (x,y) -> x+2*y ; f := (x, y) -> x + 2 y > f(3,4) ; 11 > f := proc() ; args[1] + 2* args[2] ; end ; f := proc() args[1] + 2*args[2] end proc > f(3,4) ; 11 > f := proc(x,y) ; return x+2*y ; end ; f := proc(x, y) return x + 2*y end proc > f(3,4) ; 11 # voici un exemple typique de fonction > Fm := proc() ; > if nargs = 0 then > # la phrase suivante sera affichée si on tape Fm() > print(" Fm(n) calcule 2^n -1 pour n entier") ; > # on traite le cas particulier (elif est mis pour else if) > elif args[1] = 0 then RETURN(1) > # et le cas général *) > else RETURN(2^args[1] - 1) > fi ; > end : # surtout ne pas mettre ; car sinon, > # la valeur renvoyée est affichée > Fm() ; " Fm(n) calcule 2^n -1 pour n entier" # un exemple plus complet : > Interv := proc() > local a,b,n,h ; > if nargs = 0 > then > print(`Interv(a,b,n) renvoie points dont le premier est a`) ; > print(` et le dernier est b`) ; > print(` n est facultatif ; par défaut : n=10`) ; > else > if nargs < 2 > then ERROR(` il vous faut au moins deux paramètres numériques`) ; > else > a := args[1] ; b := args[2] ; > if nargs <= 2 then n := 10 ; else n := args[3] ; fi ; > h := (b-a)/(n-1) ; > RETURN(evalm([a$n] + h*[$0..(n-1)])) ; > fi ; > fi ; > end : > Interv(0,1) ; [0, 1/9, 2/9, 1/3, 4/9, 5/9, 2/3, 7/9, 8/9, 1] > Interv(0,1,5) ; [0, 1/4, 1/2, 3/4, 1] > Interv(0,1.0,5) ; [0., 0.2500000000, 0.5000000000, 0.7500000000, 1.000000000] # les fonctions définies par l'utilisateur peuvent auss # être appliquées aux listes > SC := proc(x) RETURN((x+1)^2) : end: > CSC1 := proc(x) > RETURN(map(a->(a+1)^2,[op(x)])) : > end: > CSC2 := proc(x) > RETURN(map(SC,[op(x)])) : > end: > GSC := proc(x) > if nops([x]) = 1 > then RETURN((x+1)^2) : > else RETURN(map(SC,[op(x)])) : > fi ; end : > SC( 3 ) ; 16 > CSC1( [1,5,10]) ; [4, 36, 121] > CSC2( [1,5,10]) ; [4, 36, 121] > GSC( [1,5,10]) ; 2 ([1, 5, 10] + 1) ################################################################################### # # chapitre 1 : Ensembles et Fonctions # ################################################################################### # utilisation de nops pour trouver le nombre d'éléments de { x,y } > restart ; > nops({x,y}) ; # on doit trouver 2 2 > y := x ; y := x > nops({x,y}) ; # on doit maintenant trouver 1 1 # nops permet de trouver le nombre de voyelles > nops({A,E,I,O,U,Y}) ; 6 # mais length aussi, avec les chaines de caractères > length("AEIOUY") ; 6 # length pour un nombre entier donne son nombre de chiffres > length(2^16) ; 5 # ce qui est plus lisible que > 2^16 ; 65536 # on aurait aussi pu utiliser > 2.0^16 ; 65536.00000 # mais attention à length pour des nombres non entiers : > length(20.6) ; # renvoie 7 ??? 7 > length(2/3) ; # renvoie 5 ??? 5 # ED est l'ensemble des entiers de 0 à 10 # D est incorrect comme variable (lettre réservée à la dérivation) # EP : les nombres pairs de ED # EI : les nombres impairs de ED > ED:={$0..10} ; ED := {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} > D:={$0..10} ; # volontairement incorrect (symbole de dérivation) Error, attempting to assign to `D` which is protected > ES:={$1..10} ; ES := {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} > EP:=select(x->type(x,even),ED) ; EP := {0, 2, 4, 6, 8, 10} > EI:=select(x->not type(x,even),ED) ; EI := {1, 3, 5, 7, 9} # pour tester si x est inclus dans y, on écrit > estinclusdans := (x,y) -> evalb(x = x intersect y) ; estinclusdans := (x, y) -> evalb(x = x intersect y) # ce qui reinvente member : member(x,y) <==> estinclusdans(x,y) # pour passer en revue toutes les inclusions, on fait une matrice de tests > L := vector(4) ; L := array(1 .. 4, []) > L[1] := ED ; L[1] := {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} > L[2] := ES ; L[2] := {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} > L[3] := EP ; L[3] := {0, 2, 4, 6, 8, 10} > L[4] := EI ; L[4] := {1, 3, 5, 7, 9} > n := linalg[vectdim](L) ; n := 4 > inclusions := matrix(n,n, (i,j) -> estinclusdans( L[i],L[j] ) ) ; [true false false false] [ ] [true true false false] inclusions := [ ] [true false true false] [ ] [true true false true ] > evalm(inclusions) ; [true false false false] [ ] [true true false false] [ ] [true false true false] [ ] [true true false true ] # les parties d'un ensemble se calculent avec powerset du "package" combinat > E := {a,b,c} ; E := {c, a, b} > combinat[powerset](E) ; {{c, a, b}, {a, b}, {c, b}, {c}, {a}, {c, a}, {b}, {}} # on aurait pu aussi écrire # # with(combinat) ; # powerset(E) ; # # mais cela charge toutes les fonctions de combinat. # décommenter l'instruction suivante pour voir 256 éléments : #combinat[powerset]( combinat[powerset](E) ) ; # exemple d'une union rendue disjointe > A := { a,b,c,d,e } ; A := {c, e, a, d, b} > B := { d,e,f,g } ; B := {e, d, f, g} > C := B minus (B \intersect A) ; C := {f, g} > evalb( (A union B)=(A union C ) ) ; true > restart ; > evalb( (A union B)=(A union ( B minus (B \intersect A)) ) ) ; false # pour vérifier que {} est l'élémen neutre de union > {} union X ; X # pour voir les jolis symboles de Maple > (X_i intersect Y_j) union Z_k ; Z_k union (X_i intersect Y_j) # on veut tester la notion de partition > restart ; # on invente les ensembles E, X1, X3, X6 et X8 > E := { $1..10 } ; E := {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} > ensX := i -> { i, i+1, i+2 } ; ensX := i -> {i, i + 2, i + 1} # F est la famille des Xi # vérifions que les éléments de E sont ceux de F # c'est à dire que F recouvre E > F := { ensX(1), ensX(3), ensX(6), ensX(8) } ; F := {{1, 2, 3}, {3, 4, 5}, {6, 7, 8}, {8, 9, 10}} > evalb( E = map( x -> op(x) , F ) ) ; true # inventons le test a est disjoint de b # c'est à dire que l'intersection des deux ensembles est vide > sontdisjoints := (a,b) -> evalb( {} = (a intersect b) ) ; sontdisjoints := (a, b) -> evalb({} = a intersect b) > n := nops(F) ; n := 4 # tentons de tester si les éléments de F sont disjoints deux à deux > lt := seq( seq( sontdisjoints ( op(i,F),op(j,F)), j=1..n), i=1..n) ; lt := false, false, true, true, false, false, true, true, true, true, false, false, true, true, false, false > foldl( `and`, true, lt) ; false # essayons avec une forme matricielle > mh := matrix( n,n, (i,j) -> if i=j then true else sontdisjoints( op(i,F), op(j,F) ) fi ) : # et non pas ; > mt := convert( convert( mh,vector), list ) ; mt := [true, false, true, true, false, true, true, true, true, true, true, false, true, true, false, true] > foldl( `and`, true, op(mt) ) ; false # faisons une fonction de tout cela > estpartition := ( X , Y ) -> > if evalb( Y = ( map( x -> op(x) , X ) ) ) > and foldl( `and`, true, seq( seq( sontdisjoints ( op(i,X),op(j,X)), j=1..nops(X)), i=1..nops(X)) ) > then print( X, "est bien une partition de ",Y ) > else print( X, "n'est pas une partition de ",Y ) > fi > ; # fin de la fonction est espartition (mais la fonction est fausse à cause des (i,i) estpartition := proc(X, Y) option operator, arrow; if evalb(Y = map(op, X)) and foldl(`and`, true, seq( seq(sontdisjoints(op(i, X), op(j, X)), j = 1 .. nops(X)), i = 1 .. nops(X))) then print(X, "est bien une partition de ", Y) else print(X, "n'est pas une partition de ", Y) end if end proc # structurons un peu mieux notre travail > recouvre := ( X , Y ) -> evalb( Y = ( map( x -> op(x) , X ) ) ) ; recouvre := (X, Y) -> evalb(Y = map(op, X)) > sontdisjoints2a2 := proc( X ) local i,j,n,mh,mt ; > n := nops(X) ; > mh := matrix( n,n, (i,j) -> if i=j then true else sontdisjoints( op(i,X), op(j,X) ) fi ) ; > mt := convert( convert( mh,vector), list ) ; > return foldl( `and`, true, op(mt) ) ; > end ; sontdisjoints2a2 := proc(X) local i, j, n, mh, mt; n := nops(X); mh := matrix(n, n, proc(i, j) option operator, arrow; if i = j then true else sontdisjoints(op(i, X), op(j, X)) end if end proc); mt := convert(convert(mh, vector), list); return foldl(`and`, true, op(mt)) end proc # du coup, estpartition est plus lisible > estpartition := ( X , Y ) -> > if recouvre( X, Y ) and sontdisjoints2a2( X ) > then print( X, "est bien une partition de ",Y ) > else print( X, "n'est pas une partition de ",Y ) > fi > ; # fin de la fonction est espartition estpartition := proc(X, Y) option operator, arrow; if recouvre(X, Y) and sontdisjoints2a2(X) then print(X, "est bien une partition de ", Y) else print(X, "n'est pas une partition de ", Y) end if end proc # appliquons nos fonctions au problème posé > E := { $1..10 } ; E := {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} > F := { ensX(1), ensX(3), ensX(6), ensX(8) } ; F := {{1, 2, 3}, {3, 4, 5}, {6, 7, 8}, {8, 9, 10}} > ens2 := ( ensX(3) union ensX(6) ) minus ( ensX(1) union ensX(8) ) ; ens2 := {4, 5, 6, 7} > G := { ensX(1), ens2 , ensX(8) } ; G := {{1, 2, 3}, {8, 9, 10}, {4, 5, 6, 7}} > estpartition( F, E ) ; {{1, 2, 3}, {3, 4, 5}, {6, 7, 8}, {8, 9, 10}}, "n'est pas une partition de ", {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} > estpartition( G, E) ; {{1, 2, 3}, {8, 9, 10}, {4, 5, 6, 7}}, "est bien une partition de ", {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} > sontdisjoints2a2( G ) ; true # en cas de problème, on peut chercher les éléments incriminés > detailleDisjonction := proc(X) local i,j,n,e1,e2; > n := nops(X) ; > print(n,X) ; > i := 1 ; > while i <= n do > e1 := op(i,X) ; > print(i,e1) ; > j := 1 ; > while j <= n do > e2 := op(j,X) ; > print(j,e2) ; > if (not i=j) then > if not sontdisjoints( e1, e2 ) then > print("les ensembles",e1,"et",e2,"situés en position",i,"et",j,"ne sont pas disjoints ") ; > j := n ; > i := n ; > return false ; > fi : > fi : > j := j + 1 ; > od : # fin tant que sur j > i := i + 1 ; > od : # fin tant que sur i > return true ; > end ; detailleDisjonction := proc(X) local i, j, n, e1, e2; n := nops(X); print(n, X); i := 1; while i <= n do e1 := op(i, X); print(i, e1); j := 1; while j <= n do e2 := op(j, X); print(j, e2); if not (i = j) then if not sontdisjoints(e1, e2) then print("les ensembles", e1, "et", e2, "situés en position", i, "et", j, "ne sont pas disjoints "); j := n; i := n; return false end if end if; j := j + 1 end do; i := i + 1 end do; return true end proc > sontdisjoints2a2( G ) ; true > sontdisjoints2a2( F ) ; false > detailleDisjonction( F ) ; 4, {{1, 2, 3}, {3, 4, 5}, {6, 7, 8}, {8, 9, 10}} 1, {1, 2, 3} 1, {1, 2, 3} 2, {3, 4, 5} "les ensembles", {1, 2, 3}, "et", {3, 4, 5}, "situés en position", 1, "et", 2, "ne sont pas disjoints " false # attention aux paramètres > recouvre(E,F) ; false > recouvre(F,E) ; true # si on hésite, il faut que le prorgrammeur # ait prévu le rappel de la syntaxe > recouvre := proc( X , Y ) ; > if nargs=0 then print(" recouvre(X,Y) renvoie vrai si X recouvre Y ") ; > else evalb( Y = ( map( x -> op(x) , X ) ) ) ; > fi ; > end ; recouvre := proc(X, Y) if nargs = 0 then print(" recouvre(X,Y) renvoie vrai si X recouvre Y ") else evalb(Y = map(op, X)) end if end proc > recouvre() ; " recouvre(X,Y) renvoie vrai si X recouvre Y " # un bon programmeur testera aussi le nombre de paramètres... # et le type des paramètres. > recouvre := proc( X , Y ) ; > if not (nargs=2) then > print(" attention : recouvre utilise exactement 2 paramètres ") ; > print(" or ici vous en avez fourni ",nargs) ; > return ; > fi : > if not type(X,set) then > print(" erreur : dans recouvre(X,Y) X doit être de type \"ensemble\"") ; > print(" or ici, X qui vaut ",X," est de type ",whattype(X)) ; > return ; > fi ; > end ; recouvre := proc(X, Y) if not (nargs = 2) then print(" attention : recouvre utilise exactement 2 paramètres "); print(" or ici vous en avez fourni ", nargs); return end if; if not type(X, set) then print(" erreur : dans recouvre(X,Y) X doit être de type "ensemble"") ; print(" or ici, X qui vaut ", X, " est de type ", whattype(X)); return end if end proc > recouvre(1) ; " attention : recouvre utilise exactement 2 paramètres " " or ici vous en avez fourni ", 1 > recouvre(1,2) ; " erreur : dans recouvre(X,Y) X doit être de type "ensemble"" " or ici, X qui vaut ", 1, " est de type ", integer # même démarche pour le problème de la hiérarchie : # on invente inclusionHierarchique puis on l'utilise # en boucle > F := [ {}, {a}, {b} , {c}, {a,b}, {a,c}, {a,b,c} ] ; F := [{}, {a}, {b}, {c}, {a, b}, {a, c}, {a, b, c}] > inclusionHierarchique := (X,Y) -> member( (X intersect Y) , { {}, X , Y } ) ; inclusionHierarchique := (X, Y) -> member(X intersect Y, {{}, X, Y}) > esthierarchie := X -> > foldl( `and`, true, > seq( seq( inclusionHierarchique( op(i,X),op(j,X)) > , j=1..nops(X)), i=1..nops(X)) ) ; esthierarchie := X -> foldl(`and`, true, seq( seq(inclusionHierarchique(op(i, X), op(j, X)), j = 1 .. nops(X)), i = 1 .. nops(X))) > esthierarchie(F) ; false # on peut alors l'appliquer au problème posé > F := { {}, {a}, {b} , {c}, {a,b}, {a,c}, {a,b,c} } ; F := {{}, {a}, {b}, {c}, {a, b}, {a, c}, {a, b, c}} > G := F minus { {a,c} } ; G := {{}, {a}, {b}, {c}, {a, b}, {a, b, c}} > esthierarchie(G) ; true # et écrire une fonction pour détailler si ce n'est pas une hiérarchie > detailleinclusionHierarchique := proc(X) local i,j,n,e1,e2; > n := nops(X) ; > print(n,X) ; > i := 1 ; > while i <= n do > e1 := op(i,X) ; > print(i,e1) ; > j := 1 ; > while j <= n do > e2 := op(j,X) ; > print(j,e2) ; > if not inclusionHierarchique( e1, e2 ) then > print("les ensembles",e1,"et",e2,"situés en position",i,"et",j,"ne sont pas en inclusion hiérarchique ") ; > print(" car leur intersection est ",e1 intersect e2) ; > j := n ; > i := n ; > return false ; > fi : > j := j + 1 ; > od : # fin tant que sur j > i := i + 1 ; > od : # fin tant que sur i > return true ; > end ; # fin detailleinclusionHierarchique detailleinclusionHierarchique := proc(X) local i, j, n, e1, e2; n := nops(X); print(n, X); i := 1; while i <= n do e1 := op(i, X); print(i, e1); j := 1; while j <= n do e2 := op(j, X); print(j, e2); if not inclusionHierarchique(e1, e2) then print("les ensembles", e1, "et", e2, "situés en position", i, "et", j, "ne sont pas en inclusion hiérarchique "); print(" car leur intersection est ", e1 intersect e2); j := n; i := n; return false end if; j := j + 1 end do; i := i + 1 end do; return true end proc > detailleinclusionHierarchique(F) ; 7, {{}, {a}, {b}, {c}, {a, b}, {a, c}, {a, b, c}} 1, {} 1, {} 2, {a} 3, {b} 4, {c} 5, {a, b} 6, {a, c} 7, {a, b, c} ... 3, {b} 4, {c} 5, {a, b} 6, {a, c} "les ensembles", {a, b}, "et", {a, c}, "situés en position", 5, "et", 6, "ne sont pas en inclusion hiérarchique " " car leur intersection est ", {a} false # en produit cartésien un peu compliqué > E := {a,b} ; n := nops(E) ; E := {a, b} n := 2 > F := combinat[powserset](E) ; p := nops(F) ; F := combinat[powserset]({a, b}) p := 1 > matrix(n,p, (i,j) -> (op(i,E), op(j,F))) ; array(1 .. 2, 1 .. 1, [ (1, 1) = (a, {a, b}) (2, 1) = (b, {a, b}) ]) > E := [a,b] ; n := nops(E) : E := [a, b] > F := combinat[powerset](E) ; p := nops(F) : F := [[], [a], [b], [a, b]] > M := [ seq( seq( [op(i,E), op(j,F)], j=1..p ),i=1..n) ] : > map( x -> print(op(x)) , M ) : a, [] a, [a] a, [b] a, [a, b] b, [] b, [a] b, [b] b, [a, b] # un exemple de point fixe > f := x -> 2*x -1/2 ; f := x -> 2 x - 1/2 > solve( f(x)=x) ; 1/2 # un calcul de limite > limit( (x-1)*(x+1)/(x^6-1),x=-1) ; 1/3 # pas de chance, on ne saura pas comment calculer la limite ! > restart ; > infolevel[limit] := 100 ; infolevel[limit] := 100 > limit( (x-1)*(x+1)/(x^6-1),x=-1) ; 1/3 # un test de commutativité > f := (x,y) -> x*y -(x+y) ; f := (x, y) -> x y - x - y > evalb( f(x,y) = f(y,x) ) ; true > quit