इसलिए मैंने इसके बारे में थोड़ा और सोचा और कुछ प्रगति की। यहां एक जुझारू शैली में मार्टिन-लोफ के आनंदपूर्ण सरल (लेकिन असंगत) Set : Set
सिस्टम को एन्कोडिंग पर एक पहला छुरा है। यह खत्म करने का अच्छा तरीका नहीं है, लेकिन यह शुरू करने के लिए सबसे आसान जगह है। इस प्रकार के सिद्धांत का सिंटैक्स केवल लैम्बडा-कैलकुलस है जिसमें टाइप एनोटेशन, पाई-टाइप और एक ब्रह्मांड सेट है।
लक्ष्य प्रकार सिद्धांत
पूर्णता के लिए, मैं नियम प्रस्तुत करूंगा। प्रसंग वैधता सिर्फ यह कहती है कि आप खाली से समीपवर्ती ताज़े चर का निवास करके संदर्भों का निर्माण कर सकते हैं Set
।
G |- valid G |- S : Set
. |- valid G, x:S |- valid
और अब हम कह सकते हैं कि किसी भी संदर्भ में शब्दों के लिए प्रकारों को कैसे संश्लेषित किया जाए, और कुछ प्रकार के परिवर्तनों को उन शब्दों के कम्प्यूटेशनल व्यवहार में कैसे बदला जाए।
G |- valid G |- S : Set G |- T : Pi S \ x:S -> Set
G |- Set : Set G |- Pi S T : Set
G |- S : Set G, x:S |- t : T x G |- f : Pi S T G |- s : S
G |- \ x:S -> t : Pi S T G |- f s : T s
G |- valid G |- s : S G |- T : Set
G |- x : S G |- s : T
मूल से एक छोटे से बदलाव में, मैंने लंबो को एकमात्र बाध्यकारी ऑपरेटर बनाया है, इसलिए पाई का दूसरा तर्क एक फ़ंक्शन होना चाहिए जिस तरह से रिटर्न प्रकार इनपुट पर निर्भर करता है। अधिवेशन (उदाहरण के तौर पर अगाडा में, लेकिन दुख की बात हैस्केल में नहीं), लैम्ब्डा का दायरा जहाँ तक संभव हो सके, तब तक फैलता है, इसलिए जब आप उच्च-क्रम वाले ऑपरेटर का अंतिम तर्क देते हैं, तो आप अक्सर असंबद्ध को छोड़ सकते हैं। वह पी के साथ। आपका अगड़ा टाइप (x : S) -> T
बन जाता है Pi S \ x:S -> T
।
( पाचन । लैंबडा पर प्रकार एनोटेशन आवश्यक हैं यदि आप अमूर्त के प्रकार को संश्लेषित करने में सक्षम होना चाहते हैं । यदि आप अपने मोडस ऑपरेंडी के रूप में टाइप चेकिंग पर स्विच करते हैं, तो आपको अभी भी बीटा-रेडिएशन की जांच करने के लिए एनोटेशन की आवश्यकता है (\ x -> t) s
, जैसे कि आपके पास कोई रास्ता नहीं है। संपूर्ण भागों के प्रकारों का अनुमान लगाने के लिए। मैं आधुनिक डिजाइनरों को सलाह देता हूं कि वे प्रकारों की जाँच करें और बहुत ही वाक्य रचना से बीटा-रिडेक्स को बाहर करें।)
( डिग्रेशन । यह सिस्टम असंगत है क्योंकि Set:Set
"लियर विरोधाभास" की एक किस्म की एन्कोडिंग की अनुमति देता है। जब मार्टिन-लोफ ने इस सिद्धांत को प्रस्तावित किया, तो गिरार्ड ने उसे अपने असंगत सिस्टम यू में इसे एन्कोडिंग भेजा। हर्केंस के कारण बाद में विरोधाभास है। सबसे साफ विषाक्त निर्माण जो हम जानते हैं।)
संयोजक वाक्य रचना और सामान्यीकरण
किसी भी तरह, हमारे पास दो अतिरिक्त प्रतीक हैं, पाई और सेट, इसलिए हम शायद एस, के और दो अतिरिक्त प्रतीकों के साथ एक संयोजन अनुवाद का प्रबंधन कर सकते हैं: मैंने उत्पाद के लिए ब्रह्मांड और पी के लिए यू चुना।
अब हम अनपेक्षित कॉम्बीनेटरी सिंटैक्स को परिभाषित कर सकते हैं (मुफ्त चर के साथ):
data SKUP = S | K | U | P deriving (Show, Eq)
data Unty a
= C SKUP
| Unty a :. Unty a
| V a
deriving (Functor, Eq)
infixl 4 :.
ध्यान दें कि मैंने a
इस सिंटैक्स में टाइप द्वारा दर्शाए गए मुक्त चर को शामिल करने का साधन शामिल किया है । मेरे हिस्से में एक पलटा होने के अलावा (नाम के प्रत्येक वाक्यविन्यास योग्य, return
एम्बेड किए गए चर और पूर्ण >>=
प्रतिस्थापन के साथ एक नि: शुल्क संन्यासी है ), यह शर्तों को उनके दहनशील रूप में बाध्यकारी के साथ परिवर्तित करने की प्रक्रिया में मध्यवर्ती चरणों का प्रतिनिधित्व करना आसान होगा।
यहाँ सामान्यीकरण है:
norm :: Unty a -> Unty a
norm (f :. a) = norm f $. a
norm c = c
($.) :: Unty a -> Unty a -> Unty a
C S :. f :. a $. g = f $. g $. (a :. g)
C K :. a $. g = a
n $. g = n :. norm g
infixl 4 $.
(पाठक के लिए एक अभ्यास बिल्कुल सामान्य रूपों के लिए एक प्रकार को परिभाषित करना और इन कार्यों के प्रकार को तेज करना है।)
टाइप थ्योरी का प्रतिनिधित्व
अब हम अपने प्रकार के सिद्धांत के लिए एक वाक्यविन्यास को परिभाषित कर सकते हैं।
data Tm a
= Var a
| Lam (Tm a) (Tm (Su a))
| Tm a :$ Tm a
| Pi (Tm a) (Tm a)
| Set
deriving (Show, Functor)
infixl 4 :$
data Ze
magic :: Ze -> a
magic x = x `seq` error "Tragic!"
data Su a = Ze | Su a deriving (Show, Functor, Eq)
मैं बेलीगार्ड और हुक तरीके (जैसा कि बर्ड एंड पैटरसन द्वारा लोकप्रिय है) में एक डी ब्रूजन इंडेक्स प्रतिनिधित्व का उपयोग करता हूं। प्रकार Su a
में एक से अधिक तत्व हैं a
, और हम इसे एक बाइंडर के तहत नि: शुल्क चर के प्रकार के रूप में उपयोग करते हैं, Ze
नए बाध्य चर के रूप में और Su x
पुराने मुक्त चर के स्थानांतरित प्रतिनिधित्व के रूप में x
।
संयोजकों के लिए अनुवाद की शर्तें
और उस के साथ, हम ब्रैकेट अमूर्तता के आधार पर, सामान्य अनुवाद प्राप्त करते हैं ।
tm :: Tm a -> Unty a
tm (Var a) = V a
tm (Lam _ b) = bra (tm b)
tm (f :$ a) = tm f :. tm a
tm (Pi a b) = C P :. tm a :. tm b
tm Set = C U
bra :: Unty (Su a) -> Unty a
bra (V Ze) = C S :. C K :. C K
bra (V (Su x)) = C K :. V x
bra (C c) = C K :. C c
bra (f :. a) = C S :. bra f :. bra a
संयोजकों को टाइप करना
अनुवाद से पता चलता है कि हम किस तरह के कॉम्बिनेटरों का उपयोग करते हैं, जो हमें इस बात का संकेत देता है कि उनके प्रकार क्या होने चाहिए। U
और P
बस सेट निर्माता हैं, इसलिए, अनियंत्रित प्रकारों को लिखना और पाई के लिए "एग्दा संकेतन" की अनुमति है, हमारे पास होना चाहिए
U : Set
P : (A : Set) -> (B : (a : A) -> Set) -> Set
K
Combinator किसी प्रकार की एक मूल्य लिफ्ट करने के लिए प्रयोग किया जाता है A
कुछ अन्य प्रकार पर लगातार कार्य करने के लिए G
।
G : Set A : Set
K : (a : A) -> (g : G) -> A
S
Combinator एक प्रकार, जिस पर सभी भागों निर्भर हो सकता है अधिक लिफ्ट आवेदन करने के लिए प्रयोग किया जाता है।
G : Set
A : (g : G) -> Set
B : (g : G) -> (a : A g) -> Set
S : (f : (g : G) -> (a : A g) -> B g a ) ->
(a : (g : G) -> A g ) ->
(g : G) -> B g (a g)
यदि आप के प्रकार को S
देखते हैं, तो आप देखेंगे कि यह बिल्कुल प्रकार के सिद्धांत के प्रासंगिक नियम नियम को बताता है, इसलिए यह वही है जो एप्लिकेशन निर्माण को प्रतिबिंबित करने के लिए उपयुक्त है। यही इसका काम है!
हमारे पास तब केवल बंद चीजों के लिए आवेदन है
f : Pi A B
a : A
f a : B a
लेकिन एक रोड़ा है। मैंने कॉम्बिनेटर के प्रकारों को साधारण प्रकार के सिद्धांत में लिखा है, न कि संयोजन प्रकार के सिद्धांत में। सौभाग्य से, मेरे पास एक मशीन है जो अनुवाद करेगी।
एक संयोजन प्रकार प्रणाली
U : U
P : PU(S(S(KP)(S(S(KP)(SKK))(S(KK)(KU))))(S(KK)(KU)))
G : U
A : U
K : P[A](S(S(KP)(K[G]))(S(KK)(K[A])))
G : U
A : P[G](KU)
B : P[G](S(S(KP)(S(K[A])(SKK)))(S(KK)(KU)))
S : P(P[G](S(S(KP)(S(K[A])(SKK)))(S(S(KS)(S(S(KS)(S(KK)(K[B])))(S(KK)(SKK))))
(S(S(KS)(KK))(KK)))))(S(S(KP)(S(S(KP)(K[G]))(S(S(KS)(S(KK)(K[A])))
(S(S(KS)(KK))(KK)))))(S(S(KS)(S(S(KS)(S(KK)(KP)))(S(KK)(K[G]))))
(S(S(KS)(S(S(KS)(S(KK)(KS)))(S(S(KS)(S(S(KS)(S(KK)(KS)))
(S(S(KS)(S(KK)(KK)))(S(KK)(K[B])))))(S(S(KS)(S(S(KS)(S(KK)(KS)))(S(KK)(KK))))
(S(KK)(KK))))))(S(S(KS)(S(S(KS)(S(KK)(KS)))(S(S(KS)(S(KK)(KK)))
(S(S(KS)(KK))(KK)))))(S(S(KS)(S(S(KS)(S(KK)(KS)))(S(KK)(KK))))(S(KK)(KK)))))))
M : A B : U
M : B
तो वहाँ आप यह है, अपने सभी अपठनीय महिमा में: की एक संयोजन प्रस्तुति Set:Set
!
अभी भी थोड़ी समस्या है। प्रणाली की वाक्य रचना आप अनुमान लगा करने के लिए कोई रास्ता देती है G
, A
और B
के लिए मानकों S
और इसी तरह के लिए K
सिर्फ शब्दों से,। इसके विपरीत , हम टाइपिंग व्युत्पत्तियों को एल्गोरिथम रूप से सत्यापित कर सकते हैं , लेकिन हम केवल कॉम्बिनेटर शब्द टाइप नहीं कर सकते हैं जैसा कि हम मूल प्रणाली के साथ कर सकते हैं। एस और के के उपयोग पर टाइप एनोटेशन को प्रभावी ढंग से व्युत्पत्ति दर्ज करने के लिए टाइपकास्ट करने के लिए इनपुट की आवश्यकता के लिए क्या काम करना पड़ सकता है। लेकिन यह एक और कीड़ा है ...
यदि आप शुरू करने के लिए पर्याप्त उत्सुक हैं, तो यह रुकने के लिए एक अच्छी जगह है। बाकी "पर्दे के पीछे" सामान है।
संयोजकों के प्रकार उत्पन्न करना
मैंने प्रासंगिक प्रकार के सिद्धांत शब्दों से ब्रैकेट अमूर्त अनुवाद का उपयोग करके उन संयोजन प्रकारों को उत्पन्न किया। यह दिखाने के लिए कि मैंने इसे कैसे किया, और इस पोस्ट को पूरी तरह से व्यर्थ न बनाएं, मुझे अपने उपकरण पेश करने दें।
मैं संयोजन के प्रकार, उनके मापदंडों पर पूरी तरह से अमूर्त लिख सकता हूं, निम्नानुसार। मैं अपने उपयोगी pil
फ़ंक्शन का उपयोग करता हूं , जो कि डोमेन प्रकार को दोहराने से बचने के लिए पाई और लैम्ब्डा को जोड़ती है, और बल्कि मुझे चर को बांधने के लिए हास्केल के फ़ंक्शन स्थान का उपयोग करने की अनुमति देता है। शायद आप लगभग निम्नलिखित पढ़ सकते हैं!
pTy :: Tm a
pTy = fmap magic $
pil Set $ \ _A -> pil (pil _A $ \ _ -> Set) $ \ _B -> Set
kTy :: Tm a
kTy = fmap magic $
pil Set $ \ _G -> pil Set $ \ _A -> pil _A $ \ a -> pil _G $ \ g -> _A
sTy :: Tm a
sTy = fmap magic $
pil Set $ \ _G ->
pil (pil _G $ \ g -> Set) $ \ _A ->
pil (pil _G $ \ g -> pil (_A :$ g) $ \ _ -> Set) $ \ _B ->
pil (pil _G $ \ g -> pil (_A :$ g) $ \ a -> _B :$ g :$ a) $ \ f ->
pil (pil _G $ \ g -> _A :$ g) $ \ a ->
pil _G $ \ g -> _B :$ g :$ (a :$ g)
इन परिभाषित के साथ, मैंने संबंधित खुले सबटर्म्स निकाले और उन्हें अनुवाद के माध्यम से चलाया।
एक डी ब्रूजन एन्कोडिंग टूलकिट
यहाँ कैसे निर्माण करना है pil
। सबसे पहले, मैं Fin
ite सेट के एक वर्ग को परिभाषित करता हूं , जिसका उपयोग चर के लिए किया जाता है। इस तरह के हर सेट में एक कंस्ट्रक्टर- emb
प्रोटेक्टिंग एडिंग होती है ऊपर के सेट में, एक नया top
तत्व, और आप उन्हें अलग-अलग बता सकते हैं: embd
फ़ंक्शन आपको बताता है कि क्या छवि में कोई मूल्य है emb
।
class Fin x where
top :: Su x
emb :: x -> Su x
embd :: Su x -> Maybe x
हम, ज़ाहिर है, और के Fin
लिए तत्काल कर सकते हैंZe
Suc
instance Fin Ze where
top = Ze
emb = magic
embd _ = Nothing
instance Fin x => Fin (Su x) where
top = Su top
emb Ze = Ze
emb (Su x) = Su (emb x)
embd Ze = Just Ze
embd (Su x) = fmap Su (embd x)
अब मैं कमजोर संचालन के साथ कम-या-बराबर को परिभाषित कर सकता हूं ।
class (Fin x, Fin y) => Le x y where
wk :: x -> y
wk
समारोह के तत्वों को एम्बेड करना चाहिए x
के रूप में सबसे बड़ा के तत्वों y
, ताकि में अतिरिक्त बातें y
छोटे होते हैं, और इस तरह de Bruijn सूचकांक के संदर्भ में, और अधिक स्थानीय रूप से बाध्य।
instance Fin y => Le Ze y where
wk = magic
instance Le x y => Le (Su x) (Su y) where
wk x = case embd x of
Nothing -> top
Just y -> emb (wk y)
और एक बार जब आप यह पता लगा लेते हैं कि रैंक-एन स्कल्ल्डगिरी का एक हिस्सा बाकी है।
lam :: forall x. Tm x -> ((forall y. Le (Su x) y => Tm y) -> Tm (Su x)) -> Tm x
lam s f = Lam s (f (Var (wk (Ze :: Su x))))
pil :: forall x. Tm x -> ((forall y . Le (Su x) y => Tm y) -> Tm (Su x)) -> Tm x
pil s f = Pi s (lam s f)
उच्च-क्रम फ़ंक्शन आपको केवल चर का प्रतिनिधित्व करने वाला शब्द नहीं देता है, यह आपको एक अतिभारित चीज़ देता है जो किसी भी दायरे में चर का सही प्रतिनिधित्व करता है जहां चर दिखाई देता है। यही कारण है कि, इस तथ्य से कि मैं विभिन्न स्कोप को भेद करने की परेशानी में जाता हूं, हास्केल टाइपराइकर को अनुवाद के लिए आवश्यक स्थानांतरण की गणना करने के लिए पर्याप्त जानकारी देता है। एक कुत्ता क्यों रखें और खुद को भौंकें?