Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
93 kB · 2982 lines
C++
at develop
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- *//* * Main authors: * Guido Tack <tack@gecode.org> * * Contributing authors: * Gabriel Hjort Blindell <gabriel.hjort.blindell@gmail.com> * * Copyright: * Guido Tack, 2007-2012 * Gabriel Hjort Blindell, 2012 * * This file is part of Gecode, the generic constraint * development environment: * http://www.gecode.org * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */
#include <gecode/flatzinc.hh>#include <gecode/flatzinc/registry.hh>#include <gecode/flatzinc/plugin.hh>#include <gecode/flatzinc/branch.hh>
#include <gecode/search.hh>
#include <vector>#include <string>#include <sstream>#include <limits>#include <unordered_set>
namespace std {
/// Hashing for tuple sets template<> struct hash<Gecode::TupleSet> { /// Return hash key for \a x forceinline size_t operator()(const Gecode::TupleSet& x) const { return x.hash(); } };
/// Hashing for tuple sets template<> struct hash<Gecode::SharedArray<int> > { /// Return hash key for \a x forceinline size_t operator()(const Gecode::SharedArray<int>& x) const { size_t seed = static_cast<size_t>(x.size()); for (int i=x.size(); i--; ) Gecode::cmb_hash(seed, x[i]); return seed; } };
/// Hashing for DFAs template<> struct hash<Gecode::DFA> { /// Return hash key for \a d forceinline size_t operator()(const Gecode::DFA& d) const { return d.hash(); } };
}
namespace Gecode { namespace FlatZinc {
// Default random number generator Rnd defrnd(0); long long FlatZincSpace::copies = 1;
/** * \brief Branching on the introduced variables * * This brancher makes sure that when a solution is found for the model * variables, all introduced variables are either assigned, or the solution * can be extended to a solution of the introduced variables. * * The advantage over simply branching over the introduced variables is that * only one such extension will be searched for, instead of enumerating all * possible (equivalent) extensions. * */ class AuxVarBrancher : public Brancher { protected: /// Flag whether brancher is done bool done; /// Construct brancher AuxVarBrancher(Home home, TieBreak<IntVarBranch> int_varsel0, IntValBranch int_valsel0, TieBreak<BoolVarBranch> bool_varsel0, BoolValBranch bool_valsel0#ifdef GECODE_HAS_SET_VARS , SetVarBranch set_varsel0, SetValBranch set_valsel0#endif#ifdef GECODE_HAS_FLOAT_VARS , TieBreak<FloatVarBranch> float_varsel0, FloatValBranch float_valsel0#endif ) : Brancher(home), done(false), int_varsel(int_varsel0), int_valsel(int_valsel0), bool_varsel(bool_varsel0), bool_valsel(bool_valsel0)#ifdef GECODE_HAS_SET_VARS , set_varsel(set_varsel0), set_valsel(set_valsel0)#endif#ifdef GECODE_HAS_FLOAT_VARS , float_varsel(float_varsel0), float_valsel(float_valsel0)#endif {} /// Copy constructor AuxVarBrancher(Space& home, AuxVarBrancher& b) : Brancher(home, b), done(b.done) {}
/// %Choice that only signals failure or success class Choice : public Gecode::Choice { public: /// Whether brancher should fail bool fail; /// Initialize choice for brancher \a b Choice(const Brancher& b, bool fail0) : Gecode::Choice(b,1), fail(fail0) {} /// Report size occupied virtual size_t size(void) const { return sizeof(Choice); } /// Archive into \a e virtual void archive(Archive& e) const { Gecode::Choice::archive(e); e.put(fail); } };
TieBreak<IntVarBranch> int_varsel; IntValBranch int_valsel; TieBreak<BoolVarBranch> bool_varsel; BoolValBranch bool_valsel;#ifdef GECODE_HAS_SET_VARS SetVarBranch set_varsel; SetValBranch set_valsel;#endif#ifdef GECODE_HAS_FLOAT_VARS TieBreak<FloatVarBranch> float_varsel; FloatValBranch float_valsel;#endif
public: /// Check status of brancher, return true if alternatives left. virtual bool status(const Space& _home) const { if (done) return false; const FlatZincSpace& home = static_cast<const FlatZincSpace&>(_home); for (int i=0; i<home.iv_aux.size(); i++) if (!home.iv_aux[i].assigned()) return true; for (int i=0; i<home.bv_aux.size(); i++) if (!home.bv_aux[i].assigned()) return true;#ifdef GECODE_HAS_SET_VARS for (int i=0; i<home.sv_aux.size(); i++) if (!home.sv_aux[i].assigned()) return true;#endif#ifdef GECODE_HAS_FLOAT_VARS for (int i=0; i<home.fv_aux.size(); i++) if (!home.fv_aux[i].assigned()) return true;#endif // No non-assigned variables left return false; } /// Return choice virtual Choice* choice(Space& home) { done = true; FlatZincSpace& fzs = static_cast<FlatZincSpace&>(*home.clone()); fzs.needAuxVars = false; branch(fzs,fzs.iv_aux,int_varsel,int_valsel); branch(fzs,fzs.bv_aux,bool_varsel,bool_valsel);#ifdef GECODE_HAS_SET_VARS branch(fzs,fzs.sv_aux,set_varsel,set_valsel);#endif#ifdef GECODE_HAS_FLOAT_VARS branch(fzs,fzs.fv_aux,float_varsel,float_valsel);#endif Search::Options opt; opt.clone = false; FlatZincSpace* sol = dfs(&fzs, opt); if (sol) { delete sol; return new Choice(*this,false); } else { return new Choice(*this,true); } } /// Return choice virtual Choice* choice(const Space&, Archive& e) { bool fail; e >> fail; return new Choice(*this, fail); } /// Perform commit for choice \a c virtual ExecStatus commit(Space&, const Gecode::Choice& c, unsigned int) { return static_cast<const Choice&>(c).fail ? ES_FAILED : ES_OK; } /// Print explanation virtual void print(const Space&, const Gecode::Choice& c, unsigned int, std::ostream& o) const { o << "FlatZinc(" << (static_cast<const Choice&>(c).fail ? "fail" : "ok") << ")"; } /// Copy brancher virtual Actor* copy(Space& home) { return new (home) AuxVarBrancher(home, *this); } /// Post brancher static void post(Home home, TieBreak<IntVarBranch> int_varsel, IntValBranch int_valsel, TieBreak<BoolVarBranch> bool_varsel, BoolValBranch bool_valsel#ifdef GECODE_HAS_SET_VARS , SetVarBranch set_varsel, SetValBranch set_valsel#endif#ifdef GECODE_HAS_FLOAT_VARS , TieBreak<FloatVarBranch> float_varsel, FloatValBranch float_valsel#endif ) { (void) new (home) AuxVarBrancher(home, int_varsel, int_valsel, bool_varsel, bool_valsel#ifdef GECODE_HAS_SET_VARS , set_varsel, set_valsel#endif#ifdef GECODE_HAS_FLOAT_VARS , float_varsel, float_valsel#endif ); } /// Delete brancher and return its size virtual size_t dispose(Space&) { return sizeof(*this); } };
class BranchInformationO : public SharedHandle::Object { private: struct BI { std::string r0; std::string r1; std::vector<std::string> n; BI(void) : r0(""), r1(""), n(0) {} BI(const std::string& r00, const std::string& r10, const std::vector<std::string>& n0) : r0(r00), r1(r10), n(n0) {} }; std::vector<BI> v; BranchInformationO(std::vector<BI> v0) : v(v0) {} public: BranchInformationO(void) {} virtual ~BranchInformationO(void) {} virtual SharedHandle::Object* copy(void) const { return new BranchInformationO(v); } /// Add new brancher information void add(BrancherGroup bg, const std::string& rel0, const std::string& rel1, const std::vector<std::string>& n) { v.resize(std::max(static_cast<unsigned int>(v.size()),bg.id()+1)); v[bg.id()] = BI(rel0,rel1,n); } /// Output branch information void print(const Brancher& b, unsigned int a, int i, int n, std::ostream& o) const { const BI& bi = v[b.group().id()]; o << bi.n[i] << " " << (a==0 ? bi.r0 : bi.r1) << " " << n; }#ifdef GECODE_HAS_FLOAT_VARS void print(const Brancher& b, unsigned int a, int i, const FloatNumBranch& nl, std::ostream& o) const { const BI& bi = v[b.group().id()]; o << bi.n[i] << " " << (((a == 0) == nl.l) ? "<=" : ">=") << nl.n; }#endif };
BranchInformation::BranchInformation(void) : SharedHandle(nullptr) {}
BranchInformation::BranchInformation(const BranchInformation& bi) : SharedHandle(bi) {}
void BranchInformation::init(void) { assert(object() == nullptr); object(new BranchInformationO()); }
void BranchInformation::add(BrancherGroup bg, const std::string& rel0, const std::string& rel1, const std::vector<std::string>& n) { static_cast<BranchInformationO*>(object())->add(bg,rel0,rel1,n); } void BranchInformation::print(const Brancher& b, unsigned int a, int i, int n, std::ostream& o) const { static_cast<const BranchInformationO*>(object())->print(b,a,i,n,o); }#ifdef GECODE_HAS_FLOAT_VARS void BranchInformation::print(const Brancher& b, unsigned int a, int i, const FloatNumBranch& nl, std::ostream& o) const { static_cast<const BranchInformationO*>(object())->print(b,a,i,nl,o); }#endif template<class Var> void varValPrint(const Space &home, const Brancher& b, unsigned int a, Var, int i, const int& n, std::ostream& o) { static_cast<const FlatZincSpace&>(home).branchInfo.print(b,a,i,n,o); }
#ifdef GECODE_HAS_FLOAT_VARS void varValPrintF(const Space &home, const Brancher& b, unsigned int a, FloatVar, int i, const FloatNumBranch& nl, std::ostream& o) { static_cast<const FlatZincSpace&>(home).branchInfo.print(b,a,i,nl,o); }#endif
IntSet vs2is(IntVarSpec* vs) { if (vs->assigned) { return IntSet(vs->i,vs->i); } if (vs->domain()) { AST::SetLit* sl = vs->domain.some(); if (sl->interval) { return IntSet(sl->min, sl->max); } else { int* newdom = heap.alloc<int>(static_cast<unsigned long int>(sl->s.size())); for (int i=sl->s.size(); i--;) newdom[i] = sl->s[i]; IntSet ret(newdom, sl->s.size()); heap.free(newdom, static_cast<unsigned long int>(sl->s.size())); return ret; } } return IntSet(Int::Limits::min, Int::Limits::max); }
int vs2bsl(BoolVarSpec* bs) { if (bs->assigned) { return bs->i; } if (bs->domain()) { AST::SetLit* sl = bs->domain.some(); assert(sl->interval); return std::min(1, std::max(0, sl->min)); } return 0; }
int vs2bsh(BoolVarSpec* bs) { if (bs->assigned) { return bs->i; } if (bs->domain()) { AST::SetLit* sl = bs->domain.some(); assert(sl->interval); return std::max(0, std::min(1, sl->max)); } return 1; }
TieBreak<IntVarBranch> ann2ivarsel(AST::Node* ann, Rnd rnd, double decay) { if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) { if (s->id == "input_order") return TieBreak<IntVarBranch>(INT_VAR_NONE()); if (s->id == "first_fail") return TieBreak<IntVarBranch>(INT_VAR_SIZE_MIN()); if (s->id == "anti_first_fail") return TieBreak<IntVarBranch>(INT_VAR_SIZE_MAX()); if (s->id == "smallest") return TieBreak<IntVarBranch>(INT_VAR_MIN_MIN()); if (s->id == "largest") return TieBreak<IntVarBranch>(INT_VAR_MAX_MAX()); if (s->id == "occurrence") return TieBreak<IntVarBranch>(INT_VAR_DEGREE_MAX()); if (s->id == "max_regret") return TieBreak<IntVarBranch>(INT_VAR_REGRET_MIN_MAX()); if (s->id == "most_constrained") return TieBreak<IntVarBranch>(INT_VAR_SIZE_MIN(), INT_VAR_DEGREE_MAX()); if (s->id == "random") { return TieBreak<IntVarBranch>(INT_VAR_RND(rnd)); } if (s->id == "dom_w_deg") { return TieBreak<IntVarBranch>(INT_VAR_AFC_SIZE_MAX(decay)); } if (s->id == "afc_min") return TieBreak<IntVarBranch>(INT_VAR_AFC_MIN(decay)); if (s->id == "afc_max") return TieBreak<IntVarBranch>(INT_VAR_AFC_MAX(decay)); if (s->id == "afc_size_min") return TieBreak<IntVarBranch>(INT_VAR_AFC_SIZE_MIN(decay)); if (s->id == "afc_size_max") { return TieBreak<IntVarBranch>(INT_VAR_AFC_SIZE_MAX(decay)); } if (s->id == "action_min") return TieBreak<IntVarBranch>(INT_VAR_ACTION_MIN(decay)); if (s->id == "action_max") return TieBreak<IntVarBranch>(INT_VAR_ACTION_MAX(decay)); if (s->id == "action_size_min") return TieBreak<IntVarBranch>(INT_VAR_ACTION_SIZE_MIN(decay)); if (s->id == "action_size_max") return TieBreak<IntVarBranch>(INT_VAR_ACTION_SIZE_MAX(decay)); } std::cerr << "Warning, ignored search annotation: "; ann->print(std::cerr); std::cerr << std::endl; return TieBreak<IntVarBranch>(INT_VAR_NONE()); }
IntValBranch ann2ivalsel(AST::Node* ann, std::string& r0, std::string& r1, Rnd rnd) { if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) { if (s->id == "indomain_min") { r0 = "="; r1 = "!="; return INT_VAL_MIN(); } if (s->id == "indomain_max") { r0 = "="; r1 = "!="; return INT_VAL_MAX(); } if (s->id == "indomain_median") { r0 = "="; r1 = "!="; return INT_VAL_MED(); } if (s->id == "indomain_split") { r0 = "<="; r1 = ">"; return INT_VAL_SPLIT_MIN(); } if (s->id == "indomain_reverse_split") { r0 = ">"; r1 = "<="; return INT_VAL_SPLIT_MAX(); } if (s->id == "indomain_random") { r0 = "="; r1 = "!="; return INT_VAL_RND(rnd); } if (s->id == "indomain") { r0 = "="; r1 = "="; return INT_VALUES_MIN(); } if (s->id == "indomain_middle") { std::cerr << "Warning, replacing unsupported annotation " << "indomain_middle with indomain_median" << std::endl; r0 = "="; r1 = "!="; return INT_VAL_MED(); } if (s->id == "indomain_interval") { std::cerr << "Warning, replacing unsupported annotation " << "indomain_interval with indomain_split" << std::endl; r0 = "<="; r1 = ">"; return INT_VAL_SPLIT_MIN(); } } std::cerr << "Warning, ignored search annotation: "; ann->print(std::cerr); std::cerr << std::endl; r0 = "="; r1 = "!="; return INT_VAL_MIN(); }
IntAssign ann2asnivalsel(AST::Node* ann, Rnd rnd) { if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) { if (s->id == "indomain_min") return INT_ASSIGN_MIN(); if (s->id == "indomain_max") return INT_ASSIGN_MAX(); if (s->id == "indomain_median") return INT_ASSIGN_MED(); if (s->id == "indomain_random") { return INT_ASSIGN_RND(rnd); } } std::cerr << "Warning, ignored search annotation: "; ann->print(std::cerr); std::cerr << std::endl; return INT_ASSIGN_MIN(); }
TieBreak<BoolVarBranch> ann2bvarsel(AST::Node* ann, Rnd rnd, double decay) { if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) { if ((s->id == "input_order") || (s->id == "first_fail") || (s->id == "anti_first_fail") || (s->id == "smallest") || (s->id == "largest") || (s->id == "max_regret")) return TieBreak<BoolVarBranch>(BOOL_VAR_NONE()); if ((s->id == "occurrence") || (s->id == "most_constrained")) return TieBreak<BoolVarBranch>(BOOL_VAR_DEGREE_MAX()); if (s->id == "random") return TieBreak<BoolVarBranch>(BOOL_VAR_RND(rnd)); if ((s->id == "afc_min") || (s->id == "afc_size_min")) return TieBreak<BoolVarBranch>(BOOL_VAR_AFC_MIN(decay)); if ((s->id == "afc_max") || (s->id == "afc_size_max") || (s->id == "dom_w_deg")) return TieBreak<BoolVarBranch>(BOOL_VAR_AFC_MAX(decay)); if ((s->id == "action_min") && (s->id == "action_size_min")) return TieBreak<BoolVarBranch>(BOOL_VAR_ACTION_MIN(decay)); if ((s->id == "action_max") || (s->id == "action_size_max")) return TieBreak<BoolVarBranch>(BOOL_VAR_ACTION_MAX(decay)); } std::cerr << "Warning, ignored search annotation: "; ann->print(std::cerr); std::cerr << std::endl; return TieBreak<BoolVarBranch>(BOOL_VAR_NONE()); }
BoolValBranch ann2bvalsel(AST::Node* ann, std::string& r0, std::string& r1, Rnd rnd) { if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) { if (s->id == "indomain_min") { r0 = "="; r1 = "!="; return BOOL_VAL_MIN(); } if (s->id == "indomain_max") { r0 = "="; r1 = "!="; return BOOL_VAL_MAX(); } if (s->id == "indomain_median") { r0 = "="; r1 = "!="; return BOOL_VAL_MIN(); } if (s->id == "indomain_split") { r0 = "<="; r1 = ">"; return BOOL_VAL_MIN(); } if (s->id == "indomain_reverse_split") { r0 = ">"; r1 = "<="; return BOOL_VAL_MAX(); } if (s->id == "indomain_random") { r0 = "="; r1 = "!="; return BOOL_VAL_RND(rnd); } if (s->id == "indomain") { r0 = "="; r1 = "="; return BOOL_VAL_MIN(); } if (s->id == "indomain_middle") { std::cerr << "Warning, replacing unsupported annotation " << "indomain_middle with indomain_median" << std::endl; r0 = "="; r1 = "!="; return BOOL_VAL_MIN(); } if (s->id == "indomain_interval") { std::cerr << "Warning, replacing unsupported annotation " << "indomain_interval with indomain_split" << std::endl; r0 = "<="; r1 = ">"; return BOOL_VAL_MIN(); } } std::cerr << "Warning, ignored search annotation: "; ann->print(std::cerr); std::cerr << std::endl; r0 = "="; r1 = "!="; return BOOL_VAL_MIN(); }
BoolAssign ann2asnbvalsel(AST::Node* ann, Rnd rnd) { if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) { if ((s->id == "indomain_min") || (s->id == "indomain_median")) return BOOL_ASSIGN_MIN(); if (s->id == "indomain_max") return BOOL_ASSIGN_MAX(); if (s->id == "indomain_random") { return BOOL_ASSIGN_RND(rnd); } } std::cerr << "Warning, ignored search annotation: "; ann->print(std::cerr); std::cerr << std::endl; return BOOL_ASSIGN_MIN(); }
#ifdef GECODE_HAS_SET_VARS SetVarBranch ann2svarsel(AST::Node* ann, Rnd rnd, double decay) { if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) { if (s->id == "input_order") return SET_VAR_NONE(); if (s->id == "first_fail") return SET_VAR_SIZE_MIN(); if (s->id == "anti_first_fail") return SET_VAR_SIZE_MAX(); if (s->id == "smallest") return SET_VAR_MIN_MIN(); if (s->id == "largest") return SET_VAR_MAX_MAX(); if (s->id == "afc_min") return SET_VAR_AFC_MIN(decay); if (s->id == "afc_max") return SET_VAR_AFC_MAX(decay); if (s->id == "afc_size_min") return SET_VAR_AFC_SIZE_MIN(decay); if (s->id == "afc_size_max") return SET_VAR_AFC_SIZE_MAX(decay); if (s->id == "action_min") return SET_VAR_ACTION_MIN(decay); if (s->id == "action_max") return SET_VAR_ACTION_MAX(decay); if (s->id == "action_size_min") return SET_VAR_ACTION_SIZE_MIN(decay); if (s->id == "action_size_max") return SET_VAR_ACTION_SIZE_MAX(decay); if (s->id == "random") { return SET_VAR_RND(rnd); } } std::cerr << "Warning, ignored search annotation: "; ann->print(std::cerr); std::cerr << std::endl; return SET_VAR_NONE(); }
SetValBranch ann2svalsel(AST::Node* ann, std::string r0, std::string r1, Rnd rnd) { (void) rnd; if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) { if (s->id == "indomain_min") { r0 = "in"; r1 = "not in"; return SET_VAL_MIN_INC(); } if (s->id == "indomain_max") { r0 = "in"; r1 = "not in"; return SET_VAL_MAX_INC(); } if (s->id == "outdomain_min") { r1 = "in"; r0 = "not in"; return SET_VAL_MIN_EXC(); } if (s->id == "outdomain_max") { r1 = "in"; r0 = "not in"; return SET_VAL_MAX_EXC(); } } std::cerr << "Warning, ignored search annotation: "; ann->print(std::cerr); std::cerr << std::endl; r0 = "in"; r1 = "not in"; return SET_VAL_MIN_INC(); }#endif
#ifdef GECODE_HAS_FLOAT_VARS TieBreak<FloatVarBranch> ann2fvarsel(AST::Node* ann, Rnd rnd, double decay) { if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) { if (s->id == "input_order") return TieBreak<FloatVarBranch>(FLOAT_VAR_NONE()); if (s->id == "first_fail") return TieBreak<FloatVarBranch>(FLOAT_VAR_SIZE_MIN()); if (s->id == "anti_first_fail") return TieBreak<FloatVarBranch>(FLOAT_VAR_SIZE_MAX()); if (s->id == "smallest") return TieBreak<FloatVarBranch>(FLOAT_VAR_MIN_MIN()); if (s->id == "largest") return TieBreak<FloatVarBranch>(FLOAT_VAR_MAX_MAX()); if (s->id == "occurrence") return TieBreak<FloatVarBranch>(FLOAT_VAR_DEGREE_MAX()); if (s->id == "most_constrained") return TieBreak<FloatVarBranch>(FLOAT_VAR_SIZE_MIN(), FLOAT_VAR_DEGREE_MAX()); if (s->id == "random") { return TieBreak<FloatVarBranch>(FLOAT_VAR_RND(rnd)); } if (s->id == "afc_min") return TieBreak<FloatVarBranch>(FLOAT_VAR_AFC_MIN(decay)); if (s->id == "afc_max") return TieBreak<FloatVarBranch>(FLOAT_VAR_AFC_MAX(decay)); if (s->id == "afc_size_min") return TieBreak<FloatVarBranch>(FLOAT_VAR_AFC_SIZE_MIN(decay)); if (s->id == "afc_size_max") return TieBreak<FloatVarBranch>(FLOAT_VAR_AFC_SIZE_MAX(decay)); if (s->id == "action_min") return TieBreak<FloatVarBranch>(FLOAT_VAR_ACTION_MIN(decay)); if (s->id == "action_max") return TieBreak<FloatVarBranch>(FLOAT_VAR_ACTION_MAX(decay)); if (s->id == "action_size_min") return TieBreak<FloatVarBranch>(FLOAT_VAR_ACTION_SIZE_MIN(decay)); if (s->id == "action_size_max") return TieBreak<FloatVarBranch>(FLOAT_VAR_ACTION_SIZE_MAX(decay)); } std::cerr << "Warning, ignored search annotation: "; ann->print(std::cerr); std::cerr << std::endl; return TieBreak<FloatVarBranch>(FLOAT_VAR_NONE()); }
FloatValBranch ann2fvalsel(AST::Node* ann, std::string r0, std::string r1) { if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) { if (s->id == "indomain_split") { r0 = "<="; r1 = ">"; return FLOAT_VAL_SPLIT_MIN(); } if (s->id == "indomain_reverse_split") { r1 = "<="; r0 = ">"; return FLOAT_VAL_SPLIT_MAX(); } } std::cerr << "Warning, ignored search annotation: "; ann->print(std::cerr); std::cerr << std::endl; r0 = "<="; r1 = ">"; return FLOAT_VAL_SPLIT_MIN(); }
#endif
class FlatZincSpaceInitData { public: /// Hash table of tuple sets typedef std::unordered_set<TupleSet> TupleSetSet; /// Hash table of tuple sets TupleSetSet tupleSetSet;
/// Hash table of shared integer arrays typedef std::unordered_set<SharedArray<int> > IntSharedArraySet; /// Hash table of shared integer arrays IntSharedArraySet intSharedArraySet;
/// Hash table of DFAs typedef std::unordered_set<DFA> DFASet; /// Hash table of DFAs DFASet dfaSet;
/// Initialize FlatZincSpaceInitData(void) {} };
FlatZincSpace::FlatZincSpace(FlatZincSpace& f) : Space(f), _initData(nullptr), _random(f._random), _solveAnnotations(nullptr), iv_boolalias(nullptr),#ifdef GECODE_HAS_FLOAT_VARS step(f.step),#endif needAuxVars(f.needAuxVars) { _optVar = f._optVar; _optVarIsInt = f._optVarIsInt; _method = f._method; _lns = f._lns; _lnsInitialSolution = f._lnsInitialSolution; branchInfo = f.branchInfo; iv.update(*this, f.iv); main_vars.update(*this, f.main_vars); iv_lns.update(*this, f.iv_lns); intVarCount = f.intVarCount;
restart_status.update(*this, f.restart_status); int_uniform_var.update(*this, f.int_uniform_var); int_uniform_lb = f.int_uniform_lb; int_uniform_ub = f.int_uniform_ub; int_sol_var.update(*this, f.int_sol_var); int_sol_orig.update(*this, f.int_sol_orig); int_lastval_var.update(*this, f.int_lastval_var); int_lastval_val = f.int_lastval_val;
if (needAuxVars) { IntVarArgs iva; for (int i=0; i<f.iv_aux.size(); i++) { if (!f.iv_aux[i].assigned()) { iva << IntVar(); iva[iva.size()-1].update(*this, f.iv_aux[i]); } } iv_aux = IntVarArray(*this, iva); }
bv.update(*this, f.bv); boolVarCount = f.boolVarCount; if (needAuxVars) { BoolVarArgs bva; for (int i=0; i<f.bv_aux.size(); i++) { if (!f.bv_aux[i].assigned()) { bva << BoolVar(); bva[bva.size()-1].update(*this, f.bv_aux[i]); } } bv_aux = BoolVarArray(*this, bva); }
#ifdef GECODE_HAS_SET_VARS sv.update(*this, f.sv); setVarCount = f.setVarCount; if (needAuxVars) { SetVarArgs sva; for (int i=0; i<f.sv_aux.size(); i++) { if (!f.sv_aux[i].assigned()) { sva << SetVar(); sva[sva.size()-1].update(*this, f.sv_aux[i]); } } sv_aux = SetVarArray(*this, sva); }#endif#ifdef GECODE_HAS_FLOAT_VARS fv.update(*this, f.fv); floatVarCount = f.floatVarCount; if (needAuxVars) { FloatVarArgs fva; for (int i=0; i<f.fv_aux.size(); i++) { if (!f.fv_aux[i].assigned()) { fva << FloatVar(); fva[fva.size()-1].update(*this, f.fv_aux[i]); } } fv_aux = FloatVarArray(*this, fva); }#endif copies++; }
FlatZincSpace::FlatZincSpace(Rnd& random) : _initData(new FlatZincSpaceInitData), intVarCount(-1), boolVarCount(-1), floatVarCount(-1), setVarCount(-1), _optVar(-1), _optVarIsInt(true), _lns(0), _lnsInitialSolution(0), _random(random), _solveAnnotations(nullptr), needAuxVars(true) { branchInfo.init(); }
void FlatZincSpace::init(int intVars, int boolVars, int setVars, int floatVars) { (void) setVars; (void) floatVars;
intVarCount = 0; iv = IntVarArray(*this, intVars); iv_introduced = std::vector<bool>(2*intVars); iv_boolalias = alloc<int>(intVars+(intVars==0?1:0)); boolVarCount = 0; bv = BoolVarArray(*this, boolVars); bv_introduced = std::vector<bool>(2*boolVars);#ifdef GECODE_HAS_SET_VARS setVarCount = 0; sv = SetVarArray(*this, setVars); sv_introduced = std::vector<bool>(2*setVars);#endif#ifdef GECODE_HAS_FLOAT_VARS floatVarCount = 0; fv = FloatVarArray(*this, floatVars); fv_introduced = std::vector<bool>(2*floatVars);#endif }
void FlatZincSpace::newIntVar(IntVarSpec* vs) { if (vs->alias) { iv[intVarCount++] = iv[vs->i]; } else { IntSet dom(vs2is(vs)); if (dom.size()==0) { fail(); return; } else { iv[intVarCount++] = IntVar(*this, dom); } } iv_introduced[2*(intVarCount-1)] = vs->introduced; iv_introduced[2*(intVarCount-1)+1] = vs->funcDep; iv_boolalias[intVarCount-1] = -1; }
void FlatZincSpace::aliasBool2Int(int iv, int bv) { iv_boolalias[iv] = bv; } int FlatZincSpace::aliasBool2Int(int iv) { return iv_boolalias[iv]; }
void FlatZincSpace::newBoolVar(BoolVarSpec* vs) { if (vs->alias) { bv[boolVarCount++] = bv[vs->i]; } else { bv[boolVarCount++] = BoolVar(*this, vs2bsl(vs), vs2bsh(vs)); } bv_introduced[2*(boolVarCount-1)] = vs->introduced; bv_introduced[2*(boolVarCount-1)+1] = vs->funcDep; }
#ifdef GECODE_HAS_SET_VARS void FlatZincSpace::newSetVar(SetVarSpec* vs) { if (vs->alias) { sv[setVarCount++] = sv[vs->i]; } else if (vs->assigned) { assert(vs->upperBound()); AST::SetLit* vsv = vs->upperBound.some(); if (vsv->interval) { IntSet d(vsv->min, vsv->max); sv[setVarCount++] = SetVar(*this, d, d); } else { int* is = heap.alloc<int>(static_cast<unsigned long int>(vsv->s.size())); for (int i=vsv->s.size(); i--; ) is[i] = vsv->s[i]; IntSet d(is, vsv->s.size()); heap.free(is,static_cast<unsigned long int>(vsv->s.size())); sv[setVarCount++] = SetVar(*this, d, d); } } else if (vs->upperBound()) { AST::SetLit* vsv = vs->upperBound.some(); if (vsv->interval) { IntSet d(vsv->min, vsv->max); sv[setVarCount++] = SetVar(*this, IntSet::empty, d); } else { int* is = heap.alloc<int>(static_cast<unsigned long int>(vsv->s.size())); for (int i=vsv->s.size(); i--; ) is[i] = vsv->s[i]; IntSet d(is, vsv->s.size()); heap.free(is,static_cast<unsigned long int>(vsv->s.size())); sv[setVarCount++] = SetVar(*this, IntSet::empty, d); } } else { sv[setVarCount++] = SetVar(*this, IntSet::empty, IntSet(Set::Limits::min, Set::Limits::max)); } sv_introduced[2*(setVarCount-1)] = vs->introduced; sv_introduced[2*(setVarCount-1)+1] = vs->funcDep; }#else void FlatZincSpace::newSetVar(SetVarSpec*) { throw FlatZinc::Error("Gecode", "set variables not supported"); }#endif
#ifdef GECODE_HAS_FLOAT_VARS void FlatZincSpace::newFloatVar(FloatVarSpec* vs) { if (vs->alias) { fv[floatVarCount++] = fv[vs->i]; } else { double dmin, dmax; if (vs->domain()) { dmin = vs->domain.some().first; dmax = vs->domain.some().second; if (dmin > dmax) { fail(); return; } } else { dmin = Float::Limits::min; dmax = Float::Limits::max; } fv[floatVarCount++] = FloatVar(*this, dmin, dmax); } fv_introduced[2*(floatVarCount-1)] = vs->introduced; fv_introduced[2*(floatVarCount-1)+1] = vs->funcDep; }#else void FlatZincSpace::newFloatVar(FloatVarSpec*) { throw FlatZinc::Error("Gecode", "float variables not supported"); }#endif
namespace { struct ConExprOrder { bool operator() (ConExpr* ce0, ConExpr* ce1) { return ce0->args->a.size() < ce1->args->a.size(); } }; }
void FlatZincSpace::postConstraints(std::vector<ConExpr*>& ces) { ConExprOrder ceo; std::sort(ces.begin(), ces.end(), ceo);
for (unsigned int i=0; i<ces.size(); i++) { const ConExpr& ce = *ces[i]; try { registry().post(*this, ce); } catch (Gecode::Exception& e) { throw FlatZinc::Error("Gecode", e.what(), ce.ann); } catch (AST::TypeError& e) { throw FlatZinc::Error("Type error", e.what(), ce.ann); } delete ces[i]; ces[i] = nullptr; } }
void flattenAnnotations(AST::Array* ann, std::vector<AST::Node*>& out) { for (unsigned int i=0; i<ann->a.size(); i++) { if (ann->a[i]->isCall("seq_search")) { AST::Call* c = ann->a[i]->getCall(); if (c->args->isArray()) flattenAnnotations(c->args->getArray(), out); else out.push_back(c->args); } else { out.push_back(ann->a[i]); } } }
void FlatZincSpace::createBranchers(Printer&p, AST::Node* ann, FlatZincOptions& opt, bool ignoreUnknown, std::ostream& err) { int seed = opt.seed(); double decay = opt.decay(); Rnd rnd(static_cast<unsigned int>(seed)); TieBreak<IntVarBranch> def_int_varsel = INT_VAR_AFC_SIZE_MAX(0.99); IntBoolVarBranch def_intbool_varsel = INTBOOL_VAR_AFC_SIZE_MAX(0.99); IntValBranch def_int_valsel = INT_VAL_MIN(); std::string def_int_rel_left = "="; std::string def_int_rel_right = "!="; TieBreak<BoolVarBranch> def_bool_varsel = BOOL_VAR_AFC_MAX(0.99); BoolValBranch def_bool_valsel = BOOL_VAL_MIN(); std::string def_bool_rel_left = "="; std::string def_bool_rel_right = "!=";#ifdef GECODE_HAS_SET_VARS SetVarBranch def_set_varsel = SET_VAR_AFC_SIZE_MAX(0.99); SetValBranch def_set_valsel = SET_VAL_MIN_INC(); std::string def_set_rel_left = "in"; std::string def_set_rel_right = "not in";#endif#ifdef GECODE_HAS_FLOAT_VARS TieBreak<FloatVarBranch> def_float_varsel = FLOAT_VAR_SIZE_MIN(); FloatValBranch def_float_valsel = FLOAT_VAL_SPLIT_MIN(); std::string def_float_rel_left = "<="; std::string def_float_rel_right = ">";#endif
std::vector<bool> iv_searched(iv.size()); for (unsigned int i=iv.size(); i--;) iv_searched[i] = false; std::vector<bool> bv_searched(bv.size()); for (unsigned int i=bv.size(); i--;) bv_searched[i] = false;#ifdef GECODE_HAS_SET_VARS std::vector<bool> sv_searched(sv.size()); for (unsigned int i=sv.size(); i--;) sv_searched[i] = false;#endif#ifdef GECODE_HAS_FLOAT_VARS std::vector<bool> fv_searched(fv.size()); for (unsigned int i=fv.size(); i--;) fv_searched[i] = false;#endif
bool can_replay; _lns = 0; if (ann) { std::vector<AST::Node*> flatAnn; if (ann->isArray()) { flattenAnnotations(ann->getArray() , flatAnn); } else { flatAnn.push_back(ann); }
for (unsigned int i=0; i<flatAnn.size(); i++) { if (flatAnn[i]->isCall("restart_geometric")) { AST::Call* call = flatAnn[i]->getCall("restart_geometric"); opt.restart(RM_GEOMETRIC); AST::Array* args = call->getArgs(2); opt.restart_base(args->a[0]->getFloat()); opt.restart_scale(args->a[1]->getInt()); } else if (flatAnn[i]->isCall("main_vars")) { AST::Call* call = flatAnn[i]->getCall("main_vars"); AST::Array* vars = call->args->getArray(); int k=vars->a.size(); for (int j=vars->a.size(); j--;) if (vars->a[j]->isInt()) k--; main_vars = IntVarArray(*this, k); k = 0; for (unsigned int j=0; j<vars->a.size(); j++) { if (vars->a[j]->isInt()) continue; main_vars[k++] = iv[vars->a[j]->getIntVar()]; } can_replay=true; } else if (flatAnn[i]->isCall("restart_luby")) { AST::Call* call = flatAnn[i]->getCall("restart_luby"); opt.restart(RM_LUBY); opt.restart_scale(call->args->getInt()); } else if (flatAnn[i]->isCall("restart_linear")) { AST::Call* call = flatAnn[i]->getCall("restart_linear"); opt.restart(RM_LINEAR); opt.restart_scale(call->args->getInt()); } else if (flatAnn[i]->isCall("restart_constant")) { AST::Call* call = flatAnn[i]->getCall("restart_constant"); opt.restart(RM_CONSTANT); opt.restart_scale(call->args->getInt()); } else if (flatAnn[i]->isCall("restart_none")) { opt.restart(RM_NONE); } else if (flatAnn[i]->isCall("relax_and_reconstruct")) { if (_lns != 0) throw FlatZinc::Error("FlatZinc", "Only one relax_and_reconstruct annotation allowed"); AST::Call *call = flatAnn[i]->getCall("relax_and_reconstruct"); AST::Array* args; if (call->args->getArray()->a.size()==2) { args = call->getArgs(2); } else { args = call->getArgs(3); } _lns = args->a[1]->getInt(); AST::Array *vars = args->a[0]->getArray(); int k=vars->a.size(); for (int i=vars->a.size(); i--;) if (vars->a[i]->isInt()) k--; iv_lns = IntVarArray(*this, k); k = 0; for (unsigned int i=0; i<vars->a.size(); i++) { if (vars->a[i]->isInt()) continue; iv_lns[k++] = iv[vars->a[i]->getIntVar()]; } if (args->a.size()==3) { AST::Array *initial = args->a[2]->getArray(); _lnsInitialSolution = IntSharedArray(initial->a.size()); for (unsigned int i=initial->a.size(); i--;) _lnsInitialSolution[i] = initial->a[i]->getInt(); } } else if (flatAnn[i]->isCall("gecode_search")) { AST::Call* c = flatAnn[i]->getCall(); branchWithPlugin(c->args); } else if (flatAnn[i]->isCall("int_search")) { AST::Call *call = flatAnn[i]->getCall("int_search"); AST::Array *args = call->getArgs(4); AST::Array *vars = args->a[0]->getArray(); int k=vars->a.size(); for (int i=vars->a.size(); i--;) if (vars->a[i]->isInt()) k--; IntVarArgs va(k); std::vector<std::string> names; k=0; for (unsigned int i=0; i<vars->a.size(); i++) { if (vars->a[i]->isInt()) continue; va[k++] = iv[vars->a[i]->getIntVar()]; iv_searched[vars->a[i]->getIntVar()] = true; names.push_back(vars->a[i]->getVarName()); } std::string r0, r1; { BrancherGroup bg; branch(bg(*this), va, ann2ivarsel(args->a[1],rnd,decay), ann2ivalsel(args->a[2],r0,r1,rnd), nullptr, &varValPrint<IntVar>); branchInfo.add(bg,r0,r1,names); } } else if (flatAnn[i]->isCall("int_assign")) { AST::Call *call = flatAnn[i]->getCall("int_assign"); AST::Array *args = call->getArgs(2); AST::Array *vars = args->a[0]->getArray(); int k=vars->a.size(); for (int i=vars->a.size(); i--;) if (vars->a[i]->isInt()) k--; IntVarArgs va(k); k=0; for (unsigned int i=0; i<vars->a.size(); i++) { if (vars->a[i]->isInt()) continue; va[k++] = iv[vars->a[i]->getIntVar()]; iv_searched[vars->a[i]->getIntVar()] = true; } assign(*this, va, ann2asnivalsel(args->a[1],rnd), nullptr, &varValPrint<IntVar>); } else if (flatAnn[i]->isCall("bool_search")) { AST::Call *call = flatAnn[i]->getCall("bool_search"); AST::Array *args = call->getArgs(4); AST::Array *vars = args->a[0]->getArray(); int k=vars->a.size(); for (int i=vars->a.size(); i--;) if (vars->a[i]->isBool()) k--; BoolVarArgs va(k); k=0; std::vector<std::string> names; for (unsigned int i=0; i<vars->a.size(); i++) { if (vars->a[i]->isBool()) continue; va[k++] = bv[vars->a[i]->getBoolVar()]; bv_searched[vars->a[i]->getBoolVar()] = true; names.push_back(vars->a[i]->getVarName()); }
std::string r0, r1; { BrancherGroup bg; branch(bg(*this), va, ann2bvarsel(args->a[1],rnd,decay), ann2bvalsel(args->a[2],r0,r1,rnd), nullptr, &varValPrint<BoolVar>); branchInfo.add(bg,r0,r1,names); } } else if (flatAnn[i]->isCall("int_default_search")) { AST::Call *call = flatAnn[i]->getCall("int_default_search"); AST::Array *args = call->getArgs(2); def_int_varsel = ann2ivarsel(args->a[0],rnd,decay); def_int_valsel = ann2ivalsel(args->a[1], def_int_rel_left,def_int_rel_right,rnd); } else if (flatAnn[i]->isCall("bool_default_search")) { AST::Call *call = flatAnn[i]->getCall("bool_default_search"); AST::Array *args = call->getArgs(2); def_bool_varsel = ann2bvarsel(args->a[0],rnd,decay); def_bool_valsel = ann2bvalsel(args->a[1], def_bool_rel_left,def_bool_rel_right, rnd); } else if (flatAnn[i]->isCall("set_search")) {#ifdef GECODE_HAS_SET_VARS AST::Call *call = flatAnn[i]->getCall("set_search"); AST::Array *args = call->getArgs(4); AST::Array *vars = args->a[0]->getArray(); int k=vars->a.size(); for (int i=vars->a.size(); i--;) if (vars->a[i]->isSet()) k--; SetVarArgs va(k); k=0; std::vector<std::string> names; for (unsigned int i=0; i<vars->a.size(); i++) { if (vars->a[i]->isSet()) continue; va[k++] = sv[vars->a[i]->getSetVar()]; sv_searched[vars->a[i]->getSetVar()] = true; names.push_back(vars->a[i]->getVarName()); } std::string r0, r1; { BrancherGroup bg; branch(bg(*this), va, ann2svarsel(args->a[1],rnd,decay), ann2svalsel(args->a[2],r0,r1,rnd), nullptr, &varValPrint<SetVar>); branchInfo.add(bg,r0,r1,names); }#else if (!ignoreUnknown) { err << "Warning, ignored search annotation: "; flatAnn[i]->print(err); err << std::endl; }#endif } else if (flatAnn[i]->isCall("set_default_search")) {#ifdef GECODE_HAS_SET_VARS AST::Call *call = flatAnn[i]->getCall("set_default_search"); AST::Array *args = call->getArgs(2); def_set_varsel = ann2svarsel(args->a[0],rnd,decay); def_set_valsel = ann2svalsel(args->a[1], def_set_rel_left,def_set_rel_right,rnd);#else if (!ignoreUnknown) { err << "Warning, ignored search annotation: "; flatAnn[i]->print(err); err << std::endl; }#endif } else if (flatAnn[i]->isCall("float_default_search")) {#ifdef GECODE_HAS_FLOAT_VARS AST::Call *call = flatAnn[i]->getCall("float_default_search"); AST::Array *args = call->getArgs(2); def_float_varsel = ann2fvarsel(args->a[0],rnd,decay); def_float_valsel = ann2fvalsel(args->a[1], def_float_rel_left,def_float_rel_right);#else if (!ignoreUnknown) { err << "Warning, ignored search annotation: "; flatAnn[i]->print(err); err << std::endl; }#endif } else if (flatAnn[i]->isCall("float_search")) {#ifdef GECODE_HAS_FLOAT_VARS AST::Call *call = flatAnn[i]->getCall("float_search"); AST::Array *args = call->getArgs(5); AST::Array *vars = args->a[0]->getArray(); int k=vars->a.size(); for (int i=vars->a.size(); i--;) if (vars->a[i]->isFloat()) k--; FloatVarArgs va(k); k=0; std::vector<std::string> names; for (unsigned int i=0; i<vars->a.size(); i++) { if (vars->a[i]->isFloat()) continue; va[k++] = fv[vars->a[i]->getFloatVar()]; fv_searched[vars->a[i]->getFloatVar()] = true; names.push_back(vars->a[i]->getVarName()); } std::string r0, r1; { BrancherGroup bg; branch(bg(*this), va, ann2fvarsel(args->a[2],rnd,decay), ann2fvalsel(args->a[3],r0,r1), nullptr, &varValPrintF); branchInfo.add(bg,r0,r1,names); }#else if (!ignoreUnknown) { err << "Warning, ignored search annotation: "; flatAnn[i]->print(err); err << std::endl; }#endif } else { if (!ignoreUnknown) { err << "Warning, ignored search annotation: "; flatAnn[i]->print(err); err << std::endl; } } } } int introduced = 0; int funcdep = 0; int searched = 0; for (int i=iv.size(); i--;) { if (iv_searched[i] || (_method != SAT && _optVarIsInt && _optVar==i)) { searched++; } else if (iv_introduced[2*i]) { if (iv_introduced[2*i+1]) { funcdep++; } else { introduced++; } } } std::vector<std::string> iv_sol_names(iv.size()-(introduced+funcdep+searched)); IntVarArgs iv_sol(iv.size()-(introduced+funcdep+searched)); std::vector<std::string> iv_tmp_names(introduced); IntVarArgs iv_tmp(introduced); for (int i=iv.size(), j=0, k=0; i--;) { if (iv_searched[i] || (_method != SAT && _optVarIsInt && _optVar==i)) continue; if (iv_introduced[2*i]) { if (!iv_introduced[2*i+1]) { iv_tmp_names[j] = p.intVarName(i); iv_tmp[j++] = iv[i]; } } else { iv_sol_names[k] = p.intVarName(i); iv_sol[k++] = iv[i]; } }
introduced = 0; funcdep = 0; searched = 0; for (int i=bv.size(); i--;) { if (bv_searched[i]) { searched++; } else if (bv_introduced[2*i]) { if (bv_introduced[2*i+1]) { funcdep++; } else { introduced++; } } } std::vector<std::string> bv_sol_names(bv.size()-(introduced+funcdep+searched)); BoolVarArgs bv_sol(bv.size()-(introduced+funcdep+searched)); BoolVarArgs bv_tmp(introduced); std::vector<std::string> bv_tmp_names(introduced); for (int i=bv.size(), j=0, k=0; i--;) { if (bv_searched[i]) continue; if (bv_introduced[2*i]) { if (!bv_introduced[2*i+1]) { bv_tmp_names[j] = p.boolVarName(i); bv_tmp[j++] = bv[i]; } } else { bv_sol_names[k] = p.boolVarName(i); bv_sol[k++] = bv[i]; } }
if (iv_sol.size() > 0 && bv_sol.size() > 0) { branch(*this, iv_sol, bv_sol, def_intbool_varsel, def_int_valsel); } else if (iv_sol.size() > 0) { BrancherGroup bg; branch(bg(*this), iv_sol, def_int_varsel, def_int_valsel, nullptr, &varValPrint<IntVar>); branchInfo.add(bg,def_int_rel_left,def_int_rel_right,iv_sol_names); } else if (bv_sol.size() > 0) { BrancherGroup bg; branch(bg(*this), bv_sol, def_bool_varsel, def_bool_valsel, nullptr, &varValPrint<BoolVar>); branchInfo.add(bg,def_bool_rel_left,def_bool_rel_right,bv_sol_names); }#ifdef GECODE_HAS_FLOAT_VARS introduced = 0; funcdep = 0; searched = 0; for (int i=fv.size(); i--;) { if (fv_searched[i] || (_method != SAT && !_optVarIsInt && _optVar==i)) { searched++; } else if (fv_introduced[2*i]) { if (fv_introduced[2*i+1]) { funcdep++; } else { introduced++; } } } std::vector<std::string> fv_sol_names(fv.size()-(introduced+funcdep+searched)); FloatVarArgs fv_sol(fv.size()-(introduced+funcdep+searched)); FloatVarArgs fv_tmp(introduced); std::vector<std::string> fv_tmp_names(introduced); for (int i=fv.size(), j=0, k=0; i--;) { if (fv_searched[i] || (_method != SAT && !_optVarIsInt && _optVar==i)) continue; if (fv_introduced[2*i]) { if (!fv_introduced[2*i+1]) { fv_tmp_names[j] = p.floatVarName(i); fv_tmp[j++] = fv[i]; } } else { fv_sol_names[k] = p.floatVarName(i); fv_sol[k++] = fv[i]; } }
if (fv_sol.size() > 0) { BrancherGroup bg; branch(bg(*this), fv_sol, def_float_varsel, def_float_valsel, nullptr, &varValPrintF); branchInfo.add(bg,def_float_rel_left,def_float_rel_right,fv_sol_names); }#endif#ifdef GECODE_HAS_SET_VARS introduced = 0; funcdep = 0; searched = 0; for (int i=sv.size(); i--;) { if (sv_searched[i]) { searched++; } else if (sv_introduced[2*i]) { if (sv_introduced[2*i+1]) { funcdep++; } else { introduced++; } } } std::vector<std::string> sv_sol_names(sv.size()-(introduced+funcdep+searched)); SetVarArgs sv_sol(sv.size()-(introduced+funcdep+searched)); SetVarArgs sv_tmp(introduced); std::vector<std::string> sv_tmp_names(introduced); for (int i=sv.size(), j=0, k=0; i--;) { if (sv_searched[i]) continue; if (sv_introduced[2*i]) { if (!sv_introduced[2*i+1]) { sv_tmp_names[j] = p.setVarName(i); sv_tmp[j++] = sv[i]; } } else { sv_sol_names[k] = p.setVarName(i); sv_sol[k++] = sv[i]; } }
if (sv_sol.size() > 0) { BrancherGroup bg; branch(bg(*this), sv_sol, def_set_varsel, def_set_valsel, nullptr, &varValPrint<SetVar>); branchInfo.add(bg,def_set_rel_left,def_set_rel_right,sv_sol_names);
}#endif iv_aux = IntVarArray(*this, iv_tmp); bv_aux = BoolVarArray(*this, bv_tmp); int n_aux = iv_aux.size() + bv_aux.size();#ifdef GECODE_HAS_SET_VARS sv_aux = SetVarArray(*this, sv_tmp); n_aux += sv_aux.size();#endif#ifdef GECODE_HAS_FLOAT_VARS fv_aux = FloatVarArray(*this, fv_tmp); n_aux += fv_aux.size();#endif
if (n_aux > 0) { if (_method == SAT) { AuxVarBrancher::post(*this, def_int_varsel, def_int_valsel, def_bool_varsel, def_bool_valsel#ifdef GECODE_HAS_SET_VARS , def_set_varsel, def_set_valsel#endif#ifdef GECODE_HAS_FLOAT_VARS , def_float_varsel, def_float_valsel#endif ); } else { { BrancherGroup bg; branch(bg(*this),iv_aux,def_int_varsel,def_int_valsel, nullptr, &varValPrint<IntVar>); branchInfo.add(bg,def_int_rel_left,def_int_rel_right,iv_tmp_names); } { BrancherGroup bg; branch(bg(*this),bv_aux,def_bool_varsel,def_bool_valsel, nullptr, &varValPrint<BoolVar>); branchInfo.add(bg,def_bool_rel_left,def_bool_rel_right,bv_tmp_names); } #ifdef GECODE_HAS_SET_VARS { BrancherGroup bg; branch(bg(*this),sv_aux,def_set_varsel,def_set_valsel, nullptr, &varValPrint<SetVar>); branchInfo.add(bg,def_set_rel_left,def_set_rel_right,sv_tmp_names); } #endif #ifdef GECODE_HAS_FLOAT_VARS { BrancherGroup bg; branch(bg(*this),fv_aux,def_float_varsel,def_float_valsel, nullptr, &varValPrintF); branchInfo.add(bg,def_float_rel_left,def_float_rel_right,fv_tmp_names); } #endif
} }
if (_method == MIN) { if (_optVarIsInt) { std::vector<std::string> names(1); names[0] = p.intVarName(_optVar); BrancherGroup bg; branch(bg(*this), iv[_optVar], INT_VAL_MIN(), &varValPrint<IntVar>); branchInfo.add(bg,"=","!=",names); } else {#ifdef GECODE_HAS_FLOAT_VARS std::vector<std::string> names(1); names[0] = p.floatVarName(_optVar); BrancherGroup bg; branch(bg(*this), fv[_optVar], FLOAT_VAL_SPLIT_MIN(), &varValPrintF); branchInfo.add(bg,"<=",">",names);#endif } } else if (_method == MAX) { if (_optVarIsInt) { std::vector<std::string> names(1); names[0] = p.intVarName(_optVar); BrancherGroup bg; branch(bg(*this), iv[_optVar], INT_VAL_MAX(), &varValPrint<IntVar>); branchInfo.add(bg,"=","!=",names); } else {#ifdef GECODE_HAS_FLOAT_VARS std::vector<std::string> names(1); names[0] = p.floatVarName(_optVar); BrancherGroup bg; branch(bg(*this), fv[_optVar], FLOAT_VAL_SPLIT_MAX(), &varValPrintF); branchInfo.add(bg,"<=",">",names);#endif } }
// Remove unnecessary variable arrays restart_status = IntVarArray(*this, 0); int_uniform_var = IntVarArray(*this, 0); int_sol_var = IntVarArray(*this, 0); int_sol_orig = IntVarArray(*this, 0); int_lastval_var = IntVarArray(*this, 0);
if (!can_replay) { std::cerr << "No variables found to replay to" << std::endl; exit(1); } while(record) { std::string line; std::getline(record, line); if(record.eof()){ break; } std::istringstream ss = std::istringstream(line); std::vector<int> row; while(ss) { char peek = ss.peek(); if (ss.eof()) { break; } else if(peek == ',') { ss.get(); } else if (peek == '_') { ss.get(); row.push_back(INT_MIN); } else { int i; ss >> i; row.push_back(i); } } if(row.size() != main_vars.size()) { std::cerr << "Invalid record" << std::endl; exit(1); } vrecord.push_back(row); } record.close(); std::cout << "% Read " << vrecord.size() << " lines of neighbourhoods!\n"; }
AST::Array* FlatZincSpace::solveAnnotations(void) const { return _solveAnnotations; }
void FlatZincSpace::solve(AST::Array* ann) { _method = SAT; _solveAnnotations = ann; }
void FlatZincSpace::minimize(int var, bool isInt, AST::Array* ann) { _method = MIN; _optVar = var; _optVarIsInt = isInt; _solveAnnotations = ann; }
void FlatZincSpace::maximize(int var, bool isInt, AST::Array* ann) { _method = MAX; _optVar = var; _optVarIsInt = isInt; _solveAnnotations = ann; }
FlatZincSpace::~FlatZincSpace(void) { delete _initData; delete _solveAnnotations; }
#ifdef GECODE_HAS_GIST
/** * \brief Traits class for search engines */ template<class Engine> class GistEngine { };
/// Specialization for DFS template<typename S> class GistEngine<DFS<S> > { public: static void explore(S* root, const FlatZincOptions& opt, Gist::Inspector* i, Gist::Comparator* c) { Gecode::Gist::Options o; o.c_d = opt.c_d(); o.a_d = opt.a_d(); o.inspect.click(i); o.inspect.compare(c); (void) Gecode::Gist::dfs(root, o); } };
/// Specialization for BAB template<typename S> class GistEngine<BAB<S> > { public: static void explore(S* root, const FlatZincOptions& opt, Gist::Inspector* i, Gist::Comparator* c) { Gecode::Gist::Options o; o.c_d = opt.c_d(); o.a_d = opt.a_d(); o.inspect.click(i); o.inspect.compare(c); (void) Gecode::Gist::bab(root, o); } };
/// \brief An inspector for printing simple text output template<class S> class FZPrintingInspector : public Gecode::Gist::TextOutput, public Gecode::Gist::Inspector { private: const Printer& p; public: /// Constructor FZPrintingInspector(const Printer& p0); /// Use the print method of the template class S to print a space virtual void inspect(const Space& node); /// Finalize when Gist exits virtual void finalize(void); };
template<class S> FZPrintingInspector<S>::FZPrintingInspector(const Printer& p0) : TextOutput("Gecode/FlatZinc"), p(p0) {}
template<class S> void FZPrintingInspector<S>::inspect(const Space& node) { init(); dynamic_cast<const S&>(node).print(getStream(), p); getStream() << std::endl; }
template<class S> void FZPrintingInspector<S>::finalize(void) { Gecode::Gist::TextOutput::finalize(); }
template<class S> class FZPrintingComparator : public Gecode::Gist::VarComparator<S> { private: const Printer& p; public: /// Constructor FZPrintingComparator(const Printer& p0);
/// Use the compare method of the template class S to compare two spaces virtual void compare(const Space& s0, const Space& s1); };
template<class S> FZPrintingComparator<S>::FZPrintingComparator(const Printer& p0) : Gecode::Gist::VarComparator<S>("Gecode/FlatZinc"), p(p0) {}
template<class S> void FZPrintingComparator<S>::compare(const Space& s0, const Space& s1) { this->init(); try { dynamic_cast<const S&>(s0).compare(dynamic_cast<const S&>(s1), this->getStream(), p); } catch (Exception& e) { this->getStream() << "Exception: " << e.what(); } this->getStream() << std::endl; }
#endif
template<template<class> class Engine> void FlatZincSpace::runEngine(std::ostream& out, const Printer& p, const FlatZincOptions& opt, Support::Timer& t_total) { if (opt.restart()==RM_NONE) { runMeta<Engine,Driver::EngineToMeta>(out,p,opt,t_total); } else { runMeta<Engine,RBS>(out,p,opt,t_total); } }
#ifdef GECODE_HAS_CPPROFILER
class FlatZincGetInfo : public CPProfilerSearchTracer::GetInfo { public: const Printer& p; FlatZincGetInfo(const Printer& printer) : p(printer) {} virtual std::string getInfo(const Space& space) const { std::stringstream ss; if (const FlatZincSpace* fz_space = dynamic_cast<const FlatZincSpace*>(&space)) { ss << "{\n\t\"domains\": \""; ss << fz_space->getDomains(p); ss << "\"\n}"; } return ss.str(); } ~FlatZincGetInfo(void) {}; };
void printIntVar(std::ostream& os, const std::string name, const Int::IntView& x) { os << "var "; if (x.assigned()) { os << "int: " << name << " = " << x.val() << ";"; } else if (x.range()) { os << x.min() << ".." << x.max() << ": " << name << ";"; } else { os << "array_union(["; Gecode::Int::ViewRanges<Int::IntView> r(x); while (true) { os << r.min() << ".." << r.max(); ++r; if (!r()) break; os << ','; } os << "]): " << name << ";"; } os << "\n"; } void printBoolVar(std::ostream& os, const std::string name, const BoolVar& b) { os << "var bool: " << name; if(b.assigned()) os << " = " << (b.val() ? "true" : "false"); os << ";\n"; }#ifdef GECODE_HAS_FLOAT_VARS void printFloatVar(std::ostream& os, const std::string name, const Float::FloatView& f) { os << "var "; if(f.assigned()) os << "float: " << name << " = " << f.med() << ";"; else os << f.min() << ".." << f.max() << ": " << name << ";"; os << "\n"; }#endif std::string FlatZincSpace::getDomains(const Printer& p) const { std::ostringstream oss;
for (int i = 0; i < iv.size(); i++) printIntVar(oss, p.intVarName(i), iv[i]);
for (int i = 0; i < bv.size(); i++) printBoolVar(oss, p.boolVarName(i), bv[i]);
#ifdef GECODE_HAS_FLOAT_VARS for (int i = 0; i < fv.size(); i++) printFloatVar(oss, p.floatVarName(i), fv[i]);#endif#ifdef GECODE_HAS_SET_VARS for (int i = 0; i < sv.size(); i++) oss << "var " << sv[i] << ": " << p.setVarName(i) << ";" << std::endl;#endif
return oss.str(); }
#endif
template<template<class> class Engine, template<class,template<class> class> class Meta> void FlatZincSpace::runMeta(std::ostream& out, const Printer& p, const FlatZincOptions& opt, Support::Timer& t_total) {#ifdef GECODE_HAS_GIST if (opt.mode() == SM_GIST) { FZPrintingInspector<FlatZincSpace> pi(p); FZPrintingComparator<FlatZincSpace> pc(p); (void) GistEngine<Engine<FlatZincSpace> >::explore(this,opt,&pi,&pc); return; }#endif StatusStatistics sstat; unsigned int n_p = 0; Support::Timer t_solve; t_solve.start(); if (status(sstat) != SS_FAILED) { n_p = PropagatorGroup::all.size(*this); } Search::Options o; o.stop = Driver::CombinedStop::create(opt.node(), opt.fail(), opt.time(), true); o.c_d = opt.c_d(); o.a_d = opt.a_d();
#ifdef GECODE_HAS_CPPROFILER if (opt.profiler_port()) { FlatZincGetInfo* getInfo = nullptr; if (opt.profiler_info()) getInfo = new FlatZincGetInfo(p); o.tracer = new CPProfilerSearchTracer(opt.profiler_id(), opt.name(), opt.profiler_port(), getInfo); }
#endif
#ifdef GECODE_HAS_FLOAT_VARS step = opt.step();#endif o.threads = opt.threads(); o.nogoods_limit = opt.nogoods() ? opt.nogoods_limit() : 0; o.cutoff = new Search::CutoffAppend(new Search::CutoffConstant(0), 1, Driver::createCutoff(opt)); if (opt.interrupt()) Driver::CombinedStop::installCtrlHandler(true); { Meta<FlatZincSpace,Engine> se(this,o); int noOfSolutions = opt.solutions(); if (noOfSolutions == -1) { noOfSolutions = (_method == SAT) ? 1 : 0; } bool printAll = _method == SAT || opt.allSolutions() || noOfSolutions != 0; int findSol = noOfSolutions; FlatZincSpace* sol = nullptr; while (FlatZincSpace* next_sol = se.next()) { delete sol; sol = next_sol; if (printAll) { sol->print(out, p); out << "----------" << std::endl; } if (--findSol==0) goto stopped; } if (sol && !printAll) { sol->print(out, p); out << "----------" << std::endl; } if (!se.stopped()) { if (sol) { out << "==========" << std::endl; } else { out << "=====UNSATISFIABLE=====" << std::endl; } } else if (!sol) { out << "=====UNKNOWN=====" << std::endl; } delete sol; stopped: if (opt.interrupt()) Driver::CombinedStop::installCtrlHandler(false); if (opt.mode() == SM_STAT) { Gecode::Search::Statistics stat = se.statistics(); double totalTime = (t_total.stop() / 1000.0); double solveTime = (t_solve.stop() / 1000.0); double initTime = totalTime - solveTime; out << std::endl << "%%%mzn-stat: initTime=" << initTime << std::endl; out << "%%%mzn-stat: solveTime=" << solveTime << std::endl; out << "%%%mzn-stat: solutions=" << std::abs(noOfSolutions - findSol) << std::endl << "%%%mzn-stat: variables=" << (intVarCount + boolVarCount + setVarCount) << std::endl << "%%%mzn-stat: propagators=" << n_p << std::endl << "%%%mzn-stat: propagations=" << sstat.propagate+stat.propagate << std::endl << "%%%mzn-stat: nodes=" << stat.node << std::endl << "%%%mzn-stat: failures=" << stat.fail << std::endl << "%%%mzn-stat: restarts=" << stat.restart << std::endl << "%%%mzn-stat: peakDepth=" << stat.depth << std::endl << "%%%mzn-stat-end" << std::endl << std::endl; } } delete o.stop; delete o.tracer; }
#ifdef GECODE_HAS_QT void FlatZincSpace::branchWithPlugin(AST::Node* ann) { if (AST::Call* c = dynamic_cast<AST::Call*>(ann)) { QString pluginName(c->id.c_str()); if (QLibrary::isLibrary(pluginName+".dll")) { pluginName += ".dll"; } else if (QLibrary::isLibrary(pluginName+".dylib")) { pluginName = "lib" + pluginName + ".dylib"; } else if (QLibrary::isLibrary(pluginName+".so")) { // Must check .so after .dylib so that Mac OS uses .dylib pluginName = "lib" + pluginName + ".so"; } QPluginLoader pl(pluginName); QObject* plugin_o = pl.instance(); if (!plugin_o) { throw FlatZinc::Error("FlatZinc", "Error loading plugin "+pluginName.toStdString()+ ": "+pl.errorString().toStdString()); } BranchPlugin* pb = qobject_cast<BranchPlugin*>(plugin_o); if (!pb) { throw FlatZinc::Error("FlatZinc", "Error loading plugin "+pluginName.toStdString()+ ": does not contain valid PluginBrancher"); } pb->branch(*this, c); } }#else void FlatZincSpace::branchWithPlugin(AST::Node*) { throw FlatZinc::Error("FlatZinc", "Branching with plugins not supported (requires Qt support)"); }#endif
void FlatZincSpace::run(std::ostream& out, const Printer& p, const FlatZincOptions& opt, Support::Timer& t_total) { switch (_method) { case MIN: case MAX: runEngine<BAB>(out,p,opt,t_total); break; case SAT: runEngine<DFS>(out,p,opt,t_total); break; } out << "%% copies: " << copies << std::endl; }
void FlatZincSpace::constrain(const Space& s) { if (_optVarIsInt) { if (_method == MIN) rel(*this, iv[_optVar], IRT_LE, static_cast<const FlatZincSpace*>(&s)->iv[_optVar].val()); else if (_method == MAX) rel(*this, iv[_optVar], IRT_GR, static_cast<const FlatZincSpace*>(&s)->iv[_optVar].val()); } else {#ifdef GECODE_HAS_FLOAT_VARS if (_method == MIN) rel(*this, fv[_optVar], FRT_LE, static_cast<const FlatZincSpace*>(&s)->fv[_optVar].val()-step); else if (_method == MAX) rel(*this, fv[_optVar], FRT_GR, static_cast<const FlatZincSpace*>(&s)->fv[_optVar].val()+step);#endif } }
std::ifstream FlatZincSpace::record = std::ifstream("record.txt"); std::vector<std::vector<int>> FlatZincSpace::vrecord = std::vector<std::vector<int>>(); size_t FlatZincSpace::record_i = 0;
bool FlatZincSpace::slave(const MetaInfo& mi) { if (mi.type() == MetaInfo::RESTART) { for (int i = 0; i < main_vars.size(); ++i) { if (vrecord[record_i][i] > INT_MIN) { rel(*this, main_vars[i], IRT_EQ, vrecord[record_i][i]); } } record_i++;
main_vars = IntVarArray(*this, 0); return false; }
if ((mi.type() == MetaInfo::RESTART) && (mi.restart() != 0) && (_lns > 0) && (mi.last()==nullptr) && (_lnsInitialSolution.size()>0)) { for (unsigned int i=iv_lns.size(); i--;) { if (_random(99U) <= _lns) { rel(*this, iv_lns[i], IRT_EQ, _lnsInitialSolution[i]); } } return false; } else if ((mi.type() == MetaInfo::RESTART) && (mi.restart() != 0) && (_lns > 0) && mi.last()) { const FlatZincSpace& last = static_cast<const FlatZincSpace&>(*mi.last()); for (unsigned int i=iv_lns.size(); i--;) { if (_random(99U) <= _lns) { rel(*this, iv_lns[i], IRT_EQ, last.iv_lns[i]); } } return false; } return true; }
Space* FlatZincSpace::copy(void) { return new FlatZincSpace(*this); }
FlatZincSpace::Meth FlatZincSpace::method(void) const { return _method; }
int FlatZincSpace::optVar(void) const { return _optVar; }
bool FlatZincSpace::optVarIsInt(void) const { return _optVarIsInt; }
void FlatZincSpace::print(std::ostream& out, const Printer& p) const { p.print(out, iv, bv#ifdef GECODE_HAS_SET_VARS , sv#endif#ifdef GECODE_HAS_FLOAT_VARS , fv#endif ); }
void FlatZincSpace::compare(const Space& s, std::ostream& out) const { (void) s; (void) out;#ifdef GECODE_HAS_GIST const FlatZincSpace& fs = dynamic_cast<const FlatZincSpace&>(s); for (int i = 0; i < iv.size(); ++i) { std::stringstream ss; ss << "iv[" << i << "]"; std::string result(Gecode::Gist::Comparator::compare(ss.str(), iv[i], fs.iv[i])); if (result.length() > 0) out << result << std::endl; } for (int i = 0; i < bv.size(); ++i) { std::stringstream ss; ss << "bv[" << i << "]"; std::string result(Gecode::Gist::Comparator::compare(ss.str(), bv[i], fs.bv[i])); if (result.length() > 0) out << result << std::endl; }#ifdef GECODE_HAS_SET_VARS for (int i = 0; i < sv.size(); ++i) { std::stringstream ss; ss << "sv[" << i << "]"; std::string result(Gecode::Gist::Comparator::compare(ss.str(), sv[i], fs.sv[i])); if (result.length() > 0) out << result << std::endl; }#endif#ifdef GECODE_HAS_FLOAT_VARS for (int i = 0; i < fv.size(); ++i) { std::stringstream ss; ss << "fv[" << i << "]"; std::string result(Gecode::Gist::Comparator::compare(ss.str(), fv[i], fs.fv[i])); if (result.length() > 0) out << result << std::endl; }#endif#endif }
void FlatZincSpace::compare(const FlatZincSpace& s, std::ostream& out, const Printer& p) const { p.printDiff(out, iv, s.iv, bv, s.bv#ifdef GECODE_HAS_SET_VARS , sv, s.sv#endif#ifdef GECODE_HAS_FLOAT_VARS , fv, s.fv#endif ); }
void FlatZincSpace::shrinkArrays(Printer& p) { p.shrinkArrays(*this, _optVar, _optVarIsInt, iv, bv#ifdef GECODE_HAS_SET_VARS , sv#endif#ifdef GECODE_HAS_FLOAT_VARS , fv#endif ); }
IntArgs FlatZincSpace::arg2intargs(AST::Node* arg, int offset) { AST::Array* a = arg->getArray(); IntArgs ia(a->a.size()+offset); for (int i=offset; i--;) ia[i] = 0; for (int i=a->a.size(); i--;) ia[i+offset] = a->a[i]->getInt(); return ia; } TupleSet FlatZincSpace::arg2tupleset(const IntArgs& a, int noOfVars) { int noOfTuples = a.size() == 0 ? 0 : (a.size()/noOfVars);
// Build TupleSet TupleSet ts(noOfVars); for (int i=0; i<noOfTuples; i++) { IntArgs t(noOfVars); for (int j=0; j<noOfVars; j++) { t[j] = a[i*noOfVars+j]; } ts.add(t); } ts.finalize();
if (_initData) { FlatZincSpaceInitData::TupleSetSet::iterator it = _initData->tupleSetSet.find(ts); if (it != _initData->tupleSetSet.end()) { return *it; } _initData->tupleSetSet.insert(ts); }
return ts; } IntSharedArray FlatZincSpace::arg2intsharedarray(AST::Node* arg, int offset) { IntArgs ia(arg2intargs(arg,offset)); SharedArray<int> sia(ia); if (_initData) { FlatZincSpaceInitData::IntSharedArraySet::iterator it = _initData->intSharedArraySet.find(sia); if (it != _initData->intSharedArraySet.end()) { return *it; } _initData->intSharedArraySet.insert(sia); }
return sia; } IntArgs FlatZincSpace::arg2boolargs(AST::Node* arg, int offset) { AST::Array* a = arg->getArray(); IntArgs ia(a->a.size()+offset); for (int i=offset; i--;) ia[i] = 0; for (int i=a->a.size(); i--;) ia[i+offset] = a->a[i]->getBool(); return ia; } IntSharedArray FlatZincSpace::arg2boolsharedarray(AST::Node* arg, int offset) { IntArgs ia(arg2boolargs(arg,offset)); SharedArray<int> sia(ia); if (_initData) { FlatZincSpaceInitData::IntSharedArraySet::iterator it = _initData->intSharedArraySet.find(sia); if (it != _initData->intSharedArraySet.end()) { return *it; } _initData->intSharedArraySet.insert(sia); }
return sia; } IntSet FlatZincSpace::arg2intset(AST::Node* n) { AST::SetLit* sl = n->getSet(); IntSet d; if (sl->interval) { d = IntSet(sl->min, sl->max); } else { Region re; int* is = re.alloc<int>(static_cast<unsigned long int>(sl->s.size())); for (int i=sl->s.size(); i--; ) is[i] = sl->s[i]; d = IntSet(is, sl->s.size()); } return d; } IntSetArgs FlatZincSpace::arg2intsetargs(AST::Node* arg, int offset) { AST::Array* a = arg->getArray(); if (a->a.size() == 0) { IntSetArgs emptyIa(0); return emptyIa; } IntSetArgs ia(a->a.size()+offset); for (int i=offset; i--;) ia[i] = IntSet::empty; for (int i=a->a.size(); i--;) { ia[i+offset] = arg2intset(a->a[i]); } return ia; } IntVarArgs FlatZincSpace::arg2intvarargs(AST::Node* arg, int offset) { AST::Array* a = arg->getArray(); if (a->a.size() == 0) { IntVarArgs emptyIa(0); return emptyIa; } IntVarArgs ia(a->a.size()+offset); for (int i=offset; i--;) ia[i] = IntVar(*this, 0, 0); for (int i=a->a.size(); i--;) { if (a->a[i]->isIntVar()) { ia[i+offset] = iv[a->a[i]->getIntVar()]; } else { int value = a->a[i]->getInt(); IntVar iv(*this, value, value); ia[i+offset] = iv; } } return ia; } BoolVarArgs FlatZincSpace::arg2boolvarargs(AST::Node* arg, int offset, int siv) { AST::Array* a = arg->getArray(); if (a->a.size() == 0) { BoolVarArgs emptyIa(0); return emptyIa; } BoolVarArgs ia(a->a.size()+offset-(siv==-1?0:1)); for (int i=offset; i--;) ia[i] = BoolVar(*this, 0, 0); for (int i=0; i<static_cast<int>(a->a.size()); i++) { if (i==siv) continue; if (a->a[i]->isBool()) { bool value = a->a[i]->getBool(); BoolVar iv(*this, value, value); ia[offset++] = iv; } else if (a->a[i]->isIntVar() && aliasBool2Int(a->a[i]->getIntVar()) != -1) { ia[offset++] = bv[aliasBool2Int(a->a[i]->getIntVar())]; } else { ia[offset++] = bv[a->a[i]->getBoolVar()]; } } return ia; } BoolVar FlatZincSpace::arg2BoolVar(AST::Node* n) { BoolVar x0; if (n->isBool()) { x0 = BoolVar(*this, n->getBool(), n->getBool()); } else { x0 = bv[n->getBoolVar()]; } return x0; } IntVar FlatZincSpace::arg2IntVar(AST::Node* n) { IntVar x0; if (n->isIntVar()) { x0 = iv[n->getIntVar()]; } else { x0 = IntVar(*this, n->getInt(), n->getInt()); } return x0; } bool FlatZincSpace::isBoolArray(AST::Node* b, int& singleInt) { AST::Array* a = b->getArray(); singleInt = -1; if (a->a.size() == 0) return true; for (int i=a->a.size(); i--;) { if (a->a[i]->isBoolVar() || a->a[i]->isBool()) { } else if (a->a[i]->isIntVar()) { if (aliasBool2Int(a->a[i]->getIntVar()) == -1) { if (singleInt != -1) { return false; } singleInt = i; } } else { return false; } } return singleInt==-1 || a->a.size() > 1; }#ifdef GECODE_HAS_SET_VARS SetVar FlatZincSpace::arg2SetVar(AST::Node* n) { SetVar x0; if (!n->isSetVar()) { IntSet d = arg2intset(n); x0 = SetVar(*this, d, d); } else { x0 = sv[n->getSetVar()]; } return x0; } SetVarArgs FlatZincSpace::arg2setvarargs(AST::Node* arg, int offset, int doffset, const IntSet& od) { AST::Array* a = arg->getArray(); SetVarArgs ia(a->a.size()+offset); for (int i=offset; i--;) { IntSet d = i<doffset ? od : IntSet::empty; ia[i] = SetVar(*this, d, d); } for (int i=a->a.size(); i--;) { ia[i+offset] = arg2SetVar(a->a[i]); } return ia; }#endif#ifdef GECODE_HAS_FLOAT_VARS FloatValArgs FlatZincSpace::arg2floatargs(AST::Node* arg, int offset) { AST::Array* a = arg->getArray(); FloatValArgs fa(a->a.size()+offset); for (int i=offset; i--;) fa[i] = 0.0; for (int i=a->a.size(); i--;) fa[i+offset] = a->a[i]->getFloat(); return fa; } FloatVarArgs FlatZincSpace::arg2floatvarargs(AST::Node* arg, int offset) { AST::Array* a = arg->getArray(); if (a->a.size() == 0) { FloatVarArgs emptyFa(0); return emptyFa; } FloatVarArgs fa(a->a.size()+offset); for (int i=offset; i--;) fa[i] = FloatVar(*this, 0.0, 0.0); for (int i=a->a.size(); i--;) { if (a->a[i]->isFloatVar()) { fa[i+offset] = fv[a->a[i]->getFloatVar()]; } else { double value = a->a[i]->getFloat(); FloatVar fv(*this, value, value); fa[i+offset] = fv; } } return fa; } FloatVar FlatZincSpace::arg2FloatVar(AST::Node* n) { FloatVar x0; if (n->isFloatVar()) { x0 = fv[n->getFloatVar()]; } else { x0 = FloatVar(*this, n->getFloat(), n->getFloat()); } return x0; }#endif IntPropLevel FlatZincSpace::ann2ipl(AST::Node* ann) { if (ann) { if (ann->hasAtom("val")) return IPL_VAL; if (ann->hasAtom("domain")) return IPL_DOM; if (ann->hasAtom("bounds") || ann->hasAtom("boundsR") || ann->hasAtom("boundsD") || ann->hasAtom("boundsZ")) return IPL_BND; } return IPL_DEF; }
DFA FlatZincSpace::getSharedDFA(DFA& a) { if (_initData) { FlatZincSpaceInitData::DFASet::iterator it = _initData->dfaSet.find(a); if (it != _initData->dfaSet.end()) { return *it; } _initData->dfaSet.insert(a); } return a; }
void Printer::init(AST::Array* output) { _output = output; }
void Printer::printElem(std::ostream& out, AST::Node* ai, const Gecode::IntVarArray& iv, const Gecode::BoolVarArray& bv#ifdef GECODE_HAS_SET_VARS , const Gecode::SetVarArray& sv#endif#ifdef GECODE_HAS_FLOAT_VARS , const Gecode::FloatVarArray& fv#endif ) const { int k; if (ai->isInt(k)) { out << k; } else if (ai->isIntVar()) { out << iv[ai->getIntVar()]; } else if (ai->isBoolVar()) { if (bv[ai->getBoolVar()].min() == 1) { out << "true"; } else if (bv[ai->getBoolVar()].max() == 0) { out << "false"; } else { out << "false..true"; }#ifdef GECODE_HAS_SET_VARS } else if (ai->isSetVar()) { if (!sv[ai->getSetVar()].assigned()) { out << sv[ai->getSetVar()]; return; } SetVarGlbRanges svr(sv[ai->getSetVar()]); if (!svr()) { out << "{}"; return; } int min = svr.min(); int max = svr.max(); ++svr; if (svr()) { SetVarGlbValues svv(sv[ai->getSetVar()]); int i = svv.val(); out << "{" << i; ++svv; for (; svv(); ++svv) out << ", " << svv.val(); out << "}"; } else { out << min << ".." << max; }#endif#ifdef GECODE_HAS_FLOAT_VARS } else if (ai->isFloatVar()) { if (fv[ai->getFloatVar()].assigned()) { FloatVal vv = fv[ai->getFloatVar()].val(); FloatNum v; if (vv.singleton()) v = vv.min(); else if (vv < 0.0) v = vv.max(); else v = vv.min(); std::ostringstream oss; // oss << std::scientific; oss << std::setprecision(std::numeric_limits<double>::digits10); oss << v; if (oss.str().find(".") == std::string::npos) oss << ".0"; out << oss.str(); } else { out << fv[ai->getFloatVar()]; }#endif } else if (ai->isBool()) { out << (ai->getBool() ? "true" : "false"); } else if (ai->isSet()) { AST::SetLit* s = ai->getSet(); if (s->interval) { out << s->min << ".." << s->max; } else { out << "{"; for (unsigned int i=0; i<s->s.size(); i++) { out << s->s[i] << (i < s->s.size()-1 ? ", " : "}"); } } } else if (ai->isString()) { std::string s = ai->getString(); for (unsigned int i=0; i<s.size(); i++) { if (s[i] == '\\' && i<s.size()-1) { switch (s[i+1]) { case 'n': out << "\n"; break; case '\\': out << "\\"; break; case 't': out << "\t"; break; default: out << "\\" << s[i+1]; } i++; } else { out << s[i]; } } } }
void Printer::printElemDiff(std::ostream& out, AST::Node* ai, const Gecode::IntVarArray& iv1, const Gecode::IntVarArray& iv2, const Gecode::BoolVarArray& bv1, const Gecode::BoolVarArray& bv2#ifdef GECODE_HAS_SET_VARS , const Gecode::SetVarArray& sv1, const Gecode::SetVarArray& sv2#endif#ifdef GECODE_HAS_FLOAT_VARS , const Gecode::FloatVarArray& fv1, const Gecode::FloatVarArray& fv2#endif ) const {#ifdef GECODE_HAS_GIST using namespace Gecode::Gist; int k; if (ai->isInt(k)) { out << k; } else if (ai->isIntVar()) { std::string res(Comparator::compare("",iv1[ai->getIntVar()], iv2[ai->getIntVar()])); if (res.length() > 0) { res.erase(0, 1); // Remove '=' out << res; } else { out << iv1[ai->getIntVar()]; } } else if (ai->isBoolVar()) { std::string res(Comparator::compare("",bv1[ai->getBoolVar()], bv2[ai->getBoolVar()])); if (res.length() > 0) { res.erase(0, 1); // Remove '=' out << res; } else { out << bv1[ai->getBoolVar()]; }#ifdef GECODE_HAS_SET_VARS } else if (ai->isSetVar()) { std::string res(Comparator::compare("",sv1[ai->getSetVar()], sv2[ai->getSetVar()])); if (res.length() > 0) { res.erase(0, 1); // Remove '=' out << res; } else { out << sv1[ai->getSetVar()]; }#endif#ifdef GECODE_HAS_FLOAT_VARS } else if (ai->isFloatVar()) { std::string res(Comparator::compare("",fv1[ai->getFloatVar()], fv2[ai->getFloatVar()])); if (res.length() > 0) { res.erase(0, 1); // Remove '=' out << res; } else { out << fv1[ai->getFloatVar()]; }#endif } else if (ai->isBool()) { out << (ai->getBool() ? "true" : "false"); } else if (ai->isSet()) { AST::SetLit* s = ai->getSet(); if (s->interval) { out << s->min << ".." << s->max; } else { out << "{"; for (unsigned int i=0; i<s->s.size(); i++) { out << s->s[i] << (i < s->s.size()-1 ? ", " : "}"); } } } else if (ai->isString()) { std::string s = ai->getString(); for (unsigned int i=0; i<s.size(); i++) { if (s[i] == '\\' && i<s.size()-1) { switch (s[i+1]) { case 'n': out << "\n"; break; case '\\': out << "\\"; break; case 't': out << "\t"; break; default: out << "\\" << s[i+1]; } i++; } else { out << s[i]; } } }#else (void) out; (void) ai; (void) iv1; (void) iv2; (void) bv1; (void) bv2;#ifdef GECODE_HAS_SET_VARS (void) sv1; (void) sv2;#endif#ifdef GECODE_HAS_FLOAT_VARS (void) fv1; (void) fv2;#endif
#endif }
void Printer::print(std::ostream& out, const Gecode::IntVarArray& iv, const Gecode::BoolVarArray& bv#ifdef GECODE_HAS_SET_VARS , const Gecode::SetVarArray& sv#endif#ifdef GECODE_HAS_FLOAT_VARS , const Gecode::FloatVarArray& fv#endif ) const { if (_output == nullptr) return; for (unsigned int i=0; i< _output->a.size(); i++) { AST::Node* ai = _output->a[i]; if (ai->isArray()) { AST::Array* aia = ai->getArray(); int size = aia->a.size(); out << "["; for (int j=0; j<size; j++) { printElem(out,aia->a[j],iv,bv#ifdef GECODE_HAS_SET_VARS ,sv#endif#ifdef GECODE_HAS_FLOAT_VARS ,fv#endif ); if (j<size-1) out << ", "; } out << "]"; } else { printElem(out,ai,iv,bv#ifdef GECODE_HAS_SET_VARS ,sv#endif#ifdef GECODE_HAS_FLOAT_VARS ,fv#endif ); } } }
void Printer::printDiff(std::ostream& out, const Gecode::IntVarArray& iv1, const Gecode::IntVarArray& iv2, const Gecode::BoolVarArray& bv1, const Gecode::BoolVarArray& bv2#ifdef GECODE_HAS_SET_VARS , const Gecode::SetVarArray& sv1, const Gecode::SetVarArray& sv2#endif#ifdef GECODE_HAS_FLOAT_VARS , const Gecode::FloatVarArray& fv1, const Gecode::FloatVarArray& fv2#endif ) const { if (_output == nullptr) return; for (unsigned int i=0; i< _output->a.size(); i++) { AST::Node* ai = _output->a[i]; if (ai->isArray()) { AST::Array* aia = ai->getArray(); int size = aia->a.size(); out << "["; for (int j=0; j<size; j++) { printElemDiff(out,aia->a[j],iv1,iv2,bv1,bv2#ifdef GECODE_HAS_SET_VARS ,sv1,sv2#endif#ifdef GECODE_HAS_FLOAT_VARS ,fv1,fv2#endif ); if (j<size-1) out << ", "; } out << "]"; } else { printElemDiff(out,ai,iv1,iv2,bv1,bv2#ifdef GECODE_HAS_SET_VARS ,sv1,sv2#endif#ifdef GECODE_HAS_FLOAT_VARS ,fv1,fv2#endif ); } } }
void Printer::addIntVarName(const std::string& n) { iv_names.push_back(n); } void Printer::addBoolVarName(const std::string& n) { bv_names.push_back(n); }#ifdef GECODE_HAS_FLOAT_VARS void Printer::addFloatVarName(const std::string& n) { fv_names.push_back(n); }#endif#ifdef GECODE_HAS_SET_VARS void Printer::addSetVarName(const std::string& n) { sv_names.push_back(n); }#endif
void Printer::shrinkElement(AST::Node* node, std::map<int,int>& iv, std::map<int,int>& bv, std::map<int,int>& sv, std::map<int,int>& fv) { if (node->isIntVar()) { AST::IntVar* x = static_cast<AST::IntVar*>(node); if (iv.find(x->i) == iv.end()) { int newi = iv.size(); iv[x->i] = newi; } x->i = iv[x->i]; } else if (node->isBoolVar()) { AST::BoolVar* x = static_cast<AST::BoolVar*>(node); if (bv.find(x->i) == bv.end()) { int newi = bv.size(); bv[x->i] = newi; } x->i = bv[x->i]; } else if (node->isSetVar()) { AST::SetVar* x = static_cast<AST::SetVar*>(node); if (sv.find(x->i) == sv.end()) { int newi = sv.size(); sv[x->i] = newi; } x->i = sv[x->i]; } else if (node->isFloatVar()) { AST::FloatVar* x = static_cast<AST::FloatVar*>(node); if (fv.find(x->i) == fv.end()) { int newi = fv.size(); fv[x->i] = newi; } x->i = fv[x->i]; } }
void Printer::shrinkArrays(Space& home, int& optVar, bool optVarIsInt, Gecode::IntVarArray& iv, Gecode::BoolVarArray& bv#ifdef GECODE_HAS_SET_VARS , Gecode::SetVarArray& sv#endif#ifdef GECODE_HAS_FLOAT_VARS , Gecode::FloatVarArray& fv#endif ) { if (_output == nullptr) { if (optVarIsInt && optVar != -1) { IntVar ov = iv[optVar]; iv = IntVarArray(home, 1); iv[0] = ov; optVar = 0; } else { iv = IntVarArray(home, 0); } bv = BoolVarArray(home, 0);#ifdef GECODE_HAS_SET_VARS sv = SetVarArray(home, 0);#endif#ifdef GECODE_HAS_FLOAT_VARS if (!optVarIsInt && optVar != -1) { FloatVar ov = fv[optVar]; fv = FloatVarArray(home, 1); fv[0] = ov; optVar = 0; } else { fv = FloatVarArray(home,0); }#endif return; } std::map<int,int> iv_new; std::map<int,int> bv_new; std::map<int,int> sv_new; std::map<int,int> fv_new;
if (optVar != -1) { if (optVarIsInt) iv_new[optVar] = 0; else fv_new[optVar] = 0; optVar = 0; }
for (unsigned int i=0; i< _output->a.size(); i++) { AST::Node* ai = _output->a[i]; if (ai->isArray()) { AST::Array* aia = ai->getArray(); for (unsigned int j=0; j<aia->a.size(); j++) { shrinkElement(aia->a[j],iv_new,bv_new,sv_new,fv_new); } } else { shrinkElement(ai,iv_new,bv_new,sv_new,fv_new); } }
IntVarArgs iva(iv_new.size()); std::vector<std::string> iv_names_new(iv_new.size()); for (std::map<int,int>::iterator i=iv_new.begin(); i != iv_new.end(); ++i) { iva[(*i).second] = iv[(*i).first]; iv_names_new[(*i).second] = iv_names[(*i).first]; } iv = IntVarArray(home, iva); iv_names = iv_names_new;
BoolVarArgs bva(bv_new.size()); std::vector<std::string> bv_names_new(bv_new.size()); for (std::map<int,int>::iterator i=bv_new.begin(); i != bv_new.end(); ++i) { bva[(*i).second] = bv[(*i).first]; bv_names_new[(*i).second] = bv_names[(*i).first]; } bv = BoolVarArray(home, bva); bv_names = bv_names_new;
#ifdef GECODE_HAS_SET_VARS SetVarArgs sva(sv_new.size()); std::vector<std::string> sv_names_new(sv_new.size()); for (std::map<int,int>::iterator i=sv_new.begin(); i != sv_new.end(); ++i) { sva[(*i).second] = sv[(*i).first]; sv_names_new[(*i).second] = sv_names[(*i).first]; } sv = SetVarArray(home, sva); sv_names = sv_names_new;#endif
#ifdef GECODE_HAS_FLOAT_VARS FloatVarArgs fva(fv_new.size()); std::vector<std::string> fv_names_new(fv_new.size()); for (std::map<int,int>::iterator i=fv_new.begin(); i != fv_new.end(); ++i) { fva[(*i).second] = fv[(*i).first]; fv_names_new[(*i).second] = fv_names[(*i).first]; } fv = FloatVarArray(home, fva); fv_names = fv_names_new;#endif }
Printer::~Printer(void) { delete _output; }
}}
// STATISTICS: flatzinc-any