Operacje na wartościach logicznych
Wstęp teoretyczny
Choć logika stanowi podstawę przede wszystkim matematyki, odgrywa też dużą rolę w innych dziedzinach. Logika nie jest zależna od płci, ale jest funkcją języka, w jakim przekazujemy zdobyte informacje. Pokazuje jak sformułować zdanie, aby jego treść była poprawnie zrozumiana przez innych i oceniona jego prawdziwość. Logika nie istnieje nadrzędnie. Nie odkrywa się jej, ale formułuje. Jest rzeczą umowną, tak jak kierunek pisma w językach europejskich.
Logika jest łatwa i trzeba się jej nauczyć, po to by nie robić błędów przy formułowaniu zdań w pracach naukowych. Dotyczy to także prac biologicznych, gdzie posługiwanie się zaprzeczeniem (nie, nieprawda, że), spójnikami (i, oraz, lub, albo) oraz implikacją (jeżeli … to …) musi być zgodne z zasadami logiki matematycznej. Jeszcze większą rolę odgrywają te zasady w programowaniu (nie tylko w R). Zestawianie ze sobą różnych relacji i funkcji logicznych musi być całkowicie zgodne z ustalonymi zasadami logiki, często nazywanej logiką matematyczną.
Zasady te polegają na zmianach wartości logicznych zdań, które mogą być prawdziwe (czyli mieć wartość logiczną TRUE) lub fałszywe (o wartości logicznej FALSE) poprzez zastosowanie negacji, koniunkcji (i, oraz), alternatywy (lub) oraz implikacji. Wartość logiczna złożenia zdań zmienia się według reguł przedstawionych w poniższych tabelach.
Zdanie |
Negacja zdania |
TRUE |
FALSE |
FALSE |
TRUE |
Zastosowanie podwójnego przeczenia tworzy zdanie o wyjściowej wartości logicznej, potrójnego – takie, jak pojedyncze zaprzeczenie. Nie jest to w pełni zgodne z gramatyką języka polskiego, toteż stosowanie zaprzeczeń w polskojęzycznych pracach naukowych musi być dobrze przemyślane.
Zdanie 1 |
Zdanie 2 |
Koniunkcja zdań |
TRUE |
TRUE |
TRUE |
FALSE |
TRUE |
FALSE |
TRUE |
FALSE |
FALSE |
FALSE |
FALSE |
FALSE |
Jeżeli zatem piszemy “… i …” lub “… oraz…” oba człony zdania muszą być prawdziwe aby całość była prawdziwa.
Zdanie 1 |
Zdanie 2 |
Alternatywa zdań |
TRUE |
TRUE |
TRUE |
FALSE |
TRUE |
TRUE |
TRUE |
FALSE |
TRUE |
FALSE |
FALSE |
FALSE |
Jeżeli piszemy “… lub …” wystarczy by jeden człon zdania był prawdziwy, aby całość była prawdziwa.
Zdanie 1 |
Zdanie 2 |
Implikacja zdań |
TRUE |
TRUE |
TRUE |
FALSE |
TRUE |
TRUE |
TRUE |
FALSE |
FALSE |
FALSE |
FALSE |
TRUE |
Układ treści typu “jeżeli … to …” dotyczy wielu prac naukowych lub ich części konstruowanych wg. zasad a priori. Polega to na wyprowadzaniu wniosków z przyjętych (nie koniecznie prawdziwych) założeń. Rzadko udaje się je sformułować w postaci jednego zdania, ale zasady oceny prawdziwości całej konstrukcji są takie same. Jest ona tylko wtedy fałszywa, gdy założenia były prawdziwe, a wyciągnięty wniosek fałszywy. Metody zastosowane przy wyciąganiu wniosków fałszywych z prawdziwych założeń uważa się za błędne i to właśnie jest wartość logiczna implikacji. Z fałszywych założeń możemy wyciągnąć wnioski prawdziwe i fałszywe bez zrobienia błędu w rozumowaniu. Oczywiście poprawne wyciąganie wniosków dotyczy też przypadku, gdy z prawdziwych założeń wyciągamy prawdziwe wnioski.
Działania na wartościach logicznych
Wartości logiczne zdań “prawda” (TRUE) i “fałsz” (FALSE), są wartościami wielu działań oraz funkcji określonych na liczbach, znakach i tekstach. Jeżeli dużym literom T i F nie są przyporządkowane jakieś obiekty, oznaczają one domyślnie wartości logiczne – prawdę (T) i fałsz (F).
> T [1] TRUE > F [1] FALSE > True Error: object 'True' not found |
Poprawność oceny wartości logicznej najlepiej sprawdzić stosując proste relacje dla liczb, których prawdziwość łatwo sami ocenimy.
> 7>5 [1] TRUE > 3-2<1 [1] FALSE > 3^2>2^3 [1] TRUE > 3-2<=1 [1] TRUE > 3-2==1 [1] TRUE > 3-2=1 Błąd w poleceniu '3 - 2 = 1': docelowe przypisanie rozszerza się na nie-języczny obiekt > 3-2!=1 [1] FALSE |
Przy okazji widać, jak określa się podstawowe relacje między liczbami w R. Symbole < i > są tak samo używane jak w matematyce, <=, >= oznaczają słabe nierówności (mniejsze lub równe, większe lub równe). Równość liczb sprawdza relacja == a nierówność !=. Stosowany w matematyce symbol = na relację równości, ma w R inne znaczenie.
Konieczność obliczania negacji, koniunkcji i alternatywy wielu wyrażeń logicznych spowodowała zaimplementowanie do R operatorów “!”, “&”, “|” działających na wyrażeniach logicznych.
> !TRUE [1] FALSE > !FALSE [1] TRUE > TRUE & TRUE [1] TRUE > TRUE & FALSE [1] FALSE > FALSE & TRUE [1] FALSE > FALSE & FALSE [1] FALSE > TRUE | TRUE [1] TRUE > TRUE | FALSE [1] TRUE > FALSE | TRUE [1] TRUE > FALSE | FALSE [1] FALSE |
Trzeba przy tym wiedzieć, że “&&” znaczy to samo co “&”, a “||” znaczy to samo co “|”. Nie dotyczy to operatora “!”. W tym wypadku obowiązują zasady podwójnego (i wielokrotnego) przeczenia.
> TRUE & TRUE [1] TRUE > TRUE && TRUE [1] TRUE > TRUE &&& TRUE Error: unexpected '&' in "TRUE &&&" > TRUE | FALSE [1] TRUE > TRUE || FALSE [1] TRUE > TRUE ||| TRUE Error: unexpected '|' in "TRUE |||" > !TRUE [1] FALSE > !!TRUE [1] TRUE > !!!TRUE [1] FALSE |
Kolejność wykonywania działań logicznych ustalona jest zgodnie z zasadami przyjętymi w logice matematycznej – to znaczy negacje wykonywane są najpierw, a koniunkcja i alternatywa w drugiej kolejności. Działania równoważne wykonywane są w kolejności od lewej do prawej. Zmiana kolejności wymaga użycia nawiasów okrągłych.
> TRUE | TRUE & TRUE & FALSE [1] TRUE > (TRUE | TRUE) & (TRUE & FALSE) [1] FALSE > !FALSE & !TRUE [1] FALSE > !(FALSE & !TRUE) [1] TRUE |
Inne ważne działania na wartościach logicznych (implikacja, równoważność) są na tyle rzadko używane w programowaniu w R, że nie wyróżniono dla nich specjalnych operatorów. Gdy zaistnieje konieczność posługiwania się nimi, można wykorzystać twierdzenia:
implikacja(p, q) = nieprawda(alternatywa(negacja p, q))
równoważność(p, q) = alternatywa(koniunkcja(p,q), koniunkcja(negacja(p), negacja(q)))
> !(!TRUE | TRUE) [1] TRUE > !(!TRUE | FALSE) [1] FALSE > !(!FALSE | TRUE) [1] TRUE > !(!FALSE | FALSE) [1] TRUE > (TRUE & TRUE)|(!TRUE & !TRUE) [1] TRUE > (TRUE & FALSE)|(!TRUE & !FALSE) [1] FALSE > (FALSE & TRUE)|(!FALSE & !TRUE) [1] FALSE > (FALSE & FALSE)|(!FALSE & !FALSE) [1] TRUE |
Wymuszenie działań arytmetycznych na wartościach logicznych powoduje, że są one traktowane jako liczby. przy czym T=TRUE=1, F=FALSE=0.
> TRUE+3 [1] 4 > FALSE*11 [1] 0 |
W języku R rzadko wykonuje się działania logiczne bezpośrednio na wartościach TRUE i FALSE. Natomiast stosuje się je przy operowaniu pewnymi wyrażeniami, których prawdziwość ocenia program. Przypisuje im wtedy domyślnie wartości TRUE lub FALSE, a następnie wykonuje na nich odpowiednie działanie.
Funkcje logiczne
W wielu językach programowania istnieją funkcje logiczne zastępujące działania, np. NOT() lub AND(). Nie ma takich funkcji w R. Jedyna funkcją której argumentami sa wartości logiczne jest xor() – odpowiednik polskiego ‘albo’.
> # funkcja xor() > xor(TRUE,TRUE) [1] FALSE > xor(TRUE,FALSE) [1] TRUE > xor(FALSE,TRUE) [1] TRUE > xor(FALSE,FALSE) [1] FALSE |
Jest natomiast wiele funkcji, których argumentami są liczby lub teksty, a wartościami TRUE i FALSE. Są to wspomniane w poprzednich rozdziałach funkcje sprawdzające typ liczb i wyrażeń: is.numeric(), is.integer(), is.double(), is.character(). Funkcji zaczynających się od is. jest więcej. Między innymi:
- is.finite() daje wartość TRUE dla liczb i FALSE dla Inf.
- is.infinite() daje wartość FALSE dla liczb i TRUE dla Inf.
- is.nan() daje wartość TRUE dla wartości nieokreślonej NaN i TRUE dla pozostałych.
- is.na() daje wartość TRUE dla wartości pomijalnej NA i NaN oraz TRUE dla pozostałych.
> is.infinite(7/0); is.nan(7/0); is.na(7/0) [1] TRUE [1] FALSE [1] FALSE > is.infinite(sqrt(-7)); is.nan(sqrt(-7)); is.na(sqrt(-7)) [1] FALSE Komunikat ostrzegawczy: W poleceniu 'sqrt(-7)': wyprodukowano wartości NaN [1] TRUE Komunikat ostrzegawczy: W poleceniu 'sqrt(-7)': wyprodukowano wartości NaN [1] TRUE Komunikat ostrzegawczy: W poleceniu 'sqrt(-7)': wyprodukowano wartości NaN |
Wartość NA traktowana jest jako brak danych (wartość pomijalna), natomiast NaN sa to wartości błędne, nieokreślone. Wartości błędne są traktowane jak wartości pomijalne, natomiast w drugą stronę nie ma tożsamości. Wartość pomijalna nie jest wartością błędną i czasem trzeba to rozróżnić w zbiorze danych.
Sprawdzenie czy wartością jakiegoś wyrażenia jest wartość logiczna polega na zastosowaniu funkcji is.logical(). Natomiast konwersja liczb 0 i 1 oraz wyrażeń “TRUE”, “True” itp. na wartość logiczną zachodzi poprzez zastosowanie funkcji as.logical().
> # funkcja is.logical() > is.logical(T) [1] TRUE > is.logical(True) [1] FALSE > is.logical(1) [1] FALSE > # funkcja as.logical() > as.logical(0) [1] FALSE > as.logical(1) [1] TRUE > as.logical(5.768) [1] TRUE > as.logical(TRUE) [1] TRUE > as.logical("TRUE") [1] TRUE > as.logical("True") [1] TRUE > as.logical(True) Error: object 'True' not found > as.logical("a") [1] NA |