मैं कुछ दिनों के लिए एक समस्या के खिलाफ अपने सिर को टक्कर लगी हूं, लेकिन मेरे एजडा कौशल बहुत मजबूत नहीं हैं।विशेष रचनाकारों पर पैटर्न मैच
मैं एक अनुक्रमित डेटा प्रकार पर एक फ़ंक्शन लिखने की कोशिश कर रहा हूं जिसे केवल एक विशेष अनुक्रमणिका में परिभाषित किया गया है। डेटा कन्स्ट्रक्टर के कुछ विशेषज्ञों के लिए यह केवल संभव है। मैं इस तरह के एक समारोह को परिभाषित करने के बारे में पता नहीं लगा सकता। मैंने अपनी समस्या को एक छोटे से उदाहरण में कम करने की कोशिश की है।
सेटअप में प्राकृतिक संख्या की सूचियां शामिल हैं, सूची के सदस्यों को देखने के लिए एक प्रकार के साथ, और सूची सदस्यों को हटाने के लिए एक समारोह शामिल है।
open import Data.Nat
open import Relation.Binary.Core
data List : Set where
nil : List
_::_ : (x : ℕ) -> (xs : List) -> List
-- membership within a list
data _∈_ (x : ℕ) : List -> Set where
here : forall {xs} -> x ∈ (x :: xs)
there : forall {xs y} -> (mem : x ∈ xs) -> x ∈ (y :: xs)
-- delete
_\\_ : forall {x} (xs : List) -> (mem : x ∈ xs) -> List
_\\_ nil()
_\\_ (_ :: xs) here = xs
_\\_ (_ :: nil) (there())
_\\_ (x :: xs) (there p) = x :: (xs \\ p)
बस एक त्वरित जांच कि एक सिंगलटन सूची के सिर तत्व को हटाने खाली सूची है:
check : forall {x} -> nil ≡ ((x :: nil) \\ here)
check = refl
अब मुझे लगता है कि सूचियों द्वारा अनुक्रमित कुछ आवरण डेटा प्रकार है
-- Our test data type
data Foo : List -> Set where
test : Foo nil
test2 : forall {x} (xs : List) -> (mem : x ∈ xs) -> Foo (xs \\ mem)
test2
कन्स्ट्रक्टर सूची से तत्व को हटाने के परिणामस्वरूप एक सूची और सदस्यता मूल्य लेता है और डेटा प्रकार को अनुक्रमणित करता है।
अब थोड़ा मैं कहाँ अटक कर रहा हूँ मैं निम्नलिखित हस्ताक्षर के एक समारोह चाहते हैं:
foo : Foo nil -> ℕ
foo = {!!}
अर्थात, nil
को विशेष अपने सूचकांक के साथ एक Foo
मूल्य लेने। यह test
केस
foo test = 0
दूसरा मामला मुश्किल है। मैं शुरू में की तरह कुछ कल्पना:
foo : Foo nil -> ℕ
foo test = 0
foo (test2 .(_ :: nil) .here) = 1
लेकिन AGDA शिकायत है कि xs \\ mem != nil of type List when checking that the pattern test2 .(_ :: nil) .here has type Foo nil
। तो मैं एक with
-clause उपयोग करने की कोशिश:
foo : Foo nil -> ℕ
foo test = 0
foo (test2 xs m) with xs \\ m
... | nil = 1
... |()
यह वही त्रुटि अर्जित करता है। मैंने विभिन्न क्रमपरिवर्तनों के साथ प्रयोग किया है, लेकिन हां, मैं इस बात का पता नहीं लगा सकता कि n \\ m = nil
पैटर्न में वापस जानकारी का उपयोग कैसे करें। मैंने कई अन्य प्रकार की भविष्यवाणियों की कोशिश की है लेकिन एग्डा को यह बताना नहीं चाहिए कि उसे क्या जानना है। कुछ मदद की बहुत सराहना करेंगे! धन्यवाद।
अतिरिक्त: मैं AGDA में एक सबूत लिखा है कि दिए गए किसी भी xs : List
और m : x \in xs
कि (xs \\ m = nil
) का तात्पर्य है कि xs = x :: nil
और m = here
है, जो की तरह यह प्रकार चेकर को देने के लिए उपयोगी हो सकता है, लेकिन मैं लगता है मुझे यकीन नहीं है कि यह कैसे करें।
data PiEq {A : Set} {B : A -> Set} : (a : A) -> (b : A) -> (c : B a) -> (d : B b) -> Set where
pirefl : forall {x : A} {y : B x} -> PiEq {A} {B} x x y y
check' : forall {x xs m} {eq : xs \\ m ≡ nil} -> (PiEq {List} {\xs -> x ∈ xs} xs (x :: nil) m here)
check' {xs = nil} {()}
-- The only case that works
check' {xs = ._ :: nil} {here} = pirefl
-- Everything else is refuted
check' {xs = ._ :: (_ :: xs)} {here} {()}
check' {xs = ._ :: nil} {there()}
check' {xs = ._} {there here} {()}
check' {xs = ._} {there (there m)} {()}
क्या के बारे में [यह] (https://gist.github.com/vituscze/6807d6529aed9e9f60e6)? – Vitus
यूप। 'Test2' केस के प्रकार को 'फू नील' के रूप में कम करने के लिए आपको 'साथ' खंड की आवश्यकता है, लेकिन इनपुट पहले से ही 'फू नील' होना चाहिए, इसलिए आप पहले कभी 'साथ' खंड में नहीं पहुंच सकते जगह। 'फू' की पूंछ के लिए एक परिवर्तनीय मूल्य होने के कारण आप 'साथ' में जा सकते हैं, और फिर समानता सुनिश्चित करती है कि केवल 'शून्य' मामला 'साथ' के अंदर प्रासंगिक है। – zmthy
@ विटस हां! बस इतना ही! क्या आप इसे उत्तर के रूप में पोस्ट करना चाहते हैं ताकि मैं इसे स्वीकार कर सकूं? मैंने पहले ऐसा कुछ करने की कोशिश की लेकिन असफल होने में कामयाब रहा- मुझे लगता है कि मैं 'रिफ्ल' के साथ समानता पर भी मेल खाता था जो चीजों को तोड़ देता है, यानी "फू रेफल रेस्ट = 0" जोड़ना "मुझे यकीन नहीं है कि क्या होना चाहिए कन्स्ट्रक्टर टेस्ट 2 के लिए एक मामला "। यह मेरे लिए अजीब लगता है! मैंने सबूत पर मिलान किए बिना कोशिश नहीं की! बहुत बहुत धन्यवाद – dorchard