public Formula RegressObservation(Formula f)
 {
     /* There is no point in adding the observation, because it was already regressed
     CompoundFormula fWithObservation = new CompoundFormula("and");
     fWithObservation.AddOperand(f);
     if (GeneratingObservation != null)
         fWithObservation.AddOperand(GeneratingObservation);
     Formula fReduced = fWithObservation.Reduce(Observed);
      */
     Formula fReduced = f.Reduce(Observed);
     Formula fToRegress = fReduced;
     if (fToRegress is CompoundFormula)
     {
         bool bChanged = false;
         //fToRegress = ((CompoundFormula)fToRegress).RemoveNestedConjunction(out bChanged).Simplify();
     }
     if (fToRegress.IsTrue(null))
         return fToRegress;
     if (fToRegress.IsFalse(null))
         Debug.Assert(false);
     if (GeneratingAction.HasConditionalEffects)
     {
         Formula fRegressed = fToRegress.Regress(GeneratingAction, Observed);
         return fRegressed;
     }
     else
         return fToRegress;
 }
        public bool ConsistentWith(Formula fOriginal)
        {
            /*
            CompoundFormula cfCNF = (CompoundFormula)m_cfCNFHiddenState.Clone();
            cfCNF.AddOperand(f);
            cfCNF = cfCNF.ToCNF();
            if (cfCNF.IsFalse(Observed))
            {
                MaintainProblematicTag = false;
                return false;
            }
             * */
            Formula f = fOriginal.Reduce(Observed);
            if (f.ToString().Contains(Domain.FALSE_PREDICATE))
                return false;
            if (f.ToString().Contains(Domain.TRUE_PREDICATE))
                return true;
            CompoundFormula cf = null;
            List<PredicateFormula> lPredicates = new List<PredicateFormula>();
            List<CompoundFormula> lFormulas = new List<CompoundFormula>();
            if (f is PredicateFormula)
            {
                lPredicates.Add((PredicateFormula)f);
            }
            else
            {
                cf = (CompoundFormula)f;
                CompoundFormula cfCNF = (CompoundFormula)cf.ToCNF();
                if (cfCNF.Operator == "and")
                {
                    foreach (Formula fSub in cfCNF.Operands)
                    {
                        if (fSub is PredicateFormula)
                            lPredicates.Add((PredicateFormula)fSub);
                        else
                            lFormulas.Add((CompoundFormula)fSub);
                    }
                }
                else
                    lFormulas.Add(cfCNF);

            }

            if (lPredicates.Count > 0)
            {
                HashSet<int> lIndexes = new HashSet<int>();
                List<Predicate> lKnown = new List<Predicate>();
                foreach (PredicateFormula pf in lPredicates)
                {
                    if (m_dMapPredicatesToFormulas.ContainsKey((GroundedPredicate)pf.Predicate.Canonical()))
                    {
                        lKnown.Add(pf.Predicate);
                        foreach (int idx in m_dMapPredicatesToFormulas[(GroundedPredicate)pf.Predicate.Canonical()])
                            lIndexes.Add(idx);
                    }
                }
                foreach (int idx in lIndexes)
                {
                    if (m_lHiddenFormulas[idx] != null && m_lHiddenFormulas[idx].IsFalse(lKnown))
                        return false;
                }

            }
            if(true)
            {
                List<Formula> lHidden = new List<Formula>(m_lHiddenFormulas);
                lHidden.AddRange(lFormulas);
                lHidden.AddRange(lPredicates);
                List<List<Predicate>> lConsistentAssignments = RunSatSolver(lHidden, 1);
                if (MaintainProblematicTag)
                    m_lProblematicTag = null;
                if (lConsistentAssignments.Count > 0)
                {
                    if (MaintainProblematicTag)
                    {
                        m_lProblematicTag = lConsistentAssignments[0];
                    }
                }
                else
                {
                    //we have just discovered something that is inconsistent with the initial belief, so we can add its negation to the initial belief
                    AddReasoningFormula(f.Negate(), new HashSet<int>());
                }
                MaintainProblematicTag = false;
                return lConsistentAssignments.Count > 0;
            }
            if (false)//for debugging the ongoing reduction of hidden formulas given observations - here I use the original formulas + the observed
            {
                List<Formula> lHidden = new List<Formula>(m_lOriginalHiddenFormulas);
                foreach (GroundedPredicate gp in Observed)
                    lHidden.Add(new PredicateFormula(gp));
                lHidden.AddRange(lPredicates);
                List<List<Predicate>> lConsistentAssignments = RunSatSolver(lHidden, 1);
                if (MaintainProblematicTag)
                    m_lProblematicTag = null;
                if (lConsistentAssignments.Count > 0)
                {
                    if (MaintainProblematicTag)
                    {
                        m_lProblematicTag = lConsistentAssignments[0];
                        /*
                        foreach (CompoundFormula cfHidden in m_lOriginalHiddenFormulas)
                        {
                            if (cfHidden.ToString().Contains("obs1-at p2_1"))
                                    Console.WriteLine("*");
                            Formula fReduced = cfHidden.Reduce(m_lProblematicTag);
                            if (fReduced is PredicateFormula)
                            {
                                PredicateFormula pf = (PredicateFormula)fReduced;
                                if (pf.Predicate.Name == "P_FALSE")
                                    Console.WriteLine("*");
                                else if (pf.Predicate.Name != "P_TRUE" && !pf.Predicate.Negation)
                                    Console.WriteLine(pf);

                            }
                        }
                         * */
                    }
                }
                MaintainProblematicTag = false;
                return lConsistentAssignments.Count > 0;
            }
            return true;
        }