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;
        }