मैं हास्केल में sbv के साथ एक अनुकूलन समस्या को हल करने का प्रयास कर रहा हूं, लेकिन एक कंपाइलर प्राप्त करें त्रुटि।

समाधान मूल्यों की एक सूची है, और मेरे पास यह जांचने के लिए एक फ़ंक्शन है कि समाधान मान्य है (बाधा), और एक फ़ंक्शन को कम करने के लिए एक संख्या की गणना करने के लिए।

मुझे यह संकलक त्रुटि मेरे न्यूनतम उदाहरण पर मिलती है:

/home/t/sbvExample/Main.hs:28:5: error:
    • No instance for (S.SymVal S.SBool)
        arising from a use of ‘Sl.length’
    • In the expression: Sl.length xs
      In an equation for ‘toNum’: toNum xs = Sl.length xs
   |
28 |     Sl.length xs
   |     ^^^^^^^^^^^^

यहाँ कोड है:

{-# LANGUAGE ScopedTypeVariables #-} 
module Main (main) where

import qualified Data.SBV.List as Sl
import qualified Data.SBV as S


main :: IO ()
main = do
    result <- S.optimize S.Lexicographic help
    print result


help :: S.SymbolicT IO ()
help = do
    xs :: S.SList S.SBool <- S.sList "xs"
    S.constrain $ isValid xs
    S.minimize "goal" $ toNum xs


isValid :: S.SList S.SBool -> S.SBool
isValid xs =
    Sl.length xs S..> 0


toNum :: S.SList S.SBool -> S.SInteger
toNum xs =
    Sl.length xs

तो इस मूर्खतापूर्ण न्यूनतम उदाहरण में मैं एक आइटम वाली सूची की अपेक्षा करता हूं।

सुविधा के लिए मैंने इसे जीथब पर रखा है, इसलिए इसे इसके साथ बनाएं:

git clone https://github.com/8n8/sbvExample
cd sbvExample
stack build
1
5ndG 9 अप्रैल 2020, 19:11

2 जवाब

सबसे बढ़िया उत्तर

आपको यह त्रुटि संदेश इसलिए मिल रहा है क्योंकि है SBool के लिए SymVal का कोई उदाहरण नहीं, केवल Bool के लिए, और S.length S.SList SymVal मानों की अपेक्षा करता है:

length :: SymVal a => SList a -> SInteger

आप y S.SList Bool को स्वीकार करने के लिए toNum और isValid को बदलकर और xs के प्रकार को S.SList Bool में बदलकर इसे ठीक कर सकते हैं:

help :: S.SymbolicT IO ()
help = do
    xs :: S.SList Bool <- S.sList "xs"
    S.constrain $ isValid xs
    S.minimize "goal" $ toNum xs

isValid :: S.SList Bool -> S.SBool
isValid xs =
    Sl.length xs S..> 0

toNum :: S.SList Bool -> S.SInteger
toNum xs =
    Sl.length xs

आपके isValid और toNum फ़ंक्शन भी अत्यधिक विशिष्ट हैं, क्योंकि उन्हें केवल SymVal वर्ग बाधा की आवश्यकता होती है। निम्नलिखित अधिक सामान्य है और अभी भी संकलित है:

isValid :: S.SymVal a => S.SList a -> S.SBool
toNum :: S.SymVal a => S.SList a -> S.SInteger

संपादित करें

क्या यह toNum टाइपचेक करने में विफल होने के लिए नहीं था, आपने यह भी देखा होगा कि S.sList भी टाइपचेक नहीं करता है, क्योंकि इसके टाइप सिग्नेचर में SymVal रिटर्न के टाइप पैरामीटर पर बाधा है S.SList:

sList :: SymVal a => String -> Symbolic (SList a)

isValid और toNum को हटाना और केवल S.sList कंस्ट्रक्टर को रखना:

help = do
    xs :: S.SList S.SBool <- S.sList "xs"
    return ()

इस त्रुटि को फेंकता है:

• No instance for (S.SymVal S.SBool)
    arising from a use of ‘S.sList’

जो, मेरी राय में, वास्तविक मुद्दे के बारे में कुछ और बताता है। यह सिर्फ यह दिखाने के लिए जाता है कि एक न्यूनतम उदाहरण कभी-कभी अधिक न्यूनतम हो सकता है, और इसलिए अधिक सहायक हो सकता है।

3
MikaelF 9 अप्रैल 2020, 20:16