इरेटिक होल प्रकार का रिज़ॉल्यूशन


105

मुझे हाल ही में पता चला है कि प्रूफ पर मिलान करने वाले पैटर्न के साथ संयुक्त प्रकार के छेद हास्केल में एक बहुत अच्छा एजडा जैसा अनुभव प्रदान करते हैं। उदाहरण के लिए:

{-# LANGUAGE
    DataKinds, PolyKinds, TypeFamilies, 
    UndecidableInstances, GADTs, TypeOperators #-}

data (==) :: k -> k -> * where
    Refl :: x == x

sym :: a == b -> b == a
sym Refl = Refl 

data Nat = Zero | Succ Nat

data SNat :: Nat -> * where
    SZero :: SNat Zero
    SSucc :: SNat n -> SNat (Succ n)

type family a + b where
    Zero   + b = b
    Succ a + b = Succ (a + b)

addAssoc :: SNat a -> SNat b -> SNat c -> (a + (b + c)) == ((a + b) + c)
addAssoc SZero b c = Refl
addAssoc (SSucc a) b c = case addAssoc a b c of Refl -> Refl

addComm :: SNat a -> SNat b -> (a + b) == (b + a)
addComm SZero SZero = Refl
addComm (SSucc a) SZero = case addComm a SZero of Refl -> Refl
addComm SZero (SSucc b) = case addComm SZero b of Refl -> Refl
addComm sa@(SSucc a) sb@(SSucc b) =
    case addComm a sb of
        Refl -> case addComm b sa of
            Refl -> case addComm a b of
                Refl -> Refl 

वास्तव में अच्छी बात यह है कि मैं Refl -> expकंस्ट्रक्शन के दाहिने हाथ के किनारों को एक प्रकार के छेद से बदल सकता हूं , और मेरे छेद लक्ष्य प्रकारों को प्रमाण के साथ अपडेट किया जाता है, जो कि rewriteएजडा के रूप में बहुत अधिक है ।

हालांकि, कभी-कभी छेद सिर्फ अपडेट करने में विफल रहता है:

(+.) :: SNat a -> SNat b -> SNat (a + b)
SZero   +. b = b
SSucc a +. b = SSucc (a +. b)
infixl 5 +.

type family a * b where
    Zero   * b = Zero
    Succ a * b = b + (a * b)

(*.) :: SNat a -> SNat b -> SNat (a * b)
SZero   *. b = SZero
SSucc a *. b = b +. (a *. b)
infixl 6 *.

mulDistL :: SNat a -> SNat b -> SNat c -> (a * (b + c)) == ((a * b) + (a * c))
mulDistL SZero b c = Refl
mulDistL (SSucc a) b c = 
    case sym $ addAssoc b (a *. b) (c +. a *. c) of
        -- At this point the target type is
        -- ((b + c) + (n * (b + c))) == (b + ((n * b) + (c + (n * c))))
        -- The next step would be to update the RHS of the equivalence:
        Refl -> case addAssoc (a *. b) c (a *. c) of
            Refl -> _ -- but the type of this hole remains unchanged...

इसके अलावा, भले ही लक्ष्य प्रकार आवश्यक रूप से प्रमाण के अंदर न हों, अगर मैं अगड़ा से पूरी चीज में पेस्ट करता हूं तो यह अभी भी ठीक जांचता है:

mulDistL' :: SNat a -> SNat b -> SNat c -> (a * (b + c)) == ((a * b) + (a * c))
mulDistL' SZero b c = Refl
mulDistL' (SSucc a) b c = case
    (sym $ addAssoc b (a *. b) (c +. a *. c),
    addAssoc (a *. b) c (a *. c),
    addComm (a *. b) c,
    sym $ addAssoc c (a *. b) (a *. c),
    addAssoc b c (a *. b +. a *. c),
    mulDistL' a b c
    ) of (Refl, Refl, Refl, Refl, Refl, Refl) -> Refl

क्या आपके पास कोई विचार है कि ऐसा क्यों होता है (या मैं कैसे मजबूत तरीके से प्रूफ पुनर्लेखन कर सकता हूं)?


8
क्या आप कुछ ज्यादा की उम्मीद नहीं कर रहे हैं? एक समानता प्रमाण पर मिलान पैटर्न एक (द्विदिश) समानता स्थापित कर रहा है। यह स्पष्ट नहीं है कि आप इसे कहाँ और किस दिशा में लक्ष्य प्रकार पर लागू करना चाहते हैं। उदाहरण के लिए, आप symकॉल को छोड़ सकते हैं mulDistL'और आपका कोड अभी भी जाँच करेगा।
कोसमिकस

1
काफी संभवतः मैं बहुत ज्यादा उम्मीद कर रहा हूं। हालाँकि, कई मामलों में यह एजडा की तरह ही काम करता है इसलिए व्यवहार की नियमितता का पता लगाना अभी भी उपयोगी होगा। हालांकि, मैं आशावादी नहीं हूं, क्योंकि यह मामला संभवत: प्रकार चेकर के आंतों के साथ जुड़ा हुआ है।
आंद्र कोविक्स

1
यह आपके प्रश्न के लिए थोड़ा सा रूढ़िवादी है, लेकिन आप इन साक्ष्यों को समान तर्क युक्त कंघी बनाने वालों के एक सेट का उपयोग करके खींच सकते हैं। सी एफ अवधारणा का यह प्रमाण
13:13 बजे

जवाबों:


1

यदि आप इस तरह के सभी संभावित मूल्यों को उत्पन्न करना चाहते हैं, तो आप ऐसा करने के लिए एक फ़ंक्शन लिख सकते हैं, या तो प्रदान या निर्दिष्ट सीमा के साथ।

हो सकता है कि इनका निर्माण लागू करने के लिए टाइप-लेवल चर्च न्यूमर्स या कुछ इस तरह का उपयोग करना बहुत संभव हो, लेकिन यह संभवतः निश्चित रूप से बहुत ज्यादा काम है जो आप शायद चाहते हैं / जरूरत है।

यह वह नहीं हो सकता है जो आप चाहते हैं (अर्थात "z = 5 - x - y" के बाद से सिर्फ (x, y) के उपयोग को छोड़कर) लेकिन यह वैधता की अनुमति देने के लिए टाइप स्तर पर कुछ प्रकार के लागू प्रतिबंध लगाने की कोशिश करने से अधिक समझ में आता है मान।


-3

ऐसा इसलिए होता है क्योंकि मान रन टाइम पर निर्धारित किए जाते हैं। यह रन टाइम में दर्ज किए गए मूल्यों के आधार पर मूल्यों में परिवर्तन ला सकता है इसलिए यह मान लेता है कि छेद पहले से ही अपडेट है।


3
बेशक मूल्य रनटाइम पर निर्धारित किए जाते हैं, लेकिन इसका सवाल से कोई लेना-देना नहीं है। आवश्यक जानकारी पहले से ही GADT पर पैटर्न-मिलान से उपलब्ध है।
int_index
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.