תורת החישוביות/משפט הרקורסיה: הבדלים בין גרסאות בדף
תוכן שנמחק תוכן שנוסף
←תוכניות המייצרות את עצמן: הללויה. |
מ ←מכונת־טיורניג מייצרת עצמה: הגהה, עיצוב |
||
שורה 29:
בשפה הפורמלית שפיתחנו עד כה, אין "קוד של תוכנה" אלא יש מכונת־טיורינג <math>M</math>, שמכילה מצבים, מעברים וכו'. ראינו, שלכל מכונה יש '''קידוד''' <math>\langle M \rangle</math> שמתאר את המ״ט באופן חד-חד ערכי. לכן השאלה שלנו היא, האם (ואיך) ניתן לבנות מכונה <math>M</math> שכאשר מפעילים אותה, על סרט ריק, עוצרת כאשר על סרט הזיכרון מופיעה המחרוזת <math>\langle M \rangle</math>.
נביט על הפעולה <code>"הדפס כפלט את המחרוזת הבאה"</code>. עבור מ״ט ה"מחרוזת הבאה" יכולה להופיע בשני מקומות: או שהיא מופיעה על הסרט או שהיא מקודדת כחלק ממצבי המכונה <math>Q</math> ומפונקציה המעברים <math>\delta</math>. ברור שאם המחרוזת כבר נמצאת על הסרט, אז המצב די פשוט, אבל איך המחרוזת הגיעה לסרט הזיכרון מלכתחילה (הרי המכונה מתחילה כשהסרט ריק)? כלומר, ברור שההתחלה חייבת להיות הדפסת מחרוזת כלשהי על הסרט, כאשר המחרוזת ראשית מקודדת במצבים והמעברים של המכונה.
נזכיר שלכל מחרוזת קבועה
האם
כעת נביט שוב בפתרון הפסאודו־קוד שלעיל. המחרוזת שאנחנו כותבים שם '''אינה הקוד''' אלא רק מחצית הקוד, אותו יש לרשום פעמיים. בעצם יש לנו שתי פעולות שמבוצעות שם:
שורה 42:
המכונה <math>A</math> מתחילה כאשר המחרוזת x כבר קיימת על הסרט. איך x הגיעה לסרט? ע״י המכונה <math>B_x</math>. כלומר, אנחנו בונים בעצם מכונה שקודם מריצה את B ואח"כ את A. נקרא למכונה זו <math>M</math> ונסמן <math>\langle M\rangle = \langle B_x\rangle \langle A\rangle </math> לציין שהקידוד של המכונה שמריצה את B ואח״כ את A הוא הקידוד של B ולאחריו הקידוד של A.
הפעולה של מכונה <math>A</math> היא פשוטה: היא לוקחת את המחרוזת x וכותבת אותה "פעמים" על הסרט. כלומר, אחרי הרצת המכונה <math>M</math>, סרט הזיכרון יכיל את התוכן <math>xx</math>:
<center><math>(empty) \
אבל זה לא בדיוק מה שרצינו. הבדל אחד, למשל, הוא שהקידוד של <math>M</math> מכיל בהתחלה את <math>\langle B_x \rangle</math> ולא את x ישירות.
קל לתקן את ההבדל הנ״ל: נשנה את <math>A</math> כך שבמקום להדפיס את x פעמיים, תדפיס את <math>B_x</math> (ולאחריו תשאיר את המחרוזת x שגבר נמצאת בזיכרון). כפי שראינו לעיל, אם x היא מחרוזת קבועה אז קל לבנות את <math>B_x</math>: לכל אות ב־x בונים מצב ומעבר מתאים של <math>B_x</math>.
{{אתגר|בנה מ״ט שעל הקלט x משנה את סרט הזיכרון כך שיופיע הקידוד של <math>B_x</math> המתאימה{{רווח קשיח|2}}}}
נריץ את המכונה M שבנינו עד כה ונראה שמתקבל הפלט <math> \langle B_x\rangle\ x</math> (מאד דומה למה שרצינו!):
<center><math>(empty) \
נותר צעד אחרון - להגדיר מהי המחרוזת הקבועה x ?{{ש}}
הפלט שקיבלנו עד כה הוא <math>\langle B_x \rangle \langle
לסיכום, נגדיר מ״ט שמייצרת את הקידוד של עצמה. המכונה <math>M</math> על קלט כלשהו w:
# מחק את הזיכרון והרץ את <math>B_{\langle A\rangle}</math>
#הרץ את המכונה A (על סרט הזיכרון הנוכחי).
לאחר השלב הראשון סרט הזיכרון יכיל את המחרוזת <math>\langle A\rangle</math>. בשלב השני המכונה A מופעלת על המחרוזת <math>\langle A\rangle</math> (שזו מבחינתה מחרוזת סתמית לכל דבר), ומייצרת על הסרט את הקידוד <math>B_{\langle A \rangle}</math>, ושמה אותו על הסרט לפני המחרוזת הקיימת שם. בסוף התהליך הסרט
==לקריאה נוספת==
|