{-| Module : MZinHaskell Description : Integration of MiniZinc 2.0 in Haskell Copyright : (c) Some Guy, 2013 Someone Else, 2014 License : BSD3 Maintainer : Klara Marntirosian Stability : experimental This module integrates constraint solving programming through MiniZinc in Haskell. -} {-# LANGUAGE CPP #-} module Interfaces.MZinHaskell ( module Interfaces.MZAST, module Interfaces.FZSolutionParser, module Interfaces.MZPrinter, iTestModel, testModel, writeData ) where import Interfaces.Auxiliary import System.Process #ifdef unix import System.FilePath.Posix #else import System.FilePath.Windows #endif import Interfaces.MZPrinter import Interfaces.FZSolutionParser import Interfaces.MZAST hiding (UserD, PrefBop) -- | Interactively runs a model and outputs its solution(s). The function first prompts the user -- for the paths of the file in which the represented MiniZinc model will be printed and the -- data file if required. Then asks the user to choose between supported solvers and the desired -- number of solutions (only one or all supported for now). Finally, it uses the chosen solver -- and parses the solution(s). iTestModel :: MZModel -> IO () iTestModel m = do putStrLn "Enter MiniZinc model's filepath:" path <- getLine putStrLn "Is there a data file? If yes, provide its filepath:" dpath <- getLine putStrLn "Type \"fd\" for G12/FD solver or leave empty for choco solver." solver <- getLine putStrLn "Enter 0 to output all solutions." mode <- getLine testModel m path dpath solver mode -- | Runs a model and parses its solution(s). testModel :: MZModel -- ^ The model -> FilePath -- ^ The path of the file in which the represented MiniZinc model will be printed -> FilePath -- ^ The path of the data file if required, else an empty string -> String -- ^ The chose solver ("fd" for the G12/FD built-in solver or empty string for choco3) -> String -- ^ "0" for all solutions, empty string for the first solution -> IO () testModel m mzn dtf s n = do configuration <- parseConfig let mz_dir = case minizinc configuration of "" -> addTrailingPathSeparator "." str -> addTrailingPathSeparator str let mfzn = spaceFix $ mz_dir ++ "mzn2fzn" let flatzinc = spaceFix $ mz_dir ++ "flatzinc" writeFile (mzn) (Prelude.show $ printModel m) readCreateProcess (shell (mfzn ++ mzn ++ dtf)) "" let (filename, _) = splitExtension mzn let opt = case n of "0" -> " -a " _ -> " " res <- case s of "" -> let antlr = antlr_path configuration chocoParser = chocoparser configuration chocoSolver = chocosolver configuration in readCreateProcess (shell $ "java -cp ." ++ [searchPathSeparator] ++ chocoSolver ++ [searchPathSeparator] ++ chocoParser ++ [searchPathSeparator] ++ antlr ++ " org.chocosolver.parser.flatzinc.ChocoFZN" ++ opt ++ filename ++ ".fzn> " ++ filename ++ ".fzn.results.txt") "" _ -> readCreateProcess (shell $ flatzinc ++ opt ++ "-b fd " ++ filename ++ ".fzn > " ++ filename ++ ".fzn.results.txt") "" getSolution $ filename ++ ".fzn.results.txt" -- | Writes the model's data file. The 'MZModel' of the argument must contain -- only 'Assignment' items. writeData :: MZModel -> IO () writeData m = do putStrLn "Enter MiniZinc datafile's filepath:" datapath <- getLine writeFile datapath (Prelude.show $ printModel m)