public BeliefState(Problem p)
        {
            Problem = p;
            m_sPredecessor = null;
            m_lObserved = new HashSet<Predicate>();
            Unknown = new HashSet<Predicate>();
            m_lHiddenFormulas = new List<CompoundFormula>();
            m_lOriginalHiddenFormulas = new List<CompoundFormula>();
            m_dMapPredicatesToFormulas = new Dictionary<GroundedPredicate, List<int>>();

            m_lEfficientHidden = new List<EfficientFormula>();
            m_dMapPredicatesToIndexes = new Dictionary<GroundedPredicate, int>();
            m_dMapIndexToPredicate = new List<GroundedPredicate>();
            m_dMapPredicateToEfficientFormula = new List<List<int>>();

            AvailableActions = new List<Action>();
            UnderlyingEnvironmentState = null;
            m_cfCNFHiddenState = new CompoundFormula("and");
            FunctionValues = new Dictionary<string, double>();
            foreach (string sFunction in Problem.Domain.Functions)
            {
                FunctionValues[sFunction] = 0.0;
            }

            bsCOUNT++;
            ID = bsCOUNT;
        }
 private void AddKnowledgePredicatesToExistingActions(Domain d, List<Predicate> lKnowPredicates)
 {
     Actions = new List<Action>();
     ParametrizedAction aRevised = null;
     foreach (Action a in d.Actions)
     {
         aRevised = new ParametrizedAction(a.Name);
         aRevised.Preconditions = AddKnowledgePredicatesToFormula(a.Preconditions, lKnowPredicates);
         CompoundFormula cfEffects = null;
         if (a.Effects != null)
         {
             cfEffects = AddKnowledgePredicatesToFormula(a.Effects, lKnowPredicates);
         }
         else
         {
             cfEffects = new CompoundFormula("and");
         }
         if (a.Observe != null)
         {
             List<Predicate> lPredicates = GetAllPredicates(a.Observe);
             foreach (Predicate p in lPredicates)
             {
                 cfEffects.AddOperand(new PredicateFormula(new KnowPredicate(p)));
             }
         }
         aRevised.SetEffects(cfEffects);
         Actions.Add(aRevised);
     }
 }
 public CompoundFormula(CompoundFormula cf)
     : this(cf.Operator)
 {
     foreach (Formula f in cf.Operands)
         AddOperand(f);
     Simplified = cf.Simplified;
     Size = 0;
     SATSolverClauses = new List<List<int>>();
 }
 private CompoundFormula AddKnowledgePredicatesToFormula(Formula f, List<Predicate> lKnowPredicates)
 {
     CompoundFormula cf = new CompoundFormula("and");
     List<Predicate> lPredicates = GetAllPredicates(f);
     foreach (Predicate p in lPredicates)
     {
         if (lKnowPredicates.Contains(p))
             cf.AddOperand(new PredicateFormula(new KnowPredicate(p)));
     }
     cf.AddOperand(f);
     return cf;
 }
 public ReasoningPredicate(CompoundFormula cf)
     : base("Reasoning-" + cf.Operator)
 {
     Operator = cf.Operator;
     Predicates = new List<Predicate>();
     foreach (Formula f in cf.Operands)
     {
         if (f is PredicateFormula)
         {
             Predicates.Add(((PredicateFormula)f).Predicate);
         }
         else
         {
             Predicates.Add(new ReasoningPredicate((CompoundFormula)f));
         }
     }
 }
        public Action AddKnowledge(List<string> lAlwaysKnown)
        {
            Action aNew = Clone();

            CompoundFormula cfPreconditions = new CompoundFormula("and");
            HashSet<Predicate> lKnowPreconditions = new HashSet<Predicate>();
            if (Preconditions != null)
            {
                Preconditions.GetAllPredicates(lKnowPreconditions);
                cfPreconditions.AddOperand(Preconditions);
                foreach (Predicate p in lKnowPreconditions)
                    if (!lAlwaysKnown.Contains(p.Name))
                        cfPreconditions.AddOperand(new PredicateFormula(new KnowPredicate(p)));
                aNew.Preconditions = cfPreconditions;
            }
            if (Effects != null)
            {
                HashSet<Predicate> lKnowEffects = new HashSet<Predicate>();
                CompoundFormula cfEffects = new CompoundFormula("and");
                Effects.GetAllPredicates(lKnowEffects);
                cfEffects.AddOperand(Effects.Clone());

                foreach (Predicate p in lKnowEffects)
                    if (!lAlwaysKnown.Contains(p.Name))
                        cfEffects.AddOperand(new PredicateFormula(new KnowPredicate(p)));

                aNew.Effects = cfEffects;
            }
            if (Observe != null)
            {
                if (aNew.Effects == null)
                    aNew.Effects = new CompoundFormula("and");
                Predicate pObserve = ((PredicateFormula)Observe).Predicate;
                ((CompoundFormula)aNew.Effects).AddOperand(new KnowPredicate(pObserve));
            }
            return aNew;
        }
 private List<Action> RemoveDisjunctions(List<Action> lGrounded)
 {
     List<Action> lNoDisjunctions = new List<Action>();
     foreach (Action a in lGrounded)
     {
             //if (a.Name.Contains("move-KW-tag0"))
           //      Console.WriteLine("*");
         if (a.Preconditions == null || a.Preconditions is PredicateFormula)
             lNoDisjunctions.Add(a);
         else
         {
             HashSet<Predicate> hsMandatory = new HashSet<Predicate>();
             List<List<Formula>> lOptions = new List<List<Formula>>();
             ((CompoundFormula)a.Preconditions).IdentifyDisjunctions(lOptions, hsMandatory);
             CompoundFormula cfAnd = new CompoundFormula("and");
             foreach (Predicate p in hsMandatory)
                 cfAnd.AddOperand(p);
             int iIndex = 0;
             RemoveDisjunctions(a, lOptions, 0, cfAnd, lNoDisjunctions, ref iIndex);
         }
     }
     return lNoDisjunctions;
 }
 private List<Action> RemoveConditions(List<Action> lActions)
 {
     List<Action> lNoConditions = new List<Action>();
     foreach (Action a in lActions)
     {
         HashSet<Predicate> lMandatory = a.GetMandatoryEffects();
         List<CompoundFormula> lConditions = a.GetConditions();
         if (lConditions.Count == 0)
         {
             lNoConditions.Add(a);
         }
         else
         {
             int iCondition = 0;
             foreach (CompoundFormula cfCondition in lConditions)
             {
                 Action aNew = new Action(a.Name + "." + iCondition);
                 CompoundFormula cfPreconditions = new CompoundFormula("and");
                 cfPreconditions.AddOperand(a.Preconditions);
                 cfPreconditions.AddOperand(cfCondition.Operands[0]);
                 if (!cfPreconditions.IsFalse(null))
                 {
                     aNew.Preconditions = cfPreconditions;
                     CompoundFormula cfEffects = new CompoundFormula("and");
                     cfEffects.AddOperand(cfCondition.Operands[1]);
                     foreach (Predicate p in lMandatory)
                         cfEffects.AddOperand(p);
                     aNew.Effects = cfEffects;
                     lNoConditions.Add(aNew);
                     iCondition++;
                 }
             }
         }
     }
     return lNoConditions;
 }
        /*
        private List<Formula> GetLandmarks(Formula fCurrentLandmark, Dictionary<Predicate, List<Action>> dLandmarkAchievers, HashSet<Predicate> lInitialState)
        {
            CompoundFormula cfOr = new CompoundFormula("or");
            List<Formula> lFormulas = new List<Formula>();
            foreach (Predicate pKey in dLandmarkAchievers.Keys)
            {
                List<Action> lActions = dLandmarkAchievers[pKey];
                if (lActions.Count == 0)
                    continue;
                //looking for preconditions that are needed for all actions that achieve p
                HashSet<Predicate> lJointPreconditions = GetJointPreconditions(lActions);
                bool bNewLandmarkFound = false;
                if (lJointPreconditions.Count > 0)
                {
                    CompoundFormula cfAnd = new CompoundFormula("and");
                    foreach (Predicate p in lJointPreconditions)
                    {
                        if (!lInitialState.Contains(p))
                        {
                            cfAnd.AddOperand(p);
                            bNewLandmarkFound = true;
                        }
                    }
                    if(bNewLandmarkFound)
                        cfOr.AddOperand(cfAnd);
                }
                if(!bNewLandmarkFound)
                {
                    Dictionary<string, List<Predicate>> dDisjunctions = GetDisjunctivePreconditions(lActions);
                    foreach (List<Predicate> l in dDisjunctions.Values)
                    {
                        if (l.Count >= lActions.Count)
                        {
                            CompoundFormula cfInternalOr = new CompoundFormula("or");
                            foreach (Predicate p in l)
                            {
                                if (!lInitialState.Contains(p))
                                {

                                    cfOr.AddOperand(p);
                                }
                            }
                            if (cfInternalOr.Operands.Count > 0)
                                cfOr.AddOperand(cfInternalOr);
                        }
                    }
                }
            }
            Formula fSimplified = cfOr.Simplify();
            if (fSimplified is PredicateFormula)
                lFormulas.Add(fSimplified);
            else
            {
                CompoundFormula cf = (CompoundFormula)fSimplified;
                if (cf.Operator == "or")
                    lFormulas.Add(cf);
                else
                {
                    foreach (Formula fSub in cf.Operands)
                        lFormulas.Add(fSub);
                }

            }
            return lFormulas;
        }
        */
        private bool RegressLandmark(Predicate pCurrentLandmark, List<Action> lLandmarkAchievers, HashSet<Predicate> lInitialState,
            Dictionary<string, CompoundFormula> dFormulas)
        {
            if (lLandmarkAchievers.Count == 0)
                return false;
            //looking for preconditions that are needed for all actions that achieve p
            HashSet<Predicate> lJointPreconditions = GetJointPreconditions(lLandmarkAchievers);
            bool bNewLandmarkFound = false;
            if (lJointPreconditions.Count > 0)
            {

                foreach (GroundedPredicate pPrecondition in lJointPreconditions)
                {
                    if (!lInitialState.Contains(pPrecondition))
                    {
                        string sPreconditionName = GetNameAndTag(pPrecondition);
                        if (!dFormulas.ContainsKey(sPreconditionName))
                            dFormulas[sPreconditionName] = new CompoundFormula("and");

                        dFormulas[sPreconditionName].AddOperand(pPrecondition);
                        bNewLandmarkFound = true;
                    }
                }

            }

            Dictionary<string, Dictionary<string, List<Predicate>>> dDisjunctions = GetDisjunctivePreconditions(lLandmarkAchievers, lInitialState);
            foreach (string sPredicateType in dDisjunctions.Keys)//go over the different pre types
            {
                Dictionary<string, List<Predicate>> dActionToPrecondition = dDisjunctions[sPredicateType];
                if (dActionToPrecondition.Count == lLandmarkAchievers.Count)//all achivers require a pre of this type
                {
                    if (!dFormulas.ContainsKey(sPredicateType))//allowing disjunctions only for predicate types where no joint preconditions exist
                    {
                        dFormulas[sPredicateType] = new CompoundFormula("or");
                        /*
                    else
                    {
                        CompoundFormula cfOr = new CompoundFormula("or");
                        cfOr.AddOperand(dFormulas[sPredicateType]);
                        dFormulas[sPredicateType] = cfOr;
                    }
                         * */
                        foreach (KeyValuePair<string, List<Predicate>> pair in dActionToPrecondition)
                        {
                            foreach (Predicate p in pair.Value)
                            {
                                if (!lInitialState.Contains(p))
                                {
                                    dFormulas[sPredicateType].AddOperand(p);
                                }
                            }
                        }
                    }
                }
            }

            return true;
        }
 public override Formula RemoveNegations()
 {
     CompoundFormula cf = new CompoundFormula(Operator);
     foreach (Formula f in Operands)
     {
         Formula fRemoved = f.RemoveNegations();
         if (f != null)
         {
             cf.AddOperand(fRemoved);
         }
     }
     return cf;
 }
 public override Formula Regress(Action a)
 {
     CompoundFormula cfNew = new CompoundFormula(Operator);
     foreach (Formula f in Operands)
     {
         //Formula fRgressed = f.Regress(a, lObserved);
         Formula fRgressed = f.Regress(a);
         //what happens if we get  "TRUE" or "FALSE"?
         cfNew.AddOperand(fRgressed);
     }
     return cfNew.Simplify();
 }
        public override Formula Reduce(IEnumerable<Predicate> lKnown)
        {
            CompoundFormula cfReduced = new CompoundFormula(Operator);
            Formula fNew = null;
            foreach (Formula f in Operands)
            {
                bool bTrue = false;
                bool bFalse = false;
                if (f is PredicateFormula)
                {
                    fNew = null;
                    Predicate p = ((PredicateFormula)f).Predicate;
                    if (lKnown.Contains(p))
                        bTrue = true;
                    else if (lKnown.Contains(p.Negate()))
                        bFalse = true;
                    else
                        fNew = f;
                }
                else
                    fNew = ((CompoundFormula)f).Reduce(lKnown);
                //if (fNew.IsTrue(lKnown))
                if (bTrue || (!bFalse && fNew.IsTrue(null)))
                {
                    if (Operator == "or")
                        return new PredicateFormula(new GroundedPredicate(Domain.TRUE_PREDICATE));//reasoning predicate no longer informative
                    //else if (Operator == "and")
                     //   cfReduced.Operands.Remove(fNew); - not adding so no need to remove
                    else if (Operator == "oneof")
                    {//(oneof a b c) and a = (and !b !c)
                        cfReduced = new CompoundFormula("and");
                        List<Formula> lPredicates = new List<Formula>();
                        foreach (Formula pOther in Operands)
                        {
                            if (!pOther.Equals(f))
                                lPredicates.Add(pOther.Negate());
                        }
                        if (lPredicates.Count == 1)
                            return lPredicates[0];

                        cfReduced.Operands = lPredicates;
                        return cfReduced;
                    }
                    //else
                    //    throw new NotImplementedException();
                }
                //else if (fNew.IsFalse(lKnown))

                else if (bFalse || (!bTrue && fNew.IsFalse(null)))
                {
                    if (Operator == "and")
                    {
                        return new PredicateFormula(new GroundedPredicate(Domain.FALSE_PREDICATE));//formula must be false
                    }
                    /* not adding so no need to remove
                else if (Operator == "or")
                {
                    cfReduced.Operands.Remove(fNew);
                }
                else if (Operator == "oneof")
                {
                    cfReduced.Operands.Remove(fNew);
                }
                     * */
                    //else
                    //    throw new NotImplementedException();
                }
                else
                {
                    bool bOperandExists = cfReduced.AddOperand(fNew);
                    if (bOperandExists && Operator == "oneof")
                        return new PredicateFormula(new GroundedPredicate(Domain.FALSE_PREDICATE));//oneof requires only one - duplicate means trouble
                }

            }
            if (cfReduced.Operands.Count == 0)
            {
                if(Operator == "and")
                    return new PredicateFormula(new GroundedPredicate(Domain.TRUE_PREDICATE));//no negative found so total value is true
                if(Operator == "or")
                    return new PredicateFormula(new GroundedPredicate(Domain.FALSE_PREDICATE));//no positive found so total value is false
            }
            if (cfReduced.Operands.Count == 1)
                return cfReduced.Operands[0];
            if (Operator == "and")
                return cfReduced.ReduceAnd();
            if (cfReduced.Operands.Count == 1)
                return cfReduced.Operands[0];
            return cfReduced;
            //return cfReduced.Simplify(); not sure why we would need to simplify here?
        }
 public CompoundFormula ApplyConditionsII(List<CompoundFormula> lConditions)
 {
     Dictionary<Formula, Formula> dTranslations = new Dictionary<Formula, Formula>();
     foreach (CompoundFormula cfCondition in lConditions)
     {
         Formula fRest = null;
         if (cfCondition.ConditionDeletesPrecondition(out fRest))
             dTranslations[cfCondition.Operands[0].Simplify()] = fRest;
         else
         {
             CompoundFormula cfAnd = new CompoundFormula("and");
             cfAnd.AddOperand(cfCondition.Operands[0].Simplify());
             cfAnd.AddOperand(cfCondition.Operands[1].Simplify());
             dTranslations[cfCondition.Operands[0].Simplify()] = cfAnd.Simplify();
         }
     }
     if (dTranslations.Count == 0)
         return this;
     return (CompoundFormula)Replace(dTranslations);
 }
 public override Formula AddTime(int iTime)
 {
     CompoundFormula cf = new CompoundFormula(Operator);
     foreach (Formula f in Operands)
         cf.AddOperand(f.AddTime(iTime));
     return cf;
 }
 private CompoundFormula RemoveRedundancies()
 {
     if (Operator == "or")
     {
         HashSet<Predicate> lPredicates = GetAllPredicates();
         HashSet<Predicate> lObligatory = new HashSet<Predicate>();
         foreach (Predicate p in lPredicates)
         {
             List<Predicate> lNotP = new List<Predicate>();
             lNotP.Add(p.Negate());
             if (IsFalse(lNotP))
                 lObligatory.Add(p);
         }
         if (lObligatory.Count == 0)
         {
             return this;
         }
         CompoundFormula cfAnd = new CompoundFormula("and");
         CompoundFormula cfOr = new CompoundFormula("or");
         foreach (Predicate p in lObligatory)
             cfAnd.AddOperand(p);
         foreach (Formula f in Operands)
             cfOr.AddOperand(f.Reduce(lObligatory));
         cfAnd.AddOperand(cfOr);
         return cfAnd;
     }
     return this;
 }
 public override Formula Negate()
 {
     CompoundFormula cfNegate = null;
     if (Operator == "when")
         return this;//special case - "when" is not truly a boolean formula (?)
     if (Operator == "or")
         cfNegate = new CompoundFormula("and");
     if (Operator == "and")
         cfNegate = new CompoundFormula("or");
     if (Operator == "oneof")
         throw new NotImplementedException("Not handling oneof for now");
     if (Operator == "not")
         return Operands[0];
     if (cfNegate == null)
         return null;
     foreach (Formula fOperand in Operands)
         cfNegate.AddOperand(fOperand.Negate());
     return cfNegate;
 }
        public override Formula PartiallyGround(Dictionary<string, Constant> dBindings)
        {
            CompoundFormula cfGrounded = new CompoundFormula(Operator);
            foreach (Formula fSub in Operands)
            {
                Formula fGrounded = fSub.PartiallyGround(dBindings);
                if (fGrounded is PredicateFormula)
                {
                    Predicate p = ((PredicateFormula)fGrounded).Predicate;
                    if (p.Name == Domain.TRUE_PREDICATE)
                    {
                        if (Operator == "and")
                            continue;
                        else if (Operator == "or")
                            return fGrounded;
                        else
                            throw new NotImplementedException();
                    }
                    if (p.Name == Domain.FALSE_PREDICATE)
                    {
                        if (Operator == "and")
                            return fGrounded;
                        else if (Operator == "or")
                            continue;
                        else if (Operator == "when")
                        {
                            return null;
                        }
                        else
                            throw new NotImplementedException();
                    }

                }
                cfGrounded.AddOperand(fGrounded);
                if (cfGrounded.IsFalse(null))
                    return new PredicateFormula(new GroundedPredicate(Domain.FALSE_PREDICATE));
            }
            return cfGrounded;
        }
 public override Formula ApplyKnown(IEnumerable<Predicate> lKnown)
 {
     CompoundFormula cfNew = new CompoundFormula(Operator);
     if (Operator == "and" || Operator == "or" || Operator == "oneof")
     {
         foreach (Formula f in Operands)
         {
             Formula fTag = f.ApplyKnown(lKnown);
             if (fTag != null)
                 cfNew.SimpleAddOperand(fTag);
         }
     }
     else if (Operator == "when")
     {
         if (Operands[0].IsTrue(lKnown))
             return Operands[1];
         if (Operands[0].IsFalse(lKnown))
             return null;
         cfNew.AddOperand(Operands[0].ApplyKnown(lKnown));
         cfNew.AddOperand(Operands[1]);
     }
     else
         throw new NotImplementedException();
     return cfNew;
 }
 public override Formula ReduceConditions(IEnumerable<Predicate> lKnown)
 {
     CompoundFormula cfNew = new CompoundFormula(Operator);
     if (Operator == "and")// || Operator == "or" || Operator == "oneof")
     {
         foreach (Formula f in Operands)
         {
             if (f is CompoundFormula)
             {
                 Formula fTag = f.ReduceConditions(lKnown);
                 if (fTag != null)
                     cfNew.SimpleAddOperand(fTag);
             }
             else
                 cfNew.SimpleAddOperand(f);
         }
     }
     else if (Operator == "when")
     {
         Formula fReduced = Operands[0].Reduce(lKnown);
         if(fReduced.IsTrue(null))
             return Operands[1];
         if (fReduced.IsFalse(null))
             return null;
         cfNew.AddOperand(fReduced);
         cfNew.AddOperand(Operands[1]);
     }
     else
         throw new NotImplementedException();
     return cfNew;
 }
 public Formula ChooseOption(int iOption)
 {
     if (Operator == "or" || Operator == "oneof")
     {
         //in or there could be more than a single option - not implemented here
         int iActualOption = iOption % Operands.Count;
         return Operands[iActualOption].Clone();
     }
     if (Operator == "and")
     {
         CompoundFormula cfNew = new CompoundFormula("and");
         foreach (Formula fOperand in Operands)
         {
             if (fOperand is CompoundFormula)
             {
                 cfNew.AddOperand(((CompoundFormula)fOperand).ChooseOption(iOption));
             }
             else
                 cfNew.AddOperand(fOperand);
         }
         return cfNew;
     }
     if (Operator == "when")
     {
         CompoundFormula cfNew = new CompoundFormula("when");
         CompoundFormula cfGiven = new CompoundFormula("and");
         cfGiven.AddOperand(Operands[0].Clone());
         cfNew.AddOperand(cfGiven);
         cfNew.AddOperand(((CompoundFormula)Operands[1]).ChooseOption(iOption));
         return cfNew;
     }
     throw new NotFiniteNumberException();
 }
 public override Formula RemoveImpossibleOptions(IEnumerable<Predicate> lObserved)
 {
     CompoundFormula cfNew = new CompoundFormula(Operator);
     if (Operator == "and")
     {
         foreach (Formula f in Operands)
         {
             Formula fTag = f;
             if (f is CompoundFormula)
             {
                 fTag = ((CompoundFormula)f).RemoveImpossibleOptions(lObserved);
             }
             if (fTag == null)
                 return null;
             cfNew.AddOperand(fTag);
         }
     }
     else if (Operator == "or")
     {
         foreach (Formula f in Operands)
         {
             Formula fTag = f;
             if (f is CompoundFormula)
             {
                 fTag = ((CompoundFormula)f).RemoveImpossibleOptions(lObserved);
             }
             if (fTag != null)
                 cfNew.AddOperand(fTag);
         }
     }
     else if (Operator == "when")
     {
         Formula fTag = ((CompoundFormula)Operands[1]).RemoveImpossibleOptions(lObserved);
         if (fTag != null)
         {
             cfNew.AddOperand(Operands[0]);
             cfNew.AddOperand(fTag);
         }
         else
             return null;
     }
     else
         throw new NotImplementedException();
     return cfNew;
 }
 public override Formula Clone()
 {
     CompoundFormula cfClone = new CompoundFormula(Operator);
     foreach (Formula f in Operands)
         cfClone.SimpleAddOperand(f.Clone());
     return cfClone;
 }
 public CompoundFormula RemoveNestedConjunction(out bool bChanged)
 {
     bChanged = false;
     CompoundFormula cfAnd = new CompoundFormula("and");
     if (Operator == "or")
     {
         List<CompoundFormula> lCompoundOperands = new List<CompoundFormula>();
         List<PredicateFormula> lPredicateOperands = new List<PredicateFormula>();
         foreach (Formula f in Operands)
         {
             if (f is CompoundFormula)
             {
                 CompoundFormula cf = (CompoundFormula)f;
                 cf = cf.RemoveNestedConjunction(out bChanged);
                 lCompoundOperands.Add(cf);
             }
             else
                 lPredicateOperands.Add((PredicateFormula)f);
         }
         if (lCompoundOperands.Count == 0)
         {
             return this;
         }
         List<List<Formula>> lAllCombinations = GetAllCombinations(lPredicateOperands, lCompoundOperands);
         foreach (List<Formula> lCombination in lAllCombinations)
         {
             CompoundFormula cfOr = new CompoundFormula("or");
             foreach (Formula f in lCombination)
                 cfOr.AddOperand(f);
             foreach (PredicateFormula f in lPredicateOperands)
                 cfOr.AddOperand(f);
             if (!cfOr.IsTrue(new List<Predicate>()))
                 cfAnd.AddOperand(cfOr);
         }
             /*
         else if (lCompoundOperands.Count == 1)
         {
             CompoundFormula cfNestedAnd = lCompoundOperands[0];
             if (cfNestedAnd.Operator != "and")
                 throw new NotImplementedException();
             foreach (Formula f in cfNestedAnd.Operands)
             {
                 CompoundFormula cfOr = new CompoundFormula("or");
                 cfOr.AddOperand(f);
                 foreach (PredicateFormula pfOrg in lPredicateOperands)
                     cfOr.AddOperand(pfOrg);
                 cfAnd.AddOperand(cfOr);
             }
         }
         else
             throw new NotImplementedException();
              * */
         bChanged = true;
     }
     else
     {
         foreach (Formula f in Operands)
         {
             if (f is CompoundFormula)
             {
                 CompoundFormula cf = (CompoundFormula)f;
                 cf = cf.RemoveNestedConjunction(out bChanged);
                 if (cf.Operands.Count > 0)
                 {
                     if (cf.Operator == "and")
                         foreach (Formula fSub in cf.Operands)
                             cfAnd.AddOperand(fSub);
                     else
                         cfAnd.AddOperand(cf);
                 }
             }
             else
                 cfAnd.AddOperand(f);
         }
     }
     return cfAnd;
 }
 public override Formula CreateRegression(Predicate p, int iChoice)
 {
     CompoundFormula cfNew = new CompoundFormula(Operator);
     foreach (Formula f in Operands)
         cfNew.AddOperand(f.CreateRegression(p, iChoice));
     return cfNew;
 }
        private List<Formula> RegressLandmark(Formula fCurrentLandmark, Dictionary<Predicate, List<Action>> dLandmarkAchievers, HashSet<Predicate> lInitialState)
        {
            //when landmark is (or p1 p2), and p1 requires (or q1 q2) (or r1 r2) and p2 requires p3 and r3, then the result should be (or q1 q2 q3) (or r1 r2 r3)
            List<Formula> lFormulas = new List<Formula>();
            Dictionary<string, CompoundFormula> dAll = null;
            int cPredicatesToAchieve = 0;
            foreach (GroundedPredicate pLandmark in dLandmarkAchievers.Keys)
            {
                List<Action> lActions = dLandmarkAchievers[pLandmark];
                Dictionary<string, CompoundFormula> dRegressedFormulas = new Dictionary<string, CompoundFormula>();
                RegressLandmark(pLandmark, dLandmarkAchievers[pLandmark], lInitialState, dRegressedFormulas);
                string sLandmarkName = GetNameAndTag(pLandmark);
                if (dAll == null)
                    dAll = dRegressedFormulas;
                else
                {
                    Dictionary<string, CompoundFormula> dNew = new Dictionary<string, CompoundFormula>();
                    foreach (string sKey in dAll.Keys)
                    {
                        if (dRegressedFormulas.ContainsKey(sKey))
                        {
                            CompoundFormula cfOr = new CompoundFormula("or");
                            cfOr.AddOperand(dAll[sKey]);
                            cfOr.AddOperand(dRegressedFormulas[sKey]);
                            dNew[sKey] = cfOr;
                        }
                    }
                    dAll = dNew;
                }
            }
            foreach (string sPreType in dAll.Keys)
            {
                    Formula fSimplified = dAll[sPreType].Simplify();
                    //4 options here:
                    //fSimplified is a single predicate
                    //fSimplified is a simple disjunction
                    //fSimplified is a simple conjunction
                    //fSimplified is a disjunction of simple conjunctions
                    if (fSimplified is PredicateFormula)
                        lFormulas.Add(fSimplified);
                    else
                    {
                        CompoundFormula cf = (CompoundFormula)fSimplified;
                        if (cf.Operator == "and")
                        {
                            foreach (PredicateFormula pf in cf.Operands)
                                lFormulas.Add(pf);
                        }
                        else
                            lFormulas.Add(RemoveConjunctions(cf));

                    }

            }

            return lFormulas;
        }
 public override Formula GenerateGiven(string sTag, List<string> lAlwaysKnown)
 {
     CompoundFormula cfGiven = new CompoundFormula(Operator);
     foreach (Formula fOperand in Operands)
         cfGiven.AddOperand(fOperand.GenerateGiven(sTag, lAlwaysKnown));
     return cfGiven;
 }
        /*

        private bool RegressLandmark(Predicate pCurrentLandmark, List<Action> lLandmarkAchievers, HashSet<Predicate> lInitialState,
            Dictionary<string, List<Predicate>> dObligatory, Dictionary<string, List<Predicate>> dOptional)
        {

            if (lLandmarkAchievers.Count == 0)
                return false;
            //looking for preconditions that are needed for all actions that achieve p
            HashSet<Predicate> lJointPreconditions = GetJointPreconditions(lLandmarkAchievers);
            bool bNewLandmarkFound = false;
            if (lJointPreconditions.Count > 0)
            {
                foreach (GroundedPredicate pPrecondition in lJointPreconditions)
                {
                    if (!lInitialState.Contains(pPrecondition))
                    {
                        string sPreconditionName = GetNameAndTag(pPrecondition);
                        if (!dObligatory.ContainsKey(sPreconditionName))
                            dObligatory[sPreconditionName] = new List<Predicate>();

                        dObligatory[sPreconditionName].Add(pPrecondition);
                        bNewLandmarkFound = true;
                    }
                }

            }

            Dictionary<string, Dictionary<string, List<Predicate>>> dDisjunctions = GetDisjunctivePreconditions(lLandmarkAchievers, lInitialState);
            foreach (string sPredicateType in dDisjunctions.Keys)//go over the different pre types
            {
                Dictionary<string, List<Predicate>> dActionToPrecondition = dDisjunctions[sPredicateType];
                if (dActionToPrecondition.Count == lLandmarkAchievers.Count)//all achivers require a pre of this type
                {
                    if (!dOptional.ContainsKey(sPredicateType))
                        dOptional[sPredicateType] = new List<Predicate>();
                    foreach (KeyValuePair<string, List<Predicate>> pair in dActionToPrecondition)
                    {
                        foreach (Predicate p in pair.Value)
                        {
                            if (!lInitialState.Contains(p))
                            {
                                dOptional[sPredicateType].Add(p);
                            }
                        }
                    }
                }
            }

            return true;
        }

        private List<Formula> RegressLandmark(Formula fCurrentLandmark, Dictionary<Predicate, List<Action>> dLandmarkAchievers, HashSet<Predicate> lInitialState)
        {
            //when landmark is (or p1 p2), and p1 requires (or q1 q2) (or r1 r2) and p2 requires p3 and r3, then the result should be (or q1 q2 q3) (or r1 r2 r3)
            List<Formula> lFormulas = new List<Formula>();
            Dictionary<string, Dictionary<int, List<Predicate>>> dAllObligatory = new Dictionary<string, Dictionary<int, List<Predicate>>>();
            Dictionary<string, Dictionary<int, List<Predicate>>> dAllOptional = new Dictionary<string, Dictionary<int, List<Predicate>>>();
            int cPredicatesToAchieve = 0;
            foreach (GroundedPredicate pLandmark in dLandmarkAchievers.Keys)
            {
                List<Action> lActions = dLandmarkAchievers[pLandmark];
                Dictionary<string, List<Predicate>> dObligatory = new Dictionary<string, List<Predicate>>();
                Dictionary<string, List<Predicate>> dOptional = new Dictionary<string, List<Predicate>>();
                RegressLandmark(pLandmark, dLandmarkAchievers[pLandmark], lInitialState, dObligatory, dOptional);
                string sLandmarkName = GetNameAndTag(pLandmark);
                foreach (string sPreType in dObligatory.Keys)
                {
                    if (!dAllObligatory.ContainsKey(sPreType))
                        dAllObligatory[sPreType] = new Dictionary<int, List<Predicate>>();

                    dAllObligatory[sPreType][cPredicatesToAchieve] = new List<Predicate>();
                    dAllObligatory[sPreType][cPredicatesToAchieve].AddRange(dObligatory[sPreType]);
                }
                foreach (string sPreType in dOptional.Keys)
                {
                    if (!dAllOptional.ContainsKey(sPreType))
                        dAllOptional[sPreType] = new Dictionary<int, List<Predicate>>();

                    dAllOptional[sPreType][cPredicatesToAchieve] = new List<Predicate>();
                    dAllOptional[sPreType][cPredicatesToAchieve].AddRange(dOptional[sPreType]);
                }
                cPredicatesToAchieve++;
            }
            foreach (string sPreType in dAllObligatory.Keys)
            {
                if (dAllObligatory[sPreType].Count == cPredicatesToAchieve)
                {
                    CompoundFormula cfOr = new CompoundFormula("or");
                    foreach (List<Predicate> lPreconditions in dAllObligatory[sPreType].Values)
                    {
                        CompoundFormula cfAnd = new CompoundFormula("and");
                        foreach (Predicate p in lPreconditions)
                            cfAnd.AddOperand(p);
                        cfOr.AddOperand(cfAnd);
                    }
                    Formula fSimplified = cfOr.Simplify();
                    //4 options here:
                    //fSimplified is a single predicate
                    //fSimplified is a simple disjunction
                    //fSimplified is a simple conjunction
                    //fSimplified is a disjunction of simple conjunctions
                    if (fSimplified is PredicateFormula)
                        lFormulas.Add(fSimplified);
                    else
                    {
                        CompoundFormula cf = (CompoundFormula)fSimplified;
                        if (cf.Operator == "and")
                        {
                            foreach (PredicateFormula pf in cf.Operands)
                                lFormulas.Add(pf);
                        }
                        else
                            lFormulas.Add(RemoveConjunctions(cf));

                    }
                }
            }
            foreach (string sPreType in dAllOptional.Keys)
            {
                if (dAllOptional[sPreType].Count == cPredicatesToAchieve)
                {
                    CompoundFormula cfOr = new CompoundFormula("or");
                    foreach (List<Predicate> lPreconditions in dAllOptional[sPreType].Values)
                    {
                        CompoundFormula cfAnd = new CompoundFormula("or");
                        foreach (Predicate p in lPreconditions)
                            cfAnd.AddOperand(p);
                        cfOr.AddOperand(cfAnd);
                    }
                    Formula fSimplified = cfOr.Simplify();
                    //4 options here:
                    //fSimplified is a single predicate
                    //fSimplified is a simple disjunction
                    //fSimplified is a simple conjunction
                    //fSimplified is a disjunction of simple conjunctions
                    if (fSimplified is PredicateFormula)
                        lFormulas.Add(fSimplified);
                    else
                    {
                        CompoundFormula cf = (CompoundFormula)fSimplified;
                        if (cf.Operator == "and")
                        {
                            foreach (PredicateFormula pf in cf.Operands)
                                lFormulas.Add(pf);
                        }
                        else
                            lFormulas.Add(RemoveConjunctions(cf));

                    }
                }
            }

            return lFormulas;
        }

         */
        private CompoundFormula RemoveConjunctions(CompoundFormula cf)
        {
            CompoundFormula cfNew = new CompoundFormula("or");
            if (cf.Operator == "and")
            {
                foreach (PredicateFormula pf in cf.Operands)
                    cfNew.AddOperand(pf);
            }
            else
            {
                foreach (Formula fSub in cf.Operands)
                {
                    if (fSub is PredicateFormula)
                        cfNew.AddOperand(fSub);
                    else
                        cfNew.AddOperand(RemoveConjunctions((CompoundFormula)fSub));
                }
            }
            return cfNew;
        }
 public override Formula GetKnowledgeFormula(List<string> lAlwaysKnown, bool bKnowWhether)
 {
     CompoundFormula cfK = new CompoundFormula(Operator);
     foreach (Formula f in Operands)
         cfK.AddOperand(f.GetKnowledgeFormula(lAlwaysKnown, bKnowWhether));
     return cfK;
 }
 private void RemoveDisjunctions(Action a, List<List<Formula>> lOptions, int iOption, CompoundFormula cfAnd, List<Action> lNoDisjunctions, ref int iIndex)
 {
     if (iOption == lOptions.Count)
     {
         Action aNew = a.Clone();
         aNew.Name += "." + iIndex;
         iIndex++;
         aNew.Preconditions = cfAnd;
         lNoDisjunctions.Add(aNew);
     }
     else
     {
         foreach (Formula fOption in lOptions[iOption])
         {
             CompoundFormula cfNew = (CompoundFormula)cfAnd.Clone();
             cfNew.AddOperand(fOption);
             RemoveDisjunctions(a, lOptions, iOption + 1, cfNew, lNoDisjunctions, ref iIndex);
         }
     }
 }
 public override Formula Ground(Dictionary<string, Constant> dBindings)
 {
     CompoundFormula cfGrounded = new CompoundFormula(Operator);
     foreach (Formula fSub in Operands)
     {
         Formula fGrounded = fSub.Ground(dBindings);
         cfGrounded.AddOperand(fGrounded);
     }
     return cfGrounded;
 }