# Πίνακες αληθείας Μια δυαδική λογική συνάρτηση παίρνει δύο λογικές εισόδους και επιστρέφει μία λογική έξοδο. Υπάρχουν ακριβώς **δεκαέξι** τέτοιες συναρτήσεις — δηλαδή `2^(2^2)`: καθένας από τους τέσσερις συνδυασμούς εισόδου `(0,0) (0,1) (1,0) (1,1)` αντιστοιχίζεται ανεξάρτητα σε μία από δύο εξόδους, έτσι `2 × 2 × 2 × 2 = 16`. Ούτε περισσότερες, ούτε λιγότερες. Οι πέντε που έχουν δικό τους τελεστή Perl (`&&`, `||`, `xor`, συν τις δύο τετριμμένες — πάντα-αληθές και πάντα-ψευδές) είναι αυτές που γνωρίζουν όλοι. Οι άλλες έντεκα είναι σιωπηλά κι αυτές εκεί, εκφρασμένες ως μικρές συνθέσεις. Αυτό το κεφάλαιο απαριθμεί και τις δεκαέξι, τις ονομάζει, και δείχνει πώς γράφεται η καθεμία στην Perl. ## Η σύμβαση Κάθε συνάρτηση περιγράφεται πλήρως από την έξοδό της για τις τέσσερις γραμμές εισόδου, γραμμένες από πάνω προς τα κάτω με αυτή τη σειρά: ```default a b → output 0 0 → bit 1 0 1 → bit 2 1 0 → bit 3 1 1 → bit 4 ``` Διαβάζοντας αυτά τα τέσσερα bit εξόδου ως αριθμό 4 bit, δίνεται στη συνάρτηση ο δείκτης της 0..15. Έτσι το `AND` είναι `0001` (μόνο η τελευταία γραμμή είναι αληθής), το `OR` είναι `0111`, το `XOR` είναι `0110`. Τα τρία τέταρτα του πίνακα είναι απλώς αναζήτηση της σωστής γραμμής. ## Και οι δεκαέξι | # | Αλήθεια `00 01 10 11` | Όνομα | Σύμβολο | Perl απευθείας | Perl ιδιωματικά | |-----|-------------------------|-----------------------|---------------|------------------|---------------------------------------| | 0 | `0 0 0 0` | ψευδές (αντίφαση) | `⊥` | `0` / `""` | — | | 1 | `0 0 0 1` | AND | `∧` | `$a && $b` | `$a and $b` | | 2 | `0 0 1 0` | a AND NOT b | `a ∧ ¬b` | — | `$a && !$b` | | 3 | `0 0 1 1` | a (αριστερή προβολή) | `a` | `$a` | — | | 4 | `0 1 0 0` | NOT a AND b | `¬a ∧ b` | — | `!$a && $b` | | 5 | `0 1 0 1` | b (δεξιά προβολή) | `b` | `$b` | — | | 6 | `0 1 1 0` | XOR | `⊕` | `$a xor $b` | `!$a != !$b` / `($a?1:0) != ($b?1:0)` | | 7 | `0 1 1 1` | OR | `∨` | `$a || $b` | `$a or $b` | | 8 | `1 0 0 0` | NOR | `↓` (Pierce) | — | `!($a || $b)` / `!$a && !$b` | | 9 | `1 0 0 1` | XNOR / ισοδυναμία | `↔` | — | `!$a == !$b` / `($a?1:0) == ($b?1:0)` | | 10 | `1 0 1 0` | NOT b | `¬b` | `!$b` | `not $b` | | 11 | `1 0 1 1` | το b συνεπάγεται το a | `b → a` | — | `!$b || $a` | | 12 | `1 1 0 0` | NOT a | `¬a` | `!$a` | `not $a` | | 13 | `1 1 0 1` | το a συνεπάγεται το b | `a → b` | — | `!$a || $b` | | 14 | `1 1 1 0` | NAND | `↑` (Sheffer) | — | `!($a && $b)` / `!$a || !$b` | | 15 | `1 1 1 1` | αληθές (ταυτολογία) | `⊤` | `1` | — | Πέντε γραμμές έχουν απευθείας τελεστή Perl (`&&`, `||`, `xor`, `!`, συν τις δύο σταθερές). Οι άλλες έντεκα είναι σύντομες συνθέσεις αυτών. Δεν υπάρχει θεμελιώδης λόγος που η Perl γράφει κάποιες απευθείας και άλλες όχι — είναι ιστορικό, κληρονομημένο από τη C. Κάθε στήλη στα δεξιά είναι κάτι που μπορείτε να πληκτρολογήσετε σήμερα. Αξίζει να ξεχωρίσουμε δύο πράγματα από τον πίνακα. ## Συνεπαγωγή: `→` Η συνεπαγωγή είναι ο τελεστής που κανείς δεν νομίζει ότι χρησιμοποιεί, και όλοι χρησιμοποιούν συνεχώς. Το `a → b` διαβάζεται «το a συνεπάγεται το b» και είναι αληθές σε κάθε περίπτωση **εκτός** όταν το `a` είναι αληθές και το `b` είναι ψευδές. Αυτό είναι όλο. | a | b | a → b | |-----|-----|---------| | 0 | 0 | 1 | | 0 | 1 | 1 | | 1 | 0 | 0 | | 1 | 1 | 1 | Η γραφή σε Perl είναι `!$a || $b`. Αυτή η ταυτότητα — > **`a → b` ≡ `¬a ∨ b`** — είναι τόσο κοινή που αξίζει ένα όνομα· και το όνομα είναι *υλική συνεπαγωγή*. Αφού τη δείτε μία φορά, την εντοπίζετε παντού: ```perl # "if the user is admin, the request must be authenticated" # admin → authenticated die unless !$user->is_admin || $req->is_authenticated; # read aloud: "either not admin, or authenticated, or both" ``` Η μορφή `unless ... !X || Y` είναι άβολη. Το επόμενο κεφάλαιο για τους νόμους του De Morgan δείχνει πώς να την αναστρέψετε σε κάτι αναγνώσιμο. Μια δεύτερη χρήσιμη ταυτότητα: η συνεπαγωγή είναι **η άρνηση του XOR** *μόνο όταν γράφεται με έναν συγκεκριμένο τρόπο*. Μην το αποστηθίζετε αυτό — αποστηθίστε αντ” αυτού τον παρακάτω, που είναι ο πραγματικός πίνακας αναζήτησης για την εναλλαγή μεταξύ κοινών μορφών: | Στόχος | Ένας τρόπος | Ισοδύναμος τρόπος | |----------------|-----------------------|---------------------| | `a → b` | `¬a ∨ b` | `¬(a ∧ ¬b)` | | `a ↔ b` (XNOR) | `(a ∧ b) ∨ (¬a ∧ ¬b)` | `¬(a ⊕ b)` | | `a ⊕ b` (XOR) | `(a ∧ ¬b) ∨ (¬a ∧ b)` | `¬(a ↔ b)` | | `¬a` | `a ↑ a` (αυτο-NAND) | `a ⊕ 1` | Η τελευταία στήλη είναι μια προεπισκόπηση για το κεφάλαιο της λειτουργικής πληρότητας. ## Η ισοδυναμία και το XOR είναι δυϊκά Το XOR είναι αληθές ακριβώς όταν τα `a` και `b` διαφέρουν. Η ισοδυναμία (XNOR) είναι αληθής ακριβώς όταν συμφωνούν. Είναι αρνήσεις μεταξύ τους, και αυτό ακριβώς λένε οι γραμμές του πίνακα αληθείας (η γραμμή 6 είναι `0 1 1 0`, η γραμμή 9 είναι `1 0 0 1` — άρνηση κατά bit). Στην Perl η πιο καθαρή γραφή και για τα δύο είναι να κανονικοποιηθεί κάθε τελεστέος σε `0` ή `1` πρώτα και στη συνέχεια να γίνει σύγκριση με `==` ή `!=`: ```perl my $a01 = $a ? 1 : 0; my $b01 = $b ? 1 : 0; my $xor = $a01 != $b01; # true if they differ my $xnor = $a01 == $b01; # true if they agree ``` Γιατί η κανονικοποίηση; Επειδή τα `$a` και `$b` μπορεί να είναι οποιεσδήποτε αληθείς τιμές — οι συμβολοσειρές `"yes"` και `5` είναι αμφότερες αληθείς αλλά όχι ίσες. Η απευθείας σύγκρισή τους με `==` ή `eq` απαντά σε διαφορετική ερώτηση. Το λογικό XOR ρωτά «έχουν την ίδια *αλήθεια τιμής*;», όχι «είναι ίσες;». Μια σύντομη εναλλακτική χωρίς τις προσωρινές τιμές είναι `!$a != !$b` — κάθε `!` επιστρέφει το κανονικό `1` ή `""`, και στη συνέχεια το `!=` τις συγκρίνει. Δουλεύει, αλλά διαβάζεται πλάγια· η ρητή μορφή `? 1 : 0` είναι πιο αναγνώσιμη. ## Διαβάζοντας τον πίνακα αντίστροφα Μερικές φορές θα γνωρίζετε το μοτίβο αληθείας που θέλετε και θα χρειαστεί να βρείτε τον τελεστή. Παράδειγμα: «Θέλω μια συνάρτηση που να είναι αληθής εκτός αν τα `a` και `b` είναι αμφότερα ψευδή.» Διαβάστε τις γραμμές: `a=0,b=0 → 0`, `a=0,b=1 → 1`, `a=1,b=0 → 1`, `a=1,b=1 → 1`. Αυτό είναι `0 1 1 1` — γραμμή 7 — OR. Αυτό ακούγεται τετριμμένο εδώ, αλλά είναι ακριβώς πώς αποσφαλματώνετε μια μπερδεμένη συνθήκη: γράψτε τον πίνακα αληθείας της, διαβάστε τα τέσσερα bit, βρείτε τη γραμμή, και έχετε το κανονικό όνομα και την απλούστερη γραφή. ## Τι πρέπει να θυμάστε από αυτό το κεφάλαιο - Υπάρχουν ακριβώς δεκαέξι δυαδικές συναρτήσεις αληθείας· κάθε λογική έκφραση σε οποιαδήποτε γλώσσα υπολογίζει μία από αυτές. - Πέντε από τις δεκαέξι έχουν αποκλειστικό τελεστή Perl. Οι άλλες έντεκα είναι σύντομες συνθέσεις και ο παραπάνω πίνακας είναι η αναζήτηση. - Η συνεπαγωγή `a → b` είναι `¬a ∨ b`. Εμφανίζεται συνεχώς κάτω από την επιφάνεια προτάσεων `unless` και `if`. - Το XOR και το XNOR είναι αρνήσεις μεταξύ τους. Η πιο καθαρή γραφή σε Perl και για τα δύο ξεκινά με την κανονικοποίηση των τελεστέων σε `0` ή `1`.