/src/solvers/quant/ematch_instance.c

https://github.com/SRI-CSL/yices2 · C · 233 lines · 119 code · 51 blank · 63 comment · 9 complexity · f5748635654b6bdd5b6455d46869e671 MD5 · raw file

  1. /*
  2. * This file is part of the Yices SMT Solver.
  3. * Copyright (C) 2017 SRI International.
  4. *
  5. * Yices is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * Yices is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with Yices. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /*
  19. * EMATCHED INSTANCES
  20. */
  21. #include "solvers/quant/ematch_instance.h"
  22. #include "utils/hash_functions.h"
  23. typedef struct {
  24. int_hobj_t m;
  25. instance_table_t *table;
  26. term_t *vdata; // variables to be replaced
  27. occ_t *odata; // occurrences in egraph that replaces variables
  28. int32_t compile_idx; // index of yield instruction in compile instruction table
  29. uint32_t nelems;
  30. } instance_hobj_t;
  31. /*******************
  32. * INSTANCE TABLE *
  33. ******************/
  34. /*
  35. * Make the table 50% larger
  36. */
  37. static void extend_instance_table(instance_table_t *table) {
  38. uint32_t n;
  39. n = table->size + 1;
  40. n += n>>1;
  41. if (n >= MAX_INSTANCE_TABLE_SIZE) {
  42. out_of_memory();
  43. }
  44. table->data = (instance_t *) safe_realloc(table->data, n * sizeof(instance_t));
  45. table->size = n;
  46. }
  47. /*
  48. * Remove all instances of index >= n
  49. */
  50. static void shrink_instance_table(instance_table_t *table, uint32_t n) {
  51. uint32_t i;
  52. instance_t *inst;
  53. assert(n <= table->ninstances);
  54. for(i=n; i<table->ninstances; i++) {
  55. inst = &table->data[i];
  56. safe_free(inst->vdata);
  57. safe_free(inst->odata);
  58. }
  59. table->ninstances = n;
  60. }
  61. /*
  62. * Initialize: default size
  63. */
  64. void init_instance_table(instance_table_t *table) {
  65. assert(DEF_INSTANCE_TABLE_SIZE < MAX_INSTANCE_TABLE_SIZE);
  66. table->size = DEF_INSTANCE_TABLE_SIZE;
  67. table->ninstances = 0;
  68. table->data = (instance_t *) safe_malloc(DEF_INSTANCE_TABLE_SIZE * sizeof(instance_t));
  69. init_int_htbl(&table->htbl, 0);
  70. }
  71. /*
  72. * Empty the table: delete all instance objects
  73. */
  74. void reset_instance_table(instance_table_t *table) {
  75. shrink_instance_table(table, 0);
  76. reset_int_htbl(&table->htbl);
  77. }
  78. /*
  79. * Delete the table
  80. */
  81. void delete_instance_table(instance_table_t *table) {
  82. shrink_instance_table(table, 0);
  83. safe_free(table->data);
  84. table->data = NULL;
  85. delete_int_htbl(&table->htbl);
  86. }
  87. /*
  88. * Allocate a new instance index i of instance size n
  89. * - vdata/odata are not initialized
  90. */
  91. int32_t instance_table_alloc(instance_table_t *table, uint32_t n) {
  92. uint32_t i;
  93. instance_t *inst;
  94. i = table->ninstances;
  95. if (i == table->size) {
  96. extend_instance_table(table);
  97. }
  98. assert(i < table->size);
  99. table->ninstances = i+1;
  100. inst = &table->data[i];
  101. inst->nelems = n;
  102. inst->vdata = (term_t *) safe_malloc(n * sizeof(term_t));
  103. inst->odata = (occ_t *) safe_malloc(n * sizeof(occ_t));
  104. return i;
  105. }
  106. /*
  107. * Deallocate the last instance
  108. */
  109. void instance_table_dealloc(instance_table_t *table) {
  110. uint32_t n;
  111. n = table->ninstances;
  112. assert(n > 0);
  113. shrink_instance_table(table, n-1);
  114. }
  115. /***************
  116. * UTILITIES *
  117. **************/
  118. /*
  119. * Check whether a and b are equal arrays
  120. * - both must have size n
  121. */
  122. static bool equal_arrays(int32_t *a, int32_t *b, uint32_t n) {
  123. uint32_t i;
  124. for (i=0; i<n; i++) {
  125. if (a[i] != b[i]) return false;
  126. }
  127. return true;
  128. }
  129. /*
  130. * Hash for an instance match
  131. */
  132. static uint32_t hash_instance(instance_hobj_t *o) {
  133. // return jenkins_hash_intarray2((int32_t *) o->odata, o->nelems, (uint32_t) (0x1ede2341 + o->compile_idx));
  134. uint32_t h1, h2;
  135. h1 = jenkins_hash_intarray2((int32_t *) o->odata, o->nelems, 0x1ede2341);
  136. h2 = jenkins_hash_intarray2((int32_t *) o->vdata, o->nelems, 0x4dde2341);
  137. return jenkins_hash_pair(h2, 0, h1);
  138. }
  139. /*
  140. * Check if instance object o is same as already present instance at index i
  141. */
  142. static bool equal_instance(instance_hobj_t *o, uint32_t i) {
  143. instance_table_t *table;
  144. instance_t *d;
  145. table = o->table;
  146. d = table->data + i;
  147. return d->nelems == o->nelems &&
  148. // d->compile_idx == o->compile_idx &&
  149. equal_arrays(o->odata, d->odata, d->nelems) &&
  150. equal_arrays(o->vdata, d->vdata, d->nelems);
  151. }
  152. static int32_t build_instance(instance_hobj_t *o) {
  153. instance_table_t *table;
  154. instance_t *d;
  155. uint32_t j, n;
  156. int32_t i;
  157. n = o->nelems;
  158. table = o->table;
  159. i = instance_table_alloc(table, n);
  160. d = table->data + i;
  161. d->compile_idx = o->compile_idx;
  162. for(j=0; j<n; j++) {
  163. d->vdata[j] = o->vdata[j];
  164. d->odata[j] = o->odata[j];
  165. }
  166. return i;
  167. }
  168. /*
  169. * Create or retrieve the instance
  170. */
  171. int32_t mk_instance(instance_table_t *table, int32_t compile_idx, uint32_t n, term_t *vdata, occ_t *odata) {
  172. instance_hobj_t inst_hobj;
  173. inst_hobj.m.hash = (hobj_hash_t) hash_instance;
  174. inst_hobj.m.eq = (hobj_eq_t) equal_instance;
  175. inst_hobj.m.build = (hobj_build_t) build_instance;
  176. inst_hobj.table = table;
  177. inst_hobj.compile_idx = compile_idx;
  178. inst_hobj.nelems = n;
  179. inst_hobj.vdata = vdata;
  180. inst_hobj.odata = odata;
  181. return int_htbl_get_obj(&table->htbl, (int_hobj_t *) &inst_hobj);
  182. }