haskell - क्या कोई ऐसी भाषा है जिसमें बाध्यकारी प्रकार हैं?




agda dependent-type (5)

क्या एक टाइप की गई प्रोग्रामिंग भाषा है जहां मैं निम्नलिखित दो उदाहरणों जैसे प्रकारों को बाधित कर सकता हूं?

  1. एक संभाव्यता न्यूनतम मूल्य 0.0 और अधिकतम मान 1.0 के साथ एक फ़्लोटिंग पॉइंट नंबर है।

    type Probability subtype of float
    where
        max_value = 0.0
        min_value = 1.0
    
  2. एक असतत संभाव्यता वितरण एक नक्शा है, जहां: कुंजी सभी एक ही प्रकार के होनी चाहिए, मान सभी संभावनाएं हैं, और मानों का योग = 1.0।

    type DPD<K> subtype of map<K, Probability>
    where
        sum(values) = 1.0
    

जहां तक ​​मैं समझता हूं, यह हास्केल या आगाडा के साथ संभव नहीं है।


आप इसे हास्केल में लिक्विड हास्केल के साथ कर सकते हैं जो हास्केल को परिशोधन प्रकारों के साथ बढ़ाता है। भविष्यवाणियों को संकलन समय पर एक एसएमटी सॉल्वर द्वारा प्रबंधित किया जाता है जिसका अर्थ है कि सबूत पूरी तरह से स्वचालित हैं, लेकिन जो तर्क आप उपयोग कर सकते हैं वह एसएमटी सॉल्वर हैंडल द्वारा सीमित है। (खुशी से, आधुनिक एसएमटी solvers उचित बहुमुखी हैं!)

एक समस्या यह है कि मुझे नहीं लगता कि तरल हास्केल वर्तमान में फ्लोट का समर्थन करता है। यदि ऐसा नहीं होता है, तो इसे सुधारना संभव होना चाहिए क्योंकि एसएमटी सॉल्वर के लिए फ़्लोटिंग पॉइंट नंबरों के सिद्धांत हैं । आप फ्लोटिंग पॉइंट नंबरों का नाटक भी कर सकते हैं वास्तव में तर्कसंगत थे (या यहां तक ​​कि हास्केल में Rational भी उपयोग करें!)। इस बात को ध्यान में रखते हुए, आपका पहला प्रकार इस तरह दिख सकता है:

{p : Float | p >= 0 && p <= 1}

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

measure total :: [(a, Float)] -> Float
total []          = 0 
total ((_, p):ps) = p + probDist ps

(आप एक नए प्रकार में भी [] लपेटना चाहते हैं।)

अब आप एक सूची को बाधित करने के लिए परिशोधन में total उपयोग कर सकते हैं:

{dist: [(a, Float)] | total dist == 1}

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


आप जो चाहते हैं उसे परिष्करण प्रकार कहा जाता है

Agda में Probability को परिभाषित करना संभव है: Prob.agda

संभावना शर्त के साथ संभाव्यता द्रव्यमान कार्य पंक्ति 264 पर परिभाषित किया गया है।

Agda की तुलना में अधिक प्रत्यक्ष परिशोधन प्रकार वाली भाषाएं हैं, उदाहरण के लिए ATS


पर्ल 6 में "टाइप सबसेट्स" की धारणा है जो "उप प्रकार" बनाने के लिए मनमानी स्थितियों को जोड़ सकती है।

विशेष रूप से आपके प्रश्न के लिए:

subset Probability of Real where 0 .. 1;

तथा

role DPD[::T] {
  has Map[T, Probability] $.map
    where [+](.values) == 1; # calls `.values` on Map
}

(नोट: वर्तमान कार्यान्वयन में, "जहां" भाग रन-टाइम पर चेक किया जाता है, लेकिन चूंकि संकलित समय ("आपकी कक्षाएं शामिल हैं) पर" वास्तविक प्रकार "की जांच की जाती है, और चूंकि शुद्ध एनोटेशन ( is pure ) std (जो ज्यादातर perl6 है) (वे * जैसे आदि ऑपरेटरों पर भी हैं), यह केवल प्रयासों का एक मामला है (और यह और अधिक नहीं होना चाहिए)।

आम तौर पर:

# (%% is the "divisible by", which we can negate, becoming "!%%")
subset Even of Int where * %% 2; # * creates a closure around its expression
subset Odd of Int where -> $n { $n !%% 2 } # using a real "closure" ("pointy block")

फिर आप जांच सकते हैं कि स्मार्ट मिलान ऑपरेटर के साथ कोई संख्या मेल खाता है ~~ :

say 4 ~~ Even; # True
say 4 ~~ Odd; # False
say 5 ~~ Odd; # True

और, multi sub एस (या बहु जो भी, वास्तव में - बहु विधियों या अन्य) के लिए धन्यवाद, हम उस पर आधारित प्रेषण कर सकते हैं:

multi say-parity(Odd $n) { say "Number $n is odd" }
multi say-parity(Even) { say "This number is even" } # we don't name the argument, we just put its type
#Also, the last semicolon in a block is optional

पहले भाग के लिए, हाँ, वह पास्कल होगा, जिसमें पूर्णांक subranges है।


थोड़ी सी भाषा आप जो कह रहे हैं उससे बहुत कुछ का समर्थन करती है। उदाहरण के लिए:

type natural is (int x) where x >= 0
type probability is (real x) where 0.0 <= x && x <= 1.0

इन प्रकारों को पूर्व-पोस्ट-स्थितियों के रूप में भी कार्यान्वित किया जा सकता है:

function abs(int x) => (int r)
ensures r >= 0:
    //
    if x >= 0:
        return x
    else:
        return -x

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





dependent-type