fork(1) download
  1. import Data.Maybe
  2. import Data.Functor
  3.  
  4. data Prop = Var String
  5. | Not Prop
  6. | And [Prop]
  7. | Or [Prop]
  8. | Nil
  9. deriving (Show)
  10.  
  11. cutAndAppend :: Prop -> [Prop] -> [Prop]
  12. cutAndAppend (And ps) qs = ps ++ qs
  13. cutAndAppend p qs = p : qs
  14.  
  15. cutOrAppend :: Prop -> [Prop] -> [Prop]
  16. cutOrAppend (Or ps) qs = ps ++ qs
  17. cutOrAppend p qs = p : qs
  18.  
  19. smart :: ([Prop] -> Prop) -> [Prop] -> Maybe Prop
  20. smart cons [] = Nothing
  21. smart cons [x] = Just x
  22. smart cons xs = Just (cons xs)
  23.  
  24. flatten' :: Prop -> Maybe Prop
  25. flatten' Nil = Nothing
  26. flatten' (Var v) = Just (Var v)
  27. flatten' (Not p) = Not <$> flatten' p
  28. flatten' (And ps) = smart And $ foldr cutAndAppend [] $ mapMaybe flatten' ps
  29. flatten' (Or ps) = smart Or $ foldr cutOrAppend [] $ mapMaybe flatten' ps
  30.  
  31. flatten :: Prop -> Prop
  32. flatten = fromMaybe Nil . flatten'
  33.  
  34. vx = Var "x"; vy = Var "y"; vz = Var "z"
  35.  
  36. main = mapM_ (print . flatten)
  37. [ And [Or [Nil], Nil, And [Nil]]
  38. -- Nil
  39.  
  40. , And [Or [vx, vy], Or [vx, Or [vz, Nil]]]
  41. -- And [Or [Var "x",Var "y"],Or [Var "x",Var "z"]]
  42.  
  43. , Or [Or [vx, vy], Or [vx, Or [vz, Nil]]]
  44. -- Or [Var "x",Var "y",Var "x",Var "z"]
  45.  
  46. , Not (And [And [Or [Or [Nil], Or [Not vx]], Nil, And [vy]]])
  47. -- Not (And [Not (Var "x"),Var "y"])
  48.  
  49. , And []
  50. -- Nil
  51.  
  52. , Or [And [vx]]
  53. -- Var "x"
  54.  
  55. , And [vx, Or []]
  56. -- Var "x'
  57.  
  58. , And [Or [And [vx, Or [], vy, Nil]], And [vz, Or [vx]]]
  59. -- And [Var "x",Var "y",Var "z",Var "x"]
  60. ]
Success #stdin #stdout 0s 6232KB
stdin
Standard input is empty
stdout
Nil
And [Or [Var "x",Var "y"],Or [Var "x",Var "z"]]
Or [Var "x",Var "y",Var "x",Var "z"]
Not (And [Not (Var "x"),Var "y"])
Nil
Var "x"
Var "x"
And [Var "x",Var "y",Var "z",Var "x"]