/** A = x1 and x2 and ... xn create cnf to create an Equility. * @brief Solver::SatBaseClass::createTseitinOr * @param vars x1, ..., xn * @return A */ uint Solver::SatBaseClass::createTseitinAnd(std::multiset<literal>& vars){ if(vars.size() == 0) return getTrueVar(); uint A(++countVars); // if A is true, then all of the xi must be true result << A << " "; for(const literal& t: vars){ if(t.positiv){ result << "-" << t.varId << " "; }else { result << t.varId << " "; } } result << "0" << std::endl; countClausel++; // if one of the xi is false then A is false for(const literal& t: vars){ result << "-" << A << " "; if(t.positiv){ result << t.varId << " 0" << std::endl; } else { result << "-" << t.varId << " 0" << std::endl; } countClausel++; } return A; }
void Solver::SatBaseClass::readSolutionOther(const std::string &solutionFile){ std::string line; std::ifstream fileIn ( solutionFile ); while(!fileIn.eof()){ std::getline( fileIn, line ); if(line.empty()) continue; if(line[0] == 'c') continue; if(line[0] == 's') { std::transform(line.begin(), line.end(), line.begin(), ::tolower); if(line.find("unsat") != std::string::npos){ throw Exception::StringException("UNSAT"); std::cerr << line << std::endl; break; } } if(line[0] == 'v'){ line = line.substr(2); std::vector<std::string> solution = split( line, ' '); for( const std::string& s : solution ) { if(s.empty()) continue; if( s == "0") { break; } // skip negativ vars if( s[0] == '-' ) continue; uint varAsInt = std::stoi(s)-1; if(varAsInt == getTrueVar()) continue; if(varAsInt == 0) continue; if(varAsInt >= intToVar.size()) break; PosInt varAsPos = intToVar[varAsInt]; std::cout << "Ausgabe der Pos " << varAsInt << ": " << varAsPos << std::endl; gameField.getTileById(varAsPos.getValue()).setSolutionX(varAsPos.getX()); gameField.getTileById(varAsPos.getValue()).setSolutionY(varAsPos.getY()); } } } }
void Solver::SatBaseClass::readSolutionGlucose(const std::string& solutionFile){ std::string line; std::ifstream fileIn ( solutionFile.c_str()); if (fileIn.is_open()){ getline( fileIn, line ); // if it is not solved if( line == "UNSAT" ){ throw Exception::StringException("UNSAT"); std::cout << line << std::endl; // read solution }else if( line == "SAT" ){ getline( fileIn, line ); std::vector<std::string> solution = split( line, ' '); for( const std::string& s : solution ){ if( s == "0"){ break; } // skip negativ vars if( s[0] == '-' ) continue; uint varAsInt = std::stoi(s); if(varAsInt == getTrueVar()) continue; if(varAsInt >= intToVar.size()) break; PosInt varAsPos = intToVar[varAsInt]; gameField.getTileById(varAsPos.getValue()).setSolutionX(varAsPos.getX()); gameField.getTileById(varAsPos.getValue()).setSolutionY(varAsPos.getY()); } } fileIn.close(); }else { std::cerr << "Solver: Unable to open file" << std::endl; } }
void Solver::toSatDebug::createDimacs(const std::string& fileName){ // Exactly One uint sizeX(gameField.getField().getSizeX()); uint sizeY(gameField.getField().getSizeY()); for(const Tile& t: gameField.getTiles()){ std::set<PosInt> buffer; for(uint x=0; x<=sizeX - t.getSizeX(); ++x){ for(uint y=0; y<=sizeY - t.getSizeY(); ++y){ buffer.insert(PosInt(x,y,t.getId())); } } getExactlyOne(buffer); } // Modulo Contraint for(uint fieldX = 0; fieldX < sizeX; ++fieldX){ for(uint fieldY = 0; fieldY < sizeY; ++fieldY){ std::vector<Solver::literal> bufferForVar; for(const Tile& t: gameField.getTiles()){ // Variablen in Buffer Set schreiben std::multiset<Solver::literal> bufferOr; for(uint tileX=0; tileX <= fieldX; ++tileX){ if(tileX + t.getSizeX() > sizeX) break; for(uint tileY=0; tileY<=fieldY; ++tileY){ if(tileY + t.getSizeY() > sizeY) break; if(t.getField( fieldX - tileX, fieldY - tileY)){ Solver::literal lit; lit.positiv = true; lit.varId = varToInt[PosInt(tileX, tileY, t.getId())]; bufferOr.insert(lit); } } } Solver::literal lit; lit.varId =createTseitinOr(bufferOr); lit.positiv = true; bufferForVar.push_back(lit); // Set start value } if(gameField.getField().getField(fieldX,fieldY) != 0){ for(int i=0; i <gameField.getField().getField(fieldX,fieldY); ++i ){ std::cout << "Add: (" << fieldX << ", " << fieldY << ") " << i << " " << (int)gameField.getField().getField(fieldX, fieldY) << std::endl; Solver::literal lit; lit.varId =getTrueVar(); lit.positiv = true; bufferForVar.push_back(lit); } } // generierung der Ausgänge #if COMMENTSDEBUG == 1 result << "c" << std::endl; result << "c Decode at Position (" << fieldX << ", " << fieldY << ")" << std::endl; result << "c" << std::endl; #endif createModuloNAdderHalf(bufferForVar, gameField.getField().getMod()); } } /************************************************************************************************** * Debug * * ***********************************************************************************************/ uint fieldX = 0; uint fieldY = 0; std::vector<Solver::literal> bufferForVar; for(const Tile& t: gameField.getTiles()){ // Variablen in Buffer Set schreiben std::multiset<Solver::literal> bufferOr; for(uint tileX=0; tileX <= fieldX; ++tileX){ if(tileX + t.getSizeX() > sizeX) break; for(uint tileY=0; tileY<=fieldY; ++tileY){ if(tileY + t.getSizeY() > sizeY) break; if(t.getField( fieldX - tileX, fieldY - tileY)){ Solver::literal lit; lit.positiv = true; lit.varId = varToInt[PosInt(tileX, tileY, t.getId())]; bufferOr.insert(lit); } } } Solver::literal lit; lit.varId =createTseitinOr(bufferOr); lit.positiv = true; bufferForVar.push_back(lit); // Set start value } if(gameField.getField().getField(fieldX,fieldY) != 0){ for(int i=0; i <gameField.getField().getField(fieldX,fieldY); ++i ){ std::cout << "Add: (" << fieldX << ", " << fieldY << ") " << i << " " << (int)gameField.getField().getField(fieldX, fieldY) << std::endl; Solver::literal lit; lit.varId =getTrueVar(); lit.positiv = true; bufferForVar.push_back(lit); } } // generierung der Ausgänge #if COMMENTSDEBUG == 1 result << "c" << std::endl; result << "c Decode at Position (" << fieldX << ", " << fieldY << ")" << std::endl; result << "c" << std::endl; #endif createModuloNAdderHalf(bufferForVar, gameField.getField().getMod()); //*/ // write it into file std::fstream data; data.open(fileName, std::ios::out); data << "p cnf " << countVars << " " << countClausel << std::endl; data << result.str().c_str(); data.close(); }
bool my_walker(Node *node, context_walker_set_constraint *context){ if (node == NULL) return false; /* elog(LOG,"tag : %d\n",nodeTag(node)); */ if(IsA(node,BoolExpr)){ BoolExpr * bExpr =(BoolExpr *) node; bool retour = false; List * l_true_save = NULL; List * l_false_save = NULL; List * l_true = NULL; List * l_false = NULL; int nb_arg = bExpr->args->length; switch(bExpr->boolop){ case NOT_EXPR: /*(Unicité des valeur) Setisation sur le true*/ /*Pre Traitement*/ l_true_save = context->list_of_not_null_to_be_true; l_false_save = context->list_of_not_null_to_be_false; context->list_of_not_null_to_be_true = NULL; context->list_of_not_null_to_be_false = NULL; /*Traitement*/ retour = expression_tree_walker(node, my_walker, (void *) context); /*Post Traitement*/ /* elog(LOG,"\n List_false_before : %s\n",nodeToString(context->list_of_not_null_to_be_false)); */ /* elog(LOG,"\n List_true_before : %s\n",nodeToString(context->list_of_not_null_to_be_true)); */ l_true = context->list_of_not_null_to_be_true; l_false = context->list_of_not_null_to_be_false; context->list_of_not_null_to_be_true = list_concat(l_true_save,l_false); context->list_of_not_null_to_be_false = list_concat(l_false_save,l_true); /* elog(LOG,"\n List_false : %s\n",nodeToString(context->list_of_not_null_to_be_false)); */ /* elog(LOG,"\n List_true : %s\n",nodeToString(context->list_of_not_null_to_be_true)); */ return retour; break; case AND_EXPR: /*(Unicité des valeur) Setisation sur le true*/ /*Pre Traitement*/ l_true_save = context->list_of_not_null_to_be_true; l_false_save = context->list_of_not_null_to_be_false; context->list_of_not_null_to_be_true = NULL; context->list_of_not_null_to_be_false = NULL; /*Traitement*/ retour = expression_tree_walker(node, my_walker, (void *) context); /*Post traitement*/ /* elog(LOG,"\n List_false_before : %s\n",nodeToString(context->list_of_not_null_to_be_false)); */ /* elog(LOG,"\n List_true_before : %s\n",nodeToString(context->list_of_not_null_to_be_true)); */ l_true = union_list(context->list_of_not_null_to_be_true); l_false = inter_list(context->list_of_not_null_to_be_false,nb_arg); context->list_list_true = lappend(context->list_list_true,l_true); context->list_list_false = lappend(context->list_list_false,l_false); context->list_of_not_null_to_be_true = list_concat(l_true_save,l_true); context->list_of_not_null_to_be_false = list_concat(l_false_save,l_false); /* elog(LOG,"\n nb_arg : %d\n",nb_arg); */ /* elog(LOG,"\n List_false : %s\n",nodeToString(context->list_of_not_null_to_be_false)); */ /* elog(LOG,"\n List_true : %s\n",nodeToString(context->list_of_not_null_to_be_true)); */ return retour; break; case OR_EXPR: /*(Unicité des valeur) Setisation sur le true*/ /*Pre Traitement*/ l_true_save = context->list_of_not_null_to_be_true; l_false_save = context->list_of_not_null_to_be_false; context->list_of_not_null_to_be_true = NULL; context->list_of_not_null_to_be_false = NULL; /*Traitement*/ retour = expression_tree_walker(node, my_walker, (void *) context); /*Post traitement*/ /* elog(LOG,"\n List_false_before : %s\n",nodeToString(context->list_of_not_null_to_be_false)); */ /* elog(LOG,"\n List_true_before : %s\n",nodeToString(context->list_of_not_null_to_be_true)); */ l_true = inter_list(context->list_of_not_null_to_be_true,nb_arg); l_false = union_list(context->list_of_not_null_to_be_false); context->list_list_true = lappend(context->list_list_true,l_true); context->list_list_false = lappend(context->list_list_false,l_false); context->list_of_not_null_to_be_true = list_concat(l_true_save,l_true); context->list_of_not_null_to_be_false = list_concat(l_false_save,l_false); /* elog(LOG,"\n nb_arg : %d\n",nb_arg); */ /* elog(LOG,"\n List_false : %s\n",nodeToString(context->list_of_not_null_to_be_false)); */ /* elog(LOG,"\n List_true : %s\n",nodeToString(context->list_of_not_null_to_be_true)); */ return retour; break; } } if(context->ready && IsA(node,Var)){ /* elog(LOG," \n HERE1 \n"); */ Var * v = getTrueVar(context->current_trueVar,(Var *)node); /* elog(LOG," \n HERE2 \n"); */ if(!isInListTrueVar(context->list_of_not_null_in_op,v)){ context->list_of_not_null_in_op = lappend(context->list_of_not_null_in_op,v); } return expression_tree_walker(node, my_walker, (void *) context); } if(IsA(node,OpExpr)){ OpExpr * oExpr = (OpExpr *)node; if(oExpr->opno == 518 /*<>*/){ context->ready = true; context->list_of_not_null_in_op = NULL; bool retour = expression_tree_walker(node, my_walker, (void *) context); context->list_of_not_null_to_be_true = list_concat(context->list_of_not_null_to_be_true,context->list_of_not_null_in_op); return retour; } else{ return expression_tree_walker(node, my_walker, (void *) context); } /* elog(LOG,"\n List_op : %s\n",nodeToString(context->list_of_not_null_in_op)); */ } if(IsA(node,Query)){ Query * q = (Query *) node; /*Prétraitement*/ List * save_current_trueVar = context->current_trueVar; context->current_trueVar = NULL; context->current_trueVar = lappend(context->current_trueVar,save_current_trueVar); /*Traitement*/ /*Create trueVars and not_null schema*/ bool result = expression_tree_walker((Node *)q->rtable, my_walker, (void *) context); /* elog(LOG,"\n TRUE ATT :%s\n",nodeToString(context->trueVars)); */ context->trueVars = lappend(context->trueVars,context->current_trueVar); /* elog(LOG,"\nTRUE ATT :%s \n",nodeToString(context->trueVars)); */ /*Propagate*/ result = expression_tree_walker((Node *)q->jointree, my_walker, (void *) context) | result; /* elog(LOG,"\n LIST_LIST_TRUE :%s\n",nodeToString(context->list_list_true)); */ /* elog(LOG,"\n LIST_LIST_FALSE :%s\n",nodeToString(context->list_list_false)); */ /*Post Traitement*/ context->current_trueVar = save_current_trueVar; return result; } if(IsA(node,RangeTblEntry)){ RangeTblEntry * rte = (RangeTblEntry *)node; Oid relid= rte->relid; int number_col = get_relnatts(relid); AttrNumber i = 0; List * relation = NULL; for(i=1;i<=number_col;i++){ /*Create True_var*/ Var * v = makeNode(Var); v->varattno = i; /* v->varattno = context->current_varattno; */ v->vartype = relid; relation = lappend(relation,v); /*Add to not_null if needed*/ if(get_pg_att_not_null(relid,i)){ context->list_of_not_null_att_schem = lappend(context->list_of_not_null_att_schem,v); } } context->current_trueVar = lappend(context->current_trueVar,relation); /* elog(LOG,"\n TEST: %s \n",nodeToString(context->current_trueVar)); */ return false; } return expression_tree_walker(node, my_walker, (void *) context); }
Node * my_mutator (Node *node, context_modifier *context) { if (node == NULL) return NULL; /* elog(LOG,"%d",nodeTag(node)); */ if(IsA(node,BoolExpr)){ BoolExpr * bExpr =(BoolExpr *) node; if(bExpr->boolop == NOT_EXPR){ /* elog(LOG,"\nTHERENOT\n"); */ context->positive = !context->positive; Node * retour = expression_tree_mutator(node, my_mutator, (void *) context); context->positive = !context->positive; return retour; } if(bExpr->boolop == OR_EXPR || bExpr->boolop == AND_EXPR){ /*Pré traitement*/ List * l_save = context->list_of_not_null_in_current; context->list_of_not_null_in_current = list_copy(l_save); if(context->positive){ context->list_of_not_null_in_current = list_concat(context->list_of_not_null_in_current,list_nth(context->list_list_true,context->list_list_true->length - context->where_i_am - 1)); } else{ context->list_of_not_null_in_current = list_concat(context->list_of_not_null_in_current,list_nth(context->list_list_false,context->list_list_true->length - context->where_i_am - 1)); } /* elog(LOG,"\n LIST_NOT_NULL: %s \n",nodeToString(context->list_of_not_null_in_current)); */ context->where_i_am ++; Node * retour = expression_tree_mutator(node, my_mutator, (void *) context); /*Post traitement*/ context->list_of_not_null_in_current = l_save; return retour; } } if(IsA(node,Query)){ Query * q = (Query *) node; /* context->current_varlevelsup ++; */ List * save_current_trueVar = context->current_trueVar; context->current_trueVar = list_nth(context->trueVars,context->where_i_am_querry); context->where_i_am_querry = context->where_i_am_querry + 1; q->jointree = expression_tree_mutator((Node *) q->jointree, my_mutator, (void *) context); /* context->where_i_am_querry = context->where_i_am_querry - 1; */ context->current_trueVar = save_current_trueVar; /* context->current_varlevelsup --; */ return node; } if(IsA(node,OpExpr)){ /* elog(LOG,"\nTHEREOP = \n"); */ OpExpr * oExpr = (OpExpr *) node; if(context->positive && oExpr->opno == 518){ /*<>*/ context->ready = true; } if(!context->positive && oExpr->opno == 96){ /* = */ context->ready = true; } /* if(context->positive && oExpr->opno == 521){ #<{(| > |)}># */ /* context->ready = true; */ /* } */ if(oExpr->opno == 525){ /* >= */ OpExpr * equa = makeNode(OpExpr); equa->opno = 96; /*=*/ equa->args = list_concat(equa->args,oExpr->args); OpExpr * stric = makeNode(OpExpr); stric->opno = 521; /*>*/ stric->args = list_concat(stric->args,oExpr->args); List * tmp = NULL; tmp = lappend(tmp,equa); tmp = lappend(tmp,stric); Node * result = expression_tree_mutator((Node *)makeBoolExpr(OR_EXPR,tmp,-1),my_mutator,context); return result; } if(oExpr->opno == 523){ /* <= */ OpExpr * equa = makeNode(OpExpr); equa->opno = 96; /*=*/ equa->args = list_concat(equa->args,oExpr->args); OpExpr * stric = makeNode(OpExpr); stric->opno = 97; /*<*/ stric->args = list_concat(stric->args,oExpr->args); List * tmp = NULL; tmp = lappend(tmp,equa); tmp = lappend(tmp,stric); Node * result = expression_tree_mutator((Node *)makeBoolExpr(OR_EXPR,tmp,-1),my_mutator,context); return result; } /* if(context->positive && oExpr->opno == 97){ #<{(| < |)}># */ /* context->ready = true; */ /* } */ if(!context->positive && oExpr->opno == 1209){ /* LIKE */ context->ready = true; } Node * result = expression_tree_mutator(node, my_mutator, (void *) context); if(context->constraint_to_add != NULL){ if(!context->positive /* && oExpr->opno == 518 */){ context->constraint_to_add = lappend(context->constraint_to_add,result); Node * to_return = makeBoolExpr(OR_EXPR,context->constraint_to_add,-1); context->constraint_to_add = NULL; context->ready = false; /* elog(LOG,"inter :%s\n",nodeToString(to_return)); */ return to_return; } if(context->positive /* && oExpr->opno == 96 */){ context->constraint_to_add = lappend(context->constraint_to_add,result); Node * to_return = makeBoolExpr(AND_EXPR,context->constraint_to_add,-1); context->constraint_to_add = NULL; context->ready = false; return to_return; } } else return result; } if(context->ready && IsA(node, Var)) { /* elog(LOG,"\n LIST_NOT_NULL: %s \n",nodeToString(context->list_of_not_null_in_current)); */ Var * v = (Var *) node; Var * rv = getTrueVar(context->current_trueVar,v); /* elog(LOG,"\nTRUE VARS : %s \n",nodeToString(context->current_trueVar)); */ /* elog(LOG,"\nV check %s \n",nodeToString(v)); */ /* elog(LOG,"\nRV check %s \n",nodeToString(rv)); */ /* elog(LOG,"\nNOT NULL CUR: %s \n",nodeToString(context->list_of_not_null_in_current)); */ if(!context->positive && !isInListTrueVar(context->list_of_not_null_in_current,rv)){ /* elog(LOG,"\nHERE !\n"); */ OpExpr * inf0 = makeNode(OpExpr); inf0->opno = 97; /*<*/ inf0->args = lappend(inf0->args,node); Const * c0 = makeConst(23,-1,0,4,Int16GetDatum(0),false, true); inf0->args = lappend(inf0->args,c0); context->constraint_to_add = lappend(context->constraint_to_add,inf0); } if(context->positive){ /* elog(LOG,"\nHERE !\n"); */ OpExpr * inf0 = makeNode(OpExpr); inf0->opno = 521; /*>*/ inf0->args = lappend(inf0->args,node); Const * c0 = makeConst(23,-1,0,4,Int16GetDatum(0),false, true); inf0->args = lappend(inf0->args,c0); context->constraint_to_add = lappend(context->constraint_to_add,inf0); } } return expression_tree_mutator(node, my_mutator, (void *) context); }