int dm_copy (const matrix_t *src, matrix_t *tgt) { tgt->rows = src->rows; tgt->cols = src->cols; tgt->bits_per_row = src->bits_per_row; tgt->row_perm.data = NULL; tgt->row_perm.count = NULL; tgt->col_perm.data = NULL; tgt->col_perm.count = NULL; tgt->bits.data = NULL; if (dm_copy_header (&(src->row_perm), &(tgt->row_perm))) { dm_free (tgt); return -1; } if (dm_copy_header (&(src->col_perm), &(tgt->col_perm))) { dm_free (tgt); return -1; } if (src->rows != 0 && src->cols != 0) { if (bitvector_copy (&(tgt->bits), &(src->bits))) { dm_free (tgt); return -1; } } else { bitvector_create(&(tgt->bits), 0); } return 0; }
static void add_basis (vector *bases, bitvector *a) { basis *b; b = (basis *) malloc (sizeof (basis)); assert (b != NULL); b->H = cdnfformula_disjunction_unit (); b->T = vector_new (0); b->a = bitvector_copy (a); vector_add (bases, b); }
int main (void) { bitvector_t b1; bitvector_t b2; bitvector_create (&b1, 20); user_bitvector_print (&b1); bitvector_set (&b1, 4); user_bitvector_print (&b1); bitvector_copy (&b2, &b1); bitvector_unset (&b1, 4); user_bitvector_print (&b1); user_bitvector_print (&b2); // test is_empty printf ("is_empty b1? %c (should be t)\n", bitvector_is_empty(&b1)?'t':'f'); printf ("is_empty b2? %c (should be f)\n", bitvector_is_empty(&b2)?'t':'f'); // set even/odd bits in b1/b2 for(int i=0; i<20; ++i) { if (i%2) { bitvector_set(&b1,i); } else { bitvector_set(&b2,i); } } // print before union printf ("before union\n"); user_bitvector_print (&b1); user_bitvector_print (&b2); // disjoint? printf ("b1,b2 are disjoint %c (should be t)\n", bitvector_is_disjoint(&b1, &b2)?'t':'f'); printf ("union\n"); bitvector_union(&b1, &b2); // disjoint? printf ("b1,b2 are disjoint %c (should be f)\n", bitvector_is_disjoint(&b1, &b2)?'t':'f'); // print after union user_bitvector_print (&b1); user_bitvector_print (&b2); printf ("intersect\n"); bitvector_intersect(&b1, &b2); // disjoint? printf ("b1,b2 are disjoint %c (should be f)\n", bitvector_is_disjoint(&b1, &b2)?'t':'f'); // print after intersection user_bitvector_print (&b1); user_bitvector_print (&b2); printf ("invert b1\n"); bitvector_invert(&b1); // print after inversion user_bitvector_print (&b1); // disjoint? printf ("b1,b2 are disjoint %c (should be t)\n", bitvector_is_disjoint(&b1, &b2)?'t':'f'); bitvector_free (&b2); bitvector_free (&b1); matrix_t m1; matrix_t m2; dm_create (&m1, 10, 10); print_matrix (&m1); printf ("dm_set(4,4)\n"); dm_set (&m1, 4, 4); print_matrix (&m1); printf ("dm_unset(4,4)\n"); dm_unset (&m1, 4, 4); print_matrix (&m1); printf ("test shift permutation (3,4,5)(6,7)\n"); printf ("before\n"); dm_set (&m1, 3, 3); dm_set (&m1, 4, 4); dm_set (&m1, 5, 5); dm_set (&m1, 6, 6); dm_set (&m1, 7, 7); print_matrix (&m1); printf ("after\n"); // create permutation_group, apply permutation_group_t o1; dm_create_permutation_group (&o1, 2, NULL); dm_add_to_permutation_group (&o1, 3); dm_add_to_permutation_group (&o1, 4); dm_add_to_permutation_group (&o1, 5); dm_close_group (&o1); dm_add_to_permutation_group (&o1, 6); dm_add_to_permutation_group (&o1, 7); dm_permute_cols (&m1, &o1); print_matrix (&m1); dm_free_permutation_group (&o1); printf ("swap cols 6,7\n"); dm_swap_cols (&m1, 6, 7); print_matrix (&m1); printf ("swap rows 6,7\n"); dm_swap_rows (&m1, 6, 7); print_matrix (&m1); printf ("copy\n"); dm_create(&m2, dm_nrows(&m1), dm_ncols(&m1)); dm_copy (&m1, &m2); // TODO: needs some more work print_matrix (&m2); dm_sort_rows (&m1, &min_row_first); print_matrix (&m1); dm_sort_rows (&m1, &max_row_first); print_matrix (&m1); dm_print_perm (&(m1.row_perm)); printf ("to nub rows added & resorted\n"); dm_set (&m1, 7, 3); dm_set (&m1, 8, 4); dm_sort_rows (&m1, &max_row_first); print_matrix (&m1); printf ("flatten \n"); dm_flatten (&m1); print_matrix (&m1); dm_print_perm (&(m1.row_perm)); printf ("nub sorted\n"); //dm_nub_rows (&m1, &eq_rows, NULL); print_matrix (&m1); dm_print_perm (&(m1.row_perm)); /* * printf("again, now to test row order & nub idx\n"); dm_free(&m1); * dm_create(&m1, 10, 10); dm_set(&m1, 0,0); dm_set(&m1, 1,0); * dm_set(&m1, 2,3); dm_set(&m1, 3,3); print_matrix(&m1); * * printf("nub sorted\n"); * * dm_nub_rows(&m1); * * print_matrix(&m1); * * dm_print_perm(&(m1.row_perm)); */ printf ("optimize sorted\n"); dm_set (&m1, 0, 7); dm_set (&m1, 1, 6); dm_set (&m1, 3, 9); printf ("before\n"); print_matrix (&m1); dm_optimize (&m1); printf ("after\n"); print_matrix (&m1); printf ("resorted\n"); dm_sort_rows (&m1, &max_row_first); print_matrix (&m1); /* dm_nub_cols(&m1); dm_ungroup_rows(&m1); dm_ungroup_cols(&m1); print_matrix (&m1); */ // get bitvector from matrix text bitvector_create (&b1, 6); bitvector_create (&b2, 10); printf ("bitvector of row 0\n"); user_bitvector_print (&b2); printf ("bitvector of col 8\n"); user_bitvector_print (&b1); bitvector_free (&b2); bitvector_free (&b1); printf ("count test\n"); for (int i = 0; i < dm_nrows (&m1); i++) printf ("ones in row %d: %d\n", i, dm_ones_in_row (&m1, i)); for (int i = 0; i < dm_ncols (&m1); i++) printf ("ones in col %d: %d\n", i, dm_ones_in_col (&m1, i)); printf ("iterator test\n"); dm_row_iterator_t mx; dm_col_iterator_t my; for (int i = 0; i < dm_nrows (&m1); i++) { printf ("iterator row: %d\n", i); dm_create_row_iterator (&mx, &m1, i); int r; while ((r = dm_row_next (&mx)) != -1) printf (" next: %d\n", r); printf ("\n\n"); } for (int i = 0; i < dm_ncols (&m1); i++) { printf ("iterator col: %d\n", i); dm_create_col_iterator (&my, &m1, i); int r; while ((r = dm_col_next (&my)) != -1) printf (" next: %d\n", r); printf ("\n\n"); } printf ("projection test\n"); int s0[10]; int src[10]; int prj[2]; int tgt[10]; // initialize for (int i = 0; i < 10; i++) { s0[i] = -i; src[i] = i; } // do projection int prj_n = dm_project_vector (&m1, 0, src, prj); // print projection printf ("projection:"); for (int i = 0; i < prj_n; i++) { printf (" %d", prj[i]); } printf ("\n"); printf ("expansion test\n"); // do expansion int exp_n = dm_expand_vector (&m1, 0, s0, prj, tgt); (void)exp_n; // print expansion printf ("expansion:"); for (int i = 0; i < 10; i++) { printf (" %d", tgt[i]); } printf ("\n"); // subsumption printf ("subsumption test:\n"); dm_swap_rows (&m1, 0, 3); dm_swap_rows (&m1, 1, 2); dm_flatten (&m1); print_matrix (&m1); dm_subsume_rows (&m1, &eq_rows, NULL); printf ("after subsumption:\n"); print_matrix (&m1); printf ("\n"); printf ("after ungrouping:\n"); dm_ungroup_rows (&m1); print_matrix (&m1); printf ("\n"); printf ("column sort test:\n"); dm_flatten (&m1); printf ("max col first:\n"); dm_sort_cols (&m1, &max_col_first); print_matrix (&m1); printf ("min col first:\n"); dm_sort_cols (&m1, &min_col_first); print_matrix (&m1); printf ("nub columns test:\n"); dm_set (&m1, 0, 1); dm_set (&m1, 3, 1); dm_set (&m1, 3, 4); dm_set (&m1, 3, 5); dm_sort_cols (&m1, &max_col_first); // dm_flatten(&m1); printf ("max col first:\n"); print_matrix (&m1); //printf ("subsume columns:\n"); //dm_subsume_cols (&m1, &eq_cols, NULL); //dm_subsume_rows (&m1, &eq_rows, NULL); print_matrix (&m1); printf ("column permutation:\n"); dm_print_perm (&(m1.col_perm)); printf ("optimize columns:\n"); dm_optimize (&m1); print_matrix (&m1); //printf ("ungroup columns:\n"); //dm_ungroup_cols (&m1); //print_matrix (&m1); //printf ("all permutations:\n"); //dm_set (&m1, 0, 9); //dm_nub_cols(&m1, &eq_cols, NULL); //print_matrix (&m1); //dm_all_perm (&m1); dm_free (&m2); dm_free (&m1); return 0; }
boolformula_t *learn_core (void *info, uscalar_t num_vars, membership_t membership, membership_t comembership, equivalence_t equivalence, int mode) { equivalence_result_t *eq_result; conjunction *conjecture; vector *bases; bases = vector_new (0); conjecture = get_conjecture (bases); boolformula_t* b_conjecture = cdnfformula_to_boolformula (conjecture); vector_free (conjecture); eq_result = (*equivalence) (info, num_vars, boolformula_copy (b_conjecture)); if (eq_result->is_equal) { //fprintf(stderr,"Number of Variables Used : %d\n", (unsigned int)num_vars); free(eq_result); return b_conjecture; } else { boolformula_free(b_conjecture); } #ifdef DEBUG fprintf (stderr, "add first basis with "); bitvector_print (eq_result->counterexample); #endif assert (bitvector_length (eq_result->counterexample) == num_vars + 1); add_basis (bases, eq_result->counterexample); bitvector_free (eq_result->counterexample); free(eq_result); while (true) { vector *I; bitvector *v; uscalar_t j, length; conjecture = get_conjecture (bases); #ifdef DEBUG fprintf (stderr, "new conjecture = "); boolformula_print (conjecture); #endif boolformula_t* b_conjecture = cdnfformula_to_boolformula (conjecture); vector_free (conjecture); eq_result = (*equivalence) (info, num_vars, boolformula_copy (b_conjecture)); if (eq_result->is_equal) { //fprintf(stderr,"Number of Variables Used : %d\n", (unsigned int)num_vars); cleanup (bases); free (eq_result); return b_conjecture; } else { boolformula_free(b_conjecture); } /* H_i's are still in bases, only free the conjunction */ assert (bitvector_length (eq_result->counterexample) == num_vars + 1); v = eq_result->counterexample; I = get_indices_to_modify (bases, v); if (vector_length (I) == 0) { if(mode==CDNF_Plus3 && (*membership)(info,v)==true) { #ifdef DEBUG fprintf (stderr, "conflict detected on: "); bitvector_print (v); fprintf (stderr, "num of variables: %d \n",num_vars); #endif refine_bases(info, membership,comembership,bases,mode); num_vars++; } else { #ifdef DEBUG fprintf (stderr, "add basis: "); bitvector_print (v); #endif add_basis (bases, v); } bitvector_free (v); free(eq_result); vector_free (I); continue; } free(eq_result); #ifdef DEBUG fprintf (stderr, "fix m_dnf with "); bitvector_print (v); #endif length = vector_length (I); for (j = 0; j < length; j++) { uscalar_t i; basis *B; bitvector *a_i, *v_i, *xor; vector *T_i; disjunction *H_i; monomial *m; i = (uscalar_t) vector_get (I, j); B = (basis *) vector_get (bases, i); a_i = B->a; T_i = B->T; H_i = B->H; v_i = bitvector_copy (v); walk (info, membership, v_i, a_i); xor = bitvector_xor (v_i, a_i); /* when xor == 0, a conflict has occurred. */ /* assert (!bitvector_is_zeros (xor)); */ if (bitvector_is_zeros (xor)) { #ifdef DEBUG fprintf (stderr, "conflict with the basis "); bitvector_print (a_i); #endif bitvector_free (xor); bitvector_free (v_i); if(mode==CDNF_PlusPlus||mode==CDNF_Plus3) { /* increase the number of variables */ #ifdef DEBUG fprintf (stderr, "num of variables: %d \n",num_vars); #endif refine_bases (info, membership, comembership, bases,mode); num_vars++; } else { bitvector_free (v); vector_free (I); return NULL; } break; } #ifdef DEBUG fprintf (stderr, "add support "); bitvector_print (v_i); #endif /* store v_i in T_i */ /* note that the original CDNF algorithm stores xor in S_i */ vector_add (T_i, v_i); /* compute M_DNF (v_i + a_i) */ m = cdnfformula_monomial_M_DNF (xor); /* compute m (x ^ a_i) */ m = compute_m_of_x_xor_a (m, a_i); vector_add (H_i, m); bitvector_free (xor); } bitvector_free (v); vector_free (I); } }
static void initialize_levels(bitvector_t *groups, int *empty_groups, int *back, bitvector_t *reach_groups) { int level[nGrps]; // groups: i = 0 .. nGrps - 1 // vars : j = 0 .. N - 1 // level[i] = first '+' in row (highest in BDD) of group i // recast 0 .. N - 1 down to equal groups 0 .. (N - 1) / sat_granularity for (int i = 0; i < nGrps; i++) { level[i] = -1; for (int j = 0; j < N; j++) { if (dm_is_set(GBgetDMInfo(model), i, j)) { level[i] = (N - j - 1) / sat_granularity; break; } } if (level[i] == -1) level[i] = 0; } for (int i = 0; i < nGrps; i++) bitvector_set(&groups[level[i]], i); // Limit the bit vectors to the groups we are interested in and establish // which saturation levels are not used. for (int k = 0; k < max_sat_levels; k++) { bitvector_intersect(&groups[k], reach_groups); empty_groups[k] = bitvector_is_empty(&groups[k]); } if (back == NULL) return; // back[k] = last + in any group of level k bitvector_t level_matrix[max_sat_levels]; for (int k = 0; k < max_sat_levels; k++) { bitvector_create(&level_matrix[k], N); back[k] = max_sat_levels; } for (int i = 0; i < nGrps; i++) { dm_row_union(&level_matrix[level[i]], GBgetDMInfo(model), i); } for (int k = 0; k < max_sat_levels; k++) { for (int j = 0; j < k; j++) { bitvector_t temp; int empty; bitvector_copy(&temp, &level_matrix[j]); bitvector_intersect(&temp, &level_matrix[k]); empty = bitvector_is_empty(&temp); bitvector_free(&temp); if (!empty) if (j < back[k]) back[k] = j; } if (back[k] == max_sat_levels && !bitvector_is_empty(&level_matrix[k])) back[k] = k + 1; } for (int k = 0; k < max_sat_levels; k++) bitvector_free(&level_matrix[k]); }