Advertisement
tamarin_vs19

Untitled

May 18th, 2021
390
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module CountryColoring where
  2.  
  3. import EuropeBorders
  4. import Z3.Monad
  5. import Control.Monad
  6. import Data.Map (Map)
  7. import qualified Data.Map as M
  8. import qualified Data.Traversable as T
  9. import Data.Maybe
  10.  
  11. data Color = Red | Green | Blue | Yellow
  12.   deriving (Show, Eq, Ord, Enum, Bounded)
  13.  
  14. type Coloring = Map Country Color
  15.  
  16. {-
  17. Реализуйте функцию, которая с помощью Z3 вычисляет такую раскраску карты
  18. с заданными границами между странами, чтобы никакие две соседние страны
  19. не были бы покрашены одним цветом. Карта задаётся списками соседних стран
  20. для каждой страны. Пример такой карты имеется в модуле EuropeBorders.
  21. Известно, что для раскраски любой карты достаточно четырёх цветов
  22. (https://en.wikipedia.org/wiki/Four_color_theorem).
  23.  
  24. Подсказка: цвет каждой страны в формуле для SMT-солвера -- это целая
  25. переменная, равная 0, 1, 2 или 3, ограниченная также набором
  26. неравенств для всех стран, граничащих с данной страной.
  27. -}
  28.  
  29. coloring :: Map Country [Country] -> Z3 (Maybe Coloring)
  30. coloring mapCountry = do
  31.   nodes <- foldM (\acc x -> do
  32.     var <- mkFreshIntVar x
  33.     return $ M.insert var x acc
  34.                  ) M.empty (M.keys mapCountry)
  35.   _0 <- mkInteger (0 :: Integer)
  36.   _3 <- mkInteger (3 :: Integer)
  37.   assert =<< mkAnd =<< T.sequence [ mkLe _0 v | v <- M.keys nodes]
  38.   assert =<< mkAnd =<< T.sequence [ mkLe v _3 | v <- M.keys nodes]
  39.   assert =<< mkNot =<< mkOr =<< T.sequence [
  40.     mkEq v1 v2 | v1 <- M.keys nodes, v2 <- M.keys nodes,
  41.     (nodes M.! v1) `elem` (mapCountry M.! (nodes M.! v2))]
  42.   getSolution nodes
  43.   where
  44.     getSolution :: Map AST String -> Z3 (Maybe Coloring)
  45.     getSolution nodes = do
  46.       let vals = M.keys nodes
  47.       colors <- (fmap . fmap . fmap) toColor
  48.         (fmap snd $ withModel $ \m -> catMaybes <$> mapM (evalInt m) vals)
  49.       let colorMap = fmap (\cs -> zipWith (\a b -> (a, b)) [nodes M.! key | key <- vals] cs) colors
  50.       return $ fmap M.fromList colorMap
  51.     toColor i = M.fromList [(0, Red), (1, Green), (2, Blue), (3, Yellow)] M.! i
  52.  
  53.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement