| [12] | 1 | /**CFile*********************************************************************** | 
|---|
|  | 2 |  | 
|---|
|  | 3 | FileName    [smtSat.c] | 
|---|
|  | 4 |  | 
|---|
|  | 5 | PackageName [smt] | 
|---|
|  | 6 |  | 
|---|
|  | 7 | Synopsis    [Routines for smt function.] | 
|---|
|  | 8 |  | 
|---|
|  | 9 | Author      [Hyondeuk Kim] | 
|---|
|  | 10 |  | 
|---|
|  | 11 | Copyright   [Copyright (c) 1995-2004, Regents of the University of Colorado | 
|---|
|  | 12 |  | 
|---|
|  | 13 | All rights reserved. | 
|---|
|  | 14 |  | 
|---|
|  | 15 | Redistribution and use in source and binary forms, with or without | 
|---|
|  | 16 | modification, are permitted provided that the following conditions | 
|---|
|  | 17 | are met: | 
|---|
|  | 18 |  | 
|---|
|  | 19 | Redistributions of source code must retain the above copyright | 
|---|
|  | 20 | notice, this list of conditions and the following disclaimer. | 
|---|
|  | 21 |  | 
|---|
|  | 22 | Redistributions in binary form must reproduce the above copyright | 
|---|
|  | 23 | notice, this list of conditions and the following disclaimer in the | 
|---|
|  | 24 | documentation and/or other materials provided with the distribution. | 
|---|
|  | 25 |  | 
|---|
|  | 26 | Neither the name of the University of Colorado nor the names of its | 
|---|
|  | 27 | contributors may be used to endorse or promote products derived from | 
|---|
|  | 28 | this software without specific prior written permission. | 
|---|
|  | 29 |  | 
|---|
|  | 30 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
|---|
|  | 31 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
|---|
|  | 32 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | 
|---|
|  | 33 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | 
|---|
|  | 34 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | 
|---|
|  | 35 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | 
|---|
|  | 36 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 
|---|
|  | 37 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | 
|---|
|  | 38 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 
|---|
|  | 39 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | 
|---|
|  | 40 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 
|---|
|  | 41 | POSSIBILITY OF SUCH DAMAGE.] | 
|---|
|  | 42 |  | 
|---|
|  | 43 | ******************************************************************************/ | 
|---|
|  | 44 |  | 
|---|
|  | 45 | #ifdef HAVE_LIBGMP | 
|---|
|  | 46 |  | 
|---|
|  | 47 | #include "smt.h" | 
|---|
|  | 48 |  | 
|---|
|  | 49 | #define NEW_BLOCKING | 
|---|
|  | 50 |  | 
|---|
|  | 51 | int | 
|---|
|  | 52 | smt_call_theory_solver(satManager_t * m, long bound) | 
|---|
|  | 53 | { | 
|---|
|  | 54 | smtManager_t * sm = (smtManager_t *) m->SMTManager; | 
|---|
|  | 55 | int ret_val = 0; | 
|---|
|  | 56 |  | 
|---|
|  | 57 | if (sm->flag & IDL_MASK || sm->flag & RDL_MASK) | 
|---|
|  | 58 | ret_val = smt_call_dl_theory_solver(sm, bound); | 
|---|
|  | 59 | else | 
|---|
|  | 60 | exit(0); | 
|---|
|  | 61 |  | 
|---|
|  | 62 | return ret_val; | 
|---|
|  | 63 | } | 
|---|
|  | 64 |  | 
|---|
|  | 65 | int | 
|---|
|  | 66 | smt_call_dl_theory_solver(smtManager_t * sm, long bound) | 
|---|
|  | 67 | { | 
|---|
|  | 68 | satManager_t * cm = sm->cm; | 
|---|
|  | 69 | int needImplication; | 
|---|
|  | 70 | int lit, avar_lit, value; | 
|---|
|  | 71 | int i, id; | 
|---|
|  | 72 | int num_lit = 0; | 
|---|
|  | 73 |  | 
|---|
|  | 74 | if(cm->stackPos == 0) return(0); | 
|---|
|  | 75 |  | 
|---|
|  | 76 | smt_call_dl_theory_solver_preprocess(sm); | 
|---|
|  | 77 |  | 
|---|
|  | 78 | needImplication = 0; | 
|---|
|  | 79 |  | 
|---|
|  | 80 | /* send model to theory solver */ | 
|---|
|  | 81 | for(i = bound; i < cm->stackPos; i++) { | 
|---|
|  | 82 | lit = cm->decisionStack[i]; | 
|---|
|  | 83 | assert(lit>1); | 
|---|
|  | 84 | id = SATVar(lit); | 
|---|
|  | 85 | value = cm->values[id]; | 
|---|
|  | 86 | assert(value != 2); | 
|---|
|  | 87 |  | 
|---|
|  | 88 | if (id <= sm->avarArr->size) { | 
|---|
|  | 89 | if (sm->avalues[id] != value) { | 
|---|
|  | 90 | num_lit++; | 
|---|
|  | 91 | avar_lit = (value == 1) ? id : -id; | 
|---|
|  | 92 | sm->litArr = sat_array_insert(sm->litArr, avar_lit); | 
|---|
|  | 93 | sm->avalues[id] = value; | 
|---|
|  | 94 | } | 
|---|
|  | 95 | } | 
|---|
|  | 96 | } | 
|---|
|  | 97 |  | 
|---|
|  | 98 | if (num_lit == 0) | 
|---|
|  | 99 | return needImplication; | 
|---|
|  | 100 |  | 
|---|
|  | 101 | if (SATCurLevel(cm)==0) { | 
|---|
|  | 102 | sm->stats->num_lzero_ineq += num_lit; | 
|---|
|  | 103 | } | 
|---|
|  | 104 |  | 
|---|
|  | 105 | needImplication = smt_theory_solve(sm); | 
|---|
|  | 106 |  | 
|---|
|  | 107 | if ((int) sm->stats->num_bf_call%200000 == 0) | 
|---|
|  | 108 | smt_dl_report_intermediate_result(sm); | 
|---|
|  | 109 |  | 
|---|
|  | 110 | if(cm->explanation->size) { /** conflicting case **/ | 
|---|
|  | 111 |  | 
|---|
|  | 112 | /** | 
|---|
|  | 113 | * 1. add blocking clause info CNF database | 
|---|
|  | 114 | * 2. do conflict analysis with respect to blocking clause | 
|---|
|  | 115 | * 3. backtrack to backtracking level | 
|---|
|  | 116 | * 4. if needImplication==0, sat && no theory implication | 
|---|
|  | 117 | * 5. if needImplication==1, sat && theory implication | 
|---|
|  | 118 | * 6. if needImplication==2, unsat | 
|---|
|  | 119 | **/ | 
|---|
|  | 120 |  | 
|---|
|  | 121 | assert(cm->explanation->size>1); | 
|---|
|  | 122 |  | 
|---|
|  | 123 | if(SATCurLevel(cm) == 0) { | 
|---|
|  | 124 | cm->status = 0; | 
|---|
|  | 125 | return 2; | 
|---|
|  | 126 | } | 
|---|
|  | 127 |  | 
|---|
|  | 128 | smt_fit_decision_level_wrt_blocking_clause(cm, cm->explanation); | 
|---|
|  | 129 | #ifdef NEW_BLOCKING | 
|---|
|  | 130 | sat_add_blocking_clause_for_theorem_prover(cm, cm->explanation); | 
|---|
|  | 131 | #else | 
|---|
|  | 132 | c = sat_add_blocking_clause(cm, cm->explanation); | 
|---|
|  | 133 | bLevel = sat_conflict_analysis(cm, c); | 
|---|
|  | 134 | sat_undo(cm, bLevel); | 
|---|
|  | 135 |  | 
|---|
|  | 136 | csize = SATSizeClause(c); | 
|---|
|  | 137 | nMarks = 0; | 
|---|
|  | 138 | pLit = &(c->lits[0]); | 
|---|
|  | 139 | for(i = 0; i < csize; i++) { | 
|---|
|  | 140 | if(cm->values[((*pLit)>>1)] == 2) { | 
|---|
|  | 141 | nMarks++; | 
|---|
|  | 142 | iLit = (*pLit); | 
|---|
|  | 143 | } | 
|---|
|  | 144 | pLit++; | 
|---|
|  | 145 | } | 
|---|
|  | 146 | if(nMarks > 1) { | 
|---|
|  | 147 | c = sat_add_learned_clause(cm, cm->clearned); | 
|---|
|  | 148 | sat_update_variable_decay(cm); | 
|---|
|  | 149 | sat_update_clause_decay(cm); | 
|---|
|  | 150 | } | 
|---|
|  | 151 | else { | 
|---|
|  | 152 | if(cm->clearned->size == 1) { | 
|---|
|  | 153 | sat_enqueue(cm, iLit, 0); | 
|---|
|  | 154 | } | 
|---|
|  | 155 | else { | 
|---|
|  | 156 | sat_enqueue(cm, iLit, c); | 
|---|
|  | 157 | } | 
|---|
|  | 158 | } | 
|---|
|  | 159 | #endif | 
|---|
|  | 160 | needImplication = 2; | 
|---|
|  | 161 | } | 
|---|
|  | 162 |  | 
|---|
|  | 163 | return(needImplication); | 
|---|
|  | 164 | } | 
|---|
|  | 165 |  | 
|---|
|  | 166 | void | 
|---|
|  | 167 | smt_call_dl_theory_solver_preprocess(smtManager_t *sm) | 
|---|
|  | 168 | { | 
|---|
|  | 169 | satManager_t * cm = sm->cm; | 
|---|
|  | 170 |  | 
|---|
|  | 171 | sm->flag |= SAT_MASK; | 
|---|
|  | 172 | sm->lemma->size = 0; | 
|---|
|  | 173 | sm->tplits->size = 0; | 
|---|
|  | 174 | sm->cur_index = sm->litArr->size; | 
|---|
|  | 175 |  | 
|---|
|  | 176 | if (cm->explanation == 0) cm->explanation = sat_array_alloc(8); | 
|---|
|  | 177 | cm->explanation->size = 0; | 
|---|
|  | 178 | } | 
|---|
|  | 179 |  | 
|---|
|  | 180 | int | 
|---|
|  | 181 | smt_theory_solve(smtManager_t * sm) | 
|---|
|  | 182 | { | 
|---|
|  | 183 | int needImplication = 0; | 
|---|
|  | 184 |  | 
|---|
|  | 185 | if (sm->flag & IDL_MASK || sm->flag & RDL_MASK) { | 
|---|
|  | 186 |  | 
|---|
|  | 187 | if (sm->flag & MP_CONST_MASK) { | 
|---|
|  | 188 | #if 1 | 
|---|
|  | 189 | needImplication = smt_mp_dl_theory_solve(sm); | 
|---|
|  | 190 | #endif | 
|---|
|  | 191 | } else { | 
|---|
|  | 192 | if (sm->flag & IDL_MASK) | 
|---|
|  | 193 | needImplication = smt_idl_theory_solve(sm); | 
|---|
|  | 194 | else if (sm->flag & RDL_MASK) | 
|---|
|  | 195 | needImplication = smt_rdl_theory_solve(sm); | 
|---|
|  | 196 | } | 
|---|
|  | 197 |  | 
|---|
|  | 198 | } else { | 
|---|
|  | 199 | exit(0); | 
|---|
|  | 200 | } | 
|---|
|  | 201 |  | 
|---|
|  | 202 | return needImplication; | 
|---|
|  | 203 | } | 
|---|
|  | 204 |  | 
|---|
|  | 205 | void | 
|---|
|  | 206 | smt_fit_decision_level_wrt_blocking_clause( | 
|---|
|  | 207 | satManager_t * m, | 
|---|
|  | 208 | satArray_t * arr) | 
|---|
|  | 209 | { | 
|---|
|  | 210 | long i, csize, *pLit, bLevel; | 
|---|
|  | 211 |  | 
|---|
|  | 212 | csize = arr->size; | 
|---|
|  | 213 | pLit = &(arr->space[0]); | 
|---|
|  | 214 | bLevel = 0; | 
|---|
|  | 215 | for(i = 0; i < csize; i++) { | 
|---|
|  | 216 | if(m->levels[((*pLit)>>1)] > bLevel){ | 
|---|
|  | 217 | bLevel = m->levels[((*pLit)>>1)]; | 
|---|
|  | 218 | } | 
|---|
|  | 219 | pLit++; | 
|---|
|  | 220 | } | 
|---|
|  | 221 | sat_undo(m, bLevel); | 
|---|
|  | 222 | } | 
|---|
|  | 223 |  | 
|---|
|  | 224 | int | 
|---|
|  | 225 | smt_get_size_of_atomic_variable(satManager_t * cm) | 
|---|
|  | 226 | { | 
|---|
|  | 227 | smtManager_t *sm = (smtManager_t *) cm->SMTManager; | 
|---|
|  | 228 |  | 
|---|
|  | 229 | return(sm->avarArr->size); | 
|---|
|  | 230 | } | 
|---|
|  | 231 |  | 
|---|
|  | 232 | void | 
|---|
|  | 233 | smt_theory_undo(satManager_t * cm) | 
|---|
|  | 234 | { | 
|---|
|  | 235 | smtManager_t *sm = (smtManager_t *) cm->SMTManager; | 
|---|
|  | 236 |  | 
|---|
|  | 237 | if (sm->flag & IDL_MASK || sm->flag & RDL_MASK) { | 
|---|
|  | 238 | smt_dl_theory_undo(sm); | 
|---|
|  | 239 | } else { | 
|---|
|  | 240 | exit(0); | 
|---|
|  | 241 | } | 
|---|
|  | 242 | } | 
|---|
|  | 243 |  | 
|---|
|  | 244 | void | 
|---|
|  | 245 | smt_dl_theory_undo(smtManager_t * sm) | 
|---|
|  | 246 | { | 
|---|
|  | 247 | satManager_t * cm = sm->cm; | 
|---|
|  | 248 | smtGraph_t * G = sm->cG; | 
|---|
|  | 249 | smtAvar_t * avar; | 
|---|
|  | 250 | int lit, id; | 
|---|
|  | 251 | int i; | 
|---|
|  | 252 |  | 
|---|
|  | 253 | if (sm->litArr->size > 0) { | 
|---|
|  | 254 | /* | 
|---|
|  | 255 | init for smt_get_right_end_edge | 
|---|
|  | 256 | ignore unassigned edges | 
|---|
|  | 257 | */ | 
|---|
|  | 258 | G->esize = smt_get_right_end_edge_index(sm) + 1; | 
|---|
|  | 259 | } | 
|---|
|  | 260 |  | 
|---|
|  | 261 | for(i = sm->litArr->size-1; i >= 0; i--) { | 
|---|
|  | 262 | lit = sm->litArr->space[i]; | 
|---|
|  | 263 | id = (lit > 0) ? lit : -lit; | 
|---|
|  | 264 |  | 
|---|
|  | 265 | if(cm->values[id] != 2) { | 
|---|
|  | 266 | sm->litArr->size = i + 1; | 
|---|
|  | 267 | break; | 
|---|
|  | 268 | } | 
|---|
|  | 269 | avar = (smtAvar_t *) sm->id2var->space[id]; | 
|---|
|  | 270 |  | 
|---|
|  | 271 | /* check if avar is theory propagated */ | 
|---|
|  | 272 | if (avar->flag & TPROP_MASK || avar->flag & IMPLIED_MASK) { | 
|---|
|  | 273 | sm->avalues[id] = 2; | 
|---|
|  | 274 | avar->flag &= RESET_TPROP_MASK; | 
|---|
|  | 275 | avar->flag &= RESET_IMPLIED_MASK; | 
|---|
|  | 276 |  | 
|---|
|  | 277 | if(i==0) { | 
|---|
|  | 278 | sm->litArr->size=0; | 
|---|
|  | 279 | break; | 
|---|
|  | 280 | } | 
|---|
|  | 281 | continue; | 
|---|
|  | 282 | } | 
|---|
|  | 283 |  | 
|---|
|  | 284 | /* update constraint graph */ | 
|---|
|  | 285 | smt_update_edge_in_constraint_graph(sm, avar); | 
|---|
|  | 286 |  | 
|---|
|  | 287 | /* reset avar */ | 
|---|
|  | 288 | sm->avalues[id] = 2; | 
|---|
|  | 289 |  | 
|---|
|  | 290 | if(i==0) { | 
|---|
|  | 291 | sm->litArr->size=0; | 
|---|
|  | 292 | break; | 
|---|
|  | 293 | } | 
|---|
|  | 294 | } | 
|---|
|  | 295 |  | 
|---|
|  | 296 | sm->cur_index = sm->litArr->size; | 
|---|
|  | 297 |  | 
|---|
|  | 298 | return; | 
|---|
|  | 299 | } | 
|---|
|  | 300 |  | 
|---|
|  | 301 | void | 
|---|
|  | 302 | smt_update_edge_in_constraint_graph(smtManager_t * sm, smtAvar_t * avar) | 
|---|
|  | 303 | { | 
|---|
|  | 304 | satManager_t * cm = sm->cm; | 
|---|
|  | 305 | smtGraph_t * G = sm->cG; | 
|---|
|  | 306 | smtVertex_t * src, * dest; | 
|---|
|  | 307 | smtAvar_t * implied, * replacing = 0; | 
|---|
|  | 308 | smtNvar_t * lnvar, * rnvar; | 
|---|
|  | 309 | smtEdge_t *e; | 
|---|
|  | 310 | double iweight = 0, min_weight = 0; | 
|---|
|  | 311 | int dest_index, src_index; | 
|---|
|  | 312 | int id, i; | 
|---|
|  | 313 |  | 
|---|
|  | 314 | id = avar->id; | 
|---|
|  | 315 |  | 
|---|
|  | 316 | if (sm->avalues[id] == 1) { | 
|---|
|  | 317 | lnvar = (smtNvar_t *) avar->nvars->space[0]; | 
|---|
|  | 318 | rnvar = (smtNvar_t *) avar->nvars->space[1]; | 
|---|
|  | 319 | } else { | 
|---|
|  | 320 | assert(sm->avalues[id] == 0); | 
|---|
|  | 321 | lnvar = (smtNvar_t *) avar->nvars->space[1]; | 
|---|
|  | 322 | rnvar = (smtNvar_t *) avar->nvars->space[0]; | 
|---|
|  | 323 | } | 
|---|
|  | 324 |  | 
|---|
|  | 325 | src_index = rnvar->id - 1; | 
|---|
|  | 326 | dest_index = lnvar->id - 1; | 
|---|
|  | 327 | src = &(G->vHead[src_index]); | 
|---|
|  | 328 | dest = &(G->vHead[dest_index]); | 
|---|
|  | 329 | e = smt_find_edge(src, dest); | 
|---|
|  | 330 |  | 
|---|
|  | 331 | /** | 
|---|
|  | 332 | pick strongest implied atom for the replace | 
|---|
|  | 333 | implied is ordered in strength | 
|---|
|  | 334 | **/ | 
|---|
|  | 335 |  | 
|---|
|  | 336 | for(i = e->implied->size-1; i >= 0; i--) { | 
|---|
|  | 337 | implied = (smtAvar_t *) e->implied->space[i]; | 
|---|
|  | 338 | if (cm->values[implied->id] == 2) continue; | 
|---|
|  | 339 |  | 
|---|
|  | 340 | if (sm->avalues[implied->id] == 1) { | 
|---|
|  | 341 | iweight = implied->constant; | 
|---|
|  | 342 | } else if (sm->avalues[implied->id] == 0) { | 
|---|
|  | 343 | iweight = -implied->constant - sm->epsilon; | 
|---|
|  | 344 | } else | 
|---|
|  | 345 | exit(0); | 
|---|
|  | 346 |  | 
|---|
|  | 347 | min_weight = iweight; | 
|---|
|  | 348 | replacing = implied; | 
|---|
|  | 349 | e->implied->size = i; | 
|---|
|  | 350 |  | 
|---|
|  | 351 | break; | 
|---|
|  | 352 | } | 
|---|
|  | 353 |  | 
|---|
|  | 354 | if (replacing == 0) { /* no assigned implied atom */ | 
|---|
|  | 355 |  | 
|---|
|  | 356 | smt_delete_edge_in_constraint_graph(sm, e); | 
|---|
|  | 357 |  | 
|---|
|  | 358 | } else { /* replace edge : check replacing avar */ | 
|---|
|  | 359 |  | 
|---|
|  | 360 | e->avar = replacing; | 
|---|
|  | 361 | e->weight = min_weight; | 
|---|
|  | 362 | e->avar->flag &= RESET_IMPLIED_MASK; | 
|---|
|  | 363 |  | 
|---|
|  | 364 | } | 
|---|
|  | 365 |  | 
|---|
|  | 366 | return; | 
|---|
|  | 367 | } | 
|---|
|  | 368 |  | 
|---|
|  | 369 | void | 
|---|
|  | 370 | smt_delete_edge_in_constraint_graph(smtManager_t * sm, smtEdge_t * e) | 
|---|
|  | 371 | { | 
|---|
|  | 372 | smtGraph_t * G = sm->cG; | 
|---|
|  | 373 | smtVertex_t * src, * dest; | 
|---|
|  | 374 | smtEdge_t * rend_edge, * out, * in; | 
|---|
|  | 375 | int size, index; | 
|---|
|  | 376 | int i; | 
|---|
|  | 377 |  | 
|---|
|  | 378 | src = e->src; | 
|---|
|  | 379 | dest = e->dest; | 
|---|
|  | 380 |  | 
|---|
|  | 381 | size = src->outs->size; | 
|---|
|  | 382 |  | 
|---|
|  | 383 | /* delete from outgoing edge list of src */ | 
|---|
|  | 384 | for(i = 0; i < size; i++) { | 
|---|
|  | 385 | out = (smtEdge_t *) src->outs->space[i]; | 
|---|
|  | 386 | if (out == e) { | 
|---|
|  | 387 | src->outs->space[i] = src->outs->space[size-1]; | 
|---|
|  | 388 | src->outs->size--; | 
|---|
|  | 389 | break; | 
|---|
|  | 390 | } | 
|---|
|  | 391 | } | 
|---|
|  | 392 |  | 
|---|
|  | 393 | size = dest->ins->size; | 
|---|
|  | 394 |  | 
|---|
|  | 395 | /* delete from incoming edge list of dest */ | 
|---|
|  | 396 | for(i = 0; i < size; i++) { | 
|---|
|  | 397 | in = (smtEdge_t *) dest->ins->space[i]; | 
|---|
|  | 398 | if (in == e) { | 
|---|
|  | 399 | dest->ins->space[i] = dest->ins->space[size-1]; | 
|---|
|  | 400 | dest->ins->size--; | 
|---|
|  | 401 | break; | 
|---|
|  | 402 | } | 
|---|
|  | 403 | } | 
|---|
|  | 404 |  | 
|---|
|  | 405 | e->implied->size = 0; | 
|---|
|  | 406 | e->avar = 0; | 
|---|
|  | 407 | e->weight = 0; | 
|---|
|  | 408 |  | 
|---|
|  | 409 | index = e->index; | 
|---|
|  | 410 |  | 
|---|
|  | 411 | if (index >= G->esize) return; | 
|---|
|  | 412 | else rend_edge = smt_get_right_end_edge(sm); | 
|---|
|  | 413 |  | 
|---|
|  | 414 | /** move last edge to deleted edge location **/ | 
|---|
|  | 415 | if (rend_edge && rend_edge->index > index) { | 
|---|
|  | 416 | smt_put_right_end_edge_to_deleted(e, rend_edge); | 
|---|
|  | 417 | e->index = index; | 
|---|
|  | 418 | } | 
|---|
|  | 419 |  | 
|---|
|  | 420 | G->esize--; | 
|---|
|  | 421 |  | 
|---|
|  | 422 | return; | 
|---|
|  | 423 | } | 
|---|
|  | 424 |  | 
|---|
|  | 425 | smtEdge_t * | 
|---|
|  | 426 | smt_get_right_end_edge(smtManager_t * sm) | 
|---|
|  | 427 | { | 
|---|
|  | 428 | satManager_t * cm = sm->cm; | 
|---|
|  | 429 | smtGraph_t * G = sm->cG; | 
|---|
|  | 430 | smtEdge_t * e; | 
|---|
|  | 431 | smtAvar_t * avar; | 
|---|
|  | 432 | int i, j; | 
|---|
|  | 433 |  | 
|---|
|  | 434 | for(i = G->esize-1; i >= 0; i--) { | 
|---|
|  | 435 | e = &(G->eHead[i]); | 
|---|
|  | 436 | avar = e->avar; | 
|---|
|  | 437 | if (avar && cm->values[avar->id] != 2) { | 
|---|
|  | 438 | return e; | 
|---|
|  | 439 | } | 
|---|
|  | 440 |  | 
|---|
|  | 441 | /* check implied list if the implied one is assigned */ | 
|---|
|  | 442 | for(j = 0; j < e->implied->size; j++) { | 
|---|
|  | 443 | avar = (smtAvar_t *) e->implied->space[j]; | 
|---|
|  | 444 | if (sm->avalues[avar->id] != 2) { | 
|---|
|  | 445 | return e; | 
|---|
|  | 446 | } | 
|---|
|  | 447 | } | 
|---|
|  | 448 | e->implied->size = 0; | 
|---|
|  | 449 | } | 
|---|
|  | 450 |  | 
|---|
|  | 451 | return 0; | 
|---|
|  | 452 | } | 
|---|
|  | 453 |  | 
|---|
|  | 454 | int | 
|---|
|  | 455 | smt_get_right_end_edge_index(smtManager_t * sm) | 
|---|
|  | 456 | { | 
|---|
|  | 457 | satManager_t * cm = sm->cm; | 
|---|
|  | 458 | smtGraph_t * G = sm->cG; | 
|---|
|  | 459 | smtEdge_t * e; | 
|---|
|  | 460 | smtAvar_t * avar; | 
|---|
|  | 461 | int i, j; | 
|---|
|  | 462 |  | 
|---|
|  | 463 | for(i = G->esize-1; i >= 0; i--) { | 
|---|
|  | 464 | e = &(G->eHead[i]); | 
|---|
|  | 465 | avar = e->avar; | 
|---|
|  | 466 | if (cm->values[avar->id] != 2) { | 
|---|
|  | 467 | return i; | 
|---|
|  | 468 | } | 
|---|
|  | 469 | /* check implied list if the implied one is assigned */ | 
|---|
|  | 470 | for(j = 0; j < e->implied->size; j++) { | 
|---|
|  | 471 | avar = (smtAvar_t *) e->implied->space[j]; | 
|---|
|  | 472 | if (cm->values[avar->id] != 2) { | 
|---|
|  | 473 | return i; | 
|---|
|  | 474 | } | 
|---|
|  | 475 | } | 
|---|
|  | 476 | e->implied->size = 0; | 
|---|
|  | 477 | } | 
|---|
|  | 478 |  | 
|---|
|  | 479 | return 0; | 
|---|
|  | 480 | } | 
|---|
|  | 481 |  | 
|---|
|  | 482 | void | 
|---|
|  | 483 | smt_put_right_end_edge_to_deleted( | 
|---|
|  | 484 | smtEdge_t * deleted, | 
|---|
|  | 485 | smtEdge_t * rend_edge) | 
|---|
|  | 486 | { | 
|---|
|  | 487 | smtVertex_t * src, * dest; | 
|---|
|  | 488 | smtEdge_t * e; | 
|---|
|  | 489 | satArray_t * dimplied; | 
|---|
|  | 490 | int i; | 
|---|
|  | 491 |  | 
|---|
|  | 492 | src = rend_edge->src; | 
|---|
|  | 493 | dest = rend_edge->dest; | 
|---|
|  | 494 |  | 
|---|
|  | 495 | /* update outs of src */ | 
|---|
|  | 496 | for(i = 0; i < src->outs->size; i++) { | 
|---|
|  | 497 | e = (smtEdge_t *) src->outs->space[i]; | 
|---|
|  | 498 | if (e == rend_edge) { | 
|---|
|  | 499 | src->outs->space[i] = (long) deleted; | 
|---|
|  | 500 | break; | 
|---|
|  | 501 | } | 
|---|
|  | 502 | } | 
|---|
|  | 503 |  | 
|---|
|  | 504 | /* update ins of dest */ | 
|---|
|  | 505 | for(i = 0; i < dest->ins->size; i++) { | 
|---|
|  | 506 | e = (smtEdge_t *) dest->ins->space[i]; | 
|---|
|  | 507 | if (e == rend_edge) { | 
|---|
|  | 508 | dest->ins->space[i] = (long) deleted; | 
|---|
|  | 509 | break; | 
|---|
|  | 510 | } | 
|---|
|  | 511 | } | 
|---|
|  | 512 |  | 
|---|
|  | 513 | /* keep the index */ | 
|---|
|  | 514 | deleted->src = rend_edge->src; | 
|---|
|  | 515 | deleted->dest = rend_edge->dest; | 
|---|
|  | 516 |  | 
|---|
|  | 517 | dimplied = deleted->implied; | 
|---|
|  | 518 | deleted->implied = rend_edge->implied; | 
|---|
|  | 519 | rend_edge->implied = dimplied; | 
|---|
|  | 520 |  | 
|---|
|  | 521 | deleted->avar = rend_edge->avar; | 
|---|
|  | 522 |  | 
|---|
|  | 523 | deleted->weight = rend_edge->weight; | 
|---|
|  | 524 |  | 
|---|
|  | 525 | return; | 
|---|
|  | 526 | } | 
|---|
|  | 527 |  | 
|---|
|  | 528 | void | 
|---|
|  | 529 | smt_add_theory_clause( | 
|---|
|  | 530 | satManager_t * cm, | 
|---|
|  | 531 | smtAvar_t * avar, | 
|---|
|  | 532 | satArray_t * litArr) | 
|---|
|  | 533 | { | 
|---|
|  | 534 | long i, j, v, lit; | 
|---|
|  | 535 | long clevel; | 
|---|
|  | 536 | int addClause, sign; | 
|---|
|  | 537 | satClause_t * c; | 
|---|
|  | 538 | smtManager_t * sm = (smtManager_t *) cm->SMTManager; | 
|---|
|  | 539 |  | 
|---|
|  | 540 | addClause = 0; | 
|---|
|  | 541 | clevel = SATCurLevel(cm); | 
|---|
|  | 542 |  | 
|---|
|  | 543 | if(clevel == 0) { | 
|---|
|  | 544 | assert(sm->avalues[avar->id] != 2); | 
|---|
|  | 545 | if (sm->avalues[avar->id] == 0) { | 
|---|
|  | 546 | sign = 1; | 
|---|
|  | 547 | sat_enqueue(cm, (avar->id<<1)+sign, 0); | 
|---|
|  | 548 | avar->flag |= TPROP_MASK; | 
|---|
|  | 549 | sm->litArr = sat_array_insert(sm->litArr, -avar->id); | 
|---|
|  | 550 | sm->tplits = sat_array_insert(sm->tplits, -avar->id); | 
|---|
|  | 551 |  | 
|---|
|  | 552 | } else if (sm->avalues[avar->id] == 1){ | 
|---|
|  | 553 | sign = 0; | 
|---|
|  | 554 | sat_enqueue(cm, (avar->id<<1)+sign, 0); | 
|---|
|  | 555 | avar->flag |= TPROP_MASK; | 
|---|
|  | 556 | sm->litArr = sat_array_insert(sm->litArr, avar->id); | 
|---|
|  | 557 | sm->tplits = sat_array_insert(sm->tplits, avar->id); | 
|---|
|  | 558 | } | 
|---|
|  | 559 |  | 
|---|
|  | 560 | return; | 
|---|
|  | 561 | } | 
|---|
|  | 562 |  | 
|---|
|  | 563 | for(i=j=0; i < litArr->size; i++) { | 
|---|
|  | 564 | lit = litArr->space[i]; | 
|---|
|  | 565 | v = lit >> 1; | 
|---|
|  | 566 | if(cm->levels[v] != 0) { | 
|---|
|  | 567 | if(cm->levels[v] == clevel) | 
|---|
|  | 568 | addClause = 1; | 
|---|
|  | 569 | litArr->space[j++] = lit; | 
|---|
|  | 570 | } | 
|---|
|  | 571 | } | 
|---|
|  | 572 | litArr->size -= (i-j); | 
|---|
|  | 573 |  | 
|---|
|  | 574 | if(addClause == 0 || litArr->size < 2) { | 
|---|
|  | 575 | sm->avalues[avar->id] = 2; | 
|---|
|  | 576 |  | 
|---|
|  | 577 | return; | 
|---|
|  | 578 | } | 
|---|
|  | 579 |  | 
|---|
|  | 580 | if (sm->avalues[avar->id] == 0) { | 
|---|
|  | 581 | sign = 1; | 
|---|
|  | 582 | sat_enqueue(cm, (avar->id<<1)+sign, 0); | 
|---|
|  | 583 | avar->flag |= TPROP_MASK; | 
|---|
|  | 584 | sm->litArr = sat_array_insert(sm->litArr, -avar->id); | 
|---|
|  | 585 | sm->tplits = sat_array_insert(sm->tplits, -avar->id); | 
|---|
|  | 586 |  | 
|---|
|  | 587 | } else { | 
|---|
|  | 588 | sign = 0; | 
|---|
|  | 589 | sat_enqueue(cm, (avar->id<<1)+sign, 0); | 
|---|
|  | 590 | avar->flag |= TPROP_MASK; | 
|---|
|  | 591 | sm->litArr = sat_array_insert(sm->litArr, avar->id); | 
|---|
|  | 592 | sm->tplits = sat_array_insert(sm->tplits, avar->id); | 
|---|
|  | 593 | } | 
|---|
|  | 594 |  | 
|---|
|  | 595 | c = sat_add_theory_clause(cm, litArr); | 
|---|
|  | 596 |  | 
|---|
|  | 597 | cm->antes[avar->id] = c; | 
|---|
|  | 598 |  | 
|---|
|  | 599 | return; | 
|---|
|  | 600 | } | 
|---|
|  | 601 |  | 
|---|
|  | 602 | #endif | 
|---|