public static List<string> RockSampleHeuristic(PartiallySpecifiedState pssCurrent, Domain domain)
        {
            List<string> lActions = new List<string>();
            int iX = -1, iY = 1;
            int iSize = 0;
            foreach (GroundedPredicate p in pssCurrent.Observed)
            {
                if (p.Name.Contains("agent-at"))
                {
                    string[] a = p.Constants[0].Name.Substring(1).Split('-');
                    if (!p.Negation)
                    {
                        iX = int.Parse(a[0]);
                        iY = int.Parse(a[1]);
                    }
                    if (int.Parse(a[0]) > iSize)
                        iSize = int.Parse(a[0]);
                }
            }

            int iXNew = iX, iYNew = iY;

            if (iX < iSize - 1 && iY % 2 == 1)
                iXNew++;
            else if (iX > 1 && iY % 2 == 0)
                iXNew--;
            else
            {
                iYNew++;
            }
            lActions.Add("move p" + iX + "-" + iY + " p" + iXNew + "-" + iYNew);
            bool bValidSensorH1 = false;
            bool bValidSensorH0 = false;
            foreach (Action a in domain.Actions)
            {
                if (a.Name == "activate-sensor-at-p" + iXNew + "-" + iYNew + "-h1")
                    bValidSensorH1 = true;
                if (a.Name == "activate-sensor-at-p" + iXNew + "-" + iYNew + "-h0")
                    bValidSensorH0 = true;

            }
            if (bValidSensorH1)
            {
                lActions.Add("raise-antena");
                lActions.Add("activate-sensor-at-p" + iXNew + "-" + iYNew + "-h1");
                lActions.Add("observe-sensor");
                lActions.Add("lower-antena");
            }
            if(bValidSensorH0)
            {
                lActions.Add("activate-sensor-at-p" + iXNew + "-" + iYNew + "-h0");
                lActions.Add("observe-sensor");
            }
            return lActions;
        }
        public bool ValidatePlan(PartiallySpecifiedState pssCurrent)
        {
            if(pssCurrent == null)
                return false;
            if (pssCurrent.IsGoalState())
                return true;

            if (Action == null)
                return false;
            Formula fObserved = null;
            PartiallySpecifiedState psTrueState, psFalseState;

            pssCurrent.ApplyOffline(Action, out fObserved, out psTrueState, out psFalseState);
            if (Action.Observe == null)
                return SingleChild.ValidatePlan(psTrueState);
            bool bTrueOk = TrueObservationChild.ValidatePlan(psTrueState);
            bool bFalseOk = FalseObservationChild.ValidatePlan(psFalseState);
            return bTrueOk && bFalseOk;
        }
        public static List<string> MasterMindHeuristic(PartiallySpecifiedState pssCurrent, Domain domain)
        {
            List<Constant> lColors = new List<Constant>();
            List<Constant> lPegs = new List<Constant>();
            List<Constant> lValues = new List<Constant>();
            foreach (Constant c in domain.Constants)
            {
                if (c.Type.ToLower() == "color")
                    lColors.Add(c);
                if (c.Type.ToLower() == "peg")
                    lPegs.Add(c);
                if (c.Type.ToLower() == "value")
                    lValues.Add(c);
            }

            //DateTime dtStart = DateTime.Now;

            //BeliefState bs = pssCurrent.m_bsInitialBelief;

            //State s = bs.ChooseState(true);
            //List<Predicate> l = bs.RunSatSolver();

            //Console.WriteLine((DateTime.Now - dtStart).TotalSeconds);

            Permute(lColors);
            List<Constant> lGuessColors = new List<Constant>();
            for (int iPeg = 0; iPeg < lPegs.Count; iPeg++)
            {
                /*
                //foreach (GroundedPredicate gp in s.Predicates)
                foreach (GroundedPredicate gp in l)
                {
                    if (gp.ToString().StartsWith("(on p" + iPeg) && gp.Negation == false)
                    {
                        lGuessColors.Add(gp.Constants[1]);
                    }

                }
                */
                foreach (Constant cColor in lColors)
                {
                    GroundedPredicate gp = new GroundedPredicate("on");
                    gp.AddConstant(lPegs[iPeg]);
                    gp.AddConstant(cColor);
                    if (!pssCurrent.Observed.Contains(gp.Negate()))
                    {
                        lGuessColors.Add(cColor);
                        break;
                    }
                }
                lColors.Remove(lGuessColors.Last());

            }
            if (lGuessColors.Count == lPegs.Count)
            {
                List<string> lActions = new List<string>();
                string sGuess = "guess-all";
                foreach (Constant c in lGuessColors)
                    sGuess += " " + c.Name;
                lActions.Add(sGuess);
                lActions.Add("evaluate-guess");
                foreach (Constant cValue in lValues)
                {
                    lActions.Add("observe-LocationHits " + cValue.Name);
                    lActions.Add("observe-ColorHits " + cValue.Name);
                }
                return lActions;
            }
            return null;
        }
 public virtual PartiallySpecifiedState Clone()
 {
     BeliefState bsCopy = new BeliefState(m_bsInitialBelief);
     PartiallySpecifiedState bsClone = new PartiallySpecifiedState(this, bsCopy);
     return bsClone;
 }
        public PartiallySpecifiedState(PartiallySpecifiedState original, BeliefState bsInitial)
        {
            ID = STATE_COUNT++;

            m_nPlan = original.m_nPlan;
            m_lHistory = new List<string>(original.m_lHistory);
            ChildCount = original.ChildCount;
            if (original.m_lObserved != null)
            {
                m_lObserved = new HashSet<Predicate>();
                foreach (Predicate p in original.m_lObserved)
                {
                    m_lObserved.Add(p);
                }
            }
            else m_lObserved = null;

            if (original.m_lHidden != null)
            {
                m_lHidden = new HashSet<Predicate>();
                foreach (Predicate p in original.m_lHidden)
                {
                    m_lHidden.Add(p);
                }
            }
            else m_lHidden = null;

            if (original.AvailableActions != null)
            {
                AvailableActions = new List<Action>();
                foreach (Action p in original.AvailableActions)
                {
                    AvailableActions.Add(p);
                }
            }
            else AvailableActions = null;

            if (bsInitial == null)
                m_bsInitialBelief = new BeliefState(original.m_bsInitialBelief);
            else
                m_bsInitialBelief = bsInitial;

            if (original.m_sPredecessor != null)
                m_sPredecessor = new PartiallySpecifiedState(original.m_sPredecessor, m_bsInitialBelief);

            /*PartiallySpecifiedState tempPredecessorOriginal = original.m_sPredecessor;
            PartiallySpecifiedState tempPredecessorNew = m_sPredecessor;
            //m_sPredecessor
            while (tempPredecessorOriginal != null)
            {
                tempPredecessorNew = new PartiallySpecifiedState()
            }*/

            if (original.GeneratingAction != null) GeneratingAction = original.GeneratingAction.Clone();
            else GeneratingAction = null;

            if (original.GeneratingObservation != null) GeneratingObservation = original.GeneratingObservation.Clone();
            else GeneratingObservation = null;

            Problem = original.Problem;
            if (original.UnderlyingEnvironmentState != null) UnderlyingEnvironmentState = original.UnderlyingEnvironmentState.Clone();
            else UnderlyingEnvironmentState = null;

            //m_bsInitialBelief = original.m_bsInitialBelief;
            Time = original.Time;

            if (original.m_cfCNFBelief != null) m_cfCNFBelief = new CompoundFormula(original.m_cfCNFBelief);
            else m_cfCNFBelief = null;

            if (original.m_lFailureTag != null) m_lFailureTag = new List<Predicate>(original.m_lFailureTag);
            else m_lFailureTag = null;

            if (original.m_lPreviousTags != null) m_lPreviousTags = new List<List<Predicate>>(original.m_lPreviousTags);
            else m_lPreviousTags = null;

            if (original.FunctionValues != null) FunctionValues = new Dictionary<string, double>(original.FunctionValues);
            else FunctionValues = null;
        }
        public void ApplyOffline(string sActionName, out Action a, out Formula fObserve, out PartiallySpecifiedState psTrueState, out PartiallySpecifiedState psFalseState)
        {
            psTrueState = null;
            psFalseState = null;
            fObserve = null;
            a = Problem.Domain.GroundActionByName(sActionName.Split(' '));
            if (a == null || a is ParametrizedAction)
                return;

            ApplyOffline(a, out fObserve, out psTrueState, out psFalseState);
        }
        public PartiallySpecifiedState(PartiallySpecifiedState sPredecessor, Action aGeneratingAction)
        {
            ID = STATE_COUNT++;

            ChildCount = 0;

            m_bsInitialBelief = new BeliefState(sPredecessor.m_bsInitialBelief);
            Problem = m_bsInitialBelief.Problem;
            AvailableActions = new List<Action>();
            UnderlyingEnvironmentState = null;

            if (Problem.Domain.IsSimple)
            {
                m_sPredecessor = sPredecessor;
            }
            else
            {
                m_sPredecessor = new PartiallySpecifiedState(sPredecessor, m_bsInitialBelief); //recursively copies the entire history
            }

            GeneratingAction = aGeneratingAction;
            m_lObserved = new HashSet<Predicate>(sPredecessor.Observed);
            m_lHidden = new HashSet<Predicate>(sPredecessor.m_lHidden);
            ForgetPotentialEffects();

            FunctionValues = new Dictionary<string, double>();
            Time = sPredecessor.Time + 1;

            foreach (KeyValuePair<string, double> p in sPredecessor.FunctionValues)
                FunctionValues[p.Key] = p.Value;

            m_lHistory = new List<string>(sPredecessor.m_lHistory);
            m_lHistory.Add( GeneratingAction.Name);
        }
        public void ApplyOffline(Action a, out Formula fObserve, out PartiallySpecifiedState psTrueState, out PartiallySpecifiedState psFalseState)
        {
            psTrueState = null;
            psFalseState = null;
            fObserve = null;

            a = a.ApplyObserved(m_lObserved); //for removing all generaly known items from the computations.

            Formula fPreconditions = a.Preconditions;
            if (fPreconditions != null && !IsApplicable(a))
                return;
            PartiallySpecifiedState bsNew = new PartiallySpecifiedState(this, a);
            ChildCount = 1;
            if (a.Effects != null)
            {
                if (a.HasConditionalEffects)
                {
                    List<CompoundFormula> lApplicableConditions = ApplyKnown(a.GetConditions());
                    bsNew.ApplyKnowledgeLoss(lApplicableConditions);
                    HashSet<Predicate> lAddEffects = new HashSet<Predicate>(), lRemoveEffects = new HashSet<Predicate>();
                    a.GetApplicableEffects(m_lObserved, lAddEffects, lRemoveEffects, true);
                    //first removing then adding
                    foreach (Predicate p in lRemoveEffects)
                        bsNew.AddEffect(p);
                    foreach (Predicate p in lAddEffects)
                        bsNew.AddEffect(p);
                    //bsNew.UpdateHidden(a, m_lObserved);
                    bsNew.UpdateHidden();
                }
                else
                {
                    bsNew.AddEffects(a.Effects);
                }
            }
            if (a.Observe != null)
            {
                PartiallySpecifiedState bsTrue = bsNew.Clone();
                PartiallySpecifiedState bsFalse = bsNew.Clone();
                bsTrue.GeneratingObservation = a.Observe;
                bsFalse.GeneratingObservation = a.Observe.Negate();

                ChildCount = 0;

                if (ConsistentWith(bsTrue.GeneratingObservation, false))
                {
                    HashSet<int> hsModifiedTrue = bsTrue.m_bsInitialBelief.ReviseInitialBelief(bsTrue.GeneratingObservation, bsTrue);
                    if (hsModifiedTrue.Count > 0)
                    {
                        bsTrue.PropogateObservedPredicates();
                    }
                    bsTrue.AddObserved(a.Observe);
                    psTrueState = bsTrue;
                    ChildCount++;
                }
                else
                    psTrueState = null;

                if (ConsistentWith(bsFalse.GeneratingObservation, false))
                {
                    HashSet<int> hsModifiedFalse = bsFalse.m_bsInitialBelief.ReviseInitialBelief(bsFalse.GeneratingObservation, bsFalse);
                    if (hsModifiedFalse.Count > 0)
                    {
                        bsFalse.PropogateObservedPredicates();
                    }
                    bsFalse.AddObserved(a.Observe.Negate());

                    psFalseState = bsFalse;
                    ChildCount++;
                }
                else
                    psFalseState = null;
            }
            else
                psTrueState = bsNew;
        }
        private PartiallySpecifiedState Apply(Action aOrg, out Formula fObserve, bool bPropogateOnly)
        {
            //Debug.WriteLine("Executing " + a.Name);
            fObserve = null;
            if (aOrg is ParametrizedAction)
                return null;

            DateTime dtStart = DateTime.Now;

            Action a = aOrg.ApplyObserved(m_lObserved);

            //no need to check pre during propogation - they were already confirmed the first time
            if (!bPropogateOnly && a.Preconditions != null && !IsApplicable(a))
                return null;

            a.ComputeRegressions();

            tsPre += DateTime.Now - dtStart;
            dtStart = DateTime.Now;

            State sNew = null;
            if (!bPropogateOnly && UnderlyingEnvironmentState != null)
                sNew = UnderlyingEnvironmentState.Apply(a);

            CompoundFormula cfAndChoices = null;
            if (!bPropogateOnly && a.ContainsNonDeterministicEffect)
            {
                a = a.RemoveNonDeterminism(Time, out cfAndChoices);
            }

            PartiallySpecifiedState bsNew = new PartiallySpecifiedState(this, a);
            if (sNew != null)
            {
                bsNew.UnderlyingEnvironmentState = sNew;
                if (!bPropogateOnly && bsNew.Time != sNew.Time)
                    Debug.WriteLine("BUGBUG");

            }

            if (a.Effects != null)
            {
                if (a.HasConditionalEffects)
                {
                    List<CompoundFormula> lApplicableConditions = ApplyKnown(a.GetConditions());
                    bsNew.ApplyKnowledgeLoss(lApplicableConditions);
                    HashSet<Predicate> lAddEffects = new HashSet<Predicate>(), lRemoveEffects = new HashSet<Predicate>();
                    a.GetApplicableEffects(m_lObserved,lAddEffects, lRemoveEffects, true);
                    //first removing then adding
                    foreach (Predicate p in lRemoveEffects)
                        bsNew.AddEffect(p);
                    foreach (Predicate p in lAddEffects)
                        bsNew.AddEffect(p);
                    //bsNew.UpdateHidden(a, m_lObserved);
                    bsNew.UpdateHidden();
                }
                else
                {
                    bsNew.AddEffects(a.Effects);
                }
            }

            //if(m_sPredecessor != null)//the first one holds all knowns, to avoid propogation from the initial belief
             //   RemoveDuplicateObserved(bsNew.m_lObserved);//if p is true at t+1 and p is true at t, there is no point in maintaining the copy at t

            tsEffects += DateTime.Now - dtStart;
            dtStart = DateTime.Now;

            if (!bPropogateOnly && a.Observe != null)
            {
                //first applying the action (effects) and then observing
                fObserve = bsNew.UnderlyingEnvironmentState.Observe(a.Observe);

                bsNew.GeneratingObservation = fObserve;
                bsNew.AddObserved(fObserve);

                /*
                if (ReviseInitialBelief(fObserve))
                    bsNew.PropogateObservedPredicates();
                 * */
                HashSet<int> hsModified = m_bsInitialBelief.ReviseInitialBelief(fObserve, this);
                if (hsModified.Count > 0)
                {
                    if (!SDRPlanner.OptimizeMemoryConsumption)
                        bsNew.PropogateObservedPredicates();
                }

            }

            tsObs += DateTime.Now - dtStart;

            if (bsNew != null && cfAndChoices != null)
                m_bsInitialBelief.AddInitialStateFormula(cfAndChoices);

            if (!bPropogateOnly && bsNew.Time != sNew.Time)
                Debug.WriteLine("BUGBUG");

            return bsNew;
        }
 private void CopyClosedState(PartiallySpecifiedState pssClosed)
 {
     Plan = pssClosed.Plan;
     m_lOfflinePredicatesUnknown = pssClosed.m_lOfflinePredicatesUnknown;
     m_lOfflinePredicatesKnown = pssClosed.m_lOfflinePredicatesKnown;
     m_dRelevantVariablesForPrecondition = pssClosed.m_dRelevantVariablesForPrecondition;
     m_lOfflineObservedPredicates = pssClosed.m_lOfflineObservedPredicates;
 }
        public PartiallySpecifiedState(BeliefState bs)
        {
            ID = STATE_COUNT++;
            Problem = bs.Problem;
            m_sPredecessor = null;
            m_lObserved = new HashSet<Predicate>(bs.Observed);
            AvailableActions = new List<Action>();
            UnderlyingEnvironmentState = bs.UnderlyingEnvironmentState;
            m_bsInitialBelief = bs;
            ChildCount = 0;

            m_lHidden = new HashSet<Predicate>();
            foreach (CompoundFormula cf in bs.Hidden)
            {
                HashSet<Predicate> lCurrent = new HashSet<Predicate>();
                cf.GetAllPredicates(lCurrent);
                foreach (Predicate p in lCurrent)
                {
                    if (p.Negation)
                    {
                        if (!m_lHidden.Contains(p.Negate()))
                            m_lHidden.Add(p.Negate());
                    }
                    else if (!m_lHidden.Contains(p))
                        m_lHidden.Add(p);
                }

            }

            /* as long as there are no non-deterministic effects there is no need to maintain all knowledge
            foreach (Predicate p in bs.Observed)
            {
                if (!Problem.Domain.AlwaysKnown(p))
                    cfBelief.AddOperand(p);
            }
             * */

            FunctionValues = new Dictionary<string, double>();
            foreach (string sFunction in Problem.Domain.Functions)
            {
                FunctionValues[sFunction] = m_bsInitialBelief.FunctionValues[sFunction];
            }

            m_lHistory = new List<string>();
        }
        public static List<string> LargeWumpusHeuristic(PartiallySpecifiedState pssCurrent, Domain d)
        {
            List<string> lActions = new List<string>();
            GroundedPredicate gpAtX = null, gpAtY = null;
            foreach (GroundedPredicate gp in pssCurrent.Observed)
            {
                if (!gp.Negation)
                {
                    if (gp.Name == "at-x")
                        gpAtX = gp;
                    if (gp.Name == "at-y")
                        gpAtY = gp;
                }
            }
            string sX = gpAtX.Constants[0].Name;
            string sY = gpAtY.Constants[0].Name;
            int iX = int.Parse(sX.Split('-')[1]);
            int iY = int.Parse(sY.Split('-')[1]);
            VisitedLocations.Add(iX * 1000 + iY);

            GroundedPredicate gpAlive = new GroundedPredicate("alive");
            if (pssCurrent.Hidden.Contains(gpAlive))
                lActions.Add("check-alive_" + sX + "_" + sY);
            GroundedPredicate gpStench = new GroundedPredicate("stench");
            gpStench.AddConstant(gpAtX.Constants[0]);
            gpStench.AddConstant(gpAtY.Constants[0]);
            if (pssCurrent.Hidden.Contains(gpStench))
                lActions.Add("smell-wumpus " + sX + " " + sY);
            GroundedPredicate gpBreeze = new GroundedPredicate("breeze");
            gpBreeze.AddConstant(gpAtX.Constants[0]);
            gpBreeze.AddConstant(gpAtY.Constants[0]);
            if (pssCurrent.Hidden.Contains(gpBreeze))
                lActions.Add("feel-breeze " + sX + " " + sY);
            GroundedPredicate gpGold = new GroundedPredicate("gold-at");
            gpGold.AddConstant(gpAtX.Constants[0]);
            gpGold.AddConstant(gpAtY.Constants[0]);
            if (pssCurrent.Hidden.Contains(gpGold))
                lActions.Add("observe-gold " + sX + " " + sY);

            if (lActions.Count == 0)
            {
                List<string> lNotVisited = new List<string>();
                List<string> lSafe = new List<string>();
                if (iX > 1)
                {
                    if(!VisitedLocations.Contains((iX - 1) * 1000 + iY))
                        lNotVisited.Add("move-left");
                    if (pssCurrent.Observed.Contains(GetSafe(iX - 1, iY)))
                        lSafe.Add("move-left");
                }
                if (iX < Size )
                {
                    if(!VisitedLocations.Contains((iX + 1) * 1000 + iY))
                        lNotVisited.Add("move-right");
                    if (pssCurrent.Observed.Contains(GetSafe(iX + 1, iY)))
                        lSafe.Add("move-right");
                }
                if (iY > 1)
                {
                    if(!VisitedLocations.Contains(iX * 1000 + (iY - 1)))
                        lNotVisited.Add("move-up");
                    if (pssCurrent.Observed.Contains(GetSafe(iX, iY - 1)))
                        lSafe.Add("move-up");
                }
                if (iY < Size)
                {
                    if(!VisitedLocations.Contains(iX * 1000 + (iY + 1)))
                        lNotVisited.Add("move-down");
                    if (pssCurrent.Observed.Contains(GetSafe(iX, iY + 1)))
                        lSafe.Add("move-down");
                }
                List<string> lSafeAndNotVisited = new List<string>(lSafe.Intersect(lNotVisited));
                if (lSafeAndNotVisited.Count > 0)
                {
                    int idx = RandomGenerator.Next(lSafeAndNotVisited.Count);
                    lActions.Add(lSafeAndNotVisited[idx]);
                }
                else if (lSafe.Count > 0)
                {
                    int idx = RandomGenerator.Next(lSafe.Count);
                    lActions.Add(lSafe[idx]);
                }
                else
                {
                    int idx = RandomGenerator.Next(4);
                    if (idx == 0)
                        lActions.Add("move-down");
                    if (idx == 1)
                        lActions.Add("move-up");
                    if (idx == 2)
                        lActions.Add("move-left");
                    if (idx == 3)
                        lActions.Add("move-right");
                }
            }

            return lActions;
        }
        public static List<string> MineSweeperHeuristic(PartiallySpecifiedState pssCurrent, Domain d, Formula fObserve)
        {
            int[,] aBoard;
            aBoard = new int[Size, Size];
            List<string> lActions = new List<string>();
            List<int> lUnknown = new List<int>();

            for (int iX = 0; iX < Size; iX++)
            {
                for (int iY = 0; iY < Size; iY++)
                {
                    GroundedPredicate gp = GetPredicate("opened", iX, iY);
                    if (pssCurrent.Observed.Contains(gp))
                    {
                        aBoard[iX, iY] = 1;//opened
                    }
                    else
                    {

                        gp = GetPredicate("mine-at", iX, iY);
                        if (pssCurrent.Observed.Contains(gp))
                        {
                            gp = GetPredicate("flagged", iX, iY);
                            if (pssCurrent.Observed.Contains(gp))
                                aBoard[iX, iY] = 4;//flagged mine
                            else
                                aBoard[iX, iY] = 2;//unflagged mine
                        }
                        else if(pssCurrent.Observed.Contains(gp.Negate()))
                            aBoard[iX, iY] = 3;//no mine
                    }
                }
            }

            List<int> lCandidates = new List<int>();
            for (int iX = 0; iX < Size; iX++)
            {
                for (int iY = 0; iY < Size; iY++)
                {
                    if (aBoard[iX, iY] == 0 || aBoard[iX, iY] == 3)
                    {
                        lCandidates.Add((iX) * 1000 + iY);
                    }
                    else if (aBoard[iX, iY] == 2)
                        lActions.Add("flag p" + iX + "-" + iY);
                }
            }

            if (lCandidates.Count > 0)
            {
                int iChosen = lCandidates[RandomGenerator.Next(lCandidates.Count)];
                int iChosenX = iChosen / 1000;
                int iChosenY = iChosen % 1000;
                lActions.Add("open-cell-" + iChosenX + "-" + iChosenY);
                //lActions.Add("open-cell p" + iChosenX + "-" + iChosenY);
                lActions.Add("observe-dead");
                for (int i = 0; i < 9; i++)
                    lActions.Add("observe-mine-count p" + iChosenX + "-" + iChosenY + " v" + i);
                Shootings++;
            }
                /*
            else if (lUnknown.Count > 0)
            {
                int iChosen = lUnknown[RandomGenerator.Next(lUnknown.Count)];
                int iChosenX = iChosen / 1000;
                int iChosenY = iChosen % 1000;
                lActions.Add("shoot p-" + iChosenX + " p-" + iChosenY);
                Shootings++;
            }
            */

            return lActions;
        }
        public HashSet<int> ReviseInitialBelief(Formula fObserve, PartiallySpecifiedState pssLast)
        {
            DateTime dtBefore = DateTime.Now;
            Stack<PartiallySpecifiedState> sTrace = new Stack<PartiallySpecifiedState>();
            Stack<List<Formula>> sForumalsTrace = new Stack<List<Formula>>();
            PartiallySpecifiedState pssCurrent = pssLast, pssSuccessor = null;
            HashSet<int> hsModifiedClauses = new HashSet<int>();
            //Formula fToRegress = fObserve, fRegressed = null;
            bool bTrueRegression = false;
            int cSteps = 0;

            count_revisions++;
            List<Formula> lCurrentFormulas = new List<Formula>();
            List<Formula> lRegressedFormulas = new List<Formula>();

            lCurrentFormulas.Add(fObserve);

            //TimeSpan ts1 = new TimeSpan(0), ts2 = new TimeSpan(0);
            //DateTime dtStart = DateTime.Now;
            while (pssCurrent.Predecessor != null)
            {
                sTrace.Push(pssCurrent);
                sForumalsTrace.Push(lCurrentFormulas);
                lRegressedFormulas = new List<Formula>();
                HashSet<Predicate> hsNew = new HashSet<Predicate>();
                foreach (Formula fCurrent in lCurrentFormulas)
                {
                    if (fCurrent.IsTrue(pssCurrent.Observed))
                        continue;//used to be break but I think that if we got here then there is no point in continuing...
                    //is false doesn't properly work here
                    //Debug.Assert(fCurrent.IsFalse(pssCurrent.Observed), "Rgression of an observation returned false");
                    //pssCurrent.GeneratingAction.ClearConditionsChoices();
                    //pssCurrent.GeneratingAction.RemoveImpossibleOptions(pssCurrent.Observed); Need to this after the regression (below)
                    //DateTime dt = DateTime.Now;
                    Formula fRegressed = pssCurrent.RegressObservation(fCurrent);
                    //ts1 += DateTime.Now - dt;
                    if (fRegressed is CompoundFormula)
                    {
                        CompoundFormula cf = (CompoundFormula)fRegressed;
                        if (cf.Operator != "and")
                        {
                            lRegressedFormulas.Add(fRegressed);
                        }
                        else
                        {
                            foreach (Formula f in cf.Operands)
                                lRegressedFormulas.Add(f);
                        }

                    }
                    else
                        lRegressedFormulas.Add(fRegressed);

                    //dt = DateTime.Now;
                    //must be after the regression so as not to make everything already known
                    if (!Problem.Domain.IsSimple || !SDRPlanner.OptimizeMemoryConsumption)
                        hsNew.UnionWith(pssCurrent.AddObserved(fCurrent));
                    //ts2 += DateTime.Now - dt;
                    //pssCurrent.AddObserved(fToRegress); //Not sure that this is valid!

                    if (!fRegressed.Equals(fCurrent))
                        //if (bTrueRegression || !fRegressed.Equals(fToRegress))
                        bTrueRegression = true;
                }
                if (hsNew.Count > 0 && pssSuccessor != null)
                {
                    hsNew = pssSuccessor.PropogateObservedPredicates(hsNew);
                    /*
                    for (int i = 0; i < sTrace.Count; i++)
                    {
                        PartiallySpecifiedState pssUpdate = sTrace.ElementAt(i);
                        hsNew = pssUpdate.PropogateObservedPredicates(hsNew);
                        if (hsNew.Count == 0)
                            break;
                    }
                     * */
                }
                pssSuccessor = pssCurrent;
                pssCurrent = pssCurrent.Predecessor;
                cSteps++;
                lCurrentFormulas = lRegressedFormulas;
            }

            Formula fFinal = null;
            if (lCurrentFormulas.Count == 0)
                return hsModifiedClauses;
            if (lCurrentFormulas.Count == 1)
            {
                fFinal = lCurrentFormulas[0].Reduce(Observed);
                fFinal = fFinal.ToCNF();
            }
            else
            {
                CompoundFormula cf = new CompoundFormula("and");
                foreach (Formula f in lCurrentFormulas)
                {
                    Formula fReduced = f.Reduce(Observed).Simplify();
                    Formula fCNF = null;
                    if (fReduced is CompoundFormula)
                        fCNF = ((CompoundFormula)fReduced).ToCNF();
                    else
                        fCNF = fReduced;
                    cf.AddOperand(fCNF);
                }
                fFinal = cf;

            }
            //Debug.WriteLine("Total time in regressobs " + ts1.TotalSeconds + " propogate " + ts2.TotalSeconds +
            //     " all " + (DateTime.Now - dtStart).TotalSeconds + " size " + fFinal.Size);

            if (fFinal.IsTrue(null))
                return hsModifiedClauses;
            DateTime dtAfterRegression = DateTime.Now;

            DateTime dtAfterReasoning = DateTime.Now;
            //Seems likely but I am unsure: if there was no real regression, then learned things can be applied to all states as is

            HashSet<Predicate> lLearned = null;
            if (BeliefState.UseEfficientFormulas)
                lLearned = AddReasoningFormulaEfficient(fFinal);
            else
                lLearned = AddReasoningFormula(fFinal, hsModifiedClauses);

            HashSet<Predicate> lOriginalLearned = new HashSet<Predicate>(lLearned);

            if (lLearned.Count > 0)
            {
                //HashSet<Predicate> lLearned = pssCurrent.ApplyReasoning(); not needed since we got the learned predicates from the belief update
                if (!Problem.Domain.IsSimple || !SDRPlanner.ComputeCompletePlanTree)
                    pssCurrent.AddObserved(lLearned);
                dtAfterReasoning = DateTime.Now;
                if (bTrueRegression)
                {
                    //while (bUpdate && sTrace.Count > 0)
                    while (sTrace.Count > 0 && lLearned.Count > 0)
                    {
                        pssCurrent = sTrace.Pop();
                        //bUpdate = pssCurrent.PropogateObservedPredicates();
                        lLearned = pssCurrent.PropogateObservedPredicates(lLearned);
                    }
                    if (SDRPlanner.OptimizeMemoryConsumption && lLearned.Count > 0)
                    {
                        pssLast.AddObserved(lLearned);
                    }
                }
                else
                {
                    if (!SDRPlanner.OptimizeMemoryConsumption)
                    {
                        while (sTrace.Count > 0)
                        {
                            pssCurrent = sTrace.Pop();
                            pssCurrent.AddObserved(lLearned);
                        }
                    }
                    else
                        pssLast.AddObserved(lLearned);
                }

            }
            /*
            Console.WriteLine("Time for belief update: " +
                (DateTime.Now - dtBefore).TotalSeconds +
                " regression " + (dtAfterRegression - dtBefore).TotalSeconds +
                " reasoning " + (dtAfterReasoning - dtAfterRegression).TotalSeconds +
                " update " + (DateTime.Now - dtAfterReasoning).TotalSeconds);
            */

            return hsModifiedClauses;
        }
 public PartiallySpecifiedState GetPartiallySpecifiedState()
 {
     PartiallySpecifiedState pss = new PartiallySpecifiedState(this);
     if(SDRPlanner.EnforceCNF)
         m_cfCNFHiddenState = (CompoundFormula)m_cfCNFHiddenState.ToCNF();
     return pss;
 }