private Action GetResetDependenciesRevealedAction(GroundedFunctionPredicate totalCostFunctionPredicate)
        {
            Action resetDependenciesRevealed = new Action(resetDependenciesActionName);

            CompoundFormula preconditions = new CompoundFormula("and");
            CompoundFormula effects       = new CompoundFormula("and");

            foreach (Constant agent in agentsConstants)
            {
                GroundedPredicate revealedSomething = new GroundedPredicate("revealed-something");
                revealedSomething.AddConstant(agent);

                Predicate notRevealedSomething = revealedSomething.Negate();

                preconditions.AddOperand(revealedSomething);
                effects.AddOperand(notRevealedSomething);
            }

            effects.AddOperand(GetIncreaseTotalCostFunction(totalCostFunctionPredicate, revealedDependencyCost));

            resetDependenciesRevealed.Preconditions = preconditions;
            resetDependenciesRevealed.SetEffects(effects);

            return(resetDependenciesRevealed);
        }
        private List <Action> GetDependenciesActions(GroundedFunctionPredicate totalCostFunctionPredicate, List <Agent> m_agents)
        {
            List <Action> dependenciesActions = new List <Action>();

            dependenciesActions.Add(GetRevealedDependencyParameterizedAction());
            dependenciesActions.AddRange(GetRevealedDummyDependencyActions(m_agents));
            dependenciesActions.Add(GetResetDependenciesRevealedAction(totalCostFunctionPredicate));
            return(dependenciesActions);
        }
        /*
         * private List<GroundedFunctionPredicate> GetInitAmountOfDependenciesRevealedToZeroPredicates(List<Agent> m_agents)
         * {
         *  List<GroundedFunctionPredicate> predicates = new List<GroundedFunctionPredicate>();
         *  foreach(Agent agent in m_agents)
         *  {
         *      predicates.Add(GetInitAmountOfDependenciesRevealedToZeroForAgentPredicate(agent));
         *  }
         *  return predicates;
         * }
         *
         * private GroundedFunctionPredicate GetInitAmountOfDependenciesRevealedToZeroForAgentPredicate(Agent agent)
         * {
         *  GroundedFunctionPredicate initAmountOfDependenciesRevealedToZero = new GroundedFunctionPredicate("=");
         *  Constant a = mapAgentToConstant[agent];
         *  GroundedFunctionPredicate amountOfDepRevGrounded = GetAmountOfDependenciesRevealedGrounded(a);
         *  FunctionConstant functionConstant = new FunctionConstant(amountOfDepRevGrounded);
         *  initAmountOfDependenciesRevealedToZero.AddFunction(functionConstant);
         *  initAmountOfDependenciesRevealedToZero.AddNumber(0);
         *
         *  return initAmountOfDependenciesRevealedToZero;
         * }
         */

        private GroundedFunctionPredicate GetInitTotalCostToZeroPredicate(GroundedFunctionPredicate totalCostFunctionPredicate)
        {
            GroundedFunctionPredicate initTotalCostToZeroPredicate = new GroundedFunctionPredicate("=");
            FunctionConstant          functionConstant             = new FunctionConstant(totalCostFunctionPredicate);

            initTotalCostToZeroPredicate.AddFunction(functionConstant);
            initTotalCostToZeroPredicate.AddNumber(0);

            return(initTotalCostToZeroPredicate);
        }
        /*
         * private ParameterizedFunctionPredicate GetIncreaseAmountOfDependenciesRevealedParameterized(ParameterizedFunctionPredicate amountOfDependenciesRevealedParameterized)
         * {
         *  ParameterizedFunctionPredicate increaseAmountOfDepRev = new ParameterizedFunctionPredicate("increase");
         *  FunctionParameter functionParameterAmountOfDepRev = new FunctionParameter(amountOfDependenciesRevealedParameterized);
         *  increaseAmountOfDepRev.AddFunction(functionParameterAmountOfDepRev);
         *  increaseAmountOfDepRev.AddNumber(1); //increase by 1.
         *  return increaseAmountOfDepRev;
         * }
         *
         * private GroundedFunctionPredicate GetIncreaseAmountOfDependenciesRevealedGrounded(GroundedFunctionPredicate amountOfDepRevGrounded)
         * {
         *  GroundedFunctionPredicate increaseAmountOfDepRev = new GroundedFunctionPredicate("increase");
         *  FunctionConstant functionParameterAmountOfDepRev = new FunctionConstant(amountOfDepRevGrounded);
         *  increaseAmountOfDepRev.AddFunction(functionParameterAmountOfDepRev);
         *  increaseAmountOfDepRev.AddNumber(1); //increase by 1.
         *  return increaseAmountOfDepRev;
         * }
         *
         * private ParameterizedFunctionPredicate GetEqualsToMax(ParameterizedFunctionPredicate amountOfDependenciesRevealedParameterized)
         * {
         *  ParameterizedFunctionPredicate equalsToMax = new ParameterizedFunctionPredicate("=");
         *  FunctionParameter functionParameterAmountOfDepRev = new FunctionParameter(amountOfDependenciesRevealedParameterized);
         *  equalsToMax.AddFunction(functionParameterAmountOfDepRev);
         *  equalsToMax.AddNumber(maxAmountOfDependencies);
         *  return equalsToMax;
         * }
         *
         * private GroundedFunctionPredicate GetEqualsToMaxGrounded(GroundedFunctionPredicate amountOfDepRevGrounded)
         * {
         *  GroundedFunctionPredicate equalsToMax = new GroundedFunctionPredicate("=");
         *  FunctionConstant functionConstantAmountOfDepRev = new FunctionConstant(amountOfDepRevGrounded);
         *  equalsToMax.AddFunction(functionConstantAmountOfDepRev);
         *  equalsToMax.AddNumber(maxAmountOfDependencies);
         *  return equalsToMax;
         * }
         *
         * private ParameterizedFunctionPredicate GetAmountOfDependenciesRevealedParameterized()
         * {
         *  ParameterizedFunctionPredicate amountOfDependenciesRevealed = new ParameterizedFunctionPredicate("amount-of-dependencies-revealed");
         *  Parameter agentParameter = GetAgentParameter();
         *  amountOfDependenciesRevealed.AddParameter(agentParameter);
         *  return amountOfDependenciesRevealed;
         * }
         *
         * private GroundedFunctionPredicate GetAmountOfDependenciesRevealedGrounded(Constant agent)
         * {
         *  GroundedFunctionPredicate amountOfDependenciesRevealed = new GroundedFunctionPredicate("amount-of-dependencies-revealed");
         *  amountOfDependenciesRevealed.AddConstant(agent);
         *
         *  return amountOfDependenciesRevealed;
         * }
         */

        private GroundedFunctionPredicate GetIncreaseTotalCostFunction(GroundedFunctionPredicate totalCostFunctionPredicate, int cost)
        {
            GroundedFunctionPredicate increaseFP = new GroundedFunctionPredicate("increase");

            FunctionConstant functionConstant = new FunctionConstant(totalCostFunctionPredicate);

            increaseFP.AddFunction(functionConstant);
            increaseFP.AddNumber(cost);

            return(increaseFP);
        }
        private GroundedFunctionPredicate GetTotalCostFunction()
        {
            GroundedFunctionPredicate totalCostFunction = new GroundedFunctionPredicate("total-cost");

            return(totalCostFunction);
        }
        private void UpdateDependenciesIntoDomainsAndProblems(List <Agent> m_agents)
        {
            GroundedFunctionPredicate totalCostFunctionPredicate = GetTotalCostFunction();

            Domain  dJoined                      = new Domain("JoinedDomain", "");
            Problem pJoined                      = new Problem("JoinedProblem", dJoined);
            State   publicStartState             = new State(pJoined);
            HashSet <GroundedPredicate> allGoals = new HashSet <GroundedPredicate>();

            List <Action> allActions = new List <Action>();

            foreach (Agent agent in m_agents)
            {
                foreach (Action action in agent.m_actions)
                {
                    List <Dependency> dependenciesForAction = new List <Dependency>();
                    List <Predicate>  regularEffects        = new List <Predicate>();

                    foreach (Predicate p in action.HashEffects)
                    {
                        Dependency dependency = new Dependency(action, p);
                        if (mapDependencyToConstant.ContainsKey(dependency))
                        {
                            //Then this is a dependency dependent action, which means we need to duplicate it several times so that we have the action with the dependency revealed and without it
                            dependenciesForAction.Add(dependency);

                            /*
                             * Constant d = mapDependencyToConstant[dependency];
                             * GroundedPredicate revealedD = new GroundedPredicate("revealed");
                             * revealedD.AddConstant(d);
                             *
                             * CompoundFormula cfCondition = new CompoundFormula("when");
                             * cfCondition.AddOperand(revealedD); //condition
                             * cfCondition.AddOperand(p); //result = the predicate we want to reveal.
                             *
                             * editedEffects.AddOperand(cfCondition);
                             */
                        }
                        else
                        {
                            regularEffects.Add(p);
                            //editedEffects.AddOperand(p); //it is not a dependency, so just reveal it regularly...
                        }
                    }

                    List <List <Dependency> > allPermutations = GetAllCombos(dependenciesForAction);
                    foreach (List <Dependency> currentPermutation in allPermutations)
                    {
                        //foreach permutation, create a corresponding action
                        string          name                = action.Name;
                        CompoundFormula editedEffects       = new CompoundFormula("and");
                        CompoundFormula editedPreconditions = new CompoundFormula("and");
                        foreach (Predicate p in action.HashPrecondition)
                        {
                            editedPreconditions.AddOperand(p);
                        }

                        foreach (Predicate p in regularEffects)
                        {
                            editedEffects.AddOperand(p);
                        }

                        if (currentPermutation.Count > 0)
                        {
                            name += "_with_dependencies";
                        }
                        foreach (Dependency dependency in currentPermutation)
                        {
                            Constant          d         = mapDependencyToConstant[dependency];
                            GroundedPredicate revealedD = new GroundedPredicate("revealed");
                            revealedD.AddConstant(d);

                            name += "_" + d.Name;
                            editedPreconditions.AddOperand(revealedD);
                            editedEffects.AddOperand(dependency.predicate);
                        }

                        editedEffects.AddOperand(GetIncreaseTotalCostFunction(totalCostFunctionPredicate, regularActionCost));

                        Action editedAction = action.Clone();
                        editedAction.Name          = name;
                        editedAction.Preconditions = editedPreconditions;
                        editedAction.SetEffects(editedEffects);
                        allActions.Add(editedAction);
                    }
                }
            }

            List <ParametrizedPredicate> parametrizedPredicates = GetParametrizedPredicates(); //Add these predeicated to the joined domain. These predicates are general ones that are part of our transformation to a different problem.
            List <GroundedPredicate>     belongsToPredicates    = GetBelongsToGroundedPredicates();
            //List<GroundedPredicate> revealedSomethingPredicates = GetRevealedSomethingGroundedPredicates();
            //List<GroundedFunctionPredicate> amountOfDepRevPredicates = GetInitAmountOfDependenciesRevealedToZeroPredicates(m_agents);
            GroundedFunctionPredicate initTotalCostToZeroPredicate = GetInitTotalCostToZeroPredicate(totalCostFunctionPredicate);

            List <Action> dependenciesActions = GetDependenciesActions();

            allActions.AddRange(dependenciesActions);

            List <string> myNewTypes = GetMyNewTypes();

            dJoined.AddFunction(totalCostFunctionPredicate.ToString());
            dJoined.Actions = allActions;

            foreach (Agent agent in m_agents)
            {
                Domain d = agent.domain;
                foreach (ParametrizedPredicate pp in d.Predicates)
                {
                    dJoined.Predicates.Add(pp);
                }
                foreach (string sType in d.Types)
                {
                    if (!dJoined.Types.Contains(sType))
                    {
                        dJoined.Types.Add(sType);
                    }
                }
                foreach (KeyValuePair <string, string> pair in d.TypeHierarchy)
                {
                    dJoined.TypeHierarchy[pair.Key] = pair.Value;
                }
                foreach (Constant c in d.Constants)
                {
                    dJoined.Constants.Add(c);
                }

                foreach (GroundedPredicate pgp in agent.startState.Predicates)
                {
                    publicStartState.AddPredicate(pgp);
                }

                foreach (GroundedPredicate goalP in agent.goal)
                {
                    allGoals.Add(goalP);
                }
            }

            foreach (ParametrizedPredicate pp in parametrizedPredicates)
            {
                if (dJoined.Predicates.Contains(pp))
                {
                    throw new Exception("The dependencies predicates must be unique, and cannot be in another domain.");
                }
                dJoined.Predicates.Add(pp);
            }

            foreach (string type in myNewTypes)
            {
                if (dJoined.Types.Contains(type))
                {
                    throw new Exception("The dependency and agent types must be unique, and cannot be in another domain.");
                }
                dJoined.Types.Add(type);
                dJoined.TypeHierarchy[type] = objectType;
            }

            foreach (Constant d in dependenciesConstants)
            {
                if (dJoined.Constants.Contains(d))
                {
                    throw new Exception("The dependencies constant names must be unique, and cannot be in another domain.");
                }
                dJoined.Constants.Add(d);
            }

            foreach (Constant a in agentsConstants)
            {
                if (dJoined.Constants.Contains(a))
                {
                    throw new Exception("The agents constant names must be unique, and cannot be in another domain.");
                }
                dJoined.Constants.Add(a);
            }

            foreach (Constant n in numberConstants)
            {
                if (dJoined.Constants.Contains(n))
                {
                    throw new Exception("The numbers constant names must be unique, and cannot be in another domain.");
                }
                dJoined.Constants.Add(n);
            }


            //private List<GroundedPredicate> nextPredicates;
            //private List<GroundedPredicate> revealedNumberOfDependenciesPredicates;

            //Add to start state:

            foreach (GroundedPredicate gp in belongsToPredicates)
            {
                if (dJoined.Predicates.Contains(gp))
                {
                    throw new Exception("The belongs-to predicates must be unique, and cannot be in another domain.");
                }
                publicStartState.AddPredicate(gp);
            }

            /*
             * foreach (GroundedPredicate gp in revealedSomethingPredicates)
             * {
             *  if (dJoined.Predicates.Contains(gp))
             *      throw new Exception("The revealed-something predicates must be unique, and cannot be in another domain.");
             *  publicStartState.AddPredicate(gp);
             * }
             */

            /*
             * foreach(GroundedFunctionPredicate gfp in amountOfDepRevPredicates)
             * {
             *  if (dJoined.Predicates.Contains(gfp))
             *      throw new Exception("The amount-of-dependencies-revealed predicates must be unique, and cannot be in another domain.");
             *  publicStartState.AddPredicate(gfp);
             * }
             */
            foreach (GroundedPredicate gp in nextPredicates)
            {
                if (dJoined.Predicates.Contains(gp))
                {
                    throw new Exception("The next predicates must be unique, and cannot be in another domain.");
                }
                publicStartState.AddPredicate(gp);
            }

            foreach (GroundedPredicate gp in revealedNumberOfDependenciesPredicates)
            {
                if (dJoined.Predicates.Contains(gp))
                {
                    throw new Exception("The revealed-number-of-dependencies predicates must be unique, and cannot be in another domain.");
                }
                publicStartState.AddPredicate(gp);
            }

            if (dJoined.Predicates.Contains(initTotalCostToZeroPredicate))
            {
                throw new Exception("The initialization of total cost predicate must be unique, and cannot be in another domain.");
            }
            publicStartState.AddPredicate(initTotalCostToZeroPredicate);

            foreach (Predicate pInit in publicStartState.Predicates)
            {
                pJoined.AddKnown(pInit);
            }

            CompoundFormula goalf = new CompoundFormula("and");

            foreach (GroundedPredicate goalP in allGoals)
            {
                goalf.AddOperand(goalP);
            }

            pJoined.Goal = goalf;

            pJoined.AddMetric("(:metric " + "minimize " + totalCostFunctionPredicate.ToString() + ")");

            joinedDomain     = dJoined;
            joinedProblem    = pJoined;
            joinedStartState = publicStartState;
        }