Coq में दो तर्कों पर किसी फ़ंक्शन को कैसे परिभाषित किया जाए?


14

मैं Coq को कैसे मना सकता हूं कि नीचे दिया गया पुनरावर्ती कार्य समाप्त हो गया है? फ़ंक्शन दो प्रेरक तर्क लेता है। वास्तव में, पुनरावृत्ति समाप्त हो जाती है क्योंकि या तो तर्क विघटित हो जाता है।

विशेष रूप से, फ़ंक्शन इनपुट के रूप में दो पेड़ लेता है।

Inductive Tree :=
| Tip: Tree
| Bin: Tree -> Tree -> Tree.

पेड़ों पर, मैं प्रेरण की निम्नलिखित शैली करना पसंद करता हूं।

Inductive TreePair :=
| TipTip : TreePair
| TipBin : Tree -> Tree -> TreePair
| BinTip : Tree -> Tree -> TreePair
| BinBin : TreePair -> TreePair -> TreePair.

Fixpoint pair (l r: Tree): TreePair :=
  match l with
    | Tip =>
      match r with
        | Tip => TipTip
        | Bin rl rr => TipBin rl rr
      end
    | Bin ll lr =>
      match r with
        | Tip => BinTip ll lr
        | Bin rl rr => BinBin (pair l rl) (pair lr r)
      end
  end.

ट्रीपेयर की परिभाषा स्वीकार की जाती है, लेकिन फ़ंक्शन जोड़ी की परिभाषा त्रुटि संदेश देती है:

Error: Cannot guess decreasing argument of fix.

इसलिए मुझे इस बात में दिलचस्पी है कि कॉक् की समाप्ति कैसे मनाई जाए।


1
क्या आपने करीने का उपयोग करने के बजाय एक उत्पाद के रूप में l और r पास करने की कोशिश की है? इसके साथ मदद करनी चाहिए।
प्रति सोग्न

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

3
यह प्रश्न वास्तव में यह सुनिश्चित करने के लिए है कि ऑपरेशन pairअच्छी तरह से परिभाषित है ताकि यह सुनिश्चित करने के लिए कि डेटा संरचनाओं पर सीमा कम हो । कोक् केवल वाहन है।
डेव क्लार्क

जवाबों:


12

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

आपकी दो-तर्क निर्धारण की परिभाषा एक सरल पैटर्न का अनुसरण करती है: या तो पहला तर्क छोटा हो जाता है, या पहला तर्क समान रहता है और दूसरा तर्क छोटा हो जाता है। यह काफी सामान्य पैटर्न एक साधारण फिक्स-इन-फिक्स द्वारा नियंत्रित किया जा सकता है।

Fixpoint pair l := fix pair1 (r : Tree) :=
  match l with
    | Tip => match r with
              | Tip => TipTip
              | Bin rl rr => TipBin rl rr
            end
    | Bin ll lr => match r with
                    | Tip => BinTip ll lr
                    | Bin rl rr => BinBin (pair1 rl) (pair lr r)
                   end
  end.

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


अब मुझे पता है कि यह मैंने क्या मांगा!
युहराई

अगर मुझे fix pair1 rशीर्ष-स्तर की दूसरी शाखा में धकेल दिया जाए तो क्या इससे कोई फ़र्क पड़ेगा match(और निश्चित रूप से किसी प्रकार के फ़ंक्शन को वापस करने के लिए पहली शाखा को अनुकूलित करें)?
दिन

@plmday: दोनों तरह से काम करते हैं। वे बाह्यता की कुछ उचित परिभाषा के लिए बाह्य रूप से समतुल्य हैं, और इससे भी महत्वपूर्ण बात यह है कि वे दोनों अच्छी तरह से टाइप किए गए हैं (विलक्षण पुनर्लेखन किसी भी प्रासंगिक सहसंयोजक (सकारात्मकता) गुणों को नहीं बदलता है)।
गिल्स एसओ- बुराई को रोकना '
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.