PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/src/muz_qe/dl_check_table.cpp

http://z3.codeplex.com
C++ | 363 lines | 291 code | 51 blank | 21 comment | 25 complexity | 247b709bc858505b7ba0f73a633249d0 MD5 | raw file
  1. /*++
  2. Copyright (c) 2010 Microsoft Corporation
  3. Module Name:
  4. dl_check_table.cpp
  5. Abstract:
  6. <abstract>
  7. Author:
  8. Nikolaj Bjorner (nbjorner) 2010-11-15
  9. Revision History:
  10. --*/
  11. #include "dl_check_table.h"
  12. #include "dl_table.h"
  13. namespace datalog {
  14. bool check_table_plugin::can_handle_signature(table_signature const& s) {
  15. return m_tocheck.can_handle_signature(s) && m_checker.can_handle_signature(s);
  16. }
  17. check_table & check_table_plugin::get(table_base& r) {
  18. return static_cast<check_table&>(r);
  19. }
  20. check_table const & check_table_plugin::get(table_base const& r) {
  21. return static_cast<check_table const &>(r);
  22. }
  23. table_base& check_table_plugin::checker(table_base& r) { return *get(r).m_checker; }
  24. table_base const& check_table_plugin::checker(table_base const& r) { return *get(r).m_checker; }
  25. table_base* check_table_plugin::checker(table_base* r) { return r?(get(*r).m_checker):0; }
  26. table_base const* check_table_plugin::checker(table_base const* r) { return r?(get(*r).m_checker):0; }
  27. table_base& check_table_plugin::tocheck(table_base& r) { return *get(r).m_tocheck; }
  28. table_base const& check_table_plugin::tocheck(table_base const& r) { return *get(r).m_tocheck; }
  29. table_base* check_table_plugin::tocheck(table_base* r) { return r?(get(*r).m_tocheck):0; }
  30. table_base const* check_table_plugin::tocheck(table_base const* r) { return r?(get(*r).m_tocheck):0; }
  31. table_base * check_table_plugin::mk_empty(const table_signature & s) {
  32. IF_VERBOSE(1, verbose_stream() << __FUNCTION__ << "\n";);
  33. table_base* checker = m_checker.mk_empty(s);
  34. table_base* tocheck = m_tocheck.mk_empty(s);
  35. return alloc(check_table, *this, s, tocheck, checker);
  36. }
  37. class check_table_plugin::join_fn : public table_join_fn {
  38. scoped_ptr<table_join_fn> m_tocheck;
  39. scoped_ptr<table_join_fn> m_checker;
  40. public:
  41. join_fn(check_table_plugin& p,
  42. const table_base & t1, const table_base & t2,
  43. unsigned col_cnt, const unsigned * cols1, const unsigned * cols2) {
  44. m_tocheck = p.get_manager().mk_join_fn(tocheck(t1), tocheck(t2), col_cnt, cols1, cols2);
  45. m_checker = p.get_manager().mk_join_fn(checker(t1), checker(t2), col_cnt, cols1, cols2);
  46. }
  47. virtual table_base* operator()(const table_base & t1, const table_base & t2) {
  48. IF_VERBOSE(1, verbose_stream() << __FUNCTION__ << "\n";);
  49. table_base* ttocheck = (*m_tocheck)(tocheck(t1), tocheck(t2));
  50. table_base* tchecker = (*m_checker)(checker(t1), checker(t2));
  51. check_table* result = alloc(check_table, get(t1).get_plugin(), ttocheck->get_signature(), ttocheck, tchecker);
  52. return result;
  53. }
  54. };
  55. table_join_fn * check_table_plugin::mk_join_fn(const table_base & t1, const table_base & t2,
  56. unsigned col_cnt, const unsigned * cols1, const unsigned * cols2) {
  57. if (!check_kind(t1) || !check_kind(t2)) {
  58. return 0;
  59. }
  60. return alloc(join_fn, *this, t1, t2, col_cnt, cols1, cols2);
  61. }
  62. class check_table_plugin::union_fn : public table_union_fn {
  63. scoped_ptr<table_union_fn> m_tocheck;
  64. scoped_ptr<table_union_fn> m_checker;
  65. public:
  66. union_fn(check_table_plugin& p, table_base const& tgt, const table_base& src, table_base const* delta) {
  67. m_tocheck = p.get_manager().mk_union_fn(tocheck(tgt), tocheck(src), tocheck(delta));
  68. m_checker = p.get_manager().mk_union_fn(checker(tgt), checker(src), checker(delta));
  69. }
  70. virtual void operator()(table_base& tgt, const table_base& src, table_base* delta) {
  71. IF_VERBOSE(1, verbose_stream() << __FUNCTION__ << "\n";);
  72. (*m_tocheck)(tocheck(tgt), tocheck(src), tocheck(delta));
  73. (*m_checker)(checker(tgt), checker(src), checker(delta));
  74. get(tgt).well_formed();
  75. if (delta) {
  76. get(*delta).well_formed();
  77. }
  78. }
  79. };
  80. table_union_fn * check_table_plugin::mk_union_fn(const table_base & tgt, const table_base & src, const table_base * delta) {
  81. if (!check_kind(tgt) || !check_kind(src) || (delta && !check_kind(*delta))) {
  82. return 0;
  83. }
  84. return alloc(union_fn, *this, tgt, src, delta);
  85. }
  86. class check_table_plugin::project_fn : public table_transformer_fn {
  87. scoped_ptr<table_transformer_fn> m_checker;
  88. scoped_ptr<table_transformer_fn> m_tocheck;
  89. public:
  90. project_fn(check_table_plugin& p, const table_base & t, unsigned col_cnt, const unsigned * removed_cols) {
  91. m_checker = p.get_manager().mk_project_fn(checker(t), col_cnt, removed_cols);
  92. m_tocheck = p.get_manager().mk_project_fn(tocheck(t), col_cnt, removed_cols);
  93. }
  94. table_base* operator()(table_base const& src) {
  95. IF_VERBOSE(1, verbose_stream() << __FUNCTION__ << "\n";);
  96. table_base* tchecker = (*m_checker)(checker(src));
  97. table_base* ttocheck = (*m_tocheck)(tocheck(src));
  98. check_table* result = alloc(check_table, get(src).get_plugin(), tchecker->get_signature(), ttocheck, tchecker);
  99. return result;
  100. }
  101. };
  102. table_transformer_fn * check_table_plugin::mk_project_fn(const table_base & t, unsigned col_cnt, const unsigned * removed_cols) {
  103. if (!check_kind(t)) {
  104. return 0;
  105. }
  106. return alloc(project_fn, *this, t, col_cnt, removed_cols);
  107. }
  108. class check_table_plugin::rename_fn : public table_transformer_fn {
  109. scoped_ptr<table_transformer_fn> m_checker;
  110. scoped_ptr<table_transformer_fn> m_tocheck;
  111. public:
  112. rename_fn(check_table_plugin& p, const table_base & t, unsigned cycle_len, unsigned const* cycle) {
  113. m_checker = p.get_manager().mk_rename_fn(checker(t), cycle_len, cycle);
  114. m_tocheck = p.get_manager().mk_rename_fn(tocheck(t), cycle_len, cycle);
  115. }
  116. table_base* operator()(table_base const& src) {
  117. IF_VERBOSE(1, verbose_stream() << __FUNCTION__ << "\n";);
  118. table_base* tchecker = (*m_checker)(checker(src));
  119. table_base* ttocheck = (*m_tocheck)(tocheck(src));
  120. check_table* result = alloc(check_table, get(src).get_plugin(), ttocheck->get_signature(), ttocheck, tchecker);
  121. return result;
  122. }
  123. };
  124. table_transformer_fn * check_table_plugin::mk_rename_fn(const table_base & t, unsigned len, const unsigned * cycle) {
  125. if (!check_kind(t)) {
  126. return 0;
  127. }
  128. return alloc(rename_fn, *this, t, len, cycle);
  129. }
  130. class check_table_plugin::filter_identical_fn : public table_mutator_fn {
  131. scoped_ptr<table_mutator_fn> m_checker;
  132. scoped_ptr<table_mutator_fn> m_tocheck;
  133. public:
  134. filter_identical_fn(check_table_plugin& p, const table_base & t,unsigned cnt, unsigned const* cols)
  135. {
  136. m_checker = p.get_manager().mk_filter_identical_fn(checker(t), cnt, cols);
  137. m_tocheck = p.get_manager().mk_filter_identical_fn(tocheck(t), cnt, cols);
  138. }
  139. void operator()(table_base & t) {
  140. (*m_checker)(checker(t));
  141. (*m_tocheck)(tocheck(t));
  142. get(t).well_formed();
  143. }
  144. };
  145. table_mutator_fn * check_table_plugin::mk_filter_identical_fn(const table_base & t, unsigned col_cnt,
  146. const unsigned * identical_cols) {
  147. if (check_kind(t)) {
  148. return alloc(filter_identical_fn, *this, t, col_cnt, identical_cols);
  149. }
  150. return 0;
  151. }
  152. class check_table_plugin::filter_equal_fn : public table_mutator_fn {
  153. scoped_ptr<table_mutator_fn> m_checker;
  154. scoped_ptr<table_mutator_fn> m_tocheck;
  155. public:
  156. filter_equal_fn(check_table_plugin& p, const table_base & t, const table_element & v, unsigned col)
  157. {
  158. m_checker = p.get_manager().mk_filter_equal_fn(checker(t), v, col);
  159. m_tocheck = p.get_manager().mk_filter_equal_fn(tocheck(t), v, col);
  160. }
  161. virtual void operator()(table_base& src) {
  162. (*m_checker)(checker(src));
  163. (*m_tocheck)(tocheck(src));
  164. get(src).well_formed();
  165. }
  166. };
  167. table_mutator_fn * check_table_plugin::mk_filter_equal_fn(const table_base & t, const table_element & value, unsigned col) {
  168. if (check_kind(t)) {
  169. return alloc(filter_equal_fn, *this, t, value, col);
  170. }
  171. return 0;
  172. }
  173. class check_table_plugin::filter_interpreted_fn : public table_mutator_fn {
  174. scoped_ptr<table_mutator_fn> m_checker;
  175. scoped_ptr<table_mutator_fn> m_tocheck;
  176. public:
  177. filter_interpreted_fn(check_table_plugin& p, const table_base & t, app * condition)
  178. {
  179. m_checker = p.get_manager().mk_filter_interpreted_fn(checker(t), condition);
  180. m_tocheck = p.get_manager().mk_filter_interpreted_fn(tocheck(t), condition);
  181. }
  182. virtual void operator()(table_base& src) {
  183. (*m_checker)(checker(src));
  184. (*m_tocheck)(tocheck(src));
  185. get(src).well_formed();
  186. }
  187. };
  188. table_mutator_fn * check_table_plugin::mk_filter_interpreted_fn(const table_base & t, app * condition) {
  189. if (check_kind(t)) {
  190. return alloc(filter_interpreted_fn, *this, t, condition);
  191. }
  192. return 0;
  193. }
  194. class check_table_plugin::filter_by_negation_fn : public table_intersection_filter_fn {
  195. scoped_ptr<table_intersection_filter_fn> m_checker;
  196. scoped_ptr<table_intersection_filter_fn> m_tocheck;
  197. public:
  198. filter_by_negation_fn(
  199. check_table_plugin& p,
  200. const table_base & t,
  201. const table_base & negated_obj, unsigned joined_col_cnt,
  202. const unsigned * t_cols, const unsigned * negated_cols) {
  203. m_checker = p.get_manager().mk_filter_by_negation_fn(checker(t), checker(negated_obj), joined_col_cnt, t_cols, negated_cols);
  204. m_tocheck = p.get_manager().mk_filter_by_negation_fn(tocheck(t), tocheck(negated_obj), joined_col_cnt, t_cols, negated_cols);
  205. }
  206. virtual void operator()(table_base& src, table_base const& negated_obj) {
  207. IF_VERBOSE(1, verbose_stream() << __FUNCTION__ << "\n";);
  208. (*m_checker)(checker(src), checker(negated_obj));
  209. (*m_tocheck)(tocheck(src), tocheck(negated_obj));
  210. get(src).well_formed();
  211. }
  212. };
  213. table_intersection_filter_fn * check_table_plugin::mk_filter_by_negation_fn(const table_base & t,
  214. const table_base & negated_obj, unsigned joined_col_cnt,
  215. const unsigned * t_cols, const unsigned * negated_cols) {
  216. if (check_kind(t) && check_kind(negated_obj)) {
  217. return alloc(filter_by_negation_fn, *this, t, negated_obj, joined_col_cnt, t_cols, negated_cols);
  218. }
  219. return 0;
  220. }
  221. // ------------------
  222. // check_table
  223. check_table::check_table(check_table_plugin & p, const table_signature & sig):
  224. table_base(p, sig) {
  225. (well_formed());
  226. }
  227. check_table::check_table(check_table_plugin & p, const table_signature & sig, table_base* tocheck, table_base* checker):
  228. table_base(p, sig),
  229. m_checker(checker),
  230. m_tocheck(tocheck) {
  231. well_formed();
  232. }
  233. check_table::~check_table() {
  234. m_tocheck->deallocate();
  235. m_checker->deallocate();
  236. }
  237. bool check_table::well_formed() const {
  238. get_plugin().m_count++;
  239. if (get_plugin().m_count == 497) {
  240. std::cout << "here\n";
  241. }
  242. iterator it = m_tocheck->begin(), end = m_tocheck->end();
  243. for (; it != end; ++it) {
  244. table_fact fact;
  245. it->get_fact(fact);
  246. if (!m_checker->contains_fact(fact)) {
  247. m_tocheck->display(verbose_stream());
  248. m_checker->display(verbose_stream());
  249. verbose_stream() << get_plugin().m_count << "\n";
  250. UNREACHABLE();
  251. fatal_error(0);
  252. return false;
  253. }
  254. }
  255. iterator it2 = m_checker->begin(), end2 = m_checker->end();
  256. for (; it2 != end2; ++it2) {
  257. table_fact fact;
  258. it2->get_fact(fact);
  259. if (!m_tocheck->contains_fact(fact)) {
  260. m_tocheck->display(verbose_stream());
  261. m_checker->display(verbose_stream());
  262. verbose_stream() << get_plugin().m_count << "\n";
  263. UNREACHABLE();
  264. fatal_error(0);
  265. return false;
  266. }
  267. }
  268. return true;
  269. }
  270. bool check_table::empty() const {
  271. if (m_tocheck->empty() != m_checker->empty()) {
  272. m_tocheck->display(verbose_stream());
  273. m_checker->display(verbose_stream());
  274. verbose_stream() << get_plugin().m_count << "\n";
  275. fatal_error(0);
  276. }
  277. return m_tocheck->empty();
  278. }
  279. void check_table::add_fact(const table_fact & f) {
  280. IF_VERBOSE(1, verbose_stream() << __FUNCTION__ << "\n";);
  281. m_tocheck->add_fact(f);
  282. m_checker->add_fact(f);
  283. well_formed();
  284. }
  285. void check_table::remove_fact(const table_element* f) {
  286. IF_VERBOSE(1, verbose_stream() << __FUNCTION__ << "\n";);
  287. m_tocheck->remove_fact(f);
  288. m_checker->remove_fact(f);
  289. well_formed();
  290. }
  291. bool check_table::contains_fact(const table_fact & f) const {
  292. return m_checker->contains_fact(f);
  293. }
  294. table_base * check_table::clone() const {
  295. IF_VERBOSE(1, verbose_stream() << __FUNCTION__ << "\n";);
  296. check_table* result = alloc(check_table, get_plugin(), get_signature(), m_tocheck->clone(), m_checker->clone());
  297. return result;
  298. }
  299. table_base * check_table::complement(func_decl* p) const {
  300. check_table* result = alloc(check_table, get_plugin(), get_signature(), m_tocheck->complement(p), m_checker->complement(p));
  301. return result;
  302. }
  303. };