Closed k0stjap closed 5 years ago
Yes, that looks like a genuine bug but I still have to figure out a good fix (Basically iterating over a data structure while deleting from it, typically a bad idea...).
Thanks for the detailed report!
I had another look. The bug only occurs when the last propagator in a space is deleted which is also not stable. Hence when you add sp->status() just before the kill, things work as expected.
Hence the obvious fix would say that kills can only be performed on stable spaces.
Would that be to restrictive?
.. thanks, I see your point - and I believe I can live with the restriction!
Cheers,
--- Kostja.
I now have reconstructed the invariant that is violated. It is easy to fix but I am short on time, right now.
Fixed in develop.
thanks!
Dear Gecode developers,
it looks like If one "PropagatorGroup::kill(..)"s the only propagator in a space, the subsequent Space::status() segfault"s. In particular, The following program:
/* g++ -o bug0 =1/bug0.cpp -L/usr/local/lib -lgecodekernel -lgecodesupport -lgecodeint -lgecodesearch setenv LD_LIBRARY_PATH /usr/local/lib ./bug0
*/
include <gecode/int.hh>
include <gecode/search.hh>
using namespace Gecode;
const int iv0ds = 10;
class Sp0 : public Space { public: const char *name; IntVar iv0;
public: Sp0(const char n) : name(n), iv0(this, 0, iv0ds) {} Sp0(const char n, IntSet is) : name(n), iv0(this, is) {} Sp0(Sp0 &s) : Space(s), name(s.name) { iv0.update(*this, s.iv0); }
virtual Space copy(void) { return new Sp0(this); }
IntVar getIV0() { return (iv0); }
void print() { std::cout << name << "="; for (IntVarRanges ri(iv0); ri(); ++ri) { std::cout << ri.min() << ".." << ri.max() << " "; } std::cout << std::endl; }
void status() { switch (Space::status()) { case SS_FAILED: std::cout << "space " << name << " failed." << std::endl; break; case SS_SOLVED: std::cout << "space " << name << " is solved." << std::endl; break; case SS_BRANCH: std::cout << "space " << name << " must be branched." << std::endl; break; } } };
// int main(int argc, char* argv[]) { IntVar iv0l;
{ std::cout << std::endl << "sp = new Sp0(\"sp\", IntSet(0, 20))" << std::endl; Sp0 sp = new Sp0("sp", IntSet(0, 20)); PropagatorGroup pg; sp->print(); std::cout << "pg.size(sp) = " << pg.size(sp) << std::endl; iv0l = sp->getIV0(); BoolVar cv(sp, 0, 1); std::cout << "dom((sp)(pg), iv0l, IntSet(0, 10), cv)" << std::endl; dom((sp)(pg), iv0l, IntSet(0, 10), cv); std::cout << "pg.size(sp) = " << pg.size(sp) << std::endl; std::cout << "pg.kill(sp)" << std::endl; pg.kill(sp); std::cout << "pg.size(sp) = " << pg.size(sp) << std::endl; sp->print(); std::cout << cv << std::endl;
/ BoolVar cv2(sp, 0, 1); std::cout << "dom((sp)(pg), iv0l, IntSet(0, 10), cv2)" << std::endl; dom((sp)(pg), iv0l, IntSet(0, 10), cv2); */
}
return (0); }
crashes for me with Gecode 6.1.1 (and I do not see a relevant bug fix in the 6.2.0 changelog) as follows:
kost (286) ./bug0
sp = new Sp0("sp", IntSet(0, 20)) sp=0..20 pg.size(sp) = 0 dom((sp)(pg), iv0l, IntSet(0, 10), cv) pg.size(sp) = 1 pg.kill(sp) pg.size(sp) = 0 sp=0..20 [0..1] dom(sp, iv0l, IntSet(15, 20)) pg.size(*sp) = 0 Segmentation fault (core dumped)
.. however, if one enables the commented out code near the end of the program - with another 'dom()' progagator post, the program runs fine:
kost (284) ./bug0
sp = new Sp0("sp", IntSet(0, 20)) sp=0..20 pg.size(sp) = 0 dom((sp)(pg), iv0l, IntSet(0, 10), cv) pg.size(sp) = 1 pg.kill(sp) pg.size(sp) = 0 sp=0..20 [0..1] dom((sp)(pg), iv0l, IntSet(0, 10), cv2) dom(sp, iv0l, IntSet(15, 20)) pg.size(sp) = 1 space sp is solved. ok?? pg.size(*sp) = 0 sp=15..20 [0..1]
Did I miss something??
Cheers,
--- Kostja.