public static Var DecideVariableCountBased(List <Var> variables, CNSat solver) { int vars = variables.Count; Lit l = null; int maxCount = Int32.MaxValue; int minCount = -1; for (int i = 0; i < vars; i++) { if (variables[i].Assignment != Assignment.Unassigned) { continue; } for (int j = 0; j < variables[i].WatchList.Count; j++) { if (!variables[i].WatchList[j].Clause.Satisfied) { /*if(maxCount>variables[i].WatchList[j].Lit.VariableCount) { * l = variables[i].WatchList[j].Lit; * maxCount = l.VariableCount; * }*/ if (minCount < variables[i].WatchList[j].Lit.VariableCount) { l = variables[i].WatchList[j].Lit; minCount = l.VariableCount; } } } } if (l == null) { return(null); } Assignment ass; Var v = l.Var; ass = l.Sign; DecisionLevel d = new DecisionLevel(solver.Decisions.Count); solver.DecisionLevel.Add(d); v.Assignment = ass; solver.Decisions.Add(v); v.Reason = null; v.DecisionLevel = d; return(v); }
public void AddChecked(Lit l) { bool found = false; if (l.IsTemporary) { for (int i = 0; i < this.Literals.Count; i++) { if (this.Literals[i].IsTemporary && l.Atom == this.Literals[i].Atom) { found = true; break; } } if (!found) { Literals.Add(l); } //else { } return; } for (int i = 0; i < this.Literals.Count; i++) { if (l.Atom == this.Literals[i].Atom) { found = true; if (l.Sign != this.Literals[i].Sign) { this.IsTautologic = true; this.Literals.Clear(); } //else {} break; } } if (!found) { Literals.Add(l); } return; }
protected void DoTransform(LinkedList <Clause> clauses) { Clause curClause = null; Lit curLit = null; int j = 0; LinkedListNode <Clause> clauseNode = clauses.First; while (clauseNode != null) { if (!clauseNode.Value.IsFinished) { bool finished = true; for (j = 0; j < clauseNode.Value.Literals.Count; j++) { if (clauseNode.Value.Literals[j].IsTemporary) { finished = false; curClause = clauseNode.Value; curLit = curClause.Literals[j]; break; } } if (!finished) { //break clause on lit: LinkedListNode <Clause> prevNode = clauseNode.Previous; clauses.Remove(clauseNode); curClause.Literals.RemoveAt(j); Clause nc1, nc2; PerformStep(curClause, curLit, out nc1, out nc2); if (nc1 != null) { clauses.AddLast(nc1); } if (nc2 != null) { clauses.AddLast(nc2); } if (prevNode == null) { clauseNode = clauses.First; } else { clauseNode = prevNode.Next; } } else { clauseNode.Value.IsFinished = true; clauseNode = clauseNode.Next; } } else { clauseNode = clauseNode.Next; } } /* * for(i=0; i<clauses.Count;i++) { * if (clauses[i].IsFinished) { * continue; * } * bool finished = true; * for(j=0; j < clauses[i].Literals.Count; j++) { * if(clauses[i].Literals[j].IsTemporary) { * finished = false; * curClause = clauses[i]; * curLit = curClause.Literals[j]; * break; * } * } * if(!finished) { * //break clause on lit: * clauses.RemoveAt(i); * curClause.Literals.RemoveAt(j); * clauses.AddRange(PerformStep(curClause,curLit)); * i--; * * } else { * clauses[i].IsFinished = true; * } * } */ /*foreach(Clause c in clauses) { * if(!c.IsFinished) throw new Exception("Not Finished"); * }*/ }
protected void PerformStep(Clause c, Lit lit, out Clause newClause1, out Clause newClause2) { //List<Clause> ret = new List<Clause>(); Term formula = lit.Atom; if (formula is Max) { Max m = (Max)formula; Lit l = new Lit(m.Left, Assignment.Unassigned, true); Lit r = new Lit(m.Right, Assignment.Unassigned, true); c.AddChecked(l); c.AddChecked(r); newClause1 = c; newClause2 = null; return; } if (formula is And) { And m = (And)formula; Lit l = new Lit(m.Left, Assignment.Unassigned, true); Lit r = new Lit(m.Right, Assignment.Unassigned, true); Clause c2 = c.Clone(); c.AddChecked(l); c2.AddChecked(r); newClause1 = c; newClause2 = c2; return; } if (formula is Or) { Or m = (Or)formula; Lit l = new Lit(m.Left, Assignment.Unassigned, true); Lit r = new Lit(m.Right, Assignment.Unassigned, true); c.AddChecked(l); c.AddChecked(r); newClause1 = c; newClause2 = null; return; } if (formula is Min) { Min m = (Min)formula; Lit l = new Lit(m.Left, Assignment.Unassigned, true); Lit r = new Lit(m.Right, Assignment.Unassigned, true); Clause c2 = c.Clone(); c.AddChecked(l); c2.AddChecked(r); newClause1 = c; newClause2 = c2; return; } if (formula is LTConstraint) { lit.IsTemporary = false; lit.ComputeVariableCount(); lit.Sign = Assignment.True; this.AtomOccurrence++; Var v = null; #if USE_EXTENDED_EQUALITY if (this.TryGetVar(lit.Atom, out v)) { #else if (this.Atoms.TryGetValue(lit.Atom, out v)) { #endif lit.Var = v; } else { lit.Var = solver.newVar(); lit.Var.Term = lit.Atom; this.Atoms.Add(lit.Atom, lit.Var); } c.AddChecked(lit); newClause1 = c; newClause2 = null; return; } if (formula is LTEConstraint) { lit.IsTemporary = false; lit.ComputeVariableCount(); lit.Sign = Assignment.False; this.AtomOccurrence++; Term p = ((LTEConstraint)formula).Negate(); lit.Atom = p; Var v = null; #if USE_EXTENDED_EQUALITY if (this.TryGetVar(p, out v)) { #else if (this.Atoms.TryGetValue(p, out v)) { #endif lit.Var = v; } else { lit.Var = solver.newVar(); lit.Var.Term = p; this.Atoms.Add(p, lit.Var); } c.AddChecked(lit); newClause1 = c; newClause2 = null; return; } if (formula is Constant) { if (((Constant)formula).Value <= 0.0) { newClause1 = c; } else { newClause1 = null; } newClause2 = null; return; } Console.Error.WriteLine("U C: {0}", formula); throw new Exception("Unknown constraint in transformation: " + formula); }
public Watcher(Lit l, Clause parent) { this.Clause = parent; this.Lit = l; Lit.Var.WatchList.Add(this); }
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 void Add(Lit l) { literals.Add(l); }