ত্রুটিযুক্ত ছিদ্র ধরণের রেজোলিউশন


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'এবং আপনার কোডটি এখনও পরীক্ষা করে রাখতে পারে।
kosmikus

1
বেশ সম্ভবত আমি খুব আশা করছি। তবে অনেক ক্ষেত্রে এটি ঠিক আগদার মতো কাজ করে তাই আচরণের নিয়মকানুনগুলি খুঁজে বের করতে এটি এখনও কার্যকর হবে useful যদিও আমি আশাবাদী নই, যেহেতু বিষয়টি টাইপ চেকারের অন্ত্রের সাথে গভীরভাবে জড়িত।
আন্দ্রেস কোভিকস

1
এটি আপনার প্রশ্নের জন্য কিছুটা অরথগোনাল, তবে আপনি সমীকরণীয় যুক্তি সংযোজকগুলির একটি সেট à লা আগদা ব্যবহার করে এই প্রমাণগুলি সরিয়ে ফেলতে পারেন। Cf. ধারণার এই প্রমাণ
গ্যালাইস

উত্তর:


1

আপনি যদি এই জাতীয় সমস্ত মান উত্পন্ন করতে চান, তবে আপনি প্রদত্ত বা নির্দিষ্ট সীমা দ্বারা এটি করার জন্য একটি ফাংশন লিখতে পারেন।

এগুলির সৃষ্টি প্রয়োগের জন্য টাইপ-লেভেল চার্চ সংখ্যা বা এমন কিছু ব্যবহার করা খুব সম্ভব হতে পারে তবে আপনি সম্ভবত যা চান / প্রয়োজন তা এটি প্রায় অবশ্যই খুব বেশি কাজ।

এটি আপনি যা চান তা হতে পারে না (যেমন "z = 5 - x - y" থেকে কেবল (x, y) ব্যবহার করা বাদে) তবে বৈধ অনুমতি দেওয়ার জন্য প্রকারের স্তরে কিছু প্রকারের সীমাবদ্ধতা রাখার চেষ্টা করার চেয়ে এটি আরও বোধগম্য হয় মান।


-3

এটি ঘটে কারণ মানগুলি রান সময়ে নির্ধারিত হয়। এটি রান সময়ে কী প্রবেশ করানো হয়েছে তার উপর নির্ভর করে মানগুলির একটি রূপান্তর আনতে পারে সুতরাং এটি ধরে নিয়েছে যে গর্তটি ইতিমধ্যে আপডেট হয়েছে।


3
অবশ্যই মানগুলি রানটাইমের সময় নির্ধারিত হয় তবে প্রশ্নের সাথে এর কোনও যোগসূত্র নেই। GADT এ প্যাটার্ন-মিল থেকে প্রয়োজনীয় তথ্য ইতিমধ্যে উপলব্ধ available
int_index
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.