如果你想隨機產生一些東西,我建議一個非確定性monad,其中MonadRandom是一個流行的選擇。
我會建議這個程序有兩個輸入:vars
,變量的個數,以及clauses
的子句數。當然,你也可以隨機生成子句的數量,使用相同的想法。這裏有一個素描:
import Control.Monad.Random (Rand, StdGen, uniform)
import Control.Applicative ((<$>))
import Control.Monad (replicateM)
type Cloud = Rand StdGen -- for "probability cloud"
newtype Var = Var Int
data Atom = Positive Var -- X
| Negative Var -- not X
type CNF = [[Atom]] -- conjunction of disjunctions
genCNF :: Int -> Int -> Cloud CNF
genCNF vars clauses = replicateM clauses genClause
where
genClause :: Could [Atom]
genClause = replicateM 3 genAtom -- for CNF-3
genAtom :: Cloud Atom
genAtom = do
f <- uniform [Positive, Negative]
v <- Var <$> uniform [0..vars-1]
return (f v)
我列入where
子句中的可選類型簽名,以使其更易於遵循結構。
本質上,請按照您嘗試生成的內容的「語法」每個非終結者都有一個gen*
函數。
我不知道如何判斷一個CNF表達式是容易還是困難。
monadrandom這應該真正被稱爲 「隨機性單子」 而不是 「nondetermism單子」 –
@PhilipJF,我想到的是,那個'[]'&CO通常被稱爲不確定性,但我沒有看到爲什麼稱蘭德爲非確定性單子會是不正確的。從語義上講,它屬於同一個家族。你知道一個很好的理由嗎? – luqui
好吧,monadrandom會產生一個結果的概率分佈,這與非確定性實際上不是一回事,它在語義上只是給你一個集合。 –