// Manipulation Helper Functions void V3SvrBoolector::setTargetValue(const V3NetId& id, const V3BitVecX& value, const uint32_t& depth, V3SvrDataVec& formula) { // Note : This Function will set formula such that AND(formula) represents (id == value) uint32_t size = value.size(); assert (size == _ntk->getNetWidth(id)); BtorExp* const aExp = getVerifyData(id, depth); assert (aExp); char* bv_value = new char[size + 1]; BtorExp *bExp, *cExp; uint32_t i = size, j = 0; while (i--) { if ('1' == value[i]) bv_value[j++] = '1'; else if ('0' == value[i]) bv_value[j++] = '0'; else if (j) { bv_value[j] = '\0'; bExp = boolector_slice(_Solver, aExp, i + j, i + 1); cExp = boolector_const(_Solver, bv_value); j = 0; formula.push_back(getPosExp(boolector_eq(_Solver, bExp, cExp))); boolector_release(_Solver, bExp); boolector_release(_Solver, cExp); } } if (j) { bv_value[j] = '\0'; if (j == size) bExp = boolector_copy(_Solver, aExp); else bExp = boolector_slice(_Solver, aExp, j - 1, 0); cExp = boolector_const(_Solver, bv_value); formula.push_back(getPosExp(boolector_eq(_Solver, bExp, cExp))); boolector_release(_Solver, bExp); boolector_release(_Solver, cExp); } delete[] bv_value; }
int main (void) { Btor *btor; BtorNode *array, *read, *max, *temp, *ugt, *formula, *index; BtorNode *indices[ARRAY1_EXAMPLE_ARRAY_SIZE]; int i, result; btor = boolector_new (); /* We create all possible constants that are used as read indices */ for (i = 0; i < ARRAY1_EXAMPLE_ARRAY_SIZE; i++) indices[i] = boolector_int (btor, i, ARRAY1_EXAMPLE_INDEX_BW); array = boolector_array (btor, ARRAY1_EXAMPLE_VALUE_BW, ARRAY1_EXAMPLE_INDEX_BW, NULL); /* Current maximum is first element of array */ max = boolector_read (btor, array, indices[0]); /* Symbolic loop unrolling */ for (i = 1; i < ARRAY1_EXAMPLE_ARRAY_SIZE; i++) { read = boolector_read (btor, array, indices[i]); ugt = boolector_ugt (btor, read, max); /* found a new maximum? */ temp = boolector_cond (btor, ugt, read, max); boolector_release (btor, max); max = temp; boolector_release (btor, read); boolector_release (btor, ugt); } /* Now we show that 'max' is indeed a maximum */ /* We read at an arbitrary position */ index = boolector_var (btor, ARRAY1_EXAMPLE_INDEX_BW, NULL); read = boolector_read (btor, array, index); /* We assume that it is possible that the read value is greater than 'max' */ formula = boolector_ugt (btor, read, max); /* We assert the formula and call Boolector */ boolector_assert (btor, formula); result = boolector_sat (btor); if (result == BOOLECTOR_UNSAT) printf ("Formula is unsatisfiable\n"); else abort (); /* clean up */ for (i = 0; i < ARRAY1_EXAMPLE_ARRAY_SIZE; i++) boolector_release (btor, indices[i]); boolector_release (btor, formula); boolector_release (btor, read); boolector_release (btor, index); boolector_release (btor, max); boolector_release (btor, array); assert (boolector_get_refs (btor) == 0); boolector_delete (btor); return 0; }
void V3SvrBoolector::assertProperty(const size_t& exp, const bool& invert) { if (invert ^ isNegFormula(exp)) { BtorExp* invExp = boolector_not(_Solver, getOriExp(exp)); boolector_assert(_Solver, invExp); boolector_release(_Solver, invExp); } else boolector_assert(_Solver, getOriExp(exp)); }
const size_t V3SvrBoolector::setTargetValue(const V3NetId& id, const V3BitVecX& value, const uint32_t& depth, const size_t& prev) { // Construct formula y = b0 & b1' & b3 & ... & bn', and return expr y if (prev) assert (!isNegFormula(prev)); // Constrain input prev expr should NOT be negative! uint32_t size = value.size(); assert (size == _ntk->getNetWidth(id)); BtorExp* const aExp = getVerifyData(id, depth); assert (aExp); BtorExp* pExp = (prev) ? boolector_copy(_Solver, getOriExp(prev)) : 0, *bExp, *cExp, *eExp; char* bv_value = new char[size + 1]; uint32_t i = size, j = 0; while (i--) { if ('1' == value[i]) bv_value[j++] = '1'; else if ('0' == value[i]) bv_value[j++] = '0'; else if (j) { bv_value[j] = '\0'; bExp = boolector_slice(_Solver, aExp, i + j, i + 1); cExp = boolector_const(_Solver, bv_value); eExp = boolector_eq(_Solver, bExp, cExp); boolector_release(_Solver, bExp); boolector_release(_Solver, cExp); if (pExp) { bExp = boolector_and(_Solver, pExp, eExp); boolector_release(_Solver, pExp); boolector_release(_Solver, eExp); pExp = bExp; } else pExp = eExp; j = 0; } } if (j) { bv_value[j] = '\0'; if (j == size) bExp = boolector_copy(_Solver, aExp); else bExp = boolector_slice(_Solver, aExp, j - 1, 0); cExp = boolector_const(_Solver, bv_value); eExp = boolector_eq(_Solver, bExp, cExp); boolector_release(_Solver, bExp); boolector_release(_Solver, cExp); if (pExp) { bExp = boolector_and(_Solver, pExp, eExp); boolector_release(_Solver, pExp); boolector_release(_Solver, eExp); pExp = bExp; } else pExp = eExp; } delete[] bv_value; assert (!isNegFormula(getPosExp(pExp))); return getPosExp(pExp); }
void V3SvrBoolector::add_FF_Formula(const V3NetId& out, const uint32_t& depth) { // Check Output Validation assert (validNetId(out)); assert (V3_FF == _ntk->getGateType(out)); assert (!getVerifyData(out, depth)); const uint32_t index = getV3NetIndex(out); assert (depth == _ntkData[index].size()); const uint32_t width = _ntk->getNetWidth(out); assert (width); if (_freeBound) { // Set BtorExp* _ntkData[index].push_back(boolector_var(_Solver, width, NULL)); } else if (depth) { // Build FF I/O Relation const V3NetId in1 = _ntk->getInputNetId(out, 0); assert (validNetId(in1)); BtorExp* const exp1 = getVerifyData(in1, depth - 1); assert (exp1); // Set BtorExp* _ntkData[index].push_back(boolector_copy(_Solver, exp1)); } else { // Set BtorExp* _ntkData[index].push_back(boolector_var(_Solver, width, NULL)); BtorExp* const exp = _ntkData[index].back(); assert (exp); // Build FF Initial State const V3NetId in1 = _ntk->getInputNetId(out, 1); assert (validNetId(in1)); const V3BvNtk* const ntk = dynamic_cast<const V3BvNtk*>(_ntk); if (ntk) { if (BV_CONST == ntk->getGateType(in1)) { const V3BitVecX* const value = ntk->getInputConstValue(in1); assert (value); assert (width == value->size()); char* bv_value = new char[width + 1]; bv_value[width] = '\0'; for (uint32_t i = 0, j = width - 1; i < width; ++i, --j) bv_value[j] = (*value)[i]; BtorExp* const init_exp = boolector_const(_Solver, bv_value); assert (init_exp); _init.push_back(boolector_eq(_Solver, exp, init_exp)); delete[] bv_value; boolector_release(_Solver, init_exp); } else { // Build Initial Circuit BtorExp* const exp1 = getVerifyData(in1, 0); assert (exp1); _init.push_back(boolector_eq(_Solver, exp, exp1)); } } else { if (AIG_FALSE == _ntk->getGateType(in1)) _init.push_back(!isV3NetInverted(in1) ? boolector_not(_Solver, exp) : boolector_copy(_Solver, exp)); else { // Build Initial Circuit BtorExp* const exp1 = getVerifyData(in1, 0); assert (exp1); _init.push_back(boolector_eq(_Solver, exp, exp1)); } } } assert (getVerifyData(out, depth)); }
const size_t V3SvrBoolector::setImplyIntersection(const V3SvrDataVec& Exps) { if (Exps.size() == 0) return 0; vector<size_t>::const_iterator it = Exps.begin(); assert (*it); BtorExp *aExp = (isNegFormula(*it) ? boolector_not(_Solver, getOriExp(*it)) : boolector_copy(_Solver, getOriExp(*it))); BtorExp *bExp, *oExp; ++it; for (; it != Exps.end(); ++it) { assert (*it); assert (aExp); bExp = (isNegFormula(*it) ? boolector_not(_Solver, getOriExp(*it)) : boolector_copy(_Solver, getOriExp(*it))); oExp = boolector_and(_Solver, aExp, bExp); assert (oExp); boolector_release(_Solver, aExp); boolector_release(_Solver, bExp); aExp = oExp; } bExp = boolector_var(_Solver, 1, NULL); oExp = boolector_implies(_Solver, bExp, aExp); boolector_assert(_Solver, oExp); boolector_release(_Solver, oExp); boolector_release(_Solver, aExp); assert (!isNegFormula(getPosExp(bExp))); assert (bExp); return getPosExp(bExp); }
int main () { int sat_result; BtorExp *array, *index1, *index2, *read1, *read2, *eq, *ne; Btor *btor; btor = boolector_new (); boolector_enable_inc_usage (btor); array = boolector_array (btor, ARRAY3_EXAMPLE_VALUE_BW, ARRAY3_EXAMPLE_INDEX_BW, NULL); index1 = boolector_var (btor, ARRAY3_EXAMPLE_INDEX_BW, NULL); index2 = boolector_var (btor, ARRAY3_EXAMPLE_INDEX_BW, NULL); read1 = boolector_read (btor, array, index1); read2 = boolector_read (btor, array, index2); eq = boolector_eq (btor, index1, index2); ne = boolector_ne (btor, read1, read2); /* we enforce that index1 is equal to index 2 */ boolector_assert (btor, eq); sat_result = boolector_sat (btor); assert (sat_result == BOOLECTOR_SAT); /* now we additionally assume that the read values differ * the instance is now unsatasfiable as read congruence is violated */ boolector_assume (btor, ne); sat_result = boolector_sat (btor); assert (sat_result == BOOLECTOR_UNSAT); /* after the SAT call the assumptions are gone * the instance is now satisfiable again */ sat_result = boolector_sat (btor); assert (sat_result == BOOLECTOR_SAT); boolector_release (btor, array); boolector_release (btor, index1); boolector_release (btor, index2); boolector_release (btor, read1); boolector_release (btor, read2); boolector_release (btor, eq); boolector_release (btor, ne); boolector_delete (btor); return 0; }
int main (void) { Btor *btor; BtorNode *x, *y, *temp, *old_x, *old_y, *eq1, *eq2, *and, *formula; int result; btor = boolector_new (); x = boolector_var (btor, BV1_EXAMPLE_NUM_BITS, NULL); y = boolector_var (btor, BV1_EXAMPLE_NUM_BITS, NULL); /* remember initial values of x and y */ old_x = boolector_copy (btor, x); old_y = boolector_copy (btor, y); /* x = x ^ y */ temp = boolector_xor (btor, x, y); boolector_release (btor, x); x = temp; /* y = x ^ y */ temp = boolector_xor (btor, x, y); boolector_release (btor, y); y = temp; /* x = x ^ y */ temp = boolector_xor (btor, x, y); boolector_release (btor, x); x = temp; /* Now, we have to show that old_x = y and old_y = x */ eq1 = boolector_eq (btor, old_x, y); eq2 = boolector_eq (btor, old_y, x); and = boolector_and (btor, eq1, eq2); /* In order to prove that this is a theorem, we negate the whole * formula and show that the negation is unsatisfiable */ formula = boolector_not (btor, and); /* We assert the formula and call Boolector */ boolector_assert (btor, formula); result = boolector_sat (btor); if (result == BOOLECTOR_UNSAT) printf ("Formula is unsatisfiable\n"); else abort (); /* cleanup */ boolector_release (btor, x); boolector_release (btor, old_x); boolector_release (btor, y); boolector_release (btor, old_y); boolector_release (btor, eq1); boolector_release (btor, eq2); boolector_release (btor, and); boolector_release (btor, formula); assert (boolector_get_refs (btor) == 0); boolector_delete (btor); return 0; }
int main (void) { Btor *btor; BoolectorNode *array1, *array2, *zero, *one, *val1, *val2; BoolectorNode *write1, *write2, *formula; char **indices, **values; int result, size, i; btor = boolector_new (); boolector_set_opt (btor, "model_gen", 1); zero = boolector_zero (btor, ARRAY2_EXAMPLE_INDEX_BW); one = boolector_one (btor, ARRAY2_EXAMPLE_INDEX_BW); val1 = boolector_int (btor, 3, ARRAY2_EXAMPLE_VALUE_BW); val2 = boolector_int (btor, 5, ARRAY2_EXAMPLE_VALUE_BW); array1 = boolector_array (btor, ARRAY2_EXAMPLE_VALUE_BW, ARRAY2_EXAMPLE_INDEX_BW, NULL); array2 = boolector_array (btor, ARRAY2_EXAMPLE_VALUE_BW, ARRAY2_EXAMPLE_INDEX_BW, NULL); write1 = boolector_write (btor, array1, zero, val1); write2 = boolector_write (btor, array2, one, val2); /* Note: we compare two arrays for equality ---> needs extensional theory */ formula = boolector_eq (btor, write1, write2); boolector_assert (btor, formula); result = boolector_sat (btor); if (result == BOOLECTOR_SAT) printf ("Formula is satisfiable\n"); else abort (); /* Formula is satisfiable, we can obtain array models: */ boolector_array_assignment (btor, array1, &indices, &values, &size); if (size > 0) { printf ("Array1:\n"); for (i = 0; i < size; i++) printf ("Array1[%s] = %s\n", indices[i], values[i]); boolector_free_array_assignment (btor, indices, values, size); } boolector_array_assignment (btor, array2, &indices, &values, &size); if (size > 0) { printf ("\nArray2:\n"); for (i = 0; i < size; i++) printf ("Array2[%s] = %s\n", indices[i], values[i]); boolector_free_array_assignment (btor, indices, values, size); } boolector_array_assignment (btor, write1, &indices, &values, &size); if (size > 0) { printf ("\nWrite1:\n"); for (i = 0; i < size; i++) printf ("Write1[%s] = %s\n", indices[i], values[i]); boolector_free_array_assignment (btor, indices, values, size); } boolector_array_assignment (btor, write2, &indices, &values, &size); if (size > 0) { printf ("\nWrite2:\n"); for (i = 0; i < size; i++) printf ("Write2[%s] = %s\n", indices[i], values[i]); boolector_free_array_assignment (btor, indices, values, size); } /* clean up */ boolector_release (btor, formula); boolector_release (btor, write1); boolector_release (btor, write2); boolector_release (btor, array1); boolector_release (btor, array2); boolector_release (btor, val1); boolector_release (btor, val2); boolector_release (btor, zero); boolector_release (btor, one); assert (boolector_get_refs (btor) == 0); boolector_delete (btor); return 0; }
int main (void) { Btor *btor; BtorNode *v1, *v2, *add, *zero, *vars_sgt_zero, *impl; BtorNode *v1_sgt_zero, *v2_sgt_zero, *add_sgt_zero, *formula; char *assignments[10]; int result, i; btor = boolector_new (); boolector_enable_model_gen (btor); v1 = boolector_var (btor, BV2_EXAMPLE_NUM_BITS, NULL); v2 = boolector_var (btor, BV2_EXAMPLE_NUM_BITS, NULL); zero = boolector_zero (btor, BV2_EXAMPLE_NUM_BITS); v1_sgt_zero = boolector_sgt (btor, v1, zero); v2_sgt_zero = boolector_sgt (btor, v2, zero); vars_sgt_zero = boolector_and (btor, v1_sgt_zero, v2_sgt_zero); add = boolector_add (btor, v1, v2); add_sgt_zero = boolector_sgt (btor, add, zero); impl = boolector_implies (btor, vars_sgt_zero, add_sgt_zero); /* We negate the formula and try to show that the negation is unsatisfiable */ formula = boolector_not (btor, impl); /* We assert the formula and call Boolector */ boolector_assert (btor, formula); result = boolector_sat (btor); if (result == BOOLECTOR_SAT) printf ("Instance is satisfiable"); else abort (); /* The formula is not valid, we have found a counter-example. * Now, we are able to obtain assignments to arbitrary expressions */ i = 0; assignments[i++] = boolector_bv_assignment (btor, zero); assignments[i++] = boolector_bv_assignment (btor, v1); assignments[i++] = boolector_bv_assignment (btor, v2); assignments[i++] = boolector_bv_assignment (btor, add); assignments[i++] = boolector_bv_assignment (btor, v1_sgt_zero); assignments[i++] = boolector_bv_assignment (btor, v2_sgt_zero); assignments[i++] = boolector_bv_assignment (btor, vars_sgt_zero); assignments[i++] = boolector_bv_assignment (btor, add_sgt_zero); assignments[i++] = boolector_bv_assignment (btor, impl); assignments[i++] = boolector_bv_assignment (btor, formula); i = 0; printf ("Assignment to 0: %s\n", assignments[i++]); printf ("Assignment to v1: %s\n", assignments[i++]); printf ("Assignment to v2: %s\n", assignments[i++]); printf ("Assignment to v1 + v2: %s\n", assignments[i++]); printf ("Assignment to v1 > 0: %s\n", assignments[i++]); printf ("Assignment to v2 > 0: %s\n", assignments[i++]); printf ("Assignment to v1 > 0 & v2 > 0: %s\n", assignments[i++]); printf ("Assignment to v1 + v2 > 0: %s\n", assignments[i++]); printf ("Assignment to v1 > 0 & v2 > 0 => v1 + v2 > 0: %s\n", assignments[i++]); printf ("Assignment to !(v1 > 0 & v2 > 0 => v1 + v2 > 0): %s\n", assignments[i++]); for (i = 0; i < 10; i++) boolector_free_bv_assignment (btor, assignments[i]); /* cleanup */ boolector_release (btor, zero); boolector_release (btor, v1); boolector_release (btor, v2); boolector_release (btor, add); boolector_release (btor, impl); boolector_release (btor, formula); boolector_release (btor, v1_sgt_zero); boolector_release (btor, v2_sgt_zero); boolector_release (btor, vars_sgt_zero); boolector_release (btor, add_sgt_zero); assert (boolector_get_refs (btor) == 0); boolector_delete (btor); return 0; }