Aula 9: Bifurcações II / 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.
|
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:
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
|
|
|
|
|
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 |
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.