( p q) p q February 1, 2011
Sandhedsværdier og udsagnsvariable I dag handler det om logiske udsagn. Mere præcist om de logiske udsagn vi kan bygge ud fra sandhedsværdier, udsagnsvariable og logiske konnektiver. Lad os se på ingredienserne: Sandhedsværdier Vi har to og kun to sandhedsværdier: sand (S) og falsk (F). Dem er der ikke så meget pjat med. Udsagnsvariable Vi skal bruge nogle udsagnsvariable; i princippet skal vi gerne have uendeligt mange af dem, men lad os bare starte med et par stykker: p, q og r. En udsagnsvariabel er blot en slags pladsholder; den har ingen værdi. Vi kan dog tillægge den en af de to sandhedsværdier sand eller falsk og derved angive input til vores logiske udsagn.
Tre logiske konnektiver Vi kan nu skrive logiske udtryk såsom S og p. Dem er der ikke meget sjov ved. Lad os øge indsatsen en smule: Negation, konjunktion og disjunktion Vi kan danne negationen af et udsagn U som U. Og hvis vi har to udsagn U og V kan vi bygge konjunktionen U V og disjunktionen U V. Konstruktionerne svarer nogenlunde til de sproglige ikke, og hhv. eller. Men kun nogenlunde, følgende sandhedstabeller er præcise: p p F S S F p q p q p q F F F F F S F S S F F S S S S S
Udsagnslogik i Java Lad os genskabe forbindelsen til virkeligheden. Tænk gerne på udsagnsvariable som variable af typen boolean i Java. De logiske konnektiver genfindes også her: er!, er && og er. Vi spørger Java boolean p = true; boolean q = false; System.out.println("p er " + p + " og q er " + q); System.out.println("!p er " +!p); System.out.println("p && q er " + (p && q)); System.out.println("p q er " + (p q)); Hvad Java svarede p er true og q er false!p er false p && q er false p q er true
Lidt opvarmning Det er rart at tænke på et udsagn som en funktion. Man giver det sandhedsværdier som input ved at specificere udsagnsvariablene, og de logiske konnektiver udregner så en sandhedsværdi som output. Lad os, som lidt opvarmning, prøve at udregne sandhedsværdien af et mildt ubehageligt udtryk: (p q) (( p) ( q)). Som input specificerer vi at p er sand og q er falsk: (S F ) (( S) ( F )) = (S F ) (F S) = F (F S) = F S = S. Fremgansmåden turde være klar men næppe ophidsende.
(p q) (( p) ( q)) i Java Vi spørger Java boolean p = true; boolean q = false; System.out.println("p er " + p); System.out.println("q er " + q); boolean out = (p && q) ((!p) (!q)); System.out.println("Javas resultatet er " + out); Hvad Java svarede p er true q er false Javas resultatet er true
Implikation Vi tager nok et logisk konnektiv: implikation. Tag to udsagn, U og V, så kan vi bygge implikationen U V. Intuitionen er denne: hvis vi har både U V og U, så skal vi kunne slutte V. p q p q F F S F S S S F F S S S Bemærk det let besynderlige at implikationen altid er sand hvis P er falsk. Så udsagnet 2+2 = 5 implicerer faktisk at jeg har et lyssværd. Desværre er to og to fire.
Implikation i Java Implikation bruges sjældent direkte og findes derfor ikke i Java. Men det er der naturigvis råd for, vi kan jo bare bygge den selv: Vi påkalder Java public static boolean imp(boolean p, boolean q) { if (p) { if (q) return true; else return false; } else { return true; } } Hvad Java svarede imp(false, false) er true imp(false, true) er true imp(true, false) er false imp(true, true) er true
Biimplikation Og så det sidste logiske konnektiv: biimplikation. Tag to udsagn, U og V, så kan vi bygge biimplikationen U V. Implikationen er sand netop hvis både U og V har samme sandhedsværdier. p q p q F F S F S F S F F S S S
Et sidespring: Parenteser versus præcedens Som landet liggger, skal alle parenteser skrives: (( q) ( p)) (( p) q). Det kan blive tungt. Derfor giver vi konsistent med Java de logiske konnektiver forskellig præcedens: binder stærkere end som igen binder stærkere end. Og og binder svagest af alle. Så vi kan nu skrive q p p q. Nogle parenteser kan vi dog ikke stritte ud. (p q) er ikke ganske det samme som p q sidstnævnte er nemlig ( p) q.
Logisk Ækvivalens! Vi skal forstå noget centralt: To udsagn er logisk ækvivalente hvis de giver samme sandhedsværdi ved enhver specifikation af alle udsagnsvariable. De er altså ens som funktioner vi skriver imellem dem. Et eksempel: Kontraponering p q q p. Vi opskriver omhyggeligt en sandhedstabel som argument: p q p q q p q p F F S S S S F S S F S S S F F S F F S S S F F S
Seks vigtige ækvivalenser Her følger en række vigtige logiske ækvivalenser de er gode at kunne. Og bare rolig, I viser dem korrekte i øvelserne. Distributivitet p (q r) (p q) (p r). p (q r) (p q) (p r). Dobbeltnegering og Materiel Implikation De Morgans love ( p) p. p q p q. (p q) p q. (p q) p q.
Sandhedstabel for (p q) p q i Java Opskrivning af sandhedstabeller er kedsommeligt. Men vi er ferme udi programmering og koder en vej ud; her en af De Morgans love: Java befalinger boolean[] bools = {false, true}; for(boolean p : bools) { for(boolean q : bools) { System.out.println("p: " + p + ", q: " + q + ",!(p && q): " +!(p && q) + ",!p!q: " + (!p!q)); } } Javas ytringer p: false, q: false,!(p && q): true,!p!q: true p: false, q: true,!(p && q): true,!p!q: true p: true, q: false,!(p && q): true,!p!q: true p: true, q: true,!(p && q): false,!p!q: false
Udsagn: de gode og de onde Vi har de særligt gode udsagn: Tautologier Et udsagn, der altid giver sand, kaldes en tautologi. Tautologier er de udsagn, som er logisk ækvivalente med S. Og så er der de onde: Kontradiktioner (absurditeter) Et udsagn, der altid giver falsk, kaldes en kontradiktion. Kontradiktioner er de udsagn, som er logisk ækvivalente med F. Her er det kanoniske gode udsagn: p p. Og det kanoniske onde: p p. Der er mange andre, f.eks. er p (p q) gerne sand.
At regne med logiske ækvivalenser - kapow! De logiske ækvivalenser er vigtige fordi vi kan bruge dem til at regne med logiske udtryk. Lad os prøve noget som ikke er så let: lad os vise at udsagnet (p (p q)) q er en tautologi. Vi kunne opskrive en sandhedstabel men vi er mere mandige (m/k) end som så, vi bruger logiske ækvivalenser, stille og roligt: (p (p q)) q (p ( p q)) q. Her bruger vi materiel implikation p q p q lige ud ad landevejen. Lad os regne videre. (p ( p q)) q ((p p) (p q)) q Denne ækvivalens har lidt mere substans. Vi bruger den distributive lov p (q r) (p q) (p r) med med p for q og q for r.
Regne, regne, regne... ((p p) (p q)) q (F (p q)) q (p q) q. Her benytter vi først ækvivalensen p p F og derefter ækvivalensen F p p med (p q) for p. Disse småækvialenser har vi hverken navngivet eller bevist, men de er ganske ligetil. (p q) q (p q) q p q q. Her er det først materiel implikation p q p q og dernæst en af De Morgans love (p q) p q. Så er vi der næsten: p q q p S S Igen et par småækvivalenser p p S og p S S. Bom.
Uopnåelig kode Betragt følgende kodestump: Lidt Java boolean burger =...; boolean fritter =...; if (!burger fritter) { System.out.println("Karl Koder er kool"); if (burger &&!fritter) { System.out.println("Karl Koder er en klovn"); } } Spørgsmålet er nu om Karl Koder er en klovn. Det afhænger jo noget af fødevaresituationen kunne man tænke. Men nej, vi kan (vil) vise at følgende udsagn er en kontradiktion: ( p q) (p q) Derfor vil den anden print kommando aldrig blive kørt uanset værdierne af de to variable. Så programmøren er klovnen.
Karl Koders kontradiktion: ( p q) (p q) Lad os lige vise ækvivalensen fra forrige slide. En direkte måde er med distribitivitet plus det løse: ( p q) (p q) (p q) ( p q) (p q p) (p q q) (p p q) (p q q) (F q) (p F ) F F F. Lidt mere elegant kan vi bruge reglen om dobbeltnegering kreativt, efterfulgt af en af De Morgans love og oprydning: ( p q) (p q) ( ( p q)) (p q) ( ( p) q)) (p q) (p q) (p q) F.
Løkken er en tautologi Endnu en kodestump til samlingen: Lidt Java boolean vin =...; boolean ost =...; while((vin && ost) (!ost!vin)) { System.out.println("Velbekomme - spis og drik!"); vin =...; ost =...; } Hvor hurtigt slipper maden op? Man tænker: det afhænger af forsyninger og appetit, dvs. af hvad... dækker over i koden. Men vi ved bedre vi ved (snart) at følgende udsagn er en tautuologi: (p q) ( q p). Det betyder at betingelsen i løkken altid vil være sand, uanset værdierne af variablene vin og ost. Så programmøren har fået bygget sig en uendelig løkke det endeløse gilde.
Ostetautologien: (p q) ( q p) Lad os vise ækvivalensen fra forrige side. Igen kan vi køre ligepå og hårdt med en distributiv lov: (p q) ( q p) ( q p) (p q) ( q p p) ( q p q) ( q p p) (q q p) ( q S) (S p) S S S. Eller vi kan være ganske snedige og bruge De Morgan baglæns: (p q) ( q p) (p q) (q p) (p q) (p q) S Sandhedstabeller kan virke simplere og derfor tillokkende. Det er samme resultat, men de logiske ækvivalenser giver intution!