רוצים לחלק באפס 2 – נקמתו של כלומיתי

בפוסט הקודם דיברתי קצת על למה לא נהוג במתמטיקה להגדיר חלוקה באפס, מתי כן מגדירים חלוקה באפס (למשל, מתי נוח לנו לסמן את החלוקה של אחד באפס כ”אינסוף” ומה המשמעות של זה) ולמה 0/0 היה ונותר ביטוי חסר טעם להגדרה ולכן בתוכנות מחשב מתמטיות דוגמת Matlab נהוג שתוצאת הפעולה 0/0 היא קבוע בשם NaN, שמשמעותו “לא מספר” (Not a Number). קבוע בעל התכונה הסבירה שכל פעולה מתמטית שנעשה עליו לא תשנה אותו (1 ועוד “לא מספר” יהיה “לא מספר”, למשל). המוטיבציה לדיון הזה הייתה הסיפור (שכעת הוא כמעט בן שנתיים) על מורה למתמטיקה שלימד את תלמידיו תורה מתמטית חדשה שבה חלוקה באפס היא “אפשרית” ובכך פתר “בעיה בת 1,200 שנים”.

הזכרתי כאן בעבר את מושג ה”טרחן מתמטי כפייתי”. הגדרתי אותו כ”אדם (לרוב ללא רקע פורמלי במתמטיקה, אך לא בהכרח) שעוסק במתמטיקה בצורה שהיא חסרת תועלת לחלוטין, ולרוב בהתלהבות שעומדת בפרופורציה הפוכה לתועלת שלו.” וההגדרה (פרט להערת הסוגריים) מתאימה מאוד למקרה הזה. כמו כן, קישרתי כאן בעבר למאמר של יהודה בלו שעסק בחיפוש “שיטה להוצאת שורש ריבועי” (למרות שקיימות כבר שיטות מצויינות רבות לכך) - אני חושב שיש למקרה ההוא כמה נקודות דמיון בולטות למקרה הזה.

ראשית, הבעיה שיש לתקן. יהודה בלו אמר על בעיית השורש “מסיבה לא ברורה, לא מחפשים המתמטיקאים שיטה למצוא שורש ריבועי או שורש כלשהו. האם יש בידם הוכחה מתמטית שלא מתאפשרת שיטה שכזו? עדיין לא.” ומה ג’יימס אנדרסון אומר? ה-BBC מביאים את הציטוט הבא:

"Imagine you're landing on an aeroplane and the automatic pilot's working," he suggests. "If it divides by zero and the computer stops working - you're in big trouble. If your heart pacemaker divides by zero, you're dead."

מילא, תגידו, העיתונות מוציאה מהקשרה. לכן עדיף ללכת ישר למקור - מצגת לא טכנית שהכין אנדרסון למטרות פרסום עצמי. שם הוא מגיע לגבהים חדשים: ראשית, הוא מתחיל ב:

"This presentation is dedicated to the USS Yorktown which was stranded for 2 hours 40 minutes when a division-by-zero error crashed its entire network of computers, causing its engines to stop."

הסיפור המשונה הזו הוא כמובן נכון. ה-USS Yorktown אכן סבלה בשנת 1997 מתקלת מחשב אידיוטית שכזו - אחד מאנשי הצוות הזין 0 לתוך תא במסד הנתונים של הספינה, תא שכנראה לא אמור להכיל אפס, ובכך הוא גרם לתקלה של חלוקה באפס. כשתוכנית מחשב נתקלת בחלוקה באפס, היא לא מושכת בכתפיים וממשיכה הלאה - היא מכריזה על תקלה. אם אף אחד לא מטפל בתקלה (ברמת התוכנית עצמה), התוכנית מפסיקה לרוץ, וזה בדיוק מה שקרה בספינה ההיא. כשזה קורה בתוכנות שאמורות לרוץ כל הזמן ולוקח זמן רב להפעיל אותן מחדש, זו בעיה, וכך הספינה הייתה תקועה במשך כמעט שלוש שעות בלי שהתוכנה המרכזית שלה רצה. הבעיה היא שזו בכלל לא דוגמה לבעייתיות של חלוקה באפס - כפי שאמרתי בפוסט הקודם, גם אם החלוקה באפס הייתה עוברת בשלום, שום דבר לא מבטיח שהתוצאה לא הייתה גורמת לבעיות בשלב מאוחר יותר; עדיף שהספינה תיתקע לשלוש שעות מאשר שתיתקע בקרחון בגלל חישוב כיוון לא נכון, למשל.

הבעייתיות שכן מודגמת בסיפור הזה באופן יפה מאוד היא הכשל של מהנדסי התוכנה של הספינה, שלא הקפידו על אספקט חשוב של הנדסת תוכנה - עמידות (Robustness) - היכולת של המערכת לעבוד גם כשמשליכים עליה קלטים שהיא לא אמורה להתמודד איתם. כל תלמיד תכנות נתקל בזה כבר בתוכנות הראשונות שלו - נניח, הוא כותב תוכנה שמקבלת מהמשתמש שני מספרים וצריך לחבר אותם ולהציג את הסכום; אבל מה אם המשתמש מכניס “כגדכ” ו”כדגד” במקום מספרים? כאן צריך להדפיס הודעת שגיאה מתאימה ולצאת, אבל לרוב לא מקפידים על זה כשרק מתחילים ללמד תכנות - אומרים לתלמיד “תניח שהקלט תקין” וזהו. כנראה שחלק מאותם תלמידים, גם כשהם גדלים, ממשיכים להניח את אותה הנחה, או שאינם מצליחים לזהות סיטואציות “מסוכנות” שבהן קלט שגוי יגרום לתקלות. בתוכנה אמיתית, בכל פעם שבה מבצעים פעולת חלוקה, חייבים לבדוק האם בוצעה חלוקה באפס (אפשר תמיד לבדוק לפני, על ידי בחינת המשתנה שבו מחלקים; אבל אפשר גם אחרי, אם התוכנה תומכת במנגנון החזרת שגיאות, או נכתבת בשפה שבה יש מנגנון אוטומטי שכזה - וכך זה תמיד בימינו, אני מקווה) ולטפל בכך בהתאם אם זה קרה. ב-USS Yorktown פשוט לא עשו זאת. כישלון של הנדסת תוכנה, לא של העובדה שאי אפשר לחלק באפס.

לאנדרסון הדוגמאות הללו לא מספיקות. הוא חייב לתקוף באופן ישיר את כל המתמטיקה שהייתה לפניו כדי להסביר מה הוא תורם, בעצם. לכן הוא כותב שקף בעל הכותרת המפוצצת “מה הבעיה עם האריתמטיקה?” ומפרט את הבעיות, עם עוד הערה בסוגריים לכל אחת מהן: אי אפשר למצוא את הטנגנס של זווית ישרה (אינסוף), את הלוגריתם של 0 (מינוס אינסוף), אי אפשר למצוא את אפס בחזקת אפס (האות היוונית \( \Phi \)), ואי אפשר להסביר “איך מחשבים עובדים” (NaN). יותר חמור - האריתמטיקה המתמטית לא מתארת את האריתמטיקה שבה אנשים משתמשים בחיי היום יום שלהם בתור מתכנתים או משתמשים במחשבים, והיא “Sociologically invalid” (הצבע האדום במקור).

אני לא חושב שאני מבין את משמעות הטענה האחרונה כדי שאוכל להתייחס אליה (אני מנחש שהאדום, מטרתו לשמש כמו באותו נאום מפורסם שבו נכתב בהערת שוליים “נקודה חלשה. להרים את הקול!”). לשאר הטענות קל להתייחס: אפשר להגדיר את הטנגנס של זווית ישרה כאינסוף ואת הלוגריתם של 0 כמינוס אינסוף; פשוט אי אפשר יהיה לעבוד איתם אחר כך באופן אריתמטי, כמו שאי אפשר לעבוד עם אחד חלקי אפס. במקום שהאריתמטיקה תסתבך בתחום הזה היא מותירה אותו בלתי מוגדר, ומאפשרת לחשבון האינפיניטסימלי לנסח טענות מדוייקות ומועילות יותר, דוגמת “כשהזווית שואפת לפאי חלקי 2, הטנגנס שלה שואף לאינסוף”. מטלאב ודומיו דווקא כן מחזירים אינסוף ומינוס אינסוף במקרים המדוברים, לטובת מי שהמידע הזה עוזר להם. אגב, חדי העין מביניכם שצלחו את הפוסט הקודם ובקיאים בקצת מתמטיקה ודאי שמו לב שטנגנס הזווית הישרה הוא שם אחר לבעיית ה”ישר בעל שיפוע אינסופי” שדיברתי עליה.

בכל הנוגע לאפס בחזקת אפס, מבחינה פורמלית טהורה אכן הביטוי אינו מוגדר. הסיבה לכך היא כללי החזקות: לכאורה מתקיים \( 0^0=0^1\cdot 0^{-1} \) והביטוי הימני מבין השניים כלל אינו מוגדר. עם זאת, לפעמים נוח להגדיר \( 0^0=1 \). בפרט, בנוסחת הבינום של ניוטון: \( (a+b)^n=\sum_{k=0}^n{n\choose k}a^kb^{n-k} \) הכרחי לעבוד עם ההגדרה הזו כדי שהנוסחה תעבוד במקרה שהאחד מהאיברים בסוגריים הוא אפס. לבחירה השרירותית לכאורה הזו יש הגיון עמוק מעט יותר - באופן כללי, אפשר לחשוב על \( a^b \) כאשר \( a,b \) הם מספרים טבעיים בתור מספר הפונקציות מקבוצה בעלת \( b \) איברים לקבוצה בעלת \( a \) איברים. כאשר יש לנו שתי קבוצות ריקות, קיימת בינן פונקציה אחת: “הפונקציה הריקה” (לא אכנס לזה כרגע, אבל מבחינה פורמלית זו פונקציה תקינה לחלוטין). אם לעומת זאת \( b>0 \), מקבלים ש-\( 0^b=0 \) על פי אותה הגדרה בדיוק, כי לא קיימת פונקציה מקבוצה בעלת \( b>0 \) איברים אל הקבוצה הריקה (לכל איבר בקבוצת המקור חייבים להתאים איבר מקבוצת היעד - אם אין איברים שאפשר להתאים אליהם, אכלנו אותה).

הטענה שהאריתמטיקה לא מסבירה איך מחשבים עובדים בגלל NaN לא הכי ברורה לי. הרי בשורה התחתונה, את NaN אפשר לקודד באמצעות מספרים וזה בדיוק מה שקורה במחשבים, וכל מה שמחשב עושה בבסיסו (ביחידת העיבוד המרכזית שלו) הוא פעולות אריתמטיות. הטענה האחרונה של אנדרסון שעוד הצלחתי להבין, על כך שהאריתמטיקה המתמטית אינה דומה לאריתמטיקת חיי היום יום, נראית לי פשוט שגויה, על פי ההיכרות שלי עם האריתמטיקה  - ויתר על כן, האריתמטיקה החילופית שהוא מציע בהמשך לא דומה אף היא לכלום.

ובכן, קשקוש בלבוש עד כה. אנדרסון פוסל את האריתמטיקה עד אליו בכמה נפנופי ידיים בלתי מחייבים, שאני חושב שמצביעים על ניתוק גדול למדי מהמציאות (המתמטית) במקרה הטוב, ועל שרלטנות מחושבת היטב במקרה הרע. זה מזכיר לי מאוד את טענתו של יהודה בלו שהמתמטיקאים מתעלמים משום מה מבעיית הוצאת השורש.

התוכן האמיתי מגיע בשקף הבא, שכותרתו היא “מה הבעיה עם מחשבים?” ובו הוא מציג שתי נקודות מהותיות: ראשית, NaN ו-Inf ומינוס Inf, החבר’ה שמייצגים את “בלתי מוגדר” ואת אינסוף ומינוס אינסוף בתוכנות המתמטיקה הסטנדרטיות, הם “לא מספרים” כהגדרתו של אנדרסון. שנית (וזו, לדעתי, הנקודה היחידה שבאמת שווה התייחסות בכל דבריו של אנדרסון), NaN מקיים את התכונה שאינו שווה לעצמו. כלומר, אם תבצעו שני חישובים, אפילו זהים, ותכניסו את התוצאה לתוך משתנים שונים, ושני החישובים יחזירו NaN, ותבצעו השוואה בין המשתנים - תקבלו תשובה שלילית. אנדרסון טוען ש”שוויון פירושו ש-x שווה ל-x לכל x, ולכן אריתמטיקה ממוחשבת היא invalid” (שוב, האדום המביך במקור).

לנקודת “הם לא מספרים” שהעלה אנדרסון אתייחס בקרוב. בינתיים אתייחס לנקודה המהותית - למה NaN לא זהה אפילו לעצמו? לכאורה זה באמת נראה מטופש. אלא שצריך לזכור את המוטביציה לקיום NaN - הוא בא למדל ביטויים כמו 0/0, שהם חסרי משמעות באופן טוטאלי, אפילו בגישת החשבון האינפיניטסימלי, זו שאומרת ש-1/0 ו-2/0 הם זהים במובן מסויים מאוד - הגבול של שתי הפונקציות \( \frac{1}{x},\frac{2}{x} \) הוא זהה כאשר איקס שואף לאפס מימין. כפי שאמרתי בפוסט הקודם, לגבול של שבר שבו גם המונה וגם המכנה שואפים לאפס (או לגבול של מכפלה שבה אחד האיברים שואף לאפס והשני לאינסוף, וכו’) יכולים להיות ערכים שונים לגמרי. לכן מבחינה רעיונית זה שגוי להגדיר את NaN כשווה לעצמו, ובכך ליצור זהות כלשהי בין שתי הסיטואציות הללו. מבחינה מעשית זה אולי מעט מסורבל, כי כדי לבדוק האם משתנה מכיל את NaN לא ניתן להשוות אותו ל-NaN; לכן לרוב מוגדרת גם פונקציה בשם isNaN שמבצעת את הבדיקה בשביל המשתמש - ואם אין כזו, הבדיקה x==x (“האם איקס שווה לאיקס?”) מאפשרת מייד לזהות האם x הוא NaN או לא - התשובה לה תהיה שלילית אם ורק אם x הוא NaN.

אם כן, מה אנדרסון מציע כדי לפתור את הבעיות הקשות (והלא קיימות) הללו? הוא מרחיב את מערכת המספרים הממשיים למערכת שהוא קורא לה “Transreal” (המצאת שמות מפוצצים לדברים קיימים זו תכונה מאפיינת סטנדרטית של טרחנים כפייתיים - עיינו ב”המספרים הדו חזקתיים” של יהודה בלו). היא מתקבלת מהממשיים על ידי הוספת אינסוף ומינוס אינסוף (עד כאן, הכל בסדר - זה גם מה שיש ב-Matlab וגם בספרי לימוד רבים שעבורם ההרחבה הזו “משתלמת”), ועוד מספר אחד חדש, שמסומן כ-\( \Phi \) ונקרא “Nullity”, ובתרגום חופשי לעברית שלי: “כלומיתי”. אני קצת מרושע, כי Nullity היא מילה קיימת במתטיקה ובעלת משמעות שונה, ובמשמעות השונה הזו לא היה עולה על דעתי לתרגם אותה כ”כלומיתי”, אבל נו טוב. גם לי מותר ליהנות.

אנדרסון לא מפרט את תכונות הכלומיתי שלו במצגת, אבל כן במאמר שגם כן זמין לכל. בואו נקצר עניינים: מדובר ב”מספר” שמוגדר בתור 0/0; שלא ניתן להשוות אותו למספרים אחרים; ושהוא ועוד כל דבר אחר, או כפול כל דבר אחר, שווה לכלומיתי. פרט לכך הוא גם מגדיר הגדרה משונה שם - \( \Phi^{-1}=\Phi \) - “ההופכי של כלומיתי הוא כלומיתי”. כיצד זה אפשרי אם כלומיתי כפול כלומיתי הוא כלומיתי, והמשמעות של “הופכי” היא “המספר שכאשר כופלים בו, מקבלים את 1”? תמהני, אבל כמובן שאנדרסון לא מתייחס לזה ולא מגדיר את הסימון הזה של “בחזקת מינוס אחד” בשום מקום. לא קשה לראות שכל ביטוי אריתמטי שיכיל את כלומיתי יהיה שווה לכלומיתי (כי כלומיתי “בולע” כל פעולה חשבונית שמבצעים איתו). אם כן, מה ההבדל בין כלומיתי ו-NaN? יש בדיוק שני הבדלים:

  1. אנדרסון מגדיר את כלומיתי להיות שווה לכלומיתי, להבדיל מ-NaN שמוגדר לא להיות שווה לעצמו (כפי שהזכרתי לעיל).
  2. אנדרסון קורא לכלומיתי "מספר", בעוד ש-NaN, במוצהר (אפילו בשמו!) איננו מספר.

לנקודה מס’ 1 התייחסתי כבר וניסיתי להסביר מדוע זה ש-NaN אינו שווה ל-NaN הוא יתרון, לא חיסרון. הגישה הטבעית והנאיבית יותר היא כן להגדיר אותו כשווה לעצמו; האנשים הטובים ב-IEEE שטרחו ועמלו על הסטנדרט של NaN לא סתם בחרו להגדיר אותו כשונה מעצמו. אנדרסון אם כן בא לתקן את מה שאינו מקולקל בכלל, והתיקון שלו הוא מה שמקלקל; אבל “מקלקל” זו הגזמה. אין בעיה מהותית לעבוד עם כלומיתי ששווה לעצמו, כשם שאין בעיה מהותית לעבוד עם NaN שלא שווה לעצמו - המתכנת פשוט צריך להיות מודע לכך שהשוויון יעבוד/לא יעבוד, ולכתוב את הקוד שלו בהתאם.

הנקודה השנייה היא העלובה מכל. אנדרסון, לרוע מזלו, אפילו אינו טרחן כפייתי מעניין; הוא בסך הכל נותן שם חדש לדברים קיימים וחושב שבכך הוא מחולל מהפכה מחשבתית. אז הוא קורא לכלומיתי שלו “מספר” וחושב שבכך נפתרה הבעיה של “0/0 אינו מספר” - אבל מה טיבו של ה”מספר” הזה? באיזה מובן הוא שייך למערכת המספרים? האם ניתן להשוות אותו עם מספרים אחרים? לא. האם פעולה חשבונית כלשהי איתו מסוגלת לתת תוצאה בעלת משמעות? לא (רק “כלומיתי”). אם כן, באיזה מובן הכלומיתי הוא מספר בעוד ש-NaN איננו? במובן אחד בלבד - המובן ההצהרתי. טרחנים כפייתיים חזקים מאוד בתחום ההצהרתי.

לקראת סוף המצגת שלו אנדרסון מגיע לרמה חדשה של עליבות: הוא אומר ש”ב-1,200 השנים האחרונות אף אחד לא הצליח לחשב את אפס בחזקת אפס בצורה אריתמטית. עד כמה זה קשה?” ואז מציג “חישוב” של אפס בחזקת אפס. רובו הוא סטנדרטי לגמרי: \( 0^0=0^1\cdot 0^{-1}=\frac{0}{0} \) - זה דבר שברור לכל סטודנט למתמטיקה (וגם לתלמידי תיכון שחושבים על החומר, למען האמת), והבעיה היחידה היא שהביטויים בו אינם מוגדרים היטב - אלא שלאנדרסון יש שם אחר לביטוי הימני של אפס חלקי אפס - ניחשתם נכון, כלומיתי. הפלא ופלא! נפתרה בעיה בת 1,200 שנים! גילינו שאפס בחזקת אפס, שעד כה היה לא מוגדר, הוא… לא מוגדר! בשלב הבא במצגת שלו אנדרסון כבר גולש למחוזות שגעון הגדלות. הוא מתיימר להיות מסוגל לבנות סופר-מחשבים בעזרת כלומיתי. לא רואים זאת במצגת, אבל במאמרים שלו הוא מציג את הרעיון יותר לעומק - מחשב שיכיל רק פקודה אחת, מסובכת משהו, של חישוב דמוי מכפלה סקלרית. אין ממש טעם להיכנס לשאלה האם היצור הזה הוא מה שנקרא Turing Complete, כלומר חזק כמו המודל המתמטי הסטנדרטי של מחשב - אני מוכן להניח שכן. מה שברור הוא שמבחינה תיאורטית הוא לא חזק יותר כל עוד מידע מיוצג בו בצורה דיגיטלית (כלומר, כל מספר בו מיוצג כרצף סופי של אפסים ואחדים או משהו דומה, כי לא ניתן לייצג כך את כל המספרים הממשיים) - הרי ניתן לסמלץ את כלומיתי בכל שפת תכנות בסיסית (תרגיל למתכנתים - אל תטרחו, יש דברים יותר מגניבים לעשות, כמו פרוייקט אוילר). כמובן שאם המחשב שלו עובד עם כל המספרים הממשיים, זה עשוי לתת לו כוח רב יותר; אבל גם מודלים שכאלו הם לא דבר חדש, ותוספת הכלומיתי, שהיא התרומה היחידה של אנדרסון, לא מוסיפה כלום.

אבל מה? אנדרסון משוכנע שהמחשבים שלו ירוצו בסדרי גודל יותר מהר מאשר המחשבים הקיימים. הרעיון המבריק שהוא מציג בשקף הוא ש”אין צורך בחיווט כדי לבחור או לקודד פקודות, כי יש רק פקודה אחת”. זה מטופש, כי מדובר כאן בטאטוא מתחת לשטיח של הסיבוכיות של תוכנית - אוקיי, אז יהיה יותר קל לבחור או לקודד פקודות, מסכים. אבל לך תכתוב תוכנית מחשב סבירה עם הפקודה האחת הזו - תצטרך להשתמש באותה פקודה הרבה מאוד פעמים, עם קלטים שונים, כדי להשיג תוצאות שבמחשבים בני זמננו משיגים בפקודת מחשב אחת שממומשת בצורה יעילה בחומרה, בעזרת אותם חיווטים שאנדרסון יוצא נגדם. כך זה באופן כללי בתכנות - אם יש לך שפת תכנות עם מספר פקודות מצומצם, כנראה שכדי לעבוד איתה בנוחות תצטרך “להרכיב” הרבה פקודות בסיסיות נוספות מתוך מעט הפקודות שיש לך. למעשה, ככל שהזמן עובר כך המחשבים עושים דברים מסובכים יותר ברמת החיווט הבסיסי (למשל, כפל וקטורי) ולא ברמת התוכנה, פשוט כי זה יעיל יותר. להמציא שפת תכנות של פקודה אחת זה בדיוק ההפך ממה שצריך כדי ליצור מחשבים יעילים. כמובן, אולי אני טועה - כשאינטל תפשוט את הרגל בגלל אנדרסון, אודה שטעיתי.

לקראת הסוף חושף אנדרסון לראווה את הטרחן הכפייתי שבו באופן מוחלט - הוא מתיימר לפתור עם הכלומיתי שלו את כל בעיות היקום, או לפחות לנסח מחדש את משוואות מקסוול והגרביטציה הקלאסית, ואז לאחד את האלקטרודינמיקה הקוונטית עם תורת הגרביטציה (אחד מהגביעים הקדושים של הפיזיקה המודרנית, אם איני טועה).

כל זה היה נותר בגדר שעשוע לא מזיק אלמלא התקשורת הקדישה למטורלל הזה זמן מסך יקר (זמן שאפשר היה להקדיש למתמטיקאים אמיתיים, שפותרים בעיות אמיתיות, גם אם לא כאלו שיש להן את תווית 1,200 השנים הסקסית), ואלמלא היו נותנים למטורלל הזה ללמד ילדי בית ספר את תורת הכלומיתי שלו. אמנם, אני לא חושב שהנזק לילדים יהיה גדול ביותר - הם בסך הכל לומדים מה זה NaN בשלב מוקדם מדי, שבו לא באמת צריך לדעת מהו. כשהם יגדלו הם כנראה יתקלו ב-NaN האמיתי, יראו שזה כמעט כמו כלומיתי, ואולי יתעניינו מספיק כדי לחפש הסבר למה הוא לא שווה לעצמו בעוד שכלומיתי כן. אם אנדרסון מעודד כך חשיבה, אולי הוא לא רע באופן מוחלט.


נהניתם? התעניינתם? אם תרצו, אתם מוזמנים לתת טיפ:

Buy Me a Coffee at ko-fi.com