Booléens et expressions booléennes ================================== En informatique, et tout particulièrement en programmation, on a fréquemment besoin de savoir si une condition est vérifiée (vraie) ou non (fausse) pour définir les traitements appropriés (cf. cours précédent sur les instructions conditionnelles). Par exemple : - La valeur de la variable ``x`` est-elle négative ? - La valeur de la variable ``x`` est-elle supérieure à celle de la variable ``y`` ? En mathématiques, certaines fonctions sont définies en fonction de différentes conditions. C’est le cas par exemple de la fonction **factorielle** dont la définition est la suivante : - :math:`n! = 1` si :math:`n = 0` - :math:`n! = n \times (n-1)!` si :math:`n \gt 0` Les **booléens** (ou **expressions booléennes**, ou **expressions logiques**) ont été introduits par le mathématicien Georges Boole (1815-1864) pour manipuler ces expressions qui sont soit vraies soit fausses. La partie des mathématiques qui traite des différentes opérations et fonctions sur les booléens s’appelle l’\ **algèbre de Boole**. Elle est très utilisée en électronique, informatique et logique. Expression booléenne en Python (notion de **prédicat**) ------------------------------------------------------- En Python, une expression booléenne simple est appelée un **prédicat**. Un prédicat est un opérateur ou une fonction dont le résultat peut avoir deux valeurs possibles : soit ``True`` (vrai) soit ``False`` (faux). Voici quelques exemples de prédicats : - ``6 < 7`` (dont la valeur est ``True``) - ``3.14 == 12.5`` (dont la valeur est ``False``) - ``"c" in "où est ma clé usb ?"`` (dont la valeur est ``True``) Les prédicats usuels en Python ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ En Python, les prédicats usuels peuvent être définis à l’aide des opérateurs de comparaison. Dans ce cas, leur forme générale est ``exp1 opcomp exp2`` où : - ``exp1`` et ``exp2`` sont des expressions numériques ou des chaînes - ``opcomp`` est un opérateur de comparaison tel que  : - ``<`` : infériorité stricte - ``>`` : supériorité stricte - ``<=`` : l’infériorité - ``>=`` : la supériorité - ``==`` : l’égalité - ``!=`` : la différence Ils peuvent également être définis avec le test d’appartenance ``in``. Dans ce cas, leur forme générale est ``objet in sequ_ens_dict`` où : - ``objet`` est un objet ou une variable référençant un objet - ``seq_ens_dict`` est soit une séquence (chaîne, liste, tuple), soit un ensemble, soit un dictionnaire (notion abordée plus tard dans ce cours). Un prédicat peut être utilisé comme condition dans une instruction conditionnelle ``if``. La valeur du prédicat indique alors si la condition est vérifiée (valeur du prédicat à ``True``) ou pas (valeur du prédicat à ``False``). Les opérateurs booléens ~~~~~~~~~~~~~~~~~~~~~~~ Les **opérateurs booléens** permettent d’effectuer des calculs sur les prédicats. Le résultat d’un opérateur booléen est une valeur booléenne (``True`` ou ``False``). En Python, il existe trois opérateurs booléens : le ``and``, le ``or`` et le ``not``. L’opérateur ``and`` ^^^^^^^^^^^^^^^^^^^ L’opérateur ``and`` est un opérateur binaire également appelé le **et logique** ou la **conjonction**. Sa forme générale est ``p1 and p2`` où ``p1`` et ``p2`` sont des prédicats. Il est commutatif. Son résultat est vrai si et seulement si les valeurs des deux prédicats ``p1`` et ``p2`` sont vraies, comme on peut le constater sur la table de vérité ci-dessous. ===== ===== ========= p1 p2 p1 and p2 ===== ===== ========= True True True True False False False True False False False False ===== ===== ========= L’opérateur ``or`` ^^^^^^^^^^^^^^^^^^ L’opérateur ``or`` est un opérateur binaire également appelé le **ou logique** ou la **disjonction**. Sa forme générale est ``p1 or p2`` où ``p1`` et ``p2`` sont des prédicats. Il est commutatif. Son résultat est vrai lorsque au moins l’un des deux prédicats (``p1`` ou ``p2``) est vrai, comme on peut le constater sur la table de vérité ci-dessous. ===== ===== ======== p1 p2 p1 or p2 ===== ===== ======== True True True True False True False True True False False False ===== ===== ======== L’opérateur ``not`` ^^^^^^^^^^^^^^^^^^^ L’opérateur ``not`` est un opérateur unaire également appelé le **non logique** ou la **négation**. Sa forme générale est ``not p1`` où ``p1`` est un prédicat. Son résultat est vrai lorsque ``p1`` est faux et faux lorsque ``p1`` est vrai, comme on peut le constater sur la table de vérité ci-dessous. ===== ====== p1 not p1 ===== ====== True False False True ===== ====== Négations de prédicats usuels en Python ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Le tableau ci-dessous présente les négations de prédicats usuels formés à l’aide des opérateurs de comparaison. ========== ========== p1 not p1 ========== ========== ``a == 3`` ``a != 3`` ``b != 2`` ``b == 2`` ``x <= y`` ``x > y`` ``x >= y`` ``x < y`` ``x > y`` ``x <= y`` ``x < y`` ``x >= y`` ========== ========== Les lois de **De Morgan** ------------------------- Les lois de De Morgan ont été formulées par le mathématicien britannique Augustus De Morgan (1806-1871). Elles définissent les équivalences existant entre des expressions booléennes. Première loi ~~~~~~~~~~~~ Selon la première loi, **la négation de la conjonction (et logique) de deux prédicats est équivalente à la disjonction (ou logique) des négations des deux prédicats**. En utilisant les opérateurs booléens, cette loi peut s’énoncer de la manière suivante : not (P1 and P2) :math:`\Leftrightarrow` (not P1) or (not P2). En français, cela signifie que « nier l’existence simultanée de P1 et P2, c’est nier P1 ou nier P2 ». Prenons un exemple concret pour illustrer cette loi. Soit l’énoncé suivant : « Dire que x n’est pas divisible par 2 et par 3 équivaut à dire que soit x n’est pas divisible par 2, soit x n’est pas divisible par 3 ». Cet énoncé semble correct a priori, mais vérifions-le à l’aide de la première loi. Transformons tout d’abord l’énoncé « x n’est pas divisible par 2 et par 3 » en une expression booléenne en langage Python. Nous obtenons : ``not ((x % 2 == 0) and (x % 3 == 0))`` En appliquant la loi de De Morgan précédente, nous obtenons l’énoncé équivalent : ``(not (x % 2 == 0)) or (not (x % 3 == 0))`` Que nous dit cet énoncé ? Que « soit x n’est pas divisible par 2, soit x n’est pas divisible par 3 ». CQFD. Seconde loi ~~~~~~~~~~~ Selon la seconde loi, **la négation de la disjonction (ou logique) de deux prédicats est équivalente à la conjonction (et logique) des négations des deux prédicats**. En utilisant les opérateurs booléens, cette loi peut s’énoncer de la manière suivante : not (P1 or P2) :math:`\Leftrightarrow` (not P1) and (not P2). En français, cela signifie que « nier l’existence de P1 ou P2, c’est nier à la fois P1 et P2 ». Prenons un exemple concret pour illustrer cette loi. Soit l’énoncé suivant : « Dire que x n’est pas égal à 1 ou à -1 équivaut à dire que x n’est égal ni à 1 ni à -1 ». Cet énoncé semble correct a priori, mais vérifions-le à l’aide de la seconde loi. Transformons tout d’abord l’énoncé « x n’est pas égal à 1 ou à -1 » en une expression booléenne en langage Python. Nous obtenons : ``not ((x == 1) or (x == -1))`` En appliquant la loi de De Morgan précédente, nous obtenons l’énoncé équivalent : ``(not (x == 1)) and (not (x == -1))`` Que nous dit cet énoncé ? Que « x n’est égal ni à 1 ni à -1 ». CQFD.