2015-03-03 1 views
2

Existe-t-il un algorithme pour diriger toutes les combinaisons possibles d'une quantité donnée de valeurs logiques à trois valeurs?Toutes les combinaisons possibles de valeurs logiques à trois valeurs

Par exemple, F(2) doit retourner cette liste:

t t 
t u 
t f 
u t 
u u 
u f 
f t 
f u 
f f 

La fonction ressemblerait à ceci (en Haskell):

data Tril = FALSE | NULL | TRUE 

all :: Int -> [[Tril]] 
all amount = ??? 

all1 :: [Tril] 
all1 = join (all 1) 

all2 :: [(Tril, Tril)] 
all2 = map (\[f, s] -> (f, s)) (all 2) 

all3 :: [(Tril, Tril, Tril)] 
all3 = map (\[f, s, t] -> (f, s, t)) (all 3) 

Répondre

7

Vous pouvez le faire très simplement comme la compréhension de la liste:

all2 = [ (v1, v2) | v1 <- [FALSE, TRUE, NULL], v2 <- [FALSE, TRUE, NULL] ] 

Vous pouvez l'écrire de manière équivalente comme un do-bloc monadique:

all2 = do 
    v1 <- [FALSE, TRUE, NULL] 
    v2 <- [FALSE, TRUE, NULL] 
    return (v1, v2) 

Et qui nous donne une idée de la façon dont nous peut écrire la taille variable un:

all 0 = [[]] -- Note: Empty list with one empty item. 
all n = do 
    v <- [FALSE, TRUE, NULL] 
    vs <- all (n-1) 
    return (v:vs) 

il se trouve — et c'est légèrement l'esprit — c'est l'effet net de la fonction replicateM. Il faut une action monadique, fait N fois, et rassemble les résultats ensemble.

all n = replicateM n [FALSE, TRUE, NULL] 
+0

Merci pour votre réponse détaillée! –

4

replicateM fait exactement cela:

> import Control.Monad 
> replicateM 2 [1,2,3] 
[[1,1],[1,2],[1,3],[2,1],[2,2],[2,3],[3,1],[3,2],[3,3]] 

Par conséquent,

all :: Int -> [[Tril]] 
all amount = replicateM amount [FALSE,NULL,TRUE] 

Je suggère de choisir un autre nom, puisque all est déjà pris par Prelude.all.

+0

Merci pour votre réponse! :) –