public Formula RegressDet(Action a)
        {
            Formula f = a.RegressDet(Predicate);

            if (f != null)
            {
                return(f);
            }

            CompoundFormula cfAndNot   = new CompoundFormula("and");
            CompoundFormula cfOr       = new CompoundFormula("or");
            int             iCondition = 0;
            Predicate       pNegate    = Predicate.Negate();

            foreach (CompoundFormula cfCondition in a.GetConditions())
            {
                HashSet <Predicate> lEffects = cfCondition.Operands[1].GetAllPredicates();
                if (lEffects.Contains(Predicate))
                {
                    cfOr.AddOperand(cfCondition.Operands[0].CreateRegression(Predicate, -1));
                }
                else if (lEffects.Contains(pNegate))
                {
                    cfAndNot.AddOperand(cfCondition.Operands[0].CreateRegression(pNegate, -1).Negate());
                }
                iCondition++;
            }
            cfOr.AddOperand(this);
            cfAndNot.AddOperand(cfOr);
            return(cfAndNot.Simplify());
        }
        public Formula RegressII(Action a)
        {
            CompoundFormula cfAndNot = new CompoundFormula("and");
            CompoundFormula cfOr     = new CompoundFormula("or");

            /*
             * if (a.Effects is PredicateFormula)
             * {
             *  if (a.Effects.Equals(this))
             *      return AddPreconditions(a);//assuming that an effect can't be both deterministic and conditional
             * }
             * else
             * {
             *  CompoundFormula cfEffects = (CompoundFormula)a.Effects;
             *  if (cfEffects.Operator != "and")
             *      throw new NotImplementedException();
             *  foreach (Formula f in cfEffects.Operands)
             *      if (f.Equals(this))
             *          return AddPreconditions(a);//assuming that an effect can't be both deterministic and conditional
             * }
             * */
            foreach (CompoundFormula cfCondition in a.GetConditions())
            {
                HashSet <Predicate> lEffects = new HashSet <Predicate>();
                cfCondition.Operands[1].GetAllPredicates(lEffects);
                if (lEffects.Contains(Predicate))
                {
                    cfOr.AddOperand(cfCondition.Operands[0]);
                }
                if (lEffects.Contains(Predicate.Negate()))
                {
                    cfAndNot.AddOperand(cfCondition.Operands[0].Negate());
                }
            }
            cfAndNot.AddOperand(this);
            cfOr.AddOperand(cfAndNot);
            return(cfOr.Simplify());
        }
        public Formula RegressNonDet(Action a)
        {
            CompoundFormula cfAndNot   = new CompoundFormula("and");
            CompoundFormula cfOr       = new CompoundFormula("or");
            int             iCondition = 0;
            Predicate       pNegate    = Predicate.Negate();

            foreach (CompoundFormula cfCondition in a.GetConditions())
            {
                HashSet <Predicate> lEffects         = cfCondition.Operands[1].GetAllPredicates();
                HashSet <Predicate> lOptionalEffects = cfCondition.Operands[1].GetAllOptionalPredicates();
                if (lEffects.Contains(Predicate))
                {
                    int iChoice = cfCondition.GetChoiceIndex(Predicate);
                    cfOr.AddOperand(cfCondition.Operands[0].CreateRegression(Predicate, iChoice));
                    a.SetChoice(iCondition, iChoice);
                }
                else if (lEffects.Contains(pNegate))
                {
                    if (!lOptionalEffects.Contains(pNegate))
                    {
                        cfAndNot.AddOperand(cfCondition.Operands[0].Negate());
                    }
                    else
                    {
                        int iChoice      = cfCondition.GetChoiceIndex(pNegate);
                        int iOtherChoice = cfCondition.GetOtherChoiceIndex(pNegate);
                        cfAndNot.AddOperand(cfCondition.Operands[0].CreateRegression(pNegate, iChoice).Negate());
                        a.SetChoice(iCondition, iOtherChoice);
                    }
                }
                iCondition++;
            }
            cfOr.AddOperand(this);
            cfAndNot.AddOperand(cfOr);
            return(cfAndNot.Simplify());
        }