चर्च संख्या कार्यों के रूप में प्राकृतिक संख्याओं का एन्कोडिंग है।
(\ f x → (f x)) -- church number 1
(\ f x → (f (f (f x)))) -- church number 3
(\ f x → (f (f (f (f x))))) -- church number 4
केवल, आप उन्हें लागू करने के द्वारा 2 चर्च संख्या को दर्शा सकते हैं। यही है, यदि आप 4 से 2 लागू करते हैं, तो आपको चर्च नंबर मिलता है 16
, या 2^4
। जाहिर है, यह पूरी तरह से अव्यावहारिक है। चर्च के नंबरों को स्मृति की एक रैखिक राशि की आवश्यकता होती है और वास्तव में, वास्तव में धीमी होती है। कुछ इस तरह की गणना करना 10^10
- जो GHCI जल्दी से सही उत्तर देता है - उम्र लेगा और वैसे भी आपके कंप्यूटर पर मेमोरी को फिट नहीं कर सकता है।
मैं हाल ही में इष्टतम λ मूल्यांकनकर्ताओं के साथ प्रयोग कर रहा हूं। मेरे परीक्षणों पर, मैंने अपने इष्टतम λ-कैलकुलेटर पर गलती से निम्नलिखित टाइप किया:
10 ^ 10 % 13
यह गुणन माना जाता था, न कि घातांक। इससे पहले कि मैं निराशा में हमेशा के लिए चल रहे कार्यक्रम को रद्द करने के लिए अपनी उंगलियों को हिला सकता, इसने मेरे अनुरोध का जवाब दिया:
3
{ iterations: 11523, applications: 5748, used_memory: 27729 }
real 0m0.104s
user 0m0.086s
sys 0m0.019s
अपने "बग अलर्ट" चमकती के साथ, मैं Google पर गया और सत्यापित किया, 10^10%13 == 3
वास्तव में। लेकिन λ- कैलकुलेटर उस परिणाम को खोजने वाला नहीं था, यह मुश्किल से 10 ^ 10 स्टोर कर सकता है। मैंने इस पर जोर देना शुरू किया, विज्ञान के लिए। यह तुरंत मुझे जवाब 20^20%13 == 3
, 50^50%13 == 4
, 60^60%3 == 0
। मुझे उन परिणामों को सत्यापित करने के लिए बाहरी साधनों का उपयोग करना पड़ा , क्योंकि हास्केल स्वयं इसकी गणना करने में सक्षम नहीं था (पूर्णांक अतिप्रवाह के कारण) (यह है यदि आप इंटर्ज़र्स का उपयोग नहीं करते हैं, तो बेशक!)। इसकी सीमाओं को धता बताते हुए, इसका उत्तर था 200^200%31
:
5
{ iterations: 10351327, applications: 5175644, used_memory: 23754870 }
real 0m4.025s
user 0m3.686s
sys 0m0.341s
यदि हमारे पास ब्रह्मांड के प्रत्येक परमाणु के लिए ब्रह्मांड की एक प्रति थी, और हमारे पास कुल प्रत्येक परमाणु के लिए एक कंप्यूटर था, तो हम चर्च संख्या को संग्रहीत नहीं कर सकते थे 200^200
। इसने मुझे सवाल करने के लिए प्रेरित किया कि क्या मेरा मैक वास्तव में इतना शक्तिशाली था। हो सकता है कि इष्टतम मूल्यांकनकर्ता अनावश्यक शाखाओं को छोड़ दे और एक ही अंदाज में जवाब पर पहुंचे, हास्केल आलसी मूल्यांकन के साथ करता है। इसे जांचने के लिए, मैंने λ प्रोग्राम को हास्केल में संकलित किया:
data Term = F !(Term -> Term) | N !Double
instance Show Term where {
show (N x) = "(N "++(if fromIntegral (floor x) == x then show (floor x) else show x)++")";
show (F _) = "(λ...)"}
infixl 0 #
(F f) # x = f x
churchNum = F(\(N n)->F(\f->F(\x->if n<=0 then x else (f#(churchNum#(N(n-1))#f#x)))))
expMod = (F(\v0->(F(\v1->(F(\v2->((((((churchNum # v2) # (F(\v3->(F(\v4->(v3 # (F(\v5->((v4 # (F(\v6->(F(\v7->(v6 # ((v5 # v6) # v7))))))) # v5))))))))) # (F(\v3->(v3 # (F(\v4->(F(\v5->v5)))))))) # (F(\v3->((((churchNum # v1) # (churchNum # v0)) # ((((churchNum # v2) # (F(\v4->(F(\v5->(F(\v6->(v4 # (F(\v7->((v5 # v7) # v6))))))))))) # (F(\v4->v4))) # (F(\v4->(F(\v5->(v5 # v4))))))) # ((((churchNum # v2) # (F(\v4->(F(\v5->v4))))) # (F(\v4->v4))) # (F(\v4->v4))))))) # (F(\v3->(((F(\(N x)->F(\(N y)->N(x+y)))) # v3) # (N 1))))) # (N 0))))))))
main = print $ (expMod # N 5 # N 5 # N 4)
यह सही ढंग से आउटपुट 1
( 5 ^ 5 % 4
) - लेकिन ऊपर कुछ भी फेंक दें 10^10
और यह परिकल्पना को समाप्त कर, अटक जाएगा।
इष्टतम मूल्यांकनकर्ता मैं प्रयोग किया जाता एक 160 लाइनों लंबे, unoptimized जावास्क्रिप्ट प्रोग्राम है जो घातीय मापांक गणित के किसी भी प्रकार को शामिल नहीं किया है - और लैम्ब्डा-पथरी मापांक समारोह मैं भी उतना ही आसान था प्रयोग किया है:
(λab.(b(λcd.(c(λe.(d(λfg.(f(efg)))e))))(λc.(c(λde.e)))(λc.(a(b(λdef.(d(λg.(egf))))(λd.d)(λde.(ed)))(b(λde.d)(λd.d)(λd.d))))))
मैंने कोई विशिष्ट मॉड्यूलर अंकगणितीय एल्गोरिथ्म या सूत्र का उपयोग नहीं किया। तो, कैसे सही मूल्यांकन करने के लिए इष्टतम मूल्यांकनकर्ता आने में सक्षम है?
node test.js
। अगर आपका कोई प्रश्न हैं, तो मुझे से पूछें।