public bool ProbeForSolution(List <CNSAT.Var> decisions, out double[] solution) { probeCount++; /*Console.Write("SAT proposed({0}): ", decisions.Count); * foreach(CNSAT.Var v in decisions) { * v.Print(); * Console.Write(" "); * } * Console.WriteLine();*/ solution = null; for (int i = 0; i < dim; i++) { // Console.WriteLine("[{0}..{1}]",this.limits[i,0],this.limits[i,1]); this.ranges[i] = (this.limits[i, 1] - this.limits[i, 0]); } for (int i = 0; i < decisions.Count; i++) { decisions[i].CurTerm = (decisions[i].Assignment == CNSAT.Assignment.True?decisions[i].PositiveTerm:decisions[i].NegativeTerm); } //int idx = Math.Max(0,ss.DecisionLevel.Count-1); //r1 = RPropFindFeasible(decisions, ss.DecisionLevel[idx].Seed); r1 = RPropFindFeasible(decisions, lastSeed); if (r1.finalUtil < 0.5) { r1 = RPropFindFeasible(decisions, null); } if (r1.finalUtil < 0.5) { //Probe was not successfull -> assignment not valid //Console.Write("."); //Console.WriteLine("Could not find point for {0}",constraint); CNSAT.Clause learnt = new CNSAT.Clause(); foreach (CNSAT.Var v in decisions) { learnt.Add(new CNSAT.Lit(v, v.Assignment == CNSAT.Assignment.True ? CNSAT.Assignment.False : CNSAT.Assignment.True)); } ss.addTClause(learnt); return(false); } //ss.DecisionLevel[ss.DecisionLevel.Count-1].Seed = r1.finalValue; lastSeed = r1.finalValue; solution = r1.finalValue; successProbeCount++; return(true); }
public bool IntervalPropagate(List <CNSAT.Var> decisions, out double[,] curRanges) { intervalCount++; /*Console.Write("SAT proposed({0}): ", decisions.Count); * foreach(CNSAT.Var v in decisions) { * v.Print(); * Console.Write(" "); * } * Console.WriteLine(); */ //double[,] curRanges=null; List <CNSAT.Var> offending = null; if (!ip.Propagate(decisions, out curRanges, out offending)) { /*Console.WriteLine("Propagation FAILED offenders are:"); * foreach(CNSAT.Var v in offending) { * //Console.WriteLine(v + "\t"+(v.Assignment==CNSAT.Assignment.True?v.Term:v.Term.Negate())); * Console.Write(v + " "); * } * Console.WriteLine();*/ if (offending != null) { CNSAT.Clause learnt = new CNSAT.Clause(); foreach (CNSAT.Var v in offending) { learnt.Add(new CNSAT.Lit(v, v.Assignment == CNSAT.Assignment.True ? CNSAT.Assignment.False : CNSAT.Assignment.True)); } //if(learnt.Literals.Count>0) { ss.addIClause(learnt); //} } return(false); } //Console.WriteLine("Propagation succeeded"); this.limits = curRanges; successIntervalCount++; return(true); }
public bool resolveConflict(Clause c) { ++conflictCount; //Learn Clause from conflict here Clause confl = c; Clause learnt = new Clause(); int index = decisions.Count - 1; int pathC = 0; Var p = null; #if (CNSatDebug) Console.WriteLine("\nxxxxxxxxxxxxxxxxxxx"); Console.WriteLine("\nAlready Learned"); foreach (Clause a in satClauses) { a.Print(); } Console.WriteLine("\nAssignment"); this.PrintAssignments(); Console.WriteLine("\nConflict"); confl.Print(); Console.WriteLine("\nReason"); if (confl.LastModVar != null && confl.LastModVar.Reason != null) { confl.LastModVar.Reason.Print(); } else { Console.WriteLine("null"); } Console.WriteLine("-------------------\nLearning"); #endif //Find all Literals until First Unique Implication Point(UIP) do { #if (CNSatDebug) if (p != null) { Console.Write("Var "); p.Print(); Console.Write(" -> "); } confl.Print(); Console.Write("Trying "); #endif Clause cl = confl; //Inspect conflict reason clause Literals for (int j = 0; j < cl.Literals.Count; j++) { Lit q = cl.Literals[j]; //ignore UIP if (q.Var == p) { #if (CNSatDebug) q.Var.Print(); Console.Write(" n(sub) "); #endif continue; } //ignore sawnvariables and decissionlevel 0 if (!q.Var.Seen && q.Var.DecisionLevel != decisionLevel[0]) { q.Var.Seen = true; //if q has been decided in curent level: increase iterations; else add literal to learnt clause if (q.Var.DecisionLevel.Level >= (decisionLevel[decisionLevel.Count - 1].Level)) { pathC++; #if (CNSatDebug) q.Var.Print(); Console.Write(" n(curlvl) "); #endif } else { #if (CNSatDebug) q.Var.Print(); Console.Write(" add "); #endif learnt.Add(q); } } } // Select next clause to look at: //do { if(index<0) {Console.Write("BLA"); return false;} } while (!decisions[index--].Seen) { ; } p = decisions[index + 1]; confl = p.Reason; p.Seen = false; pathC--; #if (CNSatDebug) Console.WriteLine(); #endif } while (pathC > 0); #if (CNSatDebug) Console.WriteLine("-------------------"); #endif //Add UIP Lit t = new Lit(p, (p.Assignment == Assignment.False) ? Assignment.True : Assignment.False); learnt.Add(t); //Store Seen Variables for later reset List <Lit> SeenList = new List <Lit>(learnt.Literals); //simplify learnt clause //Here is still an error!!!!!!! for (int m = 0; m < learnt.Literals.Count - 1; ++m) { Lit l = learnt.Literals[m]; //Ignore Literals without reason if (l.Var.Reason == null) { continue; } else { //Check whether reason for current literal is already in learnt -> remove l Clause re = l.Var.Reason; bool found = false; foreach (Lit rel in re.Literals) { if (!rel.Var.Seen && (rel.Var.DecisionLevel != decisionLevel[0])) { found = true; break; } } if (!found) { learnt.Literals.RemoveAt(m--); } } } //Reset Seen foreach (Lit l in SeenList) { l.Var.Seen = false; } #if (CNSatDebug) Console.WriteLine("\nLearned "); learnt.Print(); //This Stuff checks whether learnt is already in learntClauses -> throws exception /* bool blub=false; * for(int r=0; r<satClauses.Count; r++) { * bool nof=true; * if(satClauses[r].Literals.Count != learnt.Literals.Count) continue; * foreach(Lit l in learnt.Literals) { * bool foundLit = false; * foreach(Lit m in satClauses[r].Literals) { * if(l.Var == (m.Var) && l.Sign == m.Sign) { * foundLit = true; * break; * } * } * nof &= foundLit; * * if (false == nof) break; * } * if(nof) blub=true; * } * if(blub) throw new Exception("jbjkjdasklfjklasdkgklsaglajgkl");*/ #endif //End Learn Clause //Find backtracklevel: DecisionLevel db; int i = 1, maxLitIndex; Lit changeLit; if (learnt.Literals.Count == 1) { db = this.decisionLevel[0]; } else { db = learnt.Literals[0].Var.DecisionLevel; maxLitIndex = 0; //Search newest decission, which affects a literal in learnt. for (i = 1; i < learnt.Literals.Count - 1; ++i) { Lit l = learnt.Literals[i]; if (db.Level < l.Var.DecisionLevel.Level) { db = l.Var.DecisionLevel; maxLitIndex = i; } } changeLit = learnt.Literals[0]; learnt.Literals[0] = learnt.Literals[maxLitIndex]; learnt.Literals[maxLitIndex] = changeLit; } #if (CNSatDebug) Console.WriteLine("Backtracking from " + this.decisionLevel[this.decisionLevel.Count - 1].Level + " to " + db.Level); #endif //Backtrack to db backTrack(db); //Add learnt clause: Unit Clauses have to be satisfied otherwise: -> UNSAT bool solvable = this.addSATClause(learnt); if (!solvable) // TODO can be removed once bugfree { Console.WriteLine("Error on insert learned clause"); return(false); } /*if(db==DecisionLevel[0] && learnt.Literals.Count>1) { * Console.WriteLine("Reached decision level 0"); * return false; * }*/ if (learnt.Literals.Count == 1) { //decisions[0].Assignment = learnt.Literals[0].Sign; learnt.Literals[0].Var.Assignment = learnt.Literals[0].Sign; learnt.Literals[0].Var.Reason = null; } //Switch assignment of UIP to satisfy learnt if (learnt.Literals.Count > 1) { //DecisionLevel d = new DecisionLevel(decisions.Count); //decisionLevel.Add(d); //Set Learnt as Reason for UIP Lit l = learnt.Literals[learnt.Literals.Count - 1]; l.Var.Assignment = l.Sign; learnt.Satisfied = true; l.Var.DecisionLevel = this.decisionLevel[this.decisionLevel.Count - 1]; l.Var.Reason = learnt; decisions.Add(l.Var); } #if (CNSatDebug) this.PrintAssignments(); Console.ReadLine(); #endif return(true); }
public Clause propagate() { int lLevel = 0; if (decisionLevel.Count > 1) { lLevel = decisionLevel[decisionLevel.Count - 1].Level; } for (int i = lLevel; i < decisions.Count; i++) { List <Watcher> watchList = decisions[i].WatchList; for (int j = 0; j < watchList.Count; j++) { Watcher w = watchList[j]; #if (CNSatDebug) decisions[i].Print(); Console.Write(" -> "); w.Clause.Print(); #endif if (w.Clause.Satisfied) { continue; } if (w.Lit.Satisfied()) { w.Clause.Satisfied = true; continue; } //TODO Do we need this? if (w.Lit.Var.Assignment == Assignment.Unassigned) { continue; } //This can be optimized !? Clause c = w.Clause; //Search for new Watch int oWId = (c.watcher[0] == w) ? 1 : 0; if (c.watcher[oWId].Lit.Satisfied()) { //TODO: Do we need this? w.Clause.Satisfied = true; continue; } bool found = false; foreach (Lit l in c.Literals) { if (c.watcher[oWId].Lit.Var != l.Var && (l.Var.Assignment == Assignment.Unassigned || l.Satisfied())) { w.Lit.Var.WatchList.Remove(w); j--; w.Lit = l; l.Var.WatchList.Add(w); found = true; if (l.Satisfied()) { w.Clause.Satisfied = true; } break; } } if (!found) { c.Activity++; //TODO Handle Watcher here ... do not return -> faster Watcher w2 = c.watcher[oWId]; if (w2.Lit.Var.Assignment == Assignment.Unassigned) { w2.Lit.Var.Assignment = w2.Lit.Sign; w2.Clause.Satisfied = true; w2.Lit.Var.DecisionLevel = decisionLevel[decisionLevel.Count - 1]; decisions.Add(w2.Lit.Var); w2.Lit.Var.Reason = c; foreach (Watcher wi in w2.Lit.Var.WatchList) { wi.Clause.LastModVar = w2.Lit.Var; } } else { return(c); } } } } return(null); }