Aula 9: Bifurcações II / Boolean Algebra



Traduzido pelo Peter Stallinga

Boolean Algebra

George Boole (1815-1864)

Matemático Inglês. A sua obra "The mathematical analysis of logic"  (A análise matemática do lógico) (1847) estabeleceu a base do lógico matemático moderno, e a sua algebra Boolean pode ser usado para desenhar computadores modernos.
O sistema de Boole é essencialmente bi-valored. Isto pode ser representado por
0     ou   1   "representação binária"
VERDADE  ou FALSA  "representação verdade"
0 V   ou  5 V   "Electrónica TTL (transistor-transistor logic)"
0 pC  ou  1 pC  (pC = pico-Coulomb)  "a carga num condensador, a unidade elementária na RAM (dinâmica)"
 

Na aula anterior (aula 8) vimos como a controlar a corrente de um programa atravês as instruções if ... then e if ... then ... else. Usamos condições como (x<1.0). Agora, imagine usamos isto num cálculo do raiz de (x2 - 4). Obviamente, não existe soluções quando x fica entre -2 e +2. Seria útil verificar se x fica neste intervalo. Uma solução poderia ser
  if (x<2) then
    if (x>-2) then
      WriteLn('Error');
Mais bonito seria fazer isto numa só condição única. Então é possível com
  if ((x<2) AND (x>-2)) then WriteLn('Error');
o que, obviamente, significa que ambas as condições (x<2 e x>-2) devem ser satisfazadas para tornar a condição inteira verdade.
Isto é um exemplo do cálculo Boolean
  condition3 := condition1 AND condition2;
  if condition3 then instruction;
Outros operadores de algebra Boolean usados em PASCAL são OR and XOR. (Outras não implementados incluem NAND and NOR). A função dos operadores  AND e OR é obvio. O operador XOR é um pouco mais complicado:  (a XOR b) significa "a ou b verdade, mas não ambas!"
O último operador Boolean implementado em PASCAL é o invertador NOT. (NOT a) retorne o contrário do a: se a for TRUE, (NOT a)é FALSE, e se a for FALSE, (NOT a)é TRUE. Nota que, enquanto AND, OR and XOR levam dois operandos (por examplo a XOR b), NOT leva só um (NOT a).
Com estes quatro operadores podemos calcular qualquer condição necessário.

Resumindo: Aqui estão as tabelas de verdade ("truth tables") dos operadores Boolean das linguagens modernas de programação:
 
 Boolean operador 
AND
OR
XOR
NOT
AND
a
b
 a AND b 
TRUE
TRUE
TRUE
TRUE
 FALSE 
FALSE
 FALSE 
TRUE
FALSE
 FALSE 
FALSE
FALSE
OR
a
b
a OR b
TRUE
TRUE
TRUE
TRUE
FALSE
TRUE
FALSE
TRUE
TRUE
 FALSE 
 FALSE 
 FALSE 
XOR
a
b
 a XOR b 
TRUE
TRUE
FALSE
TRUE
FALSE
TRUE
FALSE
TRUE
TRUE
 FALSE 
 FALSE 
 FALSE 

NOT
a
NOT a
TRUE
 FALSE 
 FALSE 
TRUE


Exemplos:

a := 1;
b := -2;
c := 3;
d := 3;

if (a>0) then
  WriteLn('VERDADE')
else
  WriteLn('FALSA');

(a>0)                     VERDADE
(b>0)                     FALSA
(a>0) AND (b>0)           FALSA
(a>0) OR (b>0)            VERDADE
(a>0) XOR (b>0)           VERDADE
NOT (a>0)                 FALSA
(NOT (a>0)) OR (b>0)      FALSA
(2=b) OR (NOT (2=b))      VERDADE
(NOT (c>0)) XOR (d>0)     VERDADE


Boolean algebra para números inteiros

Podemos também aplicar as regras da Bolean algebra aos números inteiros (byte, word, integer, longint, veja aula 5). Embora de ser fora da idea original de Boole, podemos fazer os mesmos cálculos com os números, desde que fazemos isso "one bit at a time" e usamos a convenção "1 = TRUE" e "0 = FALSE". Com esta convenção, as tabelas de verdade para cálculos Boolean tipo bit tornam-se.
AND
   a
   b
 a AND b 
1
1
1
1
 0
0
 0
1
0
 0
0
0
OR
   a 
   b 
 a OR b 
1
1
1
1
0
1
0
1
1
 0
 0
 0
XOR
   a 
   b 
 a XOR b 
1
1
0
1
0
1
0
1
1
 0
 0
 0
NOT
   a 
 NOT a 
1
0
0
1
49 = 
1 1 0 0 0 1  
24 = 
0 1 1 0 0 0  
  49 OR 24 = 
1 1 1 0 0 1  = 57 
Un exemplo, imagine queremos calcular 49 OR 24
Ao primeiro temos de converter os números ao sistema binário (veja aula 3):
  49 = 1*32 + 1*16 + 0*8 + 0*4 + 0*2 + 1*1 = 110001
  24 = 0*32 + 1*16 + 1*8 + 0*4 + 0*2 + 0*1 = 011000
Depois fazemos os cálculos (um bit por vez) com a convenção mencionada acima (1 OR 1 = 1, 1 OR 0 = 1, 0 OR 1 = 1, 0 OR 0 = 0), resultado: 111001
Este resultado deve ser convertido ao sistemo decimal system:
  111001 = 1*32 + 1*16 + 1*8 + 0*4 + 0*2 + 1*1 = 57


Bifurcações multiplas: Case ... Of

Na aula anterior (veja aula 8) usamos a instrução if ... then para escolher entre os dois ramos do nosso programa. Às vezes queremos que existe mais do que duas possibilidades a continuar o programa. Por isso existe a instrução Case ... Of.
Imagine o programa seguinte pede o utilizador (o aluno) o ano ao qual ele pertence:

  PROGRAM Years;

  VAR ano: integer;

  begin
    WriteLn('From what year are you?');
    ReadLn(ano);
    if (ano=1) then
      writeln('primeiro ano: MAT-1, CALC-1')
    else
      if (ano=2) then
        writeln('segundo ano: INF, LIN-ALG')
      else
        if (ano=3) then
          writeln('terceiro ano: ELEC, FYS')
        else
          if (ano=4) then
            writeln('quarto ano: QUI, MAT-2')
          else
            if (ano=5) then
              writeln('quinto ano: PROJECTO')
            else
              writeln('>5: AINDA NAO ACABOU?');
  end.

(Nota a estrutura do programa, com indentações. Também nota que nçã há ; antes cada else).
O programal correrá sem problemas
From what year are you?
 1
primeiro ano: MAT-1, CALC-1

From what year are you?
 4
quarto ano: QUI, MAT-2

No entanto, a estrutura do programa não fica bem legível. Para melhorizar-lhe, usamos a estrutura Case ... Of.
 

 Case expression of
   value1: instruction1; 
   value2: instruction2;
          |
   valueN: instructionN;
   else instructionE;
 end;

Enquanto que em "if condition then instruction1" a condição é necessariamente do tipo boolean (TRUE ou FALSE), em Case ... Of podemos usar qualquer expressão que dá um valor do tipo "contável", ou seja qualquer tipo de valores discretos (por exemplo: integer, byte, mas também char. No outro lado, os string e real não tomam valores discretos e por isso são proíbidos nas estruturas Case ... Of). Os valores value1 ... valueN devem ser do mesmo tipo.
O mesmo programa acima, agora usando a estrutura case ... of:

  PROGRAM Years;

  VAR ano: integer;

  begin
    WriteLn('From what year are you?');
    ReadLn(ano);
    Case ano of
      1: writeln('primeiro ano: MAT-1, CALC-1');
      2: writeln('segundo ano: INF, LIN-ALG');
      3: writeln('terceiro ano: ELEC, FYS');
      4: writeln('quarto ano: QUI, MAT-2');
      5: writeln('quinto ano: PROJECTO')
      else writeln('>5: AINDA NAO ACABOU?');
    end;
  end.

O output do programa será igual, mas agora fica mais legível.

Aula 9:    (2=B) OR (NOT (2=B)) 

Quick test:

Para testar o seu conhecimento sobre aquilo que aprendeu nesta lição, click aqui para um teste on-line. Nota que esta não á a forma do teste final!

Peter Stallinga. Universidade do Algarve, 11 março 2002