31 #include "dd/DdBuilder.hpp" 32 #include "dd/DepthFirstSearcher.hpp" 33 #include "util/demangle.hpp" 34 #include "util/MessageHandler.hpp" 67 template<
typename S,
int AR>
70 static int const ARITY = AR;
73 return *
static_cast<S*
>(
this);
76 S
const& entity()
const {
77 return *
static_cast<S const*
>(
this);
80 void printLevel(std::ostream& os,
int level)
const {
102 std::string title = typenameof<S>())
const {
104 dumper.
dump(os, title);
112 std::string
dot(std::string title = typenameof<S>())
const {
130 template<
typename T,
typename I>
131 static size_t rawHashCode_(
void const* p) {
133 I
const* a =
static_cast<I const*
>(p);
134 for (
size_t i = 0; i <
sizeof(T) /
sizeof(I); ++i) {
141 template<
typename T,
typename I>
142 static size_t rawEqualTo_(
void const* p1,
void const* p2) {
143 I
const* a1 =
static_cast<I const*
>(p1);
144 I
const* a2 =
static_cast<I const*
>(p2);
145 for (
size_t i = 0; i <
sizeof(T) /
sizeof(I); ++i) {
146 if (a1[i] != a2[i])
return false;
153 static size_t rawHashCode(T
const& o) {
154 if (
sizeof(T) %
sizeof(
size_t) == 0) {
155 return rawHashCode_<T,size_t>(&o);
157 if (
sizeof(T) %
sizeof(
unsigned int) == 0) {
158 return rawHashCode_<T,unsigned int>(&o);
160 if (
sizeof(T) %
sizeof(
unsigned short) == 0) {
161 return rawHashCode_<T,unsigned short>(&o);
163 return rawHashCode_<T,unsigned char>(&o);
167 static size_t rawEqualTo(T
const& o1, T
const& o2) {
168 if (
sizeof(T) %
sizeof(
size_t) == 0) {
169 return rawEqualTo_<T,size_t>(&o1, &o2);
171 if (
sizeof(T) %
sizeof(
unsigned int) == 0) {
172 return rawEqualTo_<T,unsigned int>(&o1, &o2);
174 if (
sizeof(T) %
sizeof(
unsigned short) == 0) {
175 return rawEqualTo_<T,unsigned short>(&o1, &o2);
177 return rawEqualTo_<T,unsigned char>(&o1, &o2);
194 template<
typename S,
int AR>
197 int datasize()
const {
201 int get_root(
void* p) {
202 return this->entity().getRoot();
205 int get_child(
void* p,
int level,
int value) {
206 assert(0 <= value && value < S::ARITY);
207 return this->entity().getChild(level, value);
210 void get_copy(
void* to,
void const* from) {
213 int merge_states(
void* p1,
void* p2) {
217 void destruct(
void* p) {
220 void destructLevel(
int level) {
223 size_t hash_code(
void const* p,
int level)
const {
227 bool equal_to(
void const* p,
void const* q,
int level)
const {
231 void print_state(std::ostream& os,
void const* p,
int level)
const {
256 template<
typename S,
typename T,
int AR>
262 static State& state(
void* p) {
263 return *
static_cast<State*
>(p);
266 static State
const& state(
void const* p) {
267 return *
static_cast<State const*
>(p);
271 int datasize()
const {
272 return sizeof(State);
275 void construct(
void* p) {
279 int get_root(
void* p) {
280 this->entity().construct(p);
281 return this->entity().getRoot(state(p));
284 int get_child(
void* p,
int level,
int value) {
285 assert(0 <= value && value < S::ARITY);
286 return this->entity().getChild(state(p), level, value);
289 void getCopy(
void* p, State
const& s) {
293 void get_copy(
void* to,
void const* from) {
294 this->entity().getCopy(to, state(from));
297 int mergeStates(State& s1, State& s2) {
301 int merge_states(
void* p1,
void* p2) {
302 return this->entity().mergeStates(state(p1), state(p2));
305 void destruct(
void* p) {
309 void destructLevel(
int level) {
312 size_t hashCode(State
const& s)
const {
313 return this->rawHashCode(s);
316 size_t hashCodeAtLevel(State
const& s,
int level)
const {
317 return this->entity().hashCode(s);
320 size_t hash_code(
void const* p,
int level)
const {
321 return this->entity().hashCodeAtLevel(state(p), level);
324 bool equalTo(State
const& s1, State
const& s2)
const {
329 bool equalToAtLevel(State
const& s1, State
const& s2,
int level)
const {
330 return this->entity().equalTo(s1, s2);
333 bool equal_to(
void const* p,
void const* q,
int level)
const {
334 return this->entity().equalToAtLevel(state(p), state(q), level);
337 void printState(std::ostream& os, State
const& s)
const {
341 void printStateAtLevel(std::ostream& os, State
const& s,
int level)
const {
342 this->entity().printState(os, s);
345 void print_state(std::ostream& os,
void const* p,
int level)
const {
346 this->entity().printStateAtLevel(os, state(p), level);
372 template<
typename S,
typename T,
int AR>
383 static State* state(
void* p) {
384 return static_cast<State*
>(p);
387 static State
const* state(
void const* p) {
388 return static_cast<State const*
>(p);
392 void setArraySize(
int n) {
395 throw std::runtime_error(
396 "Cannot set array size twice; use setArraySize(int) only once in the constructor of DD spec.");
398 dataWords = (n *
sizeof(State) +
sizeof(Word) - 1) /
sizeof(Word);
401 int getArraySize()
const {
407 arraySize(-1), dataWords(-1) {
410 int datasize()
const {
412 throw std::runtime_error(
413 "Array size is unknown; please set it by setArraySize(int) in the constructor of DD spec.");
414 return dataWords *
sizeof(Word);
417 int get_root(
void* p) {
418 return this->entity().getRoot(state(p));
421 int get_child(
void* p,
int level,
int value) {
422 assert(0 <= value && value < S::ARITY);
423 return this->entity().getChild(state(p), level, value);
426 void get_copy(
void* to,
void const* from) {
427 Word
const* pa =
static_cast<Word const*
>(from);
428 Word
const* pz = pa + dataWords;
429 Word* qa =
static_cast<Word*
>(to);
435 int mergeStates(T* a1, T* a2) {
439 int merge_states(
void* p1,
void* p2) {
440 return this->entity().mergeStates(state(p1), state(p2));
443 void destruct(
void* p) {
446 void destructLevel(
int level) {
449 size_t hashCode(State
const* s)
const {
450 Word
const* pa =
reinterpret_cast<Word const*
>(s);
451 Word
const* pz = pa + dataWords;
460 size_t hashCodeAtLevel(State
const* s,
int level)
const {
461 return this->entity().hashCode(s);
464 size_t hash_code(
void const* p,
int level)
const {
465 return this->entity().hashCodeAtLevel(state(p), level);
468 bool equalTo(State
const* s1, State
const* s2)
const {
469 Word
const* pa =
reinterpret_cast<Word const*
>(s1);
470 Word
const* qa =
reinterpret_cast<Word const*
>(s1);
471 Word
const* pz = pa + dataWords;
473 if (*pa++ != *qa++)
return false;
478 bool equalToAtLevel(State
const* s1, State
const* s2,
int level)
const {
479 return this->entity().equalTo(s1, s2);
482 bool equal_to(
void const* p,
void const* q,
int level)
const {
483 return this->entity().equalToAtLevel(state(p), state(q), level);
486 void printState(std::ostream& os, State
const* a)
const {
488 for (
int i = 0; i < arraySize; ++i) {
489 if (i > 0) os <<
",";
495 void printStateAtLevel(std::ostream& os, State
const* a,
int level)
const {
496 this->entity().printState(os, a);
499 void print_state(std::ostream& os,
void const* p,
int level)
const {
500 this->entity().printStateAtLevel(os, state(p), level);
525 template<
typename S,
typename TS,
typename TA,
int AR>
533 static int const S_WORDS = (
sizeof(S_State) +
sizeof(Word) - 1)
539 static S_State& s_state(
void* p) {
540 return *
static_cast<S_State*
>(p);
543 static S_State
const& s_state(
void const* p) {
544 return *
static_cast<S_State const*
>(p);
547 static A_State* a_state(
void* p) {
548 return reinterpret_cast<A_State*
>(
static_cast<Word*
>(p) + S_WORDS);
551 static A_State
const* a_state(
void const* p) {
552 return reinterpret_cast<A_State const*
>(
static_cast<Word const*
>(p)
557 void setArraySize(
int n) {
561 + (n *
sizeof(A_State) +
sizeof(Word) - 1) /
sizeof(Word);
564 int getArraySize()
const {
570 arraySize(-1), dataWords(-1) {
573 int datasize()
const {
574 return dataWords *
sizeof(Word);
577 void construct(
void* p) {
581 int get_root(
void* p) {
582 this->entity().construct(p);
583 return this->entity().getRoot(s_state(p), a_state(p));
586 int get_child(
void* p,
int level,
int value) {
587 assert(0 <= value && value < S::ARITY);
588 return this->entity().getChild(s_state(p), a_state(p), level, value);
591 void getCopy(
void* p, S_State
const& s) {
595 void get_copy(
void* to,
void const* from) {
596 this->entity().getCopy(to, s_state(from));
597 Word
const* pa =
static_cast<Word const*
>(from);
598 Word
const* pz = pa + dataWords;
599 Word* qa =
static_cast<Word*
>(to);
607 int mergeStates(S_State& s1, A_State* a1, S_State& s2, A_State* a2) {
611 int merge_states(
void* p1,
void* p2) {
612 return this->entity().mergeStates(s_state(p1), a_state(p1), s_state(p2),
616 void destruct(
void* p) {
619 void destructLevel(
int level) {
622 size_t hashCode(S_State
const& s)
const {
623 return this->rawHashCode(s);
626 size_t hashCodeAtLevel(S_State
const& s,
int level)
const {
627 return this->entity().hashCode(s);
630 size_t hash_code(
void const* p,
int level)
const {
631 size_t h = this->entity().hashCodeAtLevel(s_state(p), level);
633 Word
const* pa =
static_cast<Word const*
>(p);
634 Word
const* pz = pa + dataWords;
643 bool equalTo(S_State
const& s1, S_State
const& s2)
const {
644 return this->rawEqualTo(s1, s2);
647 bool equalToAtLevel(S_State
const& s1, S_State
const& s2,
int level)
const {
648 return this->entity().equalTo(s1, s2);
651 bool equal_to(
void const* p,
void const* q,
int level)
const {
652 if (!this->entity().equalToAtLevel(s_state(p), s_state(q), level))
654 Word
const* pa =
static_cast<Word const*
>(p);
655 Word
const* qa =
static_cast<Word const*
>(q);
656 Word
const* pz = pa + dataWords;
660 if (*pa++ != *qa++)
return false;
665 void printState(std::ostream& os,
667 A_State
const* a)
const {
668 os <<
"[" << s <<
":";
669 for (
int i = 0; i < arraySize; ++i) {
670 if (i > 0) os <<
",";
676 void printStateAtLevel(std::ostream& os,
680 this->entity().printState(os, s, a);
683 void print_state(std::ostream& os,
void const* p,
int level)
const {
684 this->entity().printStateAtLevel(os, s_state(p), a_state(p), level);
689 template<
typename S,
typename TS,
typename TA,
int AR>
690 class PodHybridDdSpec:
public HybridDdSpec<S,TS,TA,AR> {
friend std::ostream & operator<<(std::ostream &os, DdSpecBase const &o)
Dumps the node table in Graphviz (dot) format.
void dumpDot(std::ostream &os=std::cout, std::string title=typenameof< S >()) const
Dumps the diagram in Graphviz (DOT) format.
std::vector< std::pair< int, int > > findOneInstance() const
Returns a random instance using simple depth-first search without caching.
void dump(std::ostream &os, std::string title)
Dumps the node table in Graphviz (dot) format.
Abstract class of DD specifications using POD array states.
Abstract class of DD specifications using scalar states.
Abstract class of DD specifications using both scalar and POD array states.
Abstract class of DD specifications without states.
std::string dot(std::string title=typenameof< S >()) const
Makes an input code for Graphviz.