A set of benchmarks to compare a new prototype MiniZinc implementation
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2 3/* 4 * Main authors: 5 * Guido Tack <guido.tack@monash.edu> 6 * Gleb Belov <gleb.belov@monash.edu> 7 */ 8 9/* This Source Code Form is subject to the terms of the Mozilla Public 10 * License, v. 2.0. If a copy of the MPL was not distributed with this 11 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 12 13#ifndef __MINIZINC_SOLNS2OUT_H__ 14#define __MINIZINC_SOLNS2OUT_H__ 15 16#include <minizinc/astexception.hh> 17#include <minizinc/builtins.hh> 18#include <minizinc/file_utils.hh> 19#include <minizinc/flatten.hh> 20#include <minizinc/flatten_internal.hh> // temp., TODO 21#include <minizinc/model.hh> 22#include <minizinc/optimize.hh> 23#include <minizinc/parser.hh> 24#include <minizinc/solver_instance.hh> 25#include <minizinc/typecheck.hh> 26#include <minizinc/utils.hh> 27 28#include <ctime> 29#include <iomanip> 30#include <memory> 31#include <set> 32#include <string> 33#include <unordered_map> 34#include <vector> 35 36namespace MiniZinc { 37 38/// Class handling fzn solver's output 39/// could facilitate exhange of raw/final outputs in a portfolio 40class Solns2Out { 41protected: 42 std::unique_ptr<Env> pEnv_guard; 43 Env* pEnv = 0; 44 Model* pOutput = 0; 45 46 typedef std::pair<VarDecl*, KeepAlive> DE; 47 std::unordered_map<std::string, DE> declmap; 48 Expression* outputExpr = NULL; 49 std::string checkerModel; 50 bool fNewSol2Print = false; // should be set for evalOutput to work 51 52public: 53 std::string solution; 54 std::string comments; 55 int nLinesIgnore = 0; 56 57 struct Options { 58 std::string flag_output_file; 59 bool flag_output_comments = true; 60 bool flag_output_flush = true; 61 bool flag_output_time = false; 62 int flag_ignore_lines = 0; 63 bool flag_unique = 1; 64 bool flag_canonicalize = 0; 65 bool flag_standaloneSolns2Out = false; 66 std::string flag_output_noncanonical; 67 std::string flag_output_raw; 68 int flag_number_output = -1; 69 /// Default values, also used for input 70 const char* const solution_separator_00 = "----------"; 71 const char* const unsatisfiable_msg_00 = "=====UNSATISFIABLE====="; 72 const char* const unbounded_msg_00 = "=====UNBOUNDED====="; 73 const char* const unsatorunbnd_msg_00 = "=====UNSATorUNBOUNDED====="; 74 const char* const unknown_msg_00 = "=====UNKNOWN====="; 75 const char* const error_msg_00 = "=====ERROR====="; 76 const char* const search_complete_msg_00 = "=========="; 77 /// Output values 78 std::string solution_separator = solution_separator_00; 79 std::string solution_comma = ""; 80 std::string unsatisfiable_msg = unsatisfiable_msg_00; 81 std::string unbounded_msg = unbounded_msg_00; 82 std::string unsatorunbnd_msg = unsatorunbnd_msg_00; 83 std::string unknown_msg = unknown_msg_00; 84 std::string error_msg = error_msg_00; 85 std::string search_complete_msg = search_complete_msg_00; 86 } _opt; 87 88public: 89 ~Solns2Out(); 90 Solns2Out(std::ostream& os, std::ostream& log, const std::string& stdlibDir); 91 92 bool processOption(int& i, std::vector<std::string>& argv); 93 void printHelp(std::ostream&); 94 95 /// The output model (~.ozn) can be passed in 1 way in this base class: 96 /// passing Env* containing output() 97 bool initFromEnv(Env* pE); 98 99 /// Then, variable assignments can be passed either as text 100 /// or put directly into envi()->output() ( latter done externally 101 /// by e.g. SolverInstance::assignSolutionToOutput() ) 102 /// In the 1st case, (part of) the assignment text is passed as follows, 103 /// original end-of-lines need to be there as well 104 bool feedRawDataChunk(const char*); 105 106 SolverInstance::Status status = SolverInstance::UNKNOWN; 107 bool fStatusPrinted = false; 108 /// Should be called when entering new solution into the output model. 109 /// Default assignSolutionToOutput() does it by using findOutputVar(). 110 void declNewOutput(); 111 112 /// This can be used by assignSolutionToOutput() 113 DE& findOutputVar(ASTString); 114 115 /// In the other case, 116 /// the evaluation procedures print output/status to os 117 /// returning false means need to stop (error/ too many solutions) 118 /// Solution validation here TODO 119 /// Note that --canonicalize delays output 120 /// until ... exit, eof, ?? TODO 121 /// These functions should only be called explicitly 122 /// from SolverInstance 123 bool evalOutput(const std::string& s_ExtraInfo = ""); 124 /// This means the solver exits 125 bool evalStatus(SolverInstance::Status status); 126 127 void printStatistics(std::ostream&); 128 129 Env* getEnv() const { return pEnv; } 130 Model* getModel() const { 131 assert(getEnv()->output()); 132 return getEnv()->output(); 133 } 134 /// Get the primary output stream 135 /// First call restores stdout 136 std::ostream& getOutput(); 137 /// Get the secondary output stream 138 std::ostream& getLog(); 139 140private: 141 Timer starttime; 142 143 std::unique_ptr<std::ostream> pOut; // file output 144 std::unique_ptr<std::ostream> pOfs_non_canon; 145 std::unique_ptr<std::ostream> pOfs_raw; 146 int nSolns = 0; 147 std::set<std::string> sSolsCanon; 148 std::string line_part; // non-finished line from last chunk 149 150 /// Initialise from ozn file 151 void initFromOzn(const std::string& filename); 152 153protected: 154 std::ostream& os; 155 std::ostream& log; 156 std::vector<std::string> includePaths; 157 std::string stdlibDir; 158 159 // Basically open output 160 void init(); 161 void createOutputMap(); 162 std::map<std::string, SolverInstance::Status> mapInputStatus; 163 void createInputMap(); 164 void restoreDefaults(); 165 /// Parsing fznsolver's complete raw text output 166 void parseAssignments(std::string&); 167 /// Checking solution against checker model 168 void checkSolution(std::ostream& os); 169 bool __evalOutput(std::ostream& os); 170 bool __evalOutputFinal(bool flag_flush); 171 bool __evalStatusMsg(SolverInstance::Status status); 172}; 173 174// Passthrough Solns2Out class 175class Solns2Log { 176private: 177 std::ostream& _log; 178 std::ostream& _err_log; 179 180public: 181 Solns2Log(std::ostream& log, std::ostream& errLog) : _log(log), _err_log(errLog) {} 182 bool feedRawDataChunk(const char* data) { 183 _log << data << std::flush; 184 return true; 185 } 186 std::ostream& getLog(void) { return _err_log; } 187}; 188 189} // namespace MiniZinc 190 191#endif // __MINIZINC_SOLNS2OUT_H__