टाइप इनफरेंस

टाइप इनफरेंस का तात्पर्य औपचारिक भाषा में अभिव्यक्ति के प्रकार का स्वचालित पता लगाना है। इनमें प्रोग्रामिंग भाषाएं और गणितीय प्रकार की प्रणालियाँ सम्मिलित हैं, लेकिन कंप्यूटर विज्ञान और भाषा विज्ञान की कुछ शाखाओं में प्राकृतिक भाषाएँ भी सम्मिलित हैं।

गैरतकनीकी स्पष्टीकरण
सबसे सामान्य दृष्टिकोण में प्रकारों को उस प्रकार की किसी ऑब्जेक्ट के लिए संभावित गतिविधियों का सुझाव देने और प्रतिबंधित करने के लिए निर्दिष्ट उपयोग से जोड़ा जा सकता है। भाषा में कई संज्ञाएँ ऐसे उपयोग निर्दिष्ट करती हैं। उदाहरण के लिए, लीश शब्द लाइन शब्द की तुलना में एक अलग उपयोग को इंगित करता है। किसी चीज़ को मेज़ कहना उसे फायरवुड कहने की तुलना में किसी अन्य पदनाम को इंगित करता है, हालाँकि भौतिक रूप से यह वही चीज़ हो सकती है। जबकि उनके भौतिक गुण चीज़ों को कुछ उद्देश्यों के लिए उपयोग योग्य बनाते हैं, वे विशेष पदनामों के अधीन भी होते हैं। यह विशेष रूप से अमूर्त क्षेत्रों में स्तिथि है, अर्थात् गणित और कंप्यूटर विज्ञान, जहां सामग्री अंततः केवल बिट्स या सूत्र है।

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

टाइपिंग में, एक अभिव्यक्ति एक प्रकार का विरोध करती है। उदाहरण के लिए, $$4$$, $$2+2$$, और $$2\cdot 2$$ सभी प्रकार के साथ अलग-अलग शब्द हैं $$\mathrm{nat}$$ प्राकृतिक संख्याओं के लिए. परंपरागत रूप से, अभिव्यक्ति के बाद कोलन और उसका प्रकार आता है, जैसे $$2 : \mathrm{nat}$$. इसका मतलब यह है कि मूल्य $$2$$ प्रकार का है $$\mathrm{nat}$$. इस फॉर्म का उपयोग नए नामों की घोषणा करने के लिए भी किया जाता है, जैसे $$n : \mathrm{nat}$$, बहुत कुछ जासूस डेकर शब्दों द्वारा एक दृश्य में नए चरित्र को प्रस्तुत करने जैसा है ।

कहानी के विपरीत, जहाँ पदनाम धीरे-धीरे सामने आते हैं, औपचारिक भाषाओं में ऑब्जेक्ट को प्रायः प्रारम्भ से ही उनके प्रकार से परिभाषित करना पड़ता है। इसके अतिरिक्त, यदि अभिव्यक्तियाँ अस्पष्ट हैं, तो इच्छित उपयोग को स्पष्ट करने के लिए प्रकारों की आवश्यकता हो सकती है। उदाहरण के लिए, अभिव्यक्ति 2 का प्रकार n हो सकता है, लेकिन इसे परिमेय या वास्तविक संख्या के रूप में या यहां तक कि सरल पाठ के रूप में भी पढ़ा जा सकता है।

परिणामस्वरूप, प्रोग्राम या प्रमाण प्रकारों से इतने अधिक बोझिल हो सकते हैं कि उन्हें संदर्भ से निकालना वांछनीय है। यह अलिखित अभिव्यक्ति (अपरिभाषित नामों सहित) के उपयोगों को एकत्रित करके संभव हो सकता है। उदाहरण के लिए, यदि किसी अभिव्यक्ति में अभी तक अपरिभाषित नाम n का उपयोग किया जाता है $$n + 2$$, कोई यह निष्कर्ष निकाल सकता है कि n न्यूनतम संख्या है। किसी अभिव्यक्ति और उसके संदर्भ से प्रकार निकालने की प्रक्रिया प्रकार अनुमान है।

सामान्य तौर पर न केवल ऑब्जेक्ट, बल्कि गतिविधियां भी प्रकार की होती हैं और इन्हें केवल उनके उपयोग से ही प्रस्तुत किया जा सकता है। स्टार ट्रेक कहानी के लिए, ऐसी अज्ञात गतिविधि उत्साहजनक हो सकती है, जिसे कहानी के प्रवाह के लिए केवल क्रियान्वित किया जाता है और कभी औपचारिक रूप से प्रस्तुत नहीं किया जाता है। फिर भी जो होता है उसके आधार पर कोई इसके प्रकार (परिवहन) का अनुमान लगा सकता है। इसके अतिरिक्त, ऑब्जेक्ट और गतिविधियों दोनों का निर्माण उनके भागों से किया जा सकता है। ऐसी सेटिंग में, प्रकार का अनुमान न केवल अधिक जटिल हो सकता है, बल्कि अधिक सहायक भी हो सकता है, क्योंकि यह एक रचित दृश्य में हर चीज का पूरा विवरण एकत्र करने की अनुमति देता है, जबकि अभी भी विरोधाभासी या अनपेक्षित उपयोगों का पता लगाने में सक्षम है।

प्रकार-जाँच बनाम प्रकार-अनुमान
टाइपिंग में, एक अभिव्यक्ति E, टाइप T के विपरीत होती है, जिसे औपचारिक रूप से E : T के रूप में लिखा जाता है। सामान्यतः टाइपिंग केवल कुछ संदर्भों में ही समझ में आती है, जिसे यहां छोड़ दिया गया है।

इस सेटिंग में, निम्नलिखित प्रश्न विशेष रूप से रुचिकर हैं:


 * E : T? इस स्तिथि में, अभिव्यक्ति E और प्रकार T दोनों दिए गए हैं। अब, क्या E वास्तव में एक T है? इस परिदृश्य को प्रकार-जाँच के रूप में जाना जाता है।
 * E : _? यहाँ केवल अभिव्यक्ति ही ज्ञात है। यदि ई के लिए प्रकार प्राप्त करने का कोई तरीका है, तो हमने प्रकार अनुमान पूरा कर लिया है।
 * _ : T? विपरीत स्थिति। केवल एक प्रकार दिया गया है, क्या इसके लिए कोई अभिव्यक्ति है या प्रकार का कोई मूल्य नहीं है? क्या कोई T का उदाहरण है?

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

प्रोग्रामिंग भाषाओं में प्रकार
प्रकार कुछ दृढ़तापूर्वक सांख्यिकीय रूप से टाइप की गई भाषाओं में उपस्थित एक विशेषता है। यह प्रायः सामान्य रूप से कार्यात्मक प्रोग्रामिंग भाषाओं की विशेषता होती है। कुछ भाषाएँ जिनमें प्रकार का अनुमान सम्मिलित है उनमें C23, C++11, C# (संस्करण 3.0 से प्रारम्भ), चैपल, क्लीन, क्रिस्टल, डी, एफ#, फ्रीबेसिक, गो, हास्केल, जावा (प्रारम्भ) सम्मिलित हैं। संस्करण 10 के साथ), जूलिया, कोटलिन, एमएल, निम, ओकैमल, ओपा, क्यू#, आरपाइथॉन, रस्ट, स्काला, स्विफ्ट, टाइपस्क्रिप्ट, वैला, डार्ट, और विज़ुअल बेसिक [12] (संस्करण 9.0 से प्रारम्भ)। उनमें से अधिकांश प्रकार के अनुमान के सरल रूप का उपयोग करते हैं; हिंडले-मिलनर प्रकार प्रणाली अधिक पूर्ण प्रकार का अनुमान प्रदान कर सकती है। प्रकारों का अनुमान लगाने की क्षमता स्वचालित रूप से कई प्रोग्रामिंग कार्यों को आसान बनाती है, जिससे प्रोग्रामर प्रकार की जांच की अनुमति देते हुए प्रकार एनोटेशन को छोड़ने के लिए स्वतंत्र हो जाता है।

कुछ प्रोग्रामिंग भाषाओं में, सभी मानों में संकलन समय पर स्पष्ट रूप से घोषित एक डेटा प्रकार होता है, जो रन टाइम (प्रोग्राम जीवनचक्र चरण) | रन-टाइम पर एक विशेष अभिव्यक्ति द्वारा ग्रहण किए जा सकने वाले मानों को सीमित करता है। तेजी से, सही समय पर संकलन रन टाइम और कंपाइल टाइम के बीच अंतर को धुंधला कर देता है। हालाँकि, ऐतिहासिक रूप से, यदि किसी मान का प्रकार केवल रन-टाइम पर ज्ञात होता है, तो ये भाषाएँ गतिशील रूप से टाइप की जाती हैं। अन्य भाषाओं में, अभिव्यक्ति का प्रकार केवल संकलन के समय ही ज्ञात होता है; ये भाषाएँ स्थिर रूप से टाइप की गई हैं। अधिकांश सांख्यिकीय रूप से टाइप की गई भाषाओं में, इनपुट और आउटपुट प्रकार के फ़ंक्शन और स्थानीय चर को सामान्यतः टाइप एनोटेशन द्वारा स्पष्ट रूप से प्रदान किया जाना चाहिए। उदाहरण के लिए, एएनएसआई सी में: इस फ़ंक्शन परिभाषा का प्रकार हस्ताक्षर,, यह घोषणा करता है   एक फ़ंक्शन है जो एक तर्क, एक पूर्णांक (कंप्यूटर विज्ञान) लेता है, और एक पूर्णांक लौटाता है।   घोषित करता है कि स्थानीय चर   एक पूर्णांक है. प्रकार के अनुमान का समर्थन करने वाली एक काल्पनिक भाषा में, कोड को इस तरह लिखा जा सकता है: यह उसी तरह है जैसे डार्ट भाषा में कोड लिखा जाता है, सिवाय इसके कि यह नीचे वर्णित कुछ अतिरिक्त बाधाओं के अधीन है। संकलन समय पर सभी वेरिएबल्स के प्रकारों का अनुमान लगाना संभव होगा। उपरोक्त उदाहरण में, कंपाइलर उस  का अनुमान लगाएगा और   में पूर्णांक प्रकार है क्योंकि स्थिरांक 1 प्रकार पूर्णांक है, और इसलिए   एक फ़ंक्शन   है। वेरिएबल का उपयोग कानूनी तरीके से नहीं किया जाता है, इसलिए इसका कोई प्रकार नहीं होगा।

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

हालाँकि, अगली पंक्ति में दशमलव जोड़कर परिणाम2 की गणना की जाती है  फ़्लोटिंग-पॉइंट अंकगणित के साथ, जिसके उपयोग में विरोध उत्पन्न होता है   पूर्णांक और फ़्लोटिंग-पॉइंट अभिव्यक्ति दोनों के लिए। ऐसी स्थिति के लिए सही प्रकार-अनुमान एल्गोरिदम को #हिंडले-मिलनर प्रकार अनुमान एल्गोरिदम के रूप में जाना जाता है और 1982 से इसे सही माना जाता है। यह पिछले अनुमानों पर दोबारा गौर करता है और प्रारम्भ से ही सबसे सामान्य प्रकार का उपयोग करता है: इस स्तिथि में फ्लोटिंग- बिंदु। हालाँकि इसके हानिकारक प्रभाव हो सकते हैं, उदाहरण के लिए प्रारम्भ से ही फ़्लोटिंग-पॉइंट का उपयोग करने से सटीक समस्याएं आ सकती हैं जो पूर्णांक प्रकार के साथ नहीं होतीं।

हालाँकि, प्रायः, विकृत प्रकार-अनुमान एल्गोरिदम का उपयोग किया जाता है जो पीछे नहीं जा सकता है और इसके बजाय ऐसी स्थिति में एक त्रुटि संदेश उत्पन्न करता है। यह व्यवहार बेहतर हो सकता है क्योंकि प्रकार का अनुमान हमेशा एल्गोरिदमिक रूप से तटस्थ नहीं हो सकता है, जैसा कि पिछले फ़्लोटिंग-पॉइंट परिशुद्धता मुद्दे द्वारा दर्शाया गया है।

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

अंत में, जटिल प्रकार-अनुमान एल्गोरिदम का एक महत्वपूर्ण नकारात्मक पक्ष यह है कि परिणामी प्रकार अनुमान संकल्प मनुष्यों के लिए स्पष्ट नहीं होगा (विशेष रूप से बैकट्रैकिंग के कारण), जो हानिकारक हो सकता है क्योंकि कोड मुख्य रूप से मनुष्यों के लिए समझने योग्य है।

जस्ट-इन-टाइम संकलन का हालिया प्रवर्तन हाइब्रिड दृष्टिकोणों की अनुमति देता है जहां विभिन्न कॉलिंग संदर्भ द्वारा प्रदान किए गए तर्कों के प्रकार को संकलन समय पर जाना जाता है, और एक ही फ़ंक्शन के बड़ी संख्या में संकलित संस्करण उत्पन्न कर सकते हैं। प्रत्येक संकलित संस्करण को विभिन्न प्रकारों के सेट के लिए अनुकूलित किया जा सकता है। उदाहरण के लिए, जस्ट-इन-टाइमसंकलन add_one के न्यूनतम दो संकलित संस्करण की अनुमति देता है:


 * एक संस्करण जो पूर्णांक इनपुट स्वीकार करता है और अंतर्निहित प्रकार रूपांतरण का उपयोग करता है।
 * एक संस्करण जो फ़्लोटिंग-पॉइंट नंबर को इनपुट के रूप में स्वीकार करता है और पूरे फ़्लोटिंग पॉइंट निर्देशों का उपयोग करता है।

तकनीकी विवरण
प्रकार अनुमान, संकलन समय पर किसी अभिव्यक्ति के प्रकार को आंशिक रूप से या पूरी तरह से स्वचालित रूप से निकालने की क्षमता है। कंपाइलर प्रायः किसी चर के प्रकार या फ़ंक्शन के प्रकार के हस्ताक्षर का अनुमान लगाने में सक्षम होता है, बिना किसी स्पष्ट प्रकार के एनोटेशन दिए। कई स्थितियों में, किसी प्रोग्राम से टाइप एनोटेशन को पूरी तरह से हटाना संभव है यदि टाइप इंट्रेंस सिस्टम पर्याप्त सशक्त है, या प्रोग्राम या भाषा काफी सरल है।

किसी अभिव्यक्ति के प्रकार का अनुमान लगाने के लिए आवश्यक जानकारी प्राप्त करने के लिए, कंपाइलर या तो इस जानकारी को उसके उप-अभिव्यक्तियों के लिए दिए गए प्रकार के एनोटेशन के समग्र और बाद में कमी के रूप में इकट्ठा करता है, या विभिन्न परमाणु मूल्यों के प्रकार की अंतर्निहित समझ के माध्यम से (उदाहरण के लिए सत्य: बूल; 42: पूर्णांक; 3.14159: वास्तविक; आदि)। यह अंतर्निहित रूप से टाइप किए गए परमाणु मानों के लिए अभिव्यक्तियों की अंतिम कमी की पहचान के माध्यम से है कि एक प्रकार की अनुमान लगाने वाली भाषा के लिए कंपाइलर एक प्रोग्राम को बिना टाइप एनोटेशन के पूरी तरह से संकलित करने में सक्षम है।

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

प्रकार के अनुमान की कुछ विधियाँ बाधा संतुष्टि या संतुष्टि मॉड्यूलो सिद्धांतों पर आधारित हैं।

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

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

हिंडले-मिलनर प्रकार अनुमान एल्गोरिथ्म
प्रकार का अनुमान लगाने के लिए सबसे पहले उपयोग किए जाने वाले एल्गोरिदम को अब अनौपचारिक रूप से हिंडले-मिलनर एल्गोरिदम कहा जाता है, हालांकि एल्गोरिदम का श्रेय उचित रूप से दमास और मिलनर को दिया जाना चाहिए।

इस एल्गोरिथ्म का मूल सरल रूप से टाइप किए गए लैम्ब्डा कैलकुलस के लिए प्रकार अनुमान एल्गोरिदम है जिसे 1958 में हास्केल करी और रॉबर्ट फेयस द्वारा तैयार किया गया था। 1969 में जे. रोजर हिंडले ने इस कार्य को आगे बढ़ाया और साबित किया कि उनका एल्गोरिथ्म हमेशा सबसे सामान्य प्रकार का अनुमान लगाता है। 1978 में रॉबिन मिलनर, ने हिंडले के काम से स्वतंत्र रूप से एक समतुल्य एल्गोरिदम, एल्गोरिदम डब्ल्यू प्रदान किया। 1982 में लुइस डेमास ने अंततः साबित कर दिया कि मिलनर का एल्गोरिदम पूर्ण है और इसे बहुरूपी संदर्भों के साथ सिस्टम का समर्थन करने के लिए विस्तारित किया गया था।

सबसे सामान्य प्रकार का उपयोग करने के दुष्प्रभाव
डिज़ाइन के अनुसार, प्रकार का अनुमान, विशेष रूप से सही (बैकट्रैकिंग) प्रकार का अनुमान सबसे सामान्य प्रकार के उपयुक्त उपयोग को प्रस्तुत करेगा, हालाँकि, इसके निहितार्थ हो सकते हैं क्योंकि अधिक सामान्य प्रकार हमेशा एल्गोरिथम रूप से तटस्थ नहीं हो सकते हैं, विशिष्ट स्तिथि ये हैं:
 * फ़्लोटिंग-पॉइंट को एक सामान्य प्रकार का पूर्णांक माना जा रहा है, जबकि फ़्लोटिंग-पॉइंट सटीक मुद्दों को प्रस्तुत करेगा।
 * भिन्न/गतिशील प्रकारों को अन्य प्रकारों के एक सामान्य प्रकार के रूप में माना जा रहा है, जो कास्टिंग नियमों और तुलनाओं को प्रस्तुत करेगा जो भिन्न हो सकते हैं, उदाहरण के लिए, इस प्रकार के प्रकार संख्यात्मक परिवर्धन और स्ट्रिंग संयोजन दोनों के लिए '+' ऑपरेटर का उपयोग करते हैं, लेकिन कौन सा ऑपरेशन किया जाता है यह स्थिर के बजाय गतिशील रूप से निर्धारित किया जाता है।

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

बाहरी संबंध

 * Archived e-mail message by Roger Hindley, explains history of type inference
 * Polymorphic Type Inference by Michael Schwartzbach, gives an overview of Polymorphic type inference.
 * Basic Typechecking paper by Luca Cardelli, describes algorithm, includes implementation in Modula-2
 * Implementation of Hindley-Milner type inference in Scala, by Andrew Forrest (retrieved July 30, 2009)
 * What is Hindley-Milner? (and why is it cool?) Explains Hindley-Milner, examples in Scala
 * What is Hindley-Milner? (and why is it cool?) Explains Hindley-Milner, examples in Scala