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