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);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        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);
        }