satchmo-2.9.9.4: examples/AIS.hs
-- | The all-interval series problem.
-- https://ianm.host.cs.st-andrews.ac.uk/CSPLib/prob/prob007/spec.html
-- As I am reading it, the task is to find one (or all) graceful labellings of a path.
-- Finding one is easy, you can take [0, n, 1, n-1, 2, .. ]
-- for Definition and Background, see
-- http://www.combinatorics.org/ojs/index.php/eljc/article/view/DS6
{-# language ScopedTypeVariables #-}
import Prelude hiding ( not, product, and, or )
import qualified Prelude
import qualified Satchmo.Relation as R
import Satchmo.Code
import Satchmo.Boolean
import qualified Satchmo.Counting as C
import Satchmo.SAT.Mini
import Data.List (inits, tails, sort)
import qualified Data.Array as A
import Control.Monad ( guard, when, forM, foldM, forM_ )
import System.Environment
import Data.Ix ( range)
import Control.Applicative ((<$>))
main :: IO ()
main = do
argv <- getArgs
case argv of
[ ] -> main_with 5
[s] -> main_with $ read s
main_with :: Int -> IO ()
main_with n = do
Just a <- solve $ ais n
let xs = do
let ((u,l),(o,r)) = A.bounds a
x <- A.range (u,o)
let zs = map (\y -> a A.! (x,y) ) (A.range(l,r))
return $ length $ takeWhile Prelude.not zs
ds = map abs $ zipWith (-) xs $ drop 1 xs
print xs
print $ sort xs == [0 .. n]
print ds
print $ sort ds == [1 .. n]
ais :: Int
-> SAT (SAT (A.Array (Int,Int) Bool))
ais n = do
r :: R.Relation Int Int <-
R.relation ((0,0),(n,n))
assertM $ R.is_bijection r
forM_ [ 1 .. n-1 ] $ \ d -> do
occs <- concat <$> ( forM [ 0 .. n-1 ] $ \ x -> do
forM [0 .. n-d] $ \ v -> do
up <- and [ r R.! (x,v), r R.! (x+1,v+d) ]
down <- and [ r R.! (x,v+d), r R.! (x+1,v) ]
or [up,down] )
assertM $ C.exactly 1 occs
return $ decode r
assertM action = do x <- action ; assert [x]
fromfunc bnd f = R.build bnd $ do i <- A.range bnd ; return (i, f i )