/* recursively free a value */ void rfre_value (value val) { if (val == value_nil) return; val -> ref_count--; if (val -> ref_count) return; switch (val -> tag) { case tuple_value: rfre_value_list (val -> u.tuple); break; case large_lattice_value: rfre_int_list (val -> u.elat); default: break; }; val -> u.free = free_values; free_values = val; };
static tv_term build_term(const_gotcha_node current, const_tv_term_list_list systems) { register unsigned int ix; register unsigned int iy; int_list pos; int_list neg; tv_term result; if (systems->sz == 0) { return new_tv_term(new_int_list(), new_int_list()); } if (NULL == (result = rdup_tv_term(systems->arr[0]->arr[current->offsets[0]]))) { return NULL; } for (ix = 1; ix < current->depth; ix++) { iy = current->offsets[ix]; if (NULL == (pos = merge_sorted_int_list(result->pos, systems->arr[ix]->arr[iy]->pos))) { rfre_tv_term(result); return NULL; } if (NULL == (neg = merge_sorted_int_list(result->neg, systems->arr[ix]->arr[iy]->neg))) { rfre_tv_term(result); return NULL; } rfre_int_list(result->pos); rfre_int_list(result->neg); result->pos = pos; result->neg = neg; } return result; }
/* Finds the next array index, given a current index and the array extents. */ int_list advance_index(int_list indices, const_extent_list ranges, const_index_entry_list quantifier_indices, const_user_type_entry_list user_type_table) { register unsigned int ix; assert(indices->sz == ranges->sz); for (ix = indices->sz - 1; ix < indices->sz; ix--) { if (indices->arr[ix] < eval_int_expr(ranges->arr[ix]->to, quantifier_indices, user_type_table)) { indices->arr[ix] += 1; break; } indices->arr[ix] = eval_int_expr(ranges->arr[ix]->from, quantifier_indices, user_type_table); } if (ix >= indices->sz) { rfre_int_list(indices); return int_listNIL; } return indices; }
tv_nf pi_tison_trie(const_tv_nf cf) { unsigned int i, l, q, x, y, z; tv_nf result = truncate_copy_nf(cf); tv_literal_set_list input = get_literal_sets(cf); tv_literal_set_list output = get_literal_sets(result); tv_literal_set model; stack s, sx, sy; trie_node c, cx, cy; trie db = trie_new((trie_node_destroy_func_t)array_free, (trie_node_clone_func_t)array_copy); for (i = 0; i < input->sz; i++) { array l = literal_set_to_sorted_int_list(input->arr[i]); if (trie_is_subsumed(db, l)) { array_free(l); continue; } trie_remove_subsumed(db, l); trie_add(db, l, array_copy(l)); array_free(l); } trie_gc(db); /* We have the literal_sets in the trie now. */ if (db->root->edges == NULL) { trie_free(db); rfre_tv_nf(result); return rdup_tv_nf(cf); } for (l = 0; l < cf->variables->sz; l++) { sx = stack_new(NULL, NULL); /* Outer walk. */ stack_push(sx, db->root); while (NULL != (cx = stack_pop(sx))) { for (x = 0; x < cx->edges->sz; x++) { if (((trie_node)cx->kids->arr[x])->is_deleted) { continue; } if (((trie_node)cx->kids->arr[x])->is_terminal) { /* Inner walk. */ sy = stack_new(NULL, NULL); for (q = 0; q < sx->sz; q++) { stack_push(sy, sx->arr[q]); } stack_push(sy, cx); /* Finish the c level. */ z = x + 1; while (NULL != (cy = stack_pop(sy))) { for (y = z; y < cy->edges->sz; y++) { if (((trie_node)cy->kids->arr[y])->is_deleted) { continue; } if (((trie_node)cy->kids->arr[y])->is_terminal) { array r = resolve_int_list_literal(((trie_node)cx->kids->arr[x])->value, ((trie_node)cy->kids->arr[y])->value, l * 2); if (NULL == r) { continue; } if (trie_is_subsumed(db, r)) { array_free(r); continue; } trie_remove_subsumed(db, r); trie_add(db, r, array_copy(r)); array_free(r); } if (((trie_node)cy->kids->arr[y])->edges != NULL) { stack_push(sy, cy->kids->arr[y]); } } z = 0; } stack_free(sy); /* End of the inner walk. */ } if (((trie_node)cx->kids->arr[x])->edges != NULL) { stack_push(sx, cx->kids->arr[x]); } } } /* End of the outer walk. */ stack_free(sx); trie_gc(db); } assert(input->sz > 0); model = rdup_tv_literal_set(input->arr[0]); rfre_int_list(model->pos); rfre_int_list(model->neg); model->pos = int_listNIL; model->neg = int_listNIL; /* Convert the trie back to a clausal form. */ s = stack_new(NULL, NULL); stack_push(s, db->root); while (NULL != (c = stack_pop(s))) { for (i = 0; i < c->edges->sz; i++) { if (((trie_node)c->kids->arr[i])->is_terminal) { append_tv_literal_set_list(output, int_list_to_literal_set(((trie_node)c->kids->arr[i])->value, model)); } if (((trie_node)c->kids->arr[i])->edges != NULL) { stack_push(s, c->kids->arr[i]); } } } stack_free(s); trie_free(db); fre_tv_literal_set(model); set_literal_sets(result, output); return result; }
static int parse_DIMACS_file(FILE *f, tv_clause_list *clauses, variable_list *variables) { char buf[WORDSIZE + 1]; int lineno = 1; int start_of_line = 1; tv_clause_list cl = tv_clause_listNIL; int varcount; int tv_clausecount; int_list pos = new_int_list(); int_list neg = new_int_list(); for (;;) { int c = fgetc(f); int new_start_of_line = 0; if (c == EOF) { /* We're done. */ break; } if (c == '\n') { lineno++; new_start_of_line = 1; } if (start_of_line && c == 'p') { int res; /* A parameters line. */ if (cl != tv_clause_listNIL) { fprintf(stderr, "%d: Only one 'p' line allowed\n", lineno); return 0; } if ((res = fscanf(f, " cnf %d %d", &varcount, &tv_clausecount)) != 2) { fprintf( stderr, "%d: Malformed 'p' line\n", lineno ); return 0; } /* There should only be whitespace at this line. */ for (;;) { c = fgetc(f); if (c == '\n') { lineno++; new_start_of_line = 1; break; } } cl = setroom_tv_clause_list(new_tv_clause_list(), (unsigned int)tv_clausecount); } else if (start_of_line && c == 'c') { /* The start of a comment line. Eat the rest of it. */ for (;;) { c = fgetc( f ); if (c == EOF || c == '\n') { break; } } lineno++; new_start_of_line = 1; } else if (isspace(c)) { /* Skip. */ } else if (c == '-' || isdigit(c)) { read_word(f, c, buf, WORDSIZE); if (buf[0] == '-' && buf[1] == '\0') { /* A special case we want to complain about. */ fprintf( stderr, "%d: Solitary '-' ignored\n", lineno ); } else { if (buf[0] == '-') { int v = atoi(buf + 1); /* * We start counting the variables from '0', so * we need to do 'v-1'. */ neg = append_int_list(neg, v - 1); } else { int v = atoi(buf); if (v == 0) { /* * This terminates a tv_clause. Put it away, and * start a new one. */ if (cl != tv_clause_listNIL) { tv_clause c = new_tv_clause( pos, neg ); cl = append_tv_clause_list(cl, c); } pos = new_int_list(); neg = new_int_list(); } else { /* * We start counting the variables from '0', so * we need to do 'v-1'. */ pos = append_int_list(pos, v - 1); } } } } else { fprintf( stderr, "%d: Unexpected character '%c' ignored\n", lineno, c ); } start_of_line = new_start_of_line; } /* If there is a pending tv_clause, put it away. */ if (pos->sz != 0 || neg->sz != 0) { if (cl != tv_clause_listNIL) { tv_clause c = new_tv_clause(pos, neg); cl = append_tv_clause_list(cl, c); } } else { rfre_int_list(pos); rfre_int_list(neg); } *clauses = cl; *variables = build_dimacs_variable_list(varcount); return cl == tv_clause_listNIL ? 0 : 1; }
static void free_dpll_variable(dpll_variable var) { rfre_int_list(var->pos_clauses); rfre_int_list(var->neg_clauses); free(var); }