Introduction à la théorie des ensembles
Démonstrations
Une théorie mathématique est un ensemble d'affirmations, les assertions ou propositions vraies. Une assertion peut être admise, auquel cas on parle d'axiome ou de postulat — c'est incontournable, on ne peut pas créer une théorie ex nihilo — ou être obtenue à l'aide de règles de déductions logiques et d'autres assertions dont les axiomes. En complément de la logique propositionnelle, on enrichit le langage mathématique de symboles spécifiques à la théorie en précisant leur syntaxe et comment ils s'articulent avec la logique propositionnelle. Plus précisément, le langage de la logique des prédicats va nous permettre de construire de nouvelles propositions. Ce langage n'entre donc pas en concurrence avec celui de la logique propositionnelle mais l'enrichit.
Cette vision formaliste ne doit pas faire perdre de vue que les mathématiques seraient impraticables ou pour le moins considérablement entravées si l'on s'interdisait l'usage de la langue naturelle pour s'exprimer. Autrement dit, faire des mathématiques ne peut pas se résumer à la construction d'énoncés formels qui respectent une syntaxe stricte, à la manière d'un langage de programmation. Parler d'un entier naturel \(n\) pair n'est pas moins rigoureux que d'écrire \(n\in\N\) et que \(n\) satisfait la proprosition suivante \begin{equation} \label{eq:entierpair} \exists k\in \N\ n={\color{#FF8}2}k \end{equation} Cette proposition, — si elle n'est pas compréhensible à ce stade, elle devrait l'être à la fin de ce chapitre —, est en revanche bien plus efficace s'il faut démontrer que le carré d'un entier pair est pair. En effet, si \(n\) est pair, on dispose d'après \((\ref{eq:entierpair})\) d'un entier naturel \(k\) tel que \(n=2k\). On démontre alors que les trois implications suivantes sont vraies grâce aux propriétés du calcul en arithmétique sur \(\N\) : \begin{align*} \boxed{n={\color{#FF8}2}k}\ &\then\ n^2=({\color{#FF8}2}k)^2\\ n^2=({\color{#FF8}2}k)^2\ &\then\ n^2=4k^2\\ n^2=4k^2\ &\then\ \boxed{n^2={\color{#FF8}2}(2k^2)}. \end{align*} Et la transitivité de l'implication nous donne \[ (n={\color{#FF8}2}k)\ \then\ (n^2={\color{#FF8}2}(\underbrace{2k^2}_K)).\] En supposant que \(n=2k\), on a donc pu construire l'entier \(K:=2k^2\) tel que \(n^2=2K\), prouvant ainsi d'après la règle du modus ponens que si \(n\) est pair, son carré l'est aussi.
Le langage mathématique est un outil extrêmement puissant pour exprimer des concepts et les manipuler en les objectivants, mais les mathématiques ne peuvent être réduites à un langage, pas plus que l'informatique d'ailleurs.
On rappelle la définition introduite au chapitre précédent :
Une nouvelle assertion obtenue par déduction est appelée théorème, ou lemme si le résultat est une étape importante pour l'obtention d'un théorème, ou parfois proposition*(*) au sens de cette définition et non pas d'une formule de la logique propositionnelle., ou encore corollaire lorsqu'il s'agit d'une conséquence directe d'un théorème. Stricto sensu, chaque proposition intermédiaire obtenue dans une démonstration constitue un théorème, mais nous ne mettons en évidence que celles qui nous paraissent importantes, les autres restent dans l'anonymat.
Exemple. Considérons les deux carrés à gauche et à droite ci-dessus de mêmes côtés \(A+B\). On construit chacun des deux rectangles jaunes de la figure à droite en couplant \(2\) triangles jaunes tête-bêche de la figure à gauche. On en déduit que les aires bleues à gauche et à droite sont égales ce qui nous permet, en calculant de deux manières la surface du grand carré d'établir le théorème de Pythagore : le carré de l'hypothénuse d'un triangle rectangle est égal à la somme des carrés des autres côtés : \[H^2=A^2+B^2.\]
Cette démonstration est informelle mais justifie de manière compréhensible le résultat. Une preuve formelle utiliserait, par exemple, les outils de la géométrie cartésienne comme les vecteurs et le produit scalaire pour établir le résultat de manière algébrique.
Nous avons déjà vu trois méthodes communes qui sont utilisées pour faire une démonstration, sans qu'elles soient exclusives*(*) Exemple typique de l'effort à faire pour lever les ambiguïtés ou imprécisions de la langue naturelle. Sans cette précision, le lecteur ne sait pas si ces trois méthodes de démonstration sont les seules possibles ou non. :
Nous verrons au chapitre Combinatoire une autre méthode de démonstration appelée preuve par récurrence.
La théorie mathématique dans laquelle nous discourons, tout au moins dans ce cours, est une axiomatisation de la théorie des ensembles développée par G. Cantor à la fin du 19ème siècle, proposée par les mathématiciens allemands E. Zermelo et A. Fraenkel (abrégée en théorie ZF) pour en éliminer les paradoxes. Elle est l'aboutissement de questionnements philosophiques sur la nature du raisonnement et de la construction des ensembles qui ont culminés à la charnière du xix-ème et du xx-ème siècle. Bien entendu, les mathématiciens n'ont pas attendu le xx-ème siècle et cette théorie pour faire des démonstrations. L'apparition de contradictions et de paradoxes, conséquence de manipulations sans contraintes des ensembles infinis, a mis en péril l'édifice mathématique et a nécessité d'en fixer les règles. Pour faire une métaphore routière, conduire sur les routes sans fixer quelques règles de circulation peut aboutir à des accidents.
Cette théorie identifie tous les objets manipulés à des ensembles, nombres, fonctions, relations, vecteurs, etc. Elle fournit un nombre limité d'axiomes et de règles pour justifier leur existence ou pour les construire. Elle n'est pas la théorie des ensembles, au sens défini singulier, bien que nous emploierons souvent cette expression, mais plutôt un codage particulier et cohérent des objets qui étaient déjà utilisés en mathématiques. La plupart des axiomes expriment des propriétés qui semblent évidentes pour les ensembles tels que nous les concevons naïvement. Ils précisent dans quel cadre nous pouvons construire de nouveaux ensembles à partir de ceux que nous connaissons déjà.
L'objet de cette théorie n'est pas d'expliquer ce que sont les ensembles, mais d'établir des règles de construction afin d'éviter des paradoxes. Nous ne ferons qu'effleurer ces questions délicates dans ce cours de licence, elles seront à nouveau abordées dans un cours de calculabilité de master d'informatique. Dans la suite nous ne présenterons que les axiomes que nous utilisons intensivement, ils illustrent la démarche qui sous-tend cette théorie et dont la dimension systématique est très proche de la théorie des langages en informatique.
Ensembles
Plus prosaïquement, nous concevons un ensemble comme une collection d'objets, comme un regroupement, à la manière d'un sac de billes. Cette vision informelle est non seulement légitime mais indispensable pour élaborer nos raisonnements, il est donc exclu de la sacrifier sur l'autel du formalisme, elle est suffisante pour la licence. C'est celle du mathématicien allemand Georg Cantor qui fut l'un des pionniers sur cette question :
Les deux mots clés dans cette définition sont les mots définis et discernables. Le premier signifie que l'on doit être en mesure de dire pour tout objet s'il est un élément ou non de l'ensemble \(X\). Le second signifie que l'on doit être en mesure de distinguer les éléments d'un ensemble. Ces deux conditions expriment le fait qu'un ensemble est totalement caractérisé par ses éléments.
Les conditions définis et discernables font émerger deux relations spécifiques à la théorie des ensembles, respectivement la relation d'appartenance notée \(\in\) et la relation d'égalité notée \(=\). La proposition \(x\) est un élément de \(X\) est codée par l'expression \(x\in X\) et la proposition \(x\) est égal à \(y\) est codée \(x=y\). On écrit généralement \(x\not\in X\) au lieu de \(\neg (x\in X)\) et \(x\not= y\) au lieu de \(\neg(x=y)\). Rien n'empêche un ensemble d'être lui-même l'élément d'un autre ensemble. Si \(x\) et \(y\) satisfont \(x=y\), cela entraîne qu'ils sont synonymes, on peut échanger leurs rôles dans n'importe quelle expression mathématique sans rien changer à son interprétation.
D'autres symboles spécifiques à la théorie des ensembles sont utilisés, en particulier l'accolade ouvrante \(\{\) et l'accolade fermante \(\}\). Quand le nombre d'éléments qui définissent un ensemble \(X\) est fini — nous verrons le sens précis de la finitude dans cette théorie plus tard —, on peut le représenter par la liste de ses éléments délimités par ces deux symboles respectivement. Par exemple
\begin{align} \label{eq:ens4} X=\{1,f,3,x\}. \end{align}dont les éléments sont \(1\), \(f\), \(3\) et \(x\). Cette écriture est appelée écriture en extension de \(X\).
Comme un ensemble est entièrement déterminé par ses éléments, les répétitions éventuelles d'un même élément dans l'écriture en extension d'un ensemble sont redondantes, ainsi \[\{a,a,b,a,c\}=\{a,b,c\}.\] Un même identificateur, \(a\) dans notre exemple, ne peut pas décrire des objets différents d'un ensemble, alors que dans une interprétation physique des ensembles, on peut y ranger plusieurs exemplaires d'un même objet, comme trois stylos bic bleus par exemple, mais s'ils sont indistinguables, il ne sont pas pour autant égaux au sens mathématique. D'autre part, l'ordre dans lequel apparaissent les éléments d'un ensemble n'a aucune importance, par exemple : \[\{a,b,c\}=\{b,a,c\}=\{a,c,b\},\ \text{etc.}\]
Logique des prédicats
Prédicats et quantificateurs
Nous allons étudier la logique des prédicats, dite également logique du premier ordre, dans le cadre de la théorie des ensembles. La démarche est similaire à celle que nous avons présentée pour la logique propositionnelle, nous commençons par étudier sa syntaxe. Contrairement à la logique propositionnelle où les variables ne peuvent prendre leurs valeurs que dans l'ensemble \(\{\top,\bot\}\), les variables de la logique des prédicats peuvent prendre leurs valeurs dans des univers quelconques, en particulier dans des ensembles dans le cadre de la théorie ZF qui nous concerne ici.
Un prédicat à \(q\) variables \(x_1,x_2,\ldots,x_q\) est généralement noté de manière préfixe, c'est-à-dire \(P(x_1,x_2,\ldots,x_q)\) et on dit également que \(P\) est un prédicat \(q\)-aire. Stricto sensu, conformément à la définition ci-dessus, un prédicat contient au moins une variable, sinon il s'agit d'une proposition, mais il est commode de considérer qu'une variable propositionnelle est un prédicat d'arité \(0,\) ce qui va nous permettre d'encapsuler le langage du calcul propositionnel dans celui des prédicats.
La syntaxe des formules de la logique des prédicats hérite des règles du calcul propositionnel, mais on connecte cette fois des prédicats. Notons que si l'on se limite aux prédicats d'arité \(0\), les propositions, on retrouve le langage du calcul propositionnel. Dans le cadre de la théorie ZF on va pouvoir constituer de nouveaux prédicats en enrichissant le lexiqueavec des ensembles et des symboles spécifiques, pour commencer \(=\), \(\in\), \(\{\), et \(\}\).
On conserve la même terminologie que pour la logique propositionnelle quand on fixe la valeur d'une ou plusieurs variables d'un prédicat, il s'agit encore d'une interprétation. Notons que si une seule variable a été interprétée dans un prédicat à \(q\) variables, on dispose alors d'un prédicat à \(q-1\) variables.
La théorie des ensembles de Zermelo-Fraenkel, ou en condensé théorie zf, distingue deux types de prédicats :
Les axiomes de la théorie des ensembles élaborée par Zermelo et Fraenkel ont pour objet de fournir une famille de prédicats collectivisants suffisamment riche pour pouvoir coder tous les objets dont les mathématiciens ont besoin, mais en bridant la construction de nouveaux ensembles afin de ne pas créer de monstres générant des paradoxes. A contrario, la théorie ne dit pas quels sont les prédicats qui ne sont pas collectivisants. Sont disqualifiés de fait tous ceux dont les ensembles associés, s'ils existaient, permettraient d'en déduire une contradiction. Cantor ne faisait pas ce distinguo et son principe d'abstraction affirmait que tout prédicat définit un ensemble, ce que l'on traduirait dans le langage de la théorie ZF, en affirmant que tous les prédicats sont collectivisants. L'application de ce principe permet de construire des paradoxes, le plus célèbre d'entre eux étant probablement le paradoxe de Russel *(*) Bertrand Russel était un philosophe et mathématicien anglais et l'un des fondateurs de la logique contemporaine. Il a découvert ce paradoxe en 1901. : considérons \(P(x)\) le prédicat
\begin{equation} x\not\in x. \end{equation}Supposons que \(P(x)\) soit collectivisant en \(x\). On dispose alors de l'ensemble
\[X:=\{x\such x\not\in x\}.\]Montrons que \((X\in X)\then (X\not\in X)\). Par construction, les éléments \(x\) de l'ensemble \(X\) satisfont le prédicat \(x\not\in x\) et comme \(X\) est un élément de \(X\), lui aussi et donc \(X\not\in X\). Par conséquent la règle du modus ponens nous permet d'affirmer que si \(X\in X\) alors \(X\not\in X\) ce qui est contradictoire. Le principe de non contradiction nous oblige donc à réfuter l'hypothèse \(X\in X\), autrement dit à affirmer que \(X\not\in X\). Mais dans ce cas, l'ensemble \(X\) satisfait le prédicat \(P(x)\) et doit donc appartenir à l'ensemble \(X\) et on a de nouveau une contradiction. Voilà qui met en lumière la nécessité d'être très attentif à l'articulation entre des objets syntaxiques et l'interprétation que l'on en fait.
Deux nouveaux symboles permettent de construire des propositions à l'aide d'un prédicat \(P(x)\) et des règles syntaxiques suivantes :
En pratique, la variable \(x\) est choisie dans un ensemble \(X\), on utilise alors très souvent les deux expressions suivantes : \begin{align} \label{eq:universel} \color{white}\forall x\in X\ &{\color{white} P(x)}\ \ \text{pour coder}\ \ \forall x\ \left(x\in X\then P(x)\right),\\ \label{eq:existentiel} \color{white}\exists x\in X\ &{\color{white} P(x)}\ \ \text{pour coder}\ \ \exists x\ \left(x\in X\wedge P(x)\right). \end{align}
Quand un quantificateur précède une variable \(x\), on dit qu'elle est quantifiée ou qu'il s'agit d'une variable liée (sous-entendu à un quantificateur). Dans ce cas, on parle également de variable muette ou anonyme au sens où elle peut être remplacée partout dans l'expression par n'importe quelle autre sans en changer le sens. On peut s'en convaincre en remplaçant \(x\) par \(y\) dans les deux expressions \((\ref{eq:universel})\) et \((\ref{eq:existentiel})\). Ces deux expressions sont donc bien des propositions et pas des prédicats. Quand une variable n'est pas quantifiée elle est dite libre. Quand toutes les variables d'une formule de la logique des prédicats sont quantifiées, la formule est dite close.
Pour démontrer une proposition du type \(\forall x\in X\ \ P(x)\), on se donne un élément \(x\) quelconque de l'ensemble \(X\) et on montre que \(P(x)\) est vraie. Comme \(x\) est quelconque il symbolise n'importe quel élément de \(X\), ainsi si la proposition \(P(x)\) est vraie, elle l'est aussi pour tout autre élément de \(X\). Pour démontrer une proposition du type \(\exists x\in X\ \ P(x)\), il faut exhiber un élément particulier \(x\) de l'ensemble \(X\) tel que \(P(x)\) soit vraie, il peut d'ailleurs en exister plusieurs.
Il arrive souvent que l'on ait besoin d'exprimer l'existence d'un objet et que celui-ci est unique. On rajoute alors un point d'exclamation à la suite du quantificateur existentiel pour le signifier. La proposition \(\exists!\, x\in X\ P(x)\) est logiquement équivalente à la proposition \begin{equation} \underbrace{(\exists x\in X\ \ P(x))}_{\text{existence}}\;\wedge\;\underbrace{\Big(\forall x\in X\ \forall y\in X\ \ \big((P(x)\wedge P(y))\Rightarrow (x=y)\big)\Big)}_{\text{unicité}}. \end{equation} Le terme gauche de cette conjonction code l'existence de \(x\) et le terme droit son unicité en exprimant sous forme contraposée que deux éléments distincts \(x\) et \(y\) de l'ensemble \(X\) ne peuvent simultanément satisfaire le prédicat : \((x\neq y)\then \neg(P(x)\wedge P(y))\).
La négation des deux expressions \((\ref{eq:universel0})\) et \((\ref{eq:existentiel0})\) est conforme à celle des énoncés correspondants en langue naturelle : \begin{align*} \neg (\forall x\ P(x))&\equiv \exists x\ \neg P(x)\\ \neg (\exists x\ P(x))&\equiv \forall x\ \neg P(x) \end{align*} avec pour déclinaisons sur un ensemble \(X\) \begin{align} \label{eq:negA} \neg ({\color{orange}\forall x\in X\ P(x)})&\equiv {\color{green}\exists x\in X\ \neg P(x)}\\ \label{eq:negE} \neg ({\color{lightblue}\exists x\in X\ P(x)})&\equiv {\color{lightgreen}\forall x\in X\ \neg P(x)} \end{align}
Illustrons l'équivalence logique \((\ref{eq:negA})\) en langue naturelle en supposant que \(X\) désigne l'ensemble des étudiants qui suivent ce cours de mathématiques et \(P(x)\) le prédicat dont l'interprétation est \(P(x)\) est vrai si et seulement si l'étudiant \(x\) comprend le cours. La négation de la proposition
Ainsi, quand on veut démontrer qu'une proposition du type \(\color{orange}\forall x\in X\ \ P(X)\) est fausse, autrement dit que sa négation est vraie, il suffit d'exhiber un élément \(\color{green}x\in X\) tel que \(\color{green}\neg P(x)\), qu'on appelle un contre-exemple.
Passons à l'équivalence logique \((\ref{eq:negE})\). La négation de la proposition
Le langage mathématique ne peut laisser la place qu'à une unique interprétation. Ces différents énoncés montrent au passage que la variable \(x\) est bien muette, nous ne l'avons jamais mentionnée pour exprimer \((\ref{eq:negA})\) ou \((\ref{eq:negE})\).
Il faut donc prendre garde à l'ordre des quantificateurs et en particulier replacer les parenthèses absentes si l'on doit propager une négation comme \((\ref{eq:negA})\) ou \((\ref{eq:negE})\) pour des prédicats à plusieurs variables.
Dessinez le graphe de la fonction \(f\) définie par \(x\mapsto x^2-3\) et illustrez sur ce graphe la continuité ou non-continuité de cette fonction en \(x=2\). Faites de même avec la fonction définie par \(x\mapsto 2x\) si \(x\leq 2\) et \(x\mapsto x\) si \(x > 2\).
Quelle proposition doit satisfaire une fonction \(f:\R\rightarrow\R\) pour qu'elle soit simplement continue en tout point \(x\in\R\) ?
Une fonction \(f:\R\rightarrow\R\) est uniformément continue sur \(\R\) si elle satisfait la proposition :
\begin{equation} \label{eq:continuiteuniforme} \forall\varepsilon>0\quad\exists\delta>0\quad\forall x\in \R\quad\forall y\in \R\quad |x-y|<\delta\Rightarrow |f(x)-f(y)|<\varepsilon. \end{equation} Quelle différence remarquez-vous entre la proposition de continuité simple en tout réel et la proposition de continuité uniforme ?Écrivez la négation des deux propositions (\ref{eq:continuitesimple}) et (\ref{eq:continuiteuniforme}).
Axiomes
Nous allons à présent introduire la terminologie de base de la théorie des ensembles et définir pas-à-pas les opérations élémentaires sur les ensembles. On commence par l'inclusion.
On note \(X\not\subseteq Y\) plutôt que \(\neg(X\subseteq Y)\). Dans l'assertion \(X\) est une partie de \(Y\), il n'y a plus mention de la variable \(x\) de la proposition \((\ref{eq:inclusion})\), elle est donc bien muette. L'axiome d'extension dit que deux ensembles sont égaux si et seulement s'ils ont exactement les mêmes éléments :
C'est cet axiome que l'on applique quand on veut démontrer que deux ensembles \(X\) et \(Y\) sont égaux, on démontre la double inclusion. Cela consiste à se donner un élément quelconque \(x\in X\) et à démontrer qu'il appartient à l'ensemble \(Y\), puis à démontrer la réciproque.
Si l'on dispose de deux objets \(a\) et \(b\), l'axiome de la paire permet de considérer l'ensemble constitué de ces deux objets.Dans le cas où \(a=b\), la paire \(\{a,b\}\) est réduite à \(\{a\}\), on l'appelle singleton \(a\). L'axiome de la paire nous permet de considérer un ensemble avec deux objets et c'est grâce à cet axiome et à l'axiome de réunion plus loin, que l'on peut définir l'écriture en extension d'un ensemble.
L'axiome de sélection (ou axiome de compréhension ou encore axiome de séparation) est déjà bien connu du lecteur après le cours de mathématiques générales, il est utilisé en permanence. C'est la restriction du principe d'abstraction de Cantor, tout prédicat \(P(x)\) définit un ensemble, à condition que les objets \(x\) qui vérifient \(P(x)\) soient sélectionnés dans un ensemble pré­existant :
On peut donc collecter les éléments d'un ensemble \(X\) qui satisfont un prédicat quelconque \(P(x)\). Il est clair qu'il s'agit d'un sous-ensemble de \(X\) et que cet axiome ne permet donc pas de créer un ensemble trop gros si \(X\) a été construit conformément à la théorie. L'écriture \((\ref{eq:compr})\) d'un ensemble est dite écriture en compréhension de l'ensemble.
A = [n for n in range(10) if n % 2 == 0]En notant \(X=\{0,1,2,3,4,5,6,7,8,9\}\) et \(P(n)\) le prédicat \(\exists k\in\N\ n=2k\), la construction de la liste \(A\) des nombres entiers de \(X\) qui sont pairs en Python ci-dessus correspond à la construction de l'ensemble \(A=\{n\in X\such \exists k\in\N\ n=2k\}\) grâce à l'axiome de sélection.
L'axiome de la réunion permet de collecter tous les éléments des différents ensembles qui appartiennent à un ensemble donné :
Quand l'ensemble \(X=\{A,B\}\) est une paire d'ensembles, sa réunion est notée \(A\cup B\). C'est grâce à l'axiome de la réunion et à l'axiome de la paire que l'on a pu construire l'ensemble \((\ref{eq:ens4})\), c'est la réunion des paires \(\{1,f\}\) et \(\{3,x\}\). La réunion de l'ensemble \(\{\{a\},\{a,b,d\},\{a,c\},\{b,d\}\}\) est l'ensemble \(\{a,b,c,d\}\).
Exemples : \(X\setminus X=\varnothing\) et \(X\setminus\varnothing=X\) ou encore \(\{a,b\}\setminus\{a\}=\{b\}\).
Deux ensembles \(X\) et \(Y\) dont l'intersection \(X\cap Y=\varnothing\) est vide sont dits disjoints. En particulier l'ensemble vide est disjoint de tout ensemble \(X\). On note parfois la réunion de deux ensembles disjoints \(A\sqcup B\). L'intersection d'un ensemble d'ensembles à la manière de la réunion d'un ensemble sera définie au chapitre prochain. La différence symétrique entre deux ensembles \(X\) et \(Y\) est l'ensemble \((X\cup Y)\setminus(X\cap Y)\), on le note \(X\;\Delta\;Y\).
Pour aider à la compréhension, on représente parfois les opérations ensemblistes à l'aide d'un diagramme de Venn.*(*) John Venn était un mathématicien anglais du début du 20-ème siècle Les ensembles sont représentés sous forme de cercles ou de patates qui se chevauchent. Vous pouvez visualiser le résultat des différentes opérations ensemblistes en les survolant ci-dessous :
L'axiome des parties permet de considérer l'ensemble dont les éléments sont tous les sous-ensembles de \(X\). Nous verrons au chapitre Combinatoire qu'il est considérablement plus grand que \(X\).
L'ensemble vide est une partie de tout ensemble \(X\) puisque \(x\in\varnothing\then x\in X\) est une proposition vraie puisque \(x\in\varnothing\) est fausse. Un ensemble est bien sûr inclus dans lui-même, par conséquent l'ensemble des parties d'un ensemble \(X\) contient toujours la partie vide \(\varnothing\) et l'ensemble \(X\). Par exemple si \(X=\{a,b,c\}\), on a \[\P(X)=\{\varnothing,\{a\},\{b\},\{c\},\{a,b\},\{a,c\},\{b,c\},X\}.\] D'autre part, l'ensemble des parties de l'ensemble vide \(\P(\varnothing)=\{\varnothing\}\) qui n'est pas l'ensemble vide puisqu'il contient l'élément \(\varnothing\).
L'ordre dans lequel nous écrivons les éléments d'un ensemble en extension n'a pas d'importance, la paire \(\{x,y\}\) est donc égale à la paire \(\{y,x\}\). Comment définir un nouvel objet mathématique similaire à une paire mais pour lequel l'ordre dans lequel on écrit les deux objets a une importance ? On admettra le résultat suivant.
Le premier (resp. deuxième) terme d'un couple \(c=(x,y)\) s'appelle la première projection (resp. deuxième projection) du couple \(c\), on la note \(\text{pr}_1(c)\) (resp. \(\text{pr}_2(c)\)).
Il est aisé de vérifier que deux couples sont égaux si et seulement si leurs projections respectives sont égales. (cf. exercice suivant), ce qui répond à notre besoin. On peut bien sûr imaginer d'autres constructions ensemblistes pour ce faire. Il faut être conscient qu'il ne s'agit ici que d'un simple codage et que maintenant que ce nouvel objet est dans notre arsenal, on peut oublier l'échaffaudage qui a permis sa construction.
On peut facilement généraliser la notion de couple à la notion de \(n\)-uplet \((x_1,x_2,\ldots,x_n)\) en posant*(*) Nous verrons au chapitre 3 la définition de l'écriture indicielle \(x_i\) parachutée par endroit depuis le début de ce cours. \begin{equation} (x_1,x_2,\ldots,x_n):=\{\{x_1\},\{x_1,x_2\},\ldots,\{x_1,x_2,\ldots,x_n\}\}. \end{equation} en utilisant inductivement l'axiome de la paire et l'axiome de la réunion puis en définissant le produit cartésien de \(n\) ensembles \(X_1, X_2,\ldots,X_n\) par \begin{equation} X_1\times X_2\times\cdots\times X_n:=\{(x_1,x_2,\ldots,x_n)\such \forall i\in\{1,\ldots,n\}\ x_i\in X_i\}. \end{equation} On définit alors la \(i\)-ème projection \(\text{pr}_i\) pour tout \(i\in\{1,\ldots,n\}\) et un ensemble \(G\) de \(n\)-uplets est qualifié de \(n\)-graphe.
Cette ingénieuse construction assure que chaque ensemble est contenu dans le suivant, mimant ainsi grâce à l'inclusion \(\subseteq\) ensembliste l'ordre naturel sur les entiers \(\leq\). On identifie l'ensemble vide à \(0\) et chaque nouvel ensemble construit au nombre entier suivant (c'est le cardinal de l'ensemble en question). On code ainsi les entiers naturels tels qu'on les connaissait avant la théorie des ensembles les uns après les autres. Cette construction (ou plutôt ce codage) des entiers naturels est due au mathématicien John Von Neumann. L'axiome de l'infini assure que l'ensemble de tous ces ensembles existe, autrement dit que l'ensemble \(\N\) existe. Nous le retrouverons au chapitre Combinatoire.
Un dernier axiome, et nous achèverons là cette introduction à la théorie des ensembles, l'axiome du choix. Cet axiome nous autorise à extraire un élément de notre choix de chaque ensemble d'une famille d'ensembles pour en faire un ensemble, une sorte de menu à la carte. Cet axiome peut être intégré ou non dans la théorie des ensembles, si c'est le cas elle est appelée théorie zfc.
Considérons l'énoncé suivant : \(f\) est une application constante de l'ensemble des réels dans lui-même. On peut l'exprimer plus formellement par L'application \(f\in\R^{\R}\) vérifie la proposition \(\forall (x_1,x_2)\in\R\times\R\ \ f(x_1)=f(x_2)\), que l'on condense parfois en
\begin{equation} \label{eq:marmite0} f\in\R^\R:\quad \forall (x_1,x_2)\in\R\times\R\quad f(x_1)=f(x_2). \end{equation}On peut écrire une proposition équivalente à celle qui apparaît dans l'énoncé \((\ref{eq:marmite0})\) : \begin{equation} \label{eq:marmite} {\color{#88F}\exists c\in\R}\ \ {\color{orange}\forall x\in\R}\quad f(x)=c. \end{equation} Attention la proposition \((\ref{eq:marmite})\) n'est pas logiquement équivalente à la proposition \begin{equation} \label{eq:marmite2} {\color{orange}\forall x\in\R}\ \ {\color{#88F}\exists c\in\R}\quad f(x)=c. \end{equation} La métaphore suivante devrait aider à le comprendre. Considérons l'expression française Toute marmite a son couvercle. En notant \(M\) l'ensemble des marmites, \(C\) l'ensemble des couvercles et \(P(m,c)\) le prédicat à deux variables dont l'interprétation est \(P(m,c)\) est vrai si et seulement si le couvercle \(m\) est adapté à la marmite \(m\), on aurait une proposition similaire à la proposition \((\ref{eq:marmite2})\) : \begin{equation*} {\color{orange}\forall m\in M}\ \ {\color{#88F}\exists c\in C}\quad P(m,c). \end{equation*} Il est évident que le couvercle \(c\) dépend de la marmite \(m\) considérée. En permutant les quantificateurs, la proposition \begin{equation*} {\color{#88F}\exists c\in C}\ \ {\color{orange}\forall m\in M}\quad P(m,c). \end{equation*} exprime qu'il existe un couvercle pour toutes les marmites ce qui n'est bien sûr pas la même chose.
La proposition \((\ref{eq:marmite2})\) exprime que tout nombre réel \(x\) admet une image \(c\) dans \(\R\) pour \(f\). Il s'agit là d'une tautologie, puisque cette proposition est satisfaite par toute application par définition.
Pour une définition d'un nouvel objet mathématique, on commence par établir la liste des objets (les ingrédients) qui entrent en jeu dans sa composition que l'on complète souvent par une proposition qui doit être satisfaite par cette construction.
Pour un théorème, on commence par la liste des objets invoqués dans une proposition appelée hypothèse, que ces objets sont supposés satisfaire, puis on fournit la conclusion qui est une nouvelle proposition que ces objets satisfont comme conséquence de l'hypothèse.
Formalisation du Sudoku
Le calcul des prédicats permet de modéliser certains problèmes de manière bien plus simple que le calcul propositionnel. Considérons le problème du Sudoku. C'est un jeu solitaire qui consiste à compléter une grille de \(9\times 9\) cases réparties en 9 régions carrées \(3\times 3\) par des nombres compris entre 1 et 9 en respectant certaines règles :
La grille ci-dessous contient 26 indices, il faut compléter les autres cases.
7 | 4 | 3 | ||||||
3 | 8 | |||||||
5 | 6 | |||||||
3 | 4 | |||||||
9 | 4 | 1 | 2 | 3 | 5 | |||
6 | 9 | |||||||
5 | 8 | 7 | ||||||
5 | 3 | 9 | ||||||
4 | 5 | 8 |
La formalisation du problème du Sudoku se fait avec un langage adapté. Les constantes sont les 9 valeurs de l'ensemble \({\mathscr C}:=\{1,2,3,\ldots,9\}\) et on considère des prédicats \(S(l,c,n)\) à trois variables dans l'ensemble \(\def\CC{{\mathscr C}}\CC\) avec l'interprétation suivante : \(S(l,c,n)\) est vrai si et seulement si la case à la ligne d'indice \(l\) et à la colonne d'indice \(c\) contient la valeur \(n\). C'est bien plus économique que la logique propositionnelle avec laquelle il aurait fallu définir une variable propositionnelle pour chaque valeur possible dans chaque case, soit \(9\times 9\times 9=729\) variables.
On traduit le fait que chaque case contient exactement une valeur par les deux propositions suivantes (la première pour exprimer au moins une valeur, la seconde pour au plus une valeur) :
\begin{align*} &{\color{#88F}\forall (l,c)}\in\CC^2\ {\color{orange}\exists n}\in\CC\quad S(l,c,n),\\ &{\color{#88F}\forall (l,c)}\in\CC^2\ {\color{#FF8}\forall(n,n')}\in\CC^2\quad S(l,c,n)\wedge S(l,c,n')\then {\color{#FF8}n=n'}. \end{align*}La partie des règles R1 et R2 disant que chaque nombre apparaît une seule fois par ligne et par colonne s'exprime respectivement par les deux propositions suivantes :
\begin{align*} &\forall n\in\CC\ \forall l\in\CC\ \forall(c,c')\in\CC^2\quad S(l,c,n)\wedge S(l,c',n)\then c=c',\\ &\forall n\in\CC\ \forall c\in\CC\ \forall (l,l')\in\CC^2\quad S(l,c,n)\wedge S(l,c,n)\then l=l'. \end{align*}Pour la partie de la règle R3 disant que chaque nombre apparaît au plus une fois par région, c'est un peu plus compliqué puisque les régions sont moins faciles à mettre en évidence. On peut régler ce problème de bien des manières. Par exemple en introduisant une fonction \(r:\CC^2\rightarrow\CC\) qui à chaque couple \((l,c)\) associe le numéro de la région où se trouve la case à la ligne \(l\) et à la colonne \(c\), en numérotant les régions de \(1\) à \(9\) dans l'ordre de lecture par exemple. On aurait alors \begin{align*} &\forall (l,l',c,c',n)\in\CC^5\quad S(l,c,n)\wedge S(l',c',n)\wedge r(l,c)=r(l',c')\then (l,c)=(l',c'). \end{align*}
Chacun des 26 indices se traduit par une instanciation \(S(l,c,n) = V\) pour la valeur \(n\) affectée à la ligne \(l\) et la colonne \(c\), par exemple ici \(S(2,3,8)=V\).
Travaux pratiques
L'objectif de ces travaux pratiques est de réaliser un script qui lit une grille de Sudoku codée dans un fichier texte et tente de la compléter. Les indices dans la grille sont codés par les caractères 1 à 9 et les cases vides dont les valeurs sont à découvrir sont codées par le symbole point. Cliquez pour télécharger ce fichier exemple dans le répertoire où vous écrirez votre script.
Pour lire le contenu d'un fichier, il faut tout d'abord créer un fichier logique en l'associant à un fichier physique pour une lecture (read). C'est la fonction open qui réalise cette opération. Le nom du fichier et le mode d'accès à ce fichier (ici en lecture) sont codés par des chaînes de caractères. On récupère ensuite très facilement le contenu du fichier en créant la liste des chaînes de caractères constituées par chacune des lignes du fichier, grâce à la méthode readlines(), puis on ferme le fichier avec la méthode close() (en réalité, on indique au système que l'accès à ce fichier est à nouveau libre).
fichier = open("nom_du_fichier","r") liste = fichier.readlines() fichier.close()
On découpe une chaîne de caractères chaine suivant un séparateur sep (une chaîne de caractère également, par défaut un espace) grâce à la méthode split(sep) (chaine.split(sep)) qui renvoie la liste des sous-chaînes séparées par la chaîne sep. Par exemple, l'exécution des instructions
chaine = "maths:en:folie" print(chaine.split(":"))affichera la liste
["maths","en","folie"]
En séance
Compléments hors séance