Eq ?, eqv ?, बराबर ?, और = स्कीम में क्या अंतर है?


85

मुझे आश्चर्य है कि स्कीम के उन प्रचालनों में क्या अंतर है। मैंने स्टैक ओवरफ्लो में समान प्रश्न देखे हैं, लेकिन वे लिस्प के बारे में हैं, और उन तीन ऑपरेटरों के बीच तुलना नहीं है।

मैं योजना में विभिन्न प्रकार के कमांड लिख रहा हूं, और मुझे निम्नलिखित आउटपुट मिलते हैं:

(eq? 5 5) -->#t
(eq? 2.5 2.5) -->#f
(equal? 2.5 2.5) --> #t
(= 2.5 2.5) --> #t

यह एक केस क्यों है?


3
और वहाँ भी है eqv?, जिसका मतलब कुछ अलग है eq?याequal?
newacct

जवाबों:


155

मैं इस प्रश्न का उत्तर वृहद रूप से दूंगा। आइए =समतुल्यता विधेय से शुरू करें । =विधेय जाँच करने के लिए है कि क्या दो नंबर के बराबर हैं प्रयोग किया जाता है। यदि आप इसे कुछ और आपूर्ति करते हैं लेकिन एक संख्या है तो यह एक त्रुटि देगा:

(= 2 3)     => #f
(= 2.5 2.5) => #t
(= '() '()) => error

eq?विधेय अपने दो पैरामीटर स्मृति में एक ही वस्तु respresent जांच करने के लिए प्रयोग किया जाता है। उदाहरण के लिए:

(define x '(2 3))
(define y '(2 3))
(eq? x y)         => #f
(define y x)
(eq? x y)         => #t

ध्यान दें कि '()स्मृति में केवल एक खाली सूची है (वास्तव में खाली सूची स्मृति में मौजूद नहीं है, लेकिन स्मृति स्थान के लिए एक संकेतक को 0रिक्त सूची के रूप में माना जाता है)। इसलिए जब खाली सूचियों की तुलना eq?करना हमेशा वापस आएगा #t(क्योंकि वे स्मृति में एक ही वस्तु का प्रतिनिधित्व करते हैं):

(define x '())
(define y '())
(eq? x y)      => #t

अब कार्यान्वयन के आधार पर आदिम मूल्यों जैसे संख्याओं, तारों आदि के लिए eq?वापस आ सकता है या नहीं हो सकता है #t। उदाहरण के लिए:

(eq? 2 2)     => depends upon the implementation
(eq? "a" "a") => depends upon the implementation

यह वह जगह है जहाँ eqv?विधेय चित्र में आता है। यह विधेय eqv?के समान eq?है, सिवाय इसके कि यह हमेशा #tएक ही आदिम मूल्यों के लिए वापस आ जाएगा । उदाहरण के लिए:

(eqv? 2 2)     => #t
(eqv? "a" "a") => depends upon the implementation

इसलिए eqv?का सुपरसेट है eq?और ज्यादातर मामलों का उपयोग करना चाहिए के लिए eqv?के बजाय eq?

अंत में हम equal?विधेय पर आते हैं । equal?विधेय के रूप में ही ठीक है eqv?सिवाय इसके कि यह भी है कि क्या दो सूचियों, वैक्टर, आदि तत्व है जो संतुष्ट इसी है परीक्षण करने के लिए इस्तेमाल किया जा सकता, विधेय eqv?विधेय। उदाहरण के लिए:

(define x '(2 3))
(define y '(2 3))
(equal? x y)      => #t
(eqv? x y)        => #f

सामान्य रूप में:

  1. =जब आप परीक्षण करना चाहें कि दो संख्याएँ समान हैं , तो विधेय का उपयोग करें ।
  2. eqv?जब आप परीक्षण करना चाहें कि क्या दो गैर-संख्यात्मक मान बराबर हैं , तो विधेय का उपयोग करें ।
  3. equal?जब आप परीक्षण करना चाहें तो विधेय का उपयोग करें कि क्या दो सूचियाँ, वैक्टर आदि समान हैं।
  4. eq?जब तक आप जानते हैं कि आप क्या कर रहे हैं, तब तक विधेय का उपयोग न करें ।

7
AFAIK (eqv? "a" "a") ==> unspecified। आपको equal?(संभवतः अधिक अनुकूलित) का उपयोग करना होगाstring=?
सिल्वेस्टर

3
के अनुसार रिपोर्ट , (eq? '(1) '(1))है अनिर्दिष्ट तो अपने, (define x '(1 2))चित्रण काम न करे।
विल नेस

4
बहुत सटीक और जानकारीपूर्ण। विशेष रूप से अंत में दिशानिर्देश।
जर्मन डायगो जूल

2
लेकिन ईक? प्रतीकों के लिए परिभाषित किया गया लगता है और इस पर ध्यान दिया जाना चाहिए! यदि प्रतीक समान दिखते हैं, तो ईक? रिटर्न #t उदाहरण (eq? 'foo 'foo) -> #t, (eq? 'foo 'bar)-> असत्य '। मैं इसे यहाँ और यहाँ
पढ़ता हूँ

13

RnRS विनिर्देश से संबंधित पूरे दो पृष्ठ हैं eq?, eqv?, equal? and =। यहाँ ड्राफ्ट R7RS विशिष्टता है । इसकी जांच - पड़ताल करें!

स्पष्टीकरण:

  • = संख्याओं की तुलना, 2.5 और 2.5 संख्यात्मक रूप से बराबर हैं।
  • equal?संख्या में कमी के लिए =, 2.5 और 2.5 संख्यात्मक रूप से बराबर हैं।
  • eq?'पॉइंटर्स' की तुलना करता है। आपकी योजना कार्यान्वयन में नंबर 5, 'तत्काल' (संभावना) के रूप में कार्यान्वित किया जाता है, इस प्रकार 5 और 5 समान हैं। 2.5 नंबर को आपकी स्कीम कार्यान्वयन में एक 'फ्लोटिंग पॉइंट रिकॉर्ड' के आवंटन की आवश्यकता हो सकती है, दो पॉइंटर्स समान नहीं हैं।

1
ड्राफ्ट R7RS विशिष्टता के लिए लिंक 2018-02-04 के रूप में मृत है
यिर्मयाह

2
एक लाइव लिंक के लिए अपडेट किया गया।
गोजोनर

10

eq?है #tजब वह एक ही पते / वस्तु है। आम तौर पर एक ही प्रतीक, बूलियन और ऑब्जेक्ट के लिए # टी की उम्मीद की जा सकती है और मूल्यों के लिए # एफ विभिन्न प्रकार के होते हैं, विभिन्न मूल्यों के साथ, या नहीं एक ही संरचना योजना / लिस्प-कार्यान्वयन में अपने संकेत में टाइप एम्बेड करने और एम्बेड करने की परंपरा होती है यदि यह पर्याप्त स्थान है तो एक ही स्थान में मान। इस प्रकार कुछ संकेत वास्तव में पते नहीं हैं, लेकिन मूल्य, जैसे कि चार Rया फिक्सनम 10। ये तब होगा eq?जब "पता" एक एम्बेडेड प्रकार + मान होगा। कुछ कार्यान्वयन भी अपरिवर्तनीय स्थिरांक का पुन: उपयोग करते हैं। (eq? '(1 2 3)' (1 2 3)) की व्याख्या करते समय #f हो सकता है लेकिन #t जब संकलित किया जाता है क्योंकि यह समान पता प्राप्त कर सकता है। (जावा में स्थिर स्ट्रिंग पूल की तरह)। इस वजह से, कई जोखिम शामिल हैंeq? अनिर्दिष्ट हैं, इस प्रकार # टी या # एफ का मूल्यांकन करने वाले पर निर्भरता लागू होती है।

eqv?उसी चीज़ के लिए #t हैं eq?। यह #t भी है यदि यह एक संख्या या वर्ण है और यह मान समान है , तब भी जब डेटा एक पॉइंटर में फिट होने के लिए बहुत बड़ा है। इस प्रकार उन लोगों के लिए eqv?यह जाँचने का अतिरिक्त काम करता है कि टाइप समर्थित है, दोनों एक ही प्रकार के हैं और यह लक्ष्य ऑब्जेक्ट्स का समान डेटा मान है।

equal?समान चीज़ों के लिए #t है eqv?और यदि यह एक कंपाउंड प्रकार है जैसे कि जोड़ी, वेक्टर, स्ट्रिंग, और बाइटवेक्टर जो इसे equal?पुर्जे के साथ पुनरावृत्ति करता है । व्यवहार में यह दोनों वस्तुओं को समान दिखने पर #t को लौटा देगा । R6RS से पहले, यह equal?परिपत्र संरचनाओं पर उपयोग करने के लिए असुरक्षित है ।

=यह पसंद है eqv?लेकिन यह केवल संख्यात्मक प्रकारों के लिए काम करता है । यह अधिक कुशल हो सकता है।

string=?पसंद है equal?, लेकिन यह केवल तार के लिए काम करता है। यह अधिक कुशल हो सकता है।


6

equal? समानता के लिए पुनरावर्ती दो वस्तुओं (किसी भी प्रकार का) की तुलना करता है।

  • ध्यान दें कि यह बड़ी डेटा संरचना के लिए महंगा हो सकता है क्योंकि संभावित रूप से पूरी सूची, स्ट्रिंग, वेक्टर, आदि का पता लगाया जाना चाहिए।

  • यदि ऑब्जेक्ट में केवल एक तत्व (ईजी: संख्या, वर्ण, आदि) शामिल है, तो यह उसी तरह है eqv?


eqv? यह निर्धारित करने के लिए दो वस्तुओं का परीक्षण करता है कि क्या दोनों को "समान वस्तु के रूप में माना जाता है"।

  • eqv?और eq?बहुत ही समान संचालन हैं, और उनके बीच के अंतर कुछ हद तक कार्यान्वयन विशिष्ट होने जा रहे हैं।

eq?के रूप में ही है, eqv?लेकिन बेहतर भेदों को समझने में सक्षम हो सकता है, और अधिक कुशलता से लागू किया जा सकता है।

  • युक्ति के अनुसार, यह एक तेज और कुशल सूचक तुलना के रूप में लागू किया जा सकता है, क्योंकि इसके लिए एक अधिक जटिल ऑपरेशन का विरोध किया गया है eqv?


= संख्यात्मक समानता के लिए संख्याओं की तुलना करता है।

  • ध्यान दें कि दो से अधिक नंबर दिए जा सकते हैं, जैसे: (= 1 1.0 1/1 2/2)

मुझे लगा eq?कि वास्तविक सूचक समानता (नहीं eqv?) है। यह "सबसे अच्छा या सबसे ज्यादा भेदभाव करने वाला" है। जैसे होने (eqv? 2 2)की गारंटी है #t, लेकिन (eq? 2 2)"अनिर्दिष्ट" है। यानी यह इस बात पर निर्भर करता है कि क्या एक कार्यान्वयन प्रत्येक नई पढ़ी गई संख्या के लिए वास्तविक नई मेमोरी ऑब्जेक्ट बनाता है, या यदि यह कर सकता है तो पहले से बनाए गए एक का पुन: उपयोग करता है।
विल नेस

@WillNess - अच्छी पकड़, धन्यवाद। के बीच अंतर eq?और eqv?अन्य कार्यों की तुलना में अधिक सूक्ष्म हैं।
जस्टिन एथियर

5

आप किसी योजना के क्रियान्वयन का उल्लेख नहीं करते हैं, लेकिन रैकेट में eq?केवल तभी सही रिटर्न मिलता है जब तर्क उसी वस्तु का संदर्भ देते हैं। आपका दूसरा उदाहरण #f पैदावार है क्योंकि सिस्टम प्रत्येक तर्क के लिए एक नया फ्लोटिंग पॉइंट नंबर बना रहा है; वे एक ही वस्तु नहीं हैं।

equal?और =मूल्य तुल्यता के लिए जाँच कर रहे हैं, लेकिन =केवल संख्याओं पर लागू है।

यदि आप रैकेट का उपयोग कर रहे हैं, तो अधिक जानकारी के लिए यहां देखें। अन्यथा, अपनी योजना कार्यान्वयन के दस्तावेज की जांच करें।


3
बेहतर अभी तक ... विनिर्देश पढ़ें ... r6rs.org/final/html/r6rs/r6rs-ZH-14.html#node_sec_11.5
डिर्क

3

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

आमतौर पर eq को लागू करना संभव होगा? eqv की तुलना में अधिक कुशलता से ?, उदाहरण के लिए, एक साधारण सूचक तुलना के रूप में

यहाँ मेरा मतलब है। (eqv? 2 2)लौटने की गारंटी है #tलेकिन (eq? 2 2)अनिर्दिष्ट है। अब एक सूचक-आधारित कार्यान्वयन की कल्पना करें। इसमें eq?सिर्फ पॉइंटर तुलना है। चूंकि (eq? 2 2)अनिर्दिष्ट है, इसका मतलब है कि यह कार्यान्वयन स्रोत कोड से पढ़े गए प्रत्येक नए नंबर की नई मेमोरी ऑब्जेक्ट प्रतिनिधित्व बनाने के लिए स्वतंत्र है। eqv?वास्तव में इसके तर्कों का निरीक्षण करना चाहिए।

OTOH (eq 'a 'a)है #t। इसका मतलब यह है कि इस तरह के कार्यान्वयन को प्रतीकों को नकली नामों से पहचानना चाहिए और उन सभी के लिए स्मृति में एक ही प्रतिनिधित्व वस्तु का उपयोग करना चाहिए ।

मान लीजिए कि एक कार्यान्वयन सूचक-आधारित नहीं है। जब तक यह रिपोर्ट का पालन करता है, इससे कोई फर्क नहीं पड़ता। लेखक केवल कार्यान्वयनकर्ताओं को कार्यान्वयन की बारीकियों को निर्धारित करने के रूप में नहीं देखना चाहते हैं, इसलिए वे अपने शब्दों को सावधानी से चुनते हैं।

यह मेरा अनुमान वैसे भी है।

तो बहुत ही कम है, eq?सूचक समानता है, eqv?(परमाणु-) मूल्यों-जागरूक है, equal?संरचना-जागरूक भी है (इसके तर्कों की पुनरावृत्ति की जांच करता है, ताकि अंत में (equal? '(a) '(a))होना आवश्यक है #t), =संख्याओं के string=?लिए है, तार के लिए है, और विवरण हैं रिपोर्ट में


0

पिछले उत्तरों के अलावा, मैं कुछ टिप्पणियां जोड़ूंगा।

ये सभी विधेय identityएक वस्तु के लिए, लेकिन विभिन्न संदर्भों में सार फ़ंक्शन को परिभाषित करना चाहते हैं ।

EQ?कार्यान्वयन-निर्भर है और यह are 2 objects the same?केवल सीमित उपयोग में सवाल का जवाब नहीं देता है । कार्यान्वयन के दृष्टिकोण से, यह विधेय सिर्फ 2 संख्याओं (वस्तुओं के सूचक) की तुलना करता है, यह वस्तुओं की सामग्री को नहीं देखता है। इसलिए, उदाहरण के लिए, यदि आपका कार्यान्वयन विशिष्ट रूप से स्ट्रिंग्स को अंदर नहीं रखता है, लेकिन प्रत्येक स्ट्रिंग के लिए अलग मेमोरी आवंटित करता है, तो (eq? "a" "a")यह गलत होगा।

EQV?- यह वस्तुओं के अंदर दिखता है, लेकिन सीमित उपयोग के साथ। यदि यह सही है तो यह कार्यान्वयन-निर्भर है (eqv? (lambda(x) x) (lambda(x) x))। यहां यह एक पूर्ण दर्शन है कि इस विधेय को कैसे परिभाषित किया जाए, जैसा कि हम आजकल जानते हैं कि कुछ कार्यों की कार्यक्षमता की तुलना सीमित उपयोग के साथ करने के लिए कुछ तेज़ तरीके हैं। लेकिन eqv?बड़ी संख्या, तार आदि के लिए सुसंगत उत्तर प्रदान करता है।

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

X = Y  iff  for any P, P(X) = P(Y)
X, Y being objects and
P being any property associated with object X and Y.

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

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

अन्य विधेय के लिए संदर्भ का विश्लेषण करना आसान है।

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