private State GetCurrentState(List<Predicate> lPredicates)
 {
     State s = new State(Problem);
     foreach (Predicate p in lPredicates)
     {
         if (p is TimePredicate)
         {
             TimePredicate tp = (TimePredicate)p;
             if (tp.Time == Time)
             {
                 s.AddPredicate(tp.Predicate);
             }
         }
     }
     foreach (Predicate p in Observed)
         s.AddPredicate(p);
     return s;
 }
        private State ChooseStateForLargeDomains()
        {
            State s = new State(Problem);
            foreach (Predicate pKnown in Problem.Known)
                s.AddPredicate(pKnown);
            if (Problem.Name.Contains("Wumpus"))
            {
                int cWumpuses = LargeWumpusDomain.WumpusCount, cPits = LargeWumpusDomain.PitCount;
                List<int> lPositions = new List<int>();
                for (int i = 0; i < cWumpuses; i++)
                {
                    int pos = GetRandomUniquePosition(lPositions, LargeWumpusDomain.Size);
                    int x = pos % 1000;
                    int y = pos / 1000;
                    GroundedPredicate gpWumpus = new GroundedPredicate("wumpus-at");
                    gpWumpus.AddConstant(new Constant("pos", "p-" + x));
                    gpWumpus.AddConstant(new Constant("pos", "p-" + y));
                    s.AddPredicate(gpWumpus);
                    if (x > 1)
                    {
                        GroundedPredicate gpStench = new GroundedPredicate("stench");
                        gpStench.AddConstant(new Constant("pos", "p-" + (x - 1)));
                        gpStench.AddConstant(new Constant("pos", "p-" + y));
                        s.AddPredicate(gpStench);
                    }
                    if (x < LargeWumpusDomain.Size)
                    {
                        GroundedPredicate gpStench = new GroundedPredicate("stench");
                        gpStench.AddConstant(new Constant("pos", "p-" + (x + 1)));
                        gpStench.AddConstant(new Constant("pos", "p-" + y));
                        s.AddPredicate(gpStench);
                    }
                    if (y > 1)
                    {
                        GroundedPredicate gpStench = new GroundedPredicate("stench");
                        gpStench.AddConstant(new Constant("pos", "p-" + x));
                        gpStench.AddConstant(new Constant("pos", "p-" + (y - 1)));
                        s.AddPredicate(gpStench);
                    }
                    if (y < LargeWumpusDomain.Size)
                    {
                        GroundedPredicate gpStench = new GroundedPredicate("stench");
                        gpStench.AddConstant(new Constant("pos", "p-" + x));
                        gpStench.AddConstant(new Constant("pos", "p-" + (y + 1)));
                        s.AddPredicate(gpStench);
                    }
                }
                for (int i = 0; i < cPits; i++)
                {
                    int pos = GetRandomUniquePosition(lPositions, LargeWumpusDomain.Size);
                    int x = pos % 1000;
                    int y = pos / 1000;
                    GroundedPredicate gpPit = new GroundedPredicate("pit-at");
                    gpPit.AddConstant(new Constant("pos", "p-" + x));
                    gpPit.AddConstant(new Constant("pos", "p-" + y));
                    s.AddPredicate(gpPit);
                    if (x > 1)
                    {
                        GroundedPredicate gpBreeze = new GroundedPredicate("breeze");
                        gpBreeze.AddConstant(new Constant("pos", "p-" + (x - 1)));
                        gpBreeze.AddConstant(new Constant("pos", "p-" + y));
                        s.AddPredicate(gpBreeze);
                    }
                    if (x < LargeWumpusDomain.Size)
                    {
                        GroundedPredicate gpBreeze = new GroundedPredicate("breeze");
                        gpBreeze.AddConstant(new Constant("pos", "p-" + (x + 1)));
                        gpBreeze.AddConstant(new Constant("pos", "p-" + y));
                        s.AddPredicate(gpBreeze);
                    }
                    if (y > 1)
                    {
                        GroundedPredicate gpBreeze = new GroundedPredicate("breeze");
                        gpBreeze.AddConstant(new Constant("pos", "p-" + x));
                        gpBreeze.AddConstant(new Constant("pos", "p-" + (y - 1)));
                        s.AddPredicate(gpBreeze);
                    }
                    if (y < LargeWumpusDomain.Size)
                    {
                        GroundedPredicate gpBreeze = new GroundedPredicate("breeze");
                        gpBreeze.AddConstant(new Constant("pos", "p-" + x));
                        gpBreeze.AddConstant(new Constant("pos", "p-" + (y + 1)));
                        s.AddPredicate(gpBreeze);
                    }
                }

                for (int iX = 1; iX <= LargeWumpusDomain.Size; iX++)
                    for (int iY = 1; iY <= LargeWumpusDomain.Size; iY++)
                    {
                        if (!lPositions.Contains(iY * 1000 + iX))
                        {
                            GroundedPredicate gpSafe = new GroundedPredicate("safe");
                            gpSafe.AddConstant(new Constant("pos", "p-" + iX));
                            gpSafe.AddConstant(new Constant("pos", "p-" + iY));
                            s.AddPredicate(gpSafe);
                        }
                    }

                int pGold = GetRandomUniquePosition(lPositions, LargeWumpusDomain.Size);
                int xGold = pGold % LargeWumpusDomain.Size;
                int yGold = pGold / LargeWumpusDomain.Size;
                GroundedPredicate gpGold = new GroundedPredicate("gold-at");
                gpGold.AddConstant(new Constant("pos", "p-" + xGold));
                gpGold.AddConstant(new Constant("pos", "p-" + yGold));
                s.AddPredicate(gpGold);
            }
            if (Problem.Name.Contains("Mine"))
            {
                bool[,] aBoard = new bool[MineSweeper.Size, MineSweeper.Size];
                List<GroundedPredicate> lPredicates = new List<GroundedPredicate>();
                for (int iMine = 0; iMine < MineSweeper.Size; iMine++)
                {
                    int iX = RandomGenerator.Next(MineSweeper.Size);
                    int iY = RandomGenerator.Next(MineSweeper.Size);
                    GroundedPredicate gp = new GroundedPredicate("mine-at");
                    gp.AddConstant(new Constant("pos", "p" + iX + "-" + iY));
                    aBoard[iX, iY] = true;
                    lPredicates.Add(gp);

                }

                for (int iX = 0; iX < MineSweeper.Size; iX++)
                    for (int iY = 0; iY < MineSweeper.Size; iY++)
                    {
                        int cNeighbors = 0;
                        for (int i = -1; i <= 1; i++)
                            for (int j = -1; j <= 1; j++)
                                if (i != 0 || j != 0)
                                    if (iX + i >= 0 && iX + i < MineSweeper.Size)
                                        if (iY + j >= 0 && iY + j < MineSweeper.Size)
                                            if (aBoard[iX + i, iY + j])
                                                cNeighbors++;
                        GroundedPredicate gp = new GroundedPredicate("mine-count");
                        gp.AddConstant(new Constant("pos", "p" + iX + "-" + iY));
                        gp.AddConstant(new Constant("value", "v" + cNeighbors));
                        lPredicates.Add(gp);
                    }

                foreach (Predicate p in lPredicates)
                    s.AddPredicate(p);

            }
            if (Problem.Name.Contains("Battleship"))
            {
                int[,] aMap = new int[Battleship.Size, Battleship.Size];
                List<GroundedPredicate> lPredicates = new List<GroundedPredicate>();

                int cFailures = 0;
                for (int iShipType = Battleship.ShipTypes; iShipType > 0; iShipType--)
                {
                    int cShips = Battleship.ShipCount[iShipType];

                    int iLength = iShipType;
                    for (int iShip = 0; iShip < cShips; iShip++)
                    {
                        bool bDone = false;
                        int cAttempts = 100;
                        while (!bDone && cAttempts > 0)
                        {
                            cAttempts--;
                            int iX = RandomGenerator.Next(Battleship.Size - iLength);
                            int iY = RandomGenerator.Next(Battleship.Size - iLength);
                            bool bVertical = RandomGenerator.NextDouble() < 0.5;

                            GroundedPredicate gp = null;

                            if (bVertical)
                            {
                                bool bFree = true;
                                for (int i = 0; i < iLength && bFree; i++)
                                    if (aMap[iX, iY + i] > 0)
                                        bFree = false;
                                if (bFree)
                                {
                                    for (int i = 0; i < iLength && bFree; i++)
                                    {
                                        gp = new GroundedPredicate("ship-at");
                                        //gp.AddConstant(new Constant("ship", "s-" + iShip));
                                        gp.AddConstant(new Constant("pos", "p-" + iX));
                                        gp.AddConstant(new Constant("pos", "p-" + (iY + i)));
                                        lPredicates.Add(gp);
                                        aMap[iX, iY + i] = 2;

                                    }
                                    for (int i = -1; i <= iLength; i++)
                                    {
                                        for (int j = -1; j <= 1; j++)
                                            if (iX + j >= 0 && iX + j < Battleship.Size && iY + i >= 0 && iY + i < Battleship.Size)
                                            {
                                                if(aMap[iX + j, iY + i] == 0)
                                                    aMap[iX + j, iY + i] = 1;
                                            }
                                    }
                                    bDone = true;
                                }
                            }
                            else
                            {
                                bool bFree = true;
                                for (int i = 0; i < iLength && bFree; i++)
                                    if (aMap[iX + i, iY] > 0)
                                        bFree = false;
                                if (bFree)
                                {
                                    for (int i = 0; i < iLength && bFree; i++)
                                    {
                                        gp = new GroundedPredicate("ship-at");
                                        //gp.AddConstant(new Constant("ship", "s-" + iShip));
                                        gp.AddConstant(new Constant("pos", "p-" + (iX + i)));
                                        gp.AddConstant(new Constant("pos", "p-" + iY));
                                        lPredicates.Add(gp);
                                        aMap[iX + i, iY] = 2;
                                    }
                                    for (int i = -1; i <= iLength; i++)
                                    {
                                        for (int j = -1; j <= 1; j++)
                                            if (iX + i >= 0 && iX + i < Battleship.Size && iY + j >= 0 && iY + j < Battleship.Size)
                                            {
                                                if(aMap[iX + i, iY + j] == 0)
                                                    aMap[iX + i, iY + j] = 1;

                                            }
                                    }
                                    bDone = true;
                                }
                            }
                        }
                        if (cAttempts == 0)
                            cFailures++;
                    }
                }

                if (cFailures > 0)
                    Console.WriteLine();

                for (int iX = 0; iX < Battleship.Size; iX++)
                {
                    for (int iY = 0; iY < Battleship.Size; iY++)
                    {
                        if (aMap[iX, iY] != 2)
                        {
                            GroundedPredicate gp = new GroundedPredicate("water-at");
                            gp.AddConstant(new Constant("pos", "p-" + iX));
                            gp.AddConstant(new Constant("pos", "p-" + iY));
                            lPredicates.Add(gp);
                            Debug.Write('-');
                        }
                        else
                            Debug.Write('X');

                        /*
                        gp = new GroundedPredicate("hit");
                        gp.AddConstant(new Constant("POS", "p-" + iX));
                        gp.AddConstant(new Constant("POS", "p-" + iY));
                        gp.Negation = true;
                        lPredicates.Add(gp);
                         * */
                    }
                    Debug.Write("\n");
                }
                foreach (Predicate p in lPredicates)
                    s.AddPredicate(p);

            }

            return s;
        }
        public State ChooseState(bool bRemoveNegativePredicates)
        {
            State s = new State(Problem);
            if (Problem.Domain.Name == "mines4")
            {
                string[] a = new string[]{
                         "(obs0-at p1-1)",
                        "(obs0-at p2-1)",
                        "(obs2-at p3-1)",
                        "(mine-at p4-1)",
                        "(obs1-at p4-1)",
                        "(obs2-at p1-2)",
                        "(obs2-at p2-2)",
                        "(obs3-at p3-2)",
                        "(mine-at p4-2)",
                        "(obs1-at p4-2)",
                        "(mine-at p1-3)",
                        "(obs1-at p1-3)",
                        "(mine-at p2-3)",
                        "(obs1-at p2-3)",
                        "(obs2-at p3-3)",
                        "(obs1-at p4-3)",
                        "(obs2-at p1-4)",
                        "(obs2-at p2-4)",
                        "(obs1-at p3-4)",
                        "(obs0-at p4-4)"};
                foreach (GroundedPredicate p in m_lObserved)
                    s.AddPredicate(p);
                foreach (string str in a)
                {
                    string[] a1 = str.Replace("(","").Replace(")","").Split(' ');
                    GroundedPredicate gp = new GroundedPredicate(a1[0]);
                    gp.AddConstant(new Constant("pos", a1[1]));
                    s.AddPredicate(gp);
                }

            }
            else if (SDRPlanner.SimulationStartState == null || UnderlyingEnvironmentState != null)
            {
                if (Problem.Name.Contains("Large"))
                    s = ChooseStateForLargeDomains();
                else
                {
                    List<Predicate> lAssignment = null;
                    Debug.Write("Choosing hidden variables ");
                    while (lAssignment == null)
                    {
                        Debug.Write(".");
                        lAssignment = ChooseHiddenPredicates(m_lHiddenFormulas, true);
                    }
                    Debug.WriteLine("");
                    foreach (Predicate p in lAssignment)
                    {
                        s.AddPredicate(p);
                    }
                    foreach (GroundedPredicate p in m_lObserved)
                    {
                        s.AddPredicate(p);
                    }
                }
            }
            else
            {
                Parser p = new Parser();
                string sNextState = SDRPlanner.SimulationStartState[0];
                SDRPlanner.SimulationStartState.RemoveAt(0);
                CompoundFormula cfInit = p.ParseFormula(sNextState, Problem.Domain);
                foreach (PredicateFormula pf in cfInit.Operands)
                    s.AddPredicate(pf.Predicate);
                foreach (GroundedPredicate gp in Observed)
                    s.AddPredicate(gp);
            }
            if (bRemoveNegativePredicates)
                s.RemoveNegativePredicates();
            if (UnderlyingEnvironmentState == null)
                UnderlyingEnvironmentState = s;
            return s;
        }
        private List<State> ApplyActions(List<List<Predicate>> lChosen, List<Action> lActions)
        {
            List<State> lCurrent = new List<State>();
            foreach (List<Predicate> lState in lChosen)
            {
                State s = new State(Problem);
                foreach (Predicate p in lState)
                    s.AddPredicate(p);
                foreach (Predicate p in Observed)
                    s.AddPredicate(p);
                lCurrent.Add(s);
            }

            List<State> lNext = null;
            foreach (Action a in lActions)
            {
                lNext = new List<State>();
                foreach (State s in lCurrent)
                {
                    State sTag = s.Apply(a);
                    if (sTag == null)
                        sTag = s.Apply(a);
                    lNext.Add(sTag);
                }
                lCurrent = lNext;
            }

            return lCurrent;
        }