एक छोटी सी तरह की भाषा जो ट्यूरिंग मशीनों को अनुकरण कर सकती है


11

मैं एक छोटी सी भाषा की तलाश कर रहा हूं जो 'कंविंस' छात्रों की मदद करती है कि ट्यूरिंग मशीन एक पर्याप्त सामान्य कंप्यूटिंग मॉडल है। यही है, एक भाषा जो उन भाषाओं की तरह दिखती है जिनका वे उपयोग करते हैं, लेकिन एक ट्यूरिंग मशीन पर अनुकरण करना भी आसान है।

Papadimitriou इस काम के लिए RAM मशीनों का उपयोग करता है, लेकिन मुझे डर है कि किसी अजीब चीज़ (एक ट्यूरिंग मशीन के रूप में) की तुलना किसी अन्य अजीब चीज़ (मूल रूप से, एक असेंबली लैंग्वेज) से करना कई छात्रों के लिए असंबद्ध होगा।

कोई भी सुझाव सबसे स्वागत योग्य होगा (विशेषकर यदि वे कुछ अनुशंसित साहित्य के साथ आए हों)


7
एक कारण है कि कंप्यूटरों को मूल रूप से असेंबली भाषा में प्रोग्राम किया गया था ... कंपाइलर या दुभाषिए लिखना तुच्छ नहीं है । और ट्यूरिंग मशीनों के लिए कंपाइलर या दुभाषिए लिखना शायद अधिक कठिन है।
पीटर शोर

पीएस के साथ कुछ हद तक असहमत होना चाहिए, एक टीएम संकलक एसटी या अन्य लगभग-स्नातक अभ्यासों जैसे फैक्टरिंग उदाहरणों को परिवर्तित करने की तुलना में बहुत कठिन नहीं है। वेब पर टॉप ट्यूरिंग मशीन सिमुलेटर भी देखें । यहाँ नमूना स्रोत कोड (उच्च-स्तरीय भाषा के लिए) के साथ रूबी में लिखी गई ट्यूरिंग मशीन संकलक का एक उदाहरण है । अफसोस, ऐसा नहीं है कि अधिक पॉलिश उपलब्ध हैं। यह एक महान ओपन सोर्स प्रोजेक्ट बनायेगा।
vzn

2
@ उमरसाहब, एक संपादन प्रश्न को पहले पृष्ठ तक पंप करता है। कृपया पुराने प्रश्न को संपादित न करें जब संपादित करें प्रश्न को बेहतर नहीं बनाते हैं। साथ ही बड़ी संख्या में प्रश्नों का संपादन करना जो पहले पृष्ठ पर नहीं हैं, अच्छा नहीं है क्योंकि यह नए प्रश्नों को पहले पृष्ठ से बाहर धकेलता है। धन्यवाद।
केवह

@kaveh समझ गया।
उमर शहाब

जवाबों:


15
  • यदि आपके छात्रों ने कोई कार्यात्मक प्रोग्रामिंग की है, तो मुझे पता है कि सबसे अच्छा तरीका है अनकैप्ड लैम्ब्डा कैलकुलस के साथ शुरू करना, और फिर SKI कॉम्बिनेटर में अनुवाद करने के लिए ब्रैकेट अमूर्त प्रमेय का उपयोग करना । फिर, आप और प्रमेयों का उपयोग करके यह दिखा सकते हैं कि ट्यूरिंग मशीनें एक आंशिक संयोजन बीजगणित बनाती हैं , और इसलिए SKI संयोजन की व्याख्या कर सकती हैं।u t mरोंnयूटी

    मुझे संदेह है कि यह सबसे सरल संभव तरीका है, लेकिन मुझे यह पसंद है कि यह कम्प्यूटेबिलिटी में कुछ सबसे मौलिक प्रमेयों पर टिकी हुई है (जो आप अन्य कारणों से कवर करना चाहते हैं)।

    ऐसा प्रतीत होता है कि कुछ महीने पहले मोंटोवरफ्लो पर इसी तरह के प्रश्न का उत्तर दिया था।

  • यदि आप सी-लाइक भाषा पर सेट हैं, तो आपका रास्ता बहुत अधिक रूखा हो जाएगा, क्योंकि उनके पास एक जटिल शब्दार्थ है, जिसे आप करना चाहते हैं

    1. दिखाएँ कि ट्यूरिंग मशीनें एक ही समय में एक ढेर और ढेर का अनुकरण कर सकती हैं, और
    2. दिखाएँ कि कैसे चर को ढेर के साथ लागू किया जा सकता है, और
    3. दिखाएँ कि प्रक्रिया कॉल को स्टैक के साथ लागू किया जा सकता है।

    यह एक संकलक वर्ग की अधिकांश सामग्री है, ईमानदारी से।


7

अंडरग्राउंड में मेरा प्रोफेसर का सिद्धांत साबित करता है कि एक एकल-टेप ट्यूरिंग मशीन एक बहु-टेप ट्यूरिंग मशीन को लागू कर सकती है। यह चर घोषणा को संभालता है: यदि किसी कार्यक्रम में छह चर घोषणाएं हैं, तो इसे आसानी से सात-टेप ट्यूरिंग मशीन (प्रत्येक चर के लिए एक टेप, और अंकगणितीय और समानता-जाँच जैसे कार्यों को करने में मदद करने के लिए एक "रजिस्टर" टेप पर लागू किया जा सकता है) टेप)। उन्होंने तब दिखाया कि कैसे मूल और WHILE छोरों को लागू किया जाए, और उस समय हमारे पास एक बुनियादी ट्यूरिंग-पूर्ण सी-लाइक भाषा थी। मुझे यह संतोषजनक लगा, वैसे भी।


6

मैं अभी सोच रहा हूं कि कैसे खुद को समझाऊं कि ट्यूरिंग मशीनें कम्प्यूटेशन का एक सामान्य मॉडल हैं। मैं इस बात से सहमत हूं कि कुछ मानक पाठ्यपुस्तकों, जैसे कि सिपर में चर्च-ट्यूरिंग थीसिस का मानक उपचार बहुत पूरा नहीं है। यहाँ एक स्केच है कि मैं ट्यूरिंग मशीनों से अधिक पहचानने योग्य प्रोग्रामिंग भाषा में कैसे जा सकता हूं।

एक ब्लॉक-संरचना प्रोग्रामिंग के साथ भाषा पर विचार करें ifऔर whileबयान, साथ गैर पुनरावर्ती नामित के साथ परिभाषित कार्यों और सबरूटीन्स, बूलियन यादृच्छिक चर और सामान्य बूलियन अभिव्यक्ति, और एक भी असीम बूलियन सरणी के साथ tape[n]एक पूर्णांक सरणी सूचक के साथ nकि वृद्धि की जा सकती है या कम कर, n++या n--। सूचक nशुरू में शून्य है और सरणी tapeशुरू में सभी शून्य है। तो, यह कंप्यूटर भाषा सी-लाइक या पायथन जैसी हो सकती है, लेकिन यह अपने डेटा प्रकारों में बहुत सीमित है। वास्तव में, वे इतने सीमित हैं कि हमारे पास nबूलियन अभिव्यक्ति में सूचक का उपयोग करने का एक तरीका भी नहीं है । ऐसा मानते हुएtapeकेवल दाईं ओर अनंत है, हम nकभी भी नकारात्मक होने पर पॉइंटर अंडरफ्लो "सिस्टम एरर" की घोषणा कर सकते हैं । साथ ही, हमारी भाषा में exitएक तर्क के साथ एक कथन है, बूलियन उत्तर को आउटपुट करने के लिए।

फिर पहला बिंदु यह है कि यह प्रोग्रामिंग भाषा ट्यूरिंग मशीन के लिए एक अच्छी विनिर्देशन भाषा है। आप आसानी से देख सकते हैं कि, टेप ऐरे को छोड़कर, कोड में केवल बहुत से संभावित राज्य हैं: इसके घोषित चर के सभी, और निष्पादन की वर्तमान रेखा, और इसके सबरूटीन स्टैक की स्थिति। उत्तरार्द्ध में केवल एक सीमित मात्रा में राज्य है, क्योंकि पुनरावर्ती कार्यों की अनुमति नहीं है। आप एक "कंपाइलर" की कल्पना कर सकते हैं जो इस प्रकार के कोड से "वास्तविक" ट्यूरिंग मशीन बनाता है, लेकिन उस का विवरण महत्वपूर्ण नहीं है। मुद्दा यह है कि हमारे पास एक प्रोग्रामिंग भाषा है जिसमें बहुत अच्छे वाक्यविन्यास हैं, लेकिन बहुत आदिम डेटा प्रकार हैं।

निर्माण के बाकी हिस्सों को लाइब्रेरी कार्यों और प्री-कंपोजिशन चरणों की सीमित सूची के साथ एक अधिक जीवंत प्रोग्रामिंग भाषा में परिवर्तित करना है। हम निम्नानुसार आगे बढ़ सकते हैं:

  1. एक precompiler के साथ, हम बूलियन डेटा प्रकार को ASCII जैसे बड़े लेकिन परिमित प्रतीक वर्णमाला में विस्तारित कर सकते हैं। हम मान सकते हैं कि tapeइस बड़ी वर्णमाला में मान लिया गया है। हम टेप की शुरुआत में एक मार्कर छोड़ सकते हैं ताकि पॉइंटर अंडरफ़्लो को रोका जा सके, और टेप के अंत में टीएम को स्केटिंग से अनन्तता तक रोकने के लिए टेप के अंत में एक चल मार्कर। हम प्रतीकों ifऔर whileबयानों के लिए बूलियन के बीच मनमाने ढंग से द्विआधारी संचालन को लागू कर सकते हैं । (वास्तव में ifइसे लागू किया जा सकता है while, अगर यह उपलब्ध नहीं था।)

  2. मैंमैं

  3. हम एक टेप को प्रतीक-मूल्यवान "मेमोरी" और दूसरे को अहस्ताक्षरित, पूर्णांक-मूल्यवान "रजिस्टरों" या "वैरिएबल" के रूप में नामित करते हैं। हम पूर्णांक बाइनरी को समाप्ति मार्करों के साथ पूर्णांक संग्रहीत करते हैं। हम पहले एक रजिस्टर की कॉपी और एक रजिस्टर के बाइनरी डिक्रीमेंट को लागू करते हैं। मेमोरी पॉइंटर के बढ़ने और घटने के साथ संयोजन करके, हम प्रतीक मेमोरी के यादृच्छिक अभिगम को लागू कर सकते हैं। बाइनरी जोड़ और पूर्णांक के गुणन की गणना करने के लिए हम फ़ंक्शन भी लिख सकते हैं। बिटवाइज़ ऑपरेशंस के साथ बाइनरी एड फंक्शन, और लेफ्ट शिफ्ट के साथ 2 से गुणा करना एक फंक्शन लिखना मुश्किल नहीं है। (या वास्तव में सही बदलाव, चूंकि यह थोड़ा-सा है।) इन आदिमताओं के साथ, हम लंबे गुणा एल्गोरिथ्म का उपयोग करके दो रजिस्टरों को गुणा करने के लिए एक फ़ंक्शन लिख सकते हैं।

  4. हम सूत्र का उपयोग करके एक-आयामी प्रतीक सरणी symbol[n]से दो-आयामी प्रतीक सरणी में मेमोरी टेप को पुनर्गठित कर सकते हैं । अब हम बाइनरी में एक अहस्ताक्षरित पूर्णांक को समाप्ति चिह्न के साथ व्यक्त करने के लिए एक-आयामी, यादृच्छिक-अभिगम, पूर्णांक-मूल्यवान स्मृति प्राप्त करने के लिए स्मृति की प्रत्येक पंक्ति का उपयोग कर सकते हैं । हम मेमोरी से एक पूर्णांक रजिस्टर में रीडिंग को लागू कर सकते हैं, और एक रजिस्टर से मेमोरी में लिख सकते हैं। कई विशेषताएं अब फ़ंक्शंस के साथ लागू की जा सकती हैं: हस्ताक्षरित और फ़्लोटिंग पॉइंट अंकगणित, प्रतीक तार आदि।symbol[x,y]n = (x+y)*(x+y) + ymemory[x]

  5. केवल एक और बुनियादी सुविधा को सख्ती से एक प्री-कंपाइलर की आवश्यकता होती है, अर्थात पुनरावर्ती कार्य। यह एक तकनीक के साथ किया जा सकता है जो व्यापक रूप से व्याख्या की गई भाषाओं को लागू करने के लिए उपयोग किया जाता है। हम प्रत्येक उच्च-स्तरीय, पुनरावर्ती फ़ंक्शन को एक नाम स्ट्रिंग प्रदान करते हैं, और हम निम्न-स्तरीय कोड को एक बड़े whileलूप में व्यवस्थित करते हैं जो सामान्य पैरामीटर के साथ कॉल स्टैक बनाए रखता है: कॉलिंग पॉइंट, कॉल फ़ंक्शन और तर्कों की एक सूची।

इस बिंदु पर, निर्माण में एक उच्च-स्तरीय प्रोग्रामिंग भाषा की पर्याप्त विशेषताएं हैं जो आगे की कार्यक्षमता सीएस सिद्धांत के बजाय प्रोग्रामिंग भाषाओं और संकलकों का विषय है। इस विकसित भाषा में ट्यूरिंग-मशीन सिम्युलेटर लिखना भी पहले से आसान है। भाषा के लिए एक आत्म-संकलक लिखना बिल्कुल आसान नहीं है, लेकिन निश्चित रूप से मानक है। बेशक आपको इस सी-सी या पायथन जैसी भाषा में एक कोड से बाहरी टीएम बनाने के लिए बाहरी कंपाइलर की आवश्यकता होती है, लेकिन यह किसी भी कंप्यूटर भाषा में किया जा सकता है।

ध्यान दें कि यह स्केच किया गया कार्यान्वयन न केवल पुनरावर्ती कार्य वर्ग के लिए तर्कवादियों के चर्च-ट्यूरिंग थीसिस का समर्थन करता है, बल्कि नियतात्मक गणना पर लागू होने वाले विस्तारित (यानी, बहुपद) चर्च-ट्यूरिंग थीसिस का भी समर्थन करता है। दूसरे शब्दों में, इसमें बहुपद ओवरहेड है। वास्तव में, अगर हमें एक रैम मशीन या (मेरा व्यक्तिगत पसंदीदा) एक पेड़-टेप टीएम दिया जाता है, तो इसे रैम मेमोरी के साथ सीरियल कम्प्यूटेशन के लिए पॉलीग्लारिथमिक ओवरहेड में कम किया जा सकता है।


5

LLVM संकलक एक नए आर्किटेक्चर में एक को "सीधे प्लग" करने की अनुमति देता है। वे इस लेखन को एक नया बैक-एंड कहते हैं , और इसे कैसे करें, इसके लिए विस्तृत निर्देश और उदाहरण देते हैं। मुझे संदेह है कि आपको रैंडम एक्सेस मेमोरी के संबंध में कुछ हुप्स के माध्यम से कूदना होगा, यदि आप रैम ट्यूरिंग मशीन को लक्षित नहीं करना चाहते हैं, लेकिन यह निश्चित रूप से उल्लेखनीय है, क्योंकि मैंने कई परियोजनाएं देखी हैं जो एलएलवीएम उत्पन्न करने के लिए हैं। VHDL या अन्य बहुत अलग मशीन भाषाएं।

यह एक ट्यूरिंग मशीन के लिए कोड उत्पन्न करने वाले अत्याधुनिक ऑप्टिमाइज़िंग कंपाइलर (कई मायनों में LLVM जीसीसी से अधिक उन्नत है) का दिलचस्प प्रभाव होगा।


1

मैं सीएस सिद्धांत में नहीं हूं, लेकिन मेरे पास कुछ काम है जो उपयोगी हो सकते हैं। मैंने एक और दृष्टिकोण लिया है। मैंने सी के एक छोटे उप-सेट के साथ सीधे प्रोग्राम करने योग्य एक साधारण प्रोसेसर डिज़ाइन किया है। कोई विधानसभा कोड नहीं है, केवल सी-जैसे कोड है। आप उसी टूल का उपयोग कर सकते हैं जिसका मैंने उपयोग किया था और अपने ट्यूरिंग मशीन सिम्युलेटर को डिजाइन करने के लिए इस प्रोसेसर को संशोधित किया था। इस प्रोसेसर को डिजाइन करने, अनुकरण करने और परीक्षण करने में मुझे 4 दिन लगे, कुछ निर्देश! मेरे द्वारा उपयोग किए जाने वाले टूल ने मुझे वास्तविक VHDL सिंथेटेबल कोड उत्पन्न करने में सक्षम बनाया। यह एक सच्चा काम करने वाला प्रोसेसर है।

यहाँ एक कार्यक्रम कैसा दिखता है: सी-लाइक असेंबली प्रोग्राम का उदाहरण

यहाँ थीस टूल्स का उपयोग करने वाले प्रोसेसर की एक तस्वीर दी गई है। प्रोसेसर सर्किट

उपकरण "नोवाकॉड स्टूडियो" एक उच्च स्तरीय भाषा हार्डवेयर विवरण भाषा का उपयोग करता है। एक उदाहरण के रूप में, यहां प्रोग्राम काउंटर का कोड है: psC - समानांतर और तुल्यकालिक C - कोड नमूना पर्याप्त बात करना, अगर किसी को दिलचस्पी है, तो यहां मुझसे संपर्क करने के लिए सार्वजनिक जानकारी है: https://repertoire.uqac.ca/Fiche.aspx?id=JjstNznH0&link=1

ल्यूक


क्या पतों को खोजने के लिए मेमोरी एड्रेसिंग बिट्स के एक निश्चित # का उपयोग करता है?
vzn

हां, लेकिन मेमोरी साइज (int DataMemory [SIZE] को बदलना सरल है। भाषा चर लंबाई पूर्णांक (int: 10) का समर्थन करती है। लेकिन, चूंकि यह FPGA को लक्षित करती है, सरणी स्थैतिक और आयाम स्थिर है।
ल्यूक मोरीन

1

यहां उपयोगकर्ता GMB द्वारा प्रस्तुत विचार को कैसे लिया जाए (एक टेप के साथ ट्यूरिंग मशीन एन टेप के साथ एक ट्यूरिंग मशीन को एक टेप में एन टेप को इंटरलेस करके और उन टेपों में से किसी एक को एक बार में एन स्थानों को कूदकर पढ़ सकते हैं, एक ट्यूरिंग। एन टेप के साथ मशीन लागू कर सकते हैं ...) और एक ट्यूरिंग मशीन प्रोग्राम लिखिए जो एक सरलीकृत रैम-मशीन को लागू करता है। रैम-मशीन वास्तव में उपलब्ध एलएलवीएम या जीसीसी बैकएंड के साथ कुछ सरलीकृत, वास्तविक, सीपीयू हो सकती है। फिर GCC / LLVM का उपयोग उस CPU के लिए C प्रोग्राम को क्रॉस-कंपाइल करने के लिए किया जा सकता है और RAM-मशीन का अनुकरण करने वाली Turing machine प्रोग्राम, GCC / LLVM के आउटपुट को सिम्युलेटेड RAM- मशीन द्वारा RAM- मशीन का सिमुलेशन चलाता है। ट्यूरिंग मशीन का कार्यान्वयन कुछ बहुत ही सरल सी कोड हो सकता है जो एक छोटी सी फ़ाइल में फिट होता है।

रैम-मशीन का क्या संबंध है, फिर एक डेमो प्रोजेक्ट मौजूद है, जहां एक 32 बिट सीपीयू को 8 बिट माइक्रोकंट्रोलर और सिम्युलेटेड 32 बिट सीपीयू बूट लिनक्स द्वारा सिम्युलेटेड किया जाता है। नरक के रूप में धीमा, लेकिन लेखक , दिमित्री ग्रिनबर्ग के अनुसार , इसने काम किया। हो सकता है कि ज़ाइलिन सीपीयू (GitHub यूज़र ज़ाइलिन) सिमुलिबल रैम-मशीन के लिए एक व्यवहार्य विकल्प हो। एक और आरएआरआर-मशीन उम्मीदवार निकलस विर्थ द्वारा प्रोजेक्टऑबरन डॉट कॉम हो सकता है ।

(मेरे पाठ में "डॉट" और "कॉम" इस तथ्य के कारण हैं कि मैंने अभी, 2015_10_21, cstheory.stackexchange पर अपना खाता पंजीकृत किया है और वेब-ऐप को इस तथ्य के बावजूद, नौसिखिए उपयोगकर्ताओं के लिए 2 से अधिक लिंक की अनुमति नहीं देता है वे स्वचालित रूप से मेरे अन्य स्टैकएक्सचेंज खातों से देख सकते हैं कि मैं बेवकूफ हो सकता हूं, लेकिन मैं ट्रोल नहीं हूं।)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.