Notes and Talks/UJEP/PRG1/05

Podmínky, cykly, indexace, řetězce …

Logické výrazy (~ výrokové formy)

Jsou operace s hodnotami typu bool: False a True.

Logické operace jsou:

Precedence (přednost) těchto operátorů je not >> and >> or.

Tyto operace lze popsat pravdivostními tabulkami ( F=False, T=True):

| a | b | a and b
| F | F | F
| F | T | F
| T | F | F
| T | T | T
| a | b | a or b
| F | F | F
| F | T | T
| T | F | T
| T | T | T
| a | not a
| F | T
| T | F

Úloha:

Napište program, který vypočítá a vypíše výše uvedené pravdivostní tabulky.

Možná řešení:

Jednoduchá verze pro dvě vstupní hodnoty:

pythonprint('and')
for a in [False, True]:
  for b in [False, True]:
    print(a, b, a and b)

print()

print('or')
for a in [False, True]:
  for b in [False, True]:
    print(a, b, a or b)

print()

print('not')
for a in [False, True]:
  print(a, not a)

Pro tři vstupní hodnoty, lépe formátované:

python# převod hodnoty na 'T'/'F' pro lepší čitelnost
def ft(val):
  return 'T' if val else 'F'

print('** and **')
for a in [False, True]:
  for b in [False, True]:
    for c in [False, True]:
      print(ft(a), ft(b), ft(c), '|', ft(a and b and c))

DRY:

pythondef ft(val):
  return 'T' if val else 'F'

vals = [False, True] # <<< TOTO

print('** and **')
for a in vals:
  for b in vals:
    for c in vals:
      print(ft(a), ft(b), ft(c), '|', ft(a and b and c))

Ještě lépe pomocí znaků pro kreslení rámečků:

pythondef ft(val):
  return 'T' if val else 'F'

vals = [False, True]

print('┌───────────┐')
print('│ a b c : * │')
print('├───────────┤')

for a in vals:
  for b in vals:
    for c in vals:
      print('│', ft(a), ft(b), ft(c), ':', ft(a and b and c), '│')

print('└───────────┘')

Nebo pomocí int:

pythonprint('a b c | y')
print('------+--')

vals = [0, 1]

for a in vals:
  for b in vals:
    for c in vals:
      print(a, b, c, '|', a and b and c)

Při použití int, výsledek not je nutno převést zpět na int:

pythonprint('a | not a')
print('--+------')

vals = [0, 1]

for a in vals:
  print(a, '|', int(not a), not a)

Další logické operace

Další logické operace jsou např. implikace (jestliže a, pak b) a exkluzivní disjunkce (exclusive or, xor), definované těmito tabulkami:

| a | b | impl
| F | F | T
| F | T | T
| T | F | F
| T | T | T
| a | b | xor
| F | F | F
| F | T | T
| T | F | T
| T | T | F

Úloha:

Vyjádřete operace implikace a xor pomocí operátorů and, or, not.

Možné řešení:

Ověření pravdivostní tabulkou:

pythonvals = [0, 1]

for a in vals:
  for b in vals:
    print(a, b, '|', int(not a or b), int(a and not b or not a and b), int(a!=b))

NAND

Poznámka: Ve skutečnosti stačí jen jediný logický operátor: nand (not and). Všechny ostatní operace je možné zkonstruovat pomocí tohoto operátoru.

| a | b | nand
| F | F | T
| F | T | T
| T | F | T
| T | T | F

Další operátory:

Ověření pravdivostní tabulkou:

pythonvals = [0, 1]

def nand(a, b):
  return int(not (a and b))

for a in vals:
  for b in vals:
    print(a, b, '|', nand(a,a), int(not nand(a,b)), nand(not a, not b), nand(a, nand(a,b)), nand(nand(not a, b), nand(not b, a)))

De Morganovy zákony

De Morganovy zákony jsou pravidla, která tvrdí:

To jest:

not (a and b) == not a or  not b
not (a or  b) == not a and not b

Ověření pravdivostní tabulkou:

pythonfor a in [0, 1]:
  for b in [0, 1]:
    for c in [0, 1]:
      v1 = int(not (a and b and c))
      v2 = int(not a or not b or not c)
      print(a, b, c, '|', v1, v2, '|', v1==v2)

Ověření testem všech kombinací:

pythonholds = True

for a in [0, 1]:
  for b in [0, 1]:
    for c in [0, 1]:
      v1 = int(not (a and b and c))
      v2 = int(not a or not b or not c)
      if v1 != v2:
        holds = False

print('De Morganovo pravidlo', 'platí' if holds else 'neplatí')