Package javaff.planning

Source Code of javaff.planning.PlanningGraph

/************************************************************************
* Strathclyde Planning Group,
* Department of Computer and Information Sciences,
* University of Strathclyde, Glasgow, UK
* http://planning.cis.strath.ac.uk/
*
* Copyright 2007, Keith Halsey
* Copyright 2008, Andrew Coles and Amanda Smith
*
* (Questions/bug reports now to be sent to Andrew Coles)
*
* This file is part of JavaFF.
*
* JavaFF is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* JavaFF is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with JavaFF.  If not, see <http://www.gnu.org/licenses/>.
*
************************************************************************/

package javaff.planning;

import javaff.data.Action;
import javaff.data.GroundProblem;
import javaff.data.GroundCondition;
import javaff.data.Plan;
import javaff.data.TotalOrderPlan;
import javaff.data.strips.Proposition;

import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import java.util.HashSet;
import java.util.Map;
import java.util.Hashtable;

public class PlanningGraph
{
  //******************************************************
  // Data Structures
  //******************************************************
  Map propositionMap = new Hashtable();      // (Proposition => PGProposition)
  Map actionMap = new Hashtable();           // (Action => PGAction)

  Set propositions = new HashSet();
  Set actions = new HashSet();

  Set initial, goal;
  Set propMutexes, actionMutexes;
  List memorised;

  protected Set readyActions = null; // PGActions that have all their propositions met, but not their PGBinaryComparators or preconditions are mutex

  boolean level_off = false;
  static int NUMERIC_LIMIT = 4;
  int numeric_level_off = 0;
  int num_layers;

  //******************************************************
  // Main methods
  //******************************************************
  protected PlanningGraph()
  {

  }

  public PlanningGraph(GroundProblem gp)
  {
    setActionMap(gp.actions);
    setLinks();
    createNoOps();
    setGoal(gp.goal);
  }

  public Plan getPlan(State s)
  {
    setInitial(s);
    resetAll(s);

    //set up the intital set of facts
    Set scheduledFacts = new HashSet(initial);
    List scheduledActs = null;

    scheduledActs = createFactLayer(scheduledFacts, 0);
    List plan = null;

    //create the graph==========================================
    while (true)
    {
      scheduledFacts = createActionLayer(scheduledActs, num_layers);
      ++ num_layers;
      scheduledActs = createFactLayer(scheduledFacts, num_layers);

      if (goalMet() && !goalMutex())
      {
        plan = extractPlan();
      }
      if (plan != null) break;
      if (!level_off) numeric_level_off = 0;
      if (level_off || numeric_level_off >= NUMERIC_LIMIT) {
        //printGraph();
        break;
      }
    }



    if (plan != null)
    {
      Iterator pit = plan.iterator();
      TotalOrderPlan p = new TotalOrderPlan();
      while (pit.hasNext())
      {
        PGAction a = (PGAction) pit.next();
        if (!(a instanceof PGNoOp)) p.addAction(a.action);
      }
      //p.print(javaff.JavaFF.infoOutput);
      return p;
    }
    else return null;

  }

  //******************************************************
  // Setting it all up
  //******************************************************
  protected void setActionMap(Set gactions)
  {
    Iterator ait = gactions.iterator();
    while (ait.hasNext())
    {
      Action a = (Action) ait.next();
      PGAction pga = new PGAction(a);
      actionMap.put(a, pga);
      actions.add(pga);
    }
  }

    protected PGProposition getProposition(Proposition p)
    {
    Object o = propositionMap.get(p);
    PGProposition pgp;
    if (o == null)
    {
      pgp = new PGProposition(p);
      propositionMap.put(p, pgp);
      propositions.add(pgp);
    }
    else pgp = (PGProposition) o;
    return pgp;
    }

  protected void setLinks()
  {
    Iterator ait = actions.iterator();
    while (ait.hasNext())
    {
      PGAction pga = (PGAction) ait.next();

      Iterator csit = pga.action.getConditionalPropositions().iterator();
      while (csit.hasNext())
      {
        Proposition p = (Proposition) csit.next();
        PGProposition pgp = getProposition(p);
        pga.conditions.add(pgp);
        pgp.achieves.add(pga);
      }

      Iterator alit = pga.action.getAddPropositions().iterator();
      while (alit.hasNext())
      {
        Proposition p = (Proposition) alit.next();
        PGProposition pgp = getProposition(p);
        pga.achieves.add(pgp);
        pgp.achievedBy.add(pga);
      }

      Iterator dlit = pga.action.getDeletePropositions().iterator();
      while (dlit.hasNext())
      {
        Proposition p = (Proposition) dlit.next();
        PGProposition pgp = getProposition(p);
        pga.deletes.add(pgp);
        pgp.deletedBy.add(pga);
      }
    }
  }

  protected void resetAll(State s)
  {
    propMutexes = new HashSet();
    actionMutexes = new HashSet();

    memorised = new ArrayList();

    readyActions = new HashSet();

    num_layers=0;

    Iterator ait = actions.iterator();
    while (ait.hasNext())
    {
      PGAction a = (PGAction) ait.next();
      a.reset();
    }

    Iterator pit = propositions.iterator();
    while (pit.hasNext())
    {
      PGProposition p = (PGProposition) pit.next();
      p.reset();
    }
  }

  protected void setGoal(GroundCondition g)
  {
    goal = new HashSet();
    Iterator csit = g.getConditionalPropositions().iterator();
    while (csit.hasNext())
    {
      Proposition p = (Proposition) csit.next();
      PGProposition pgp = getProposition(p);
      goal.add(pgp);
    }
  }

  protected void setInitial(State S)
  {
    Set i = ((STRIPSState) S).facts;
    initial = new HashSet();
    Iterator csit = i.iterator();
    while (csit.hasNext())
    {
      Proposition p = (Proposition) csit.next();
      PGProposition pgp = getProposition(p);
      initial.add(pgp);
    }
  }

  protected void createNoOps()
  {
    Iterator pit = propositions.iterator();
    while (pit.hasNext())
    {
      PGProposition p = (PGProposition) pit.next();
      PGNoOp n = new PGNoOp(p);
      n.conditions.add(p);
      n.achieves.add(p);
      p.achieves.add(n);
      p.achievedBy.add(n);
      actions.add(n);
    }
  }

  //******************************************************
  // Graph Construction
  //******************************************************

  protected ArrayList createFactLayer(Set pFacts, int pLayer)
  {
    memorised.add(new HashSet());
    ArrayList scheduledActs = new ArrayList();
    HashSet newMutexes = new HashSet();
    Iterator fit = pFacts.iterator();
    while (fit.hasNext())
    {
      PGProposition f = (PGProposition) fit.next();
      if (f.layer < 0)
      {
        f.layer = pLayer;
        scheduledActs.addAll(f.achieves);
        level_off = false;

        //calculate mutexes
        if (pLayer != 0)
        {
          Iterator pit = propositions.iterator();
          while (pit.hasNext())
          {
            PGProposition p = (PGProposition) pit.next();
            if (p.layer >= 0 && checkPropMutex(f, p, pLayer))
            {
              makeMutex(f, p, pLayer, newMutexes);
            }
          }
        }

      }
    }

    //check old mutexes
    Iterator pmit = propMutexes.iterator();
    while (pmit.hasNext())
    {
      MutexPair m = (MutexPair) pmit.next();
      if (checkPropMutex(m, pLayer))
      {
        makeMutex(m.node1, m.node2, pLayer, newMutexes);
      }
      else
      {
        level_off = false;
      }
    }

    //add new mutexes to old mutexes and remove those which have disappeared
    propMutexes = newMutexes;


    return scheduledActs;
  }

  protected boolean checkPropMutex(MutexPair m, int l)
  {
    return checkPropMutex((PGProposition) m.node1, (PGProposition) m.node2, l);
  }

  protected boolean checkPropMutex(PGProposition p1, PGProposition p2, int l)
  {
    if (p1 == p2) return false;

    //Componsate for statics
    if (p1.achievedBy.isEmpty() || p2.achievedBy.isEmpty()) return false;

    Iterator a1it = p1.achievedBy.iterator();
    while(a1it.hasNext())
    {
      PGAction a1 = (PGAction) a1it.next();
      if (a1.layer >= 0)
      {
        Iterator a2it = p2.achievedBy.iterator();
        while (a2it.hasNext())
        {
          PGAction a2 = (PGAction) a2it.next();
          if (a2.layer >= 0 && !a1.mutexWith(a2, l-1)) return false;
        }
      }

    }
    return true;
  }

  protected void makeMutex(Node n1, Node n2, int l, Set mutexPairs)
  {
    n1.setMutex(n2, l);
    n2.setMutex(n1, l);
    mutexPairs.add(new MutexPair(n1, n2));
  }

  protected HashSet createActionLayer(List pActions, int pLayer)
  {
    level_off = true;
    HashSet actionSet = getAvailableActions(pActions, pLayer);
    actionSet.addAll(readyActions);
    readyActions = new HashSet();
    HashSet filteredSet = filterSet(actionSet, pLayer);
    HashSet scheduledFacts = calculateActionMutexesAndProps(filteredSet, pLayer);
    return scheduledFacts;
  }

  protected HashSet getAvailableActions(List pActions, int pLayer)
  {
    HashSet actionSet = new HashSet();
    Iterator ait = pActions.iterator();
    while (ait.hasNext())
    {
      PGAction a = (PGAction) ait.next();
      if (a.layer < 0)
      {
        a.counter++;
        a.difficulty += pLayer;
        if (a.counter >= a.conditions.size())
        {
          actionSet.add(a);
          level_off = false;
        }
      }
    }
    return actionSet;
  }

  protected HashSet filterSet(Set pActions, int pLayer)
  {                                                            
    HashSet filteredSet = new HashSet();
    Iterator ait = pActions.iterator();
    while (ait.hasNext())
    {
      PGAction a = (PGAction) ait.next();
      if (noMutexes(a.conditions, pLayer))
        filteredSet.add(a);
      else
        readyActions.add(a);
    }
    return filteredSet;
  }

  protected HashSet calculateActionMutexesAndProps(Set filteredSet,int pLayer)
  {
    HashSet newMutexes = new HashSet();

    Set newPreActions = new HashSet();
    HashSet scheduledFacts = new HashSet();

    Iterator ait = filteredSet.iterator();
    while (ait.hasNext())
    {
      PGAction a = (PGAction) ait.next();
      scheduledFacts.addAll(a.achieves);
      a.layer = pLayer;
      level_off = false;

      //caculate new mutexes
      Iterator a2it = actions.iterator();
      while (a2it.hasNext())
      {
        PGAction a2 = (PGAction) a2it.next();
        if (a2.layer >= 0 && checkActionMutex(a, a2, pLayer))
        {
          makeMutex(a, a2, pLayer, newMutexes);
        }
      }
    }

    //check old mutexes
    Iterator amit = actionMutexes.iterator();
    while (amit.hasNext())
    {
      MutexPair m = (MutexPair) amit.next();
      if (checkActionMutex(m, pLayer))
      {
        makeMutex(m.node1, m.node2, pLayer, newMutexes);
      }
      else
      {
        level_off = false;
      }
    }

    //add new mutexes to old mutexes and remove those which have disappeared
    actionMutexes = newMutexes;
    return scheduledFacts;
  }

  protected boolean checkActionMutex(MutexPair m, int l)
  {
    return checkActionMutex((PGAction)m.node1,(PGAction)m.node2, l);
  }

  protected boolean checkActionMutex(PGAction a1, PGAction a2, int l)
  {
    if (a1 == a2) return false;

    Iterator p1it = a1.deletes.iterator();
    while (p1it.hasNext())
    {
      PGProposition p1 = (PGProposition) p1it.next();;
      if (a2.achieves.contains(p1)) return true;
      if (a2.conditions.contains(p1)) return true;
    }

    Iterator p2it = a2.deletes.iterator();
    while (p2it.hasNext())
    {
      PGProposition p2 = (PGProposition) p2it.next();
      if (a1.achieves.contains(p2)) return true;
      if (a1.conditions.contains(p2)) return true;
    }

    Iterator pc1it = a1.conditions.iterator();
    while (pc1it.hasNext())
    {
      PGProposition p1 = (PGProposition) pc1it.next();
      Iterator pc2it = a2.conditions.iterator();
      while (pc2it.hasNext())
      {
        PGProposition p2 = (PGProposition) pc2it.next();
        if (p1.mutexWith(p2, l)) return true;
      }
    }

    return false;
  }


  protected boolean goalMet()
  {
    Iterator git = goal.iterator();
    while (git.hasNext())
    {
      PGProposition p = (PGProposition) git.next();
      if (p.layer < 0) return false;
    }
    return true;
  }

  protected boolean goalMutex()
  {
    return !noMutexes(goal, num_layers);
  }

  protected boolean noMutexes(Set s, int l)
  {
    Iterator sit = s.iterator();
    if (sit.hasNext())
    {
      Node n = (Node) sit.next();
      HashSet s2 = new HashSet(s);
      s2.remove(n);
      Iterator s2it = s2.iterator();
      while (s2it.hasNext())
      {
        Node n2 = (Node) s2it.next();
        if (n.mutexWith(n2, l))  return false;
      }
      return noMutexes(s2, l);
    }
    else return true;
  }

  protected boolean noMutexesTest(Node n, Set s, int l) // Tests to see if there is a mutex between n and all nodes in s
  {
    Iterator sit = s.iterator();
    while (sit.hasNext())
    {
      Node n2 = (Node) sit.next();
      if (n.mutexWith(n2, l)) return false;
    }
    return true;
  }


  //******************************************************
  // Plan Extraction
  //******************************************************


  public List extractPlan()
  {
    return searchPlan(goal, num_layers);
  }

  public List searchPlan(Set goalSet, int l)
  {

    if (l == 0)
    {
      if (initial.containsAll(goalSet)) return new ArrayList();
      else return null;
    }
    // do memorisation stuff
    Set badGoalSet = (HashSet) memorised.get(l);
    if (badGoalSet.contains(goalSet)) return null;

    List ass = searchLevel(goalSet, (l-1)); // returns a set of sets of possible action combinations
    Iterator assit = ass.iterator();

    while (assit.hasNext())
    {
      Set as = (HashSet) assit.next();
      Set newgoal = new HashSet();

      Iterator ait = as.iterator();
      while (ait.hasNext())
      {
        PGAction a = (PGAction) ait.next();
        newgoal.addAll(a.conditions);
      }

      List al = searchPlan(newgoal, (l-1));
      if (al != null)
      {
        List plan = new ArrayList(al);
        plan.addAll(as);
        return plan;
      }

    }

    // do more memorisation stuff
    badGoalSet.add(goalSet);
    return null;


  }


  public List searchLevel(Set goalSet, int layer)
  {
    if (goalSet.isEmpty())
    {
      Set s = new HashSet();
      List li = new ArrayList();
      li.add(s);
      return li;
    }

    List actionSetList = new ArrayList();
    Set newGoalSet = new HashSet(goalSet);

    Iterator git = goalSet.iterator();
    PGProposition g = (PGProposition) git.next();
    newGoalSet.remove(g);

    Iterator ait = g.achievedBy.iterator();
    while (ait.hasNext())
    {
      PGAction a = (PGAction) ait.next();
      if ((a instanceof PGNoOp) && a.layer <= layer && a.layer >= 0)
      {
        Set newnewGoalSet = new HashSet(newGoalSet);
        newnewGoalSet.removeAll(a.achieves);
        List l = searchLevel(newnewGoalSet, layer);
        Iterator lit = l.iterator();
        while (lit.hasNext())
        {
          Set s = (HashSet) lit.next();
          if (noMutexesTest(a,s,layer))
          {
            s.add(a);
            actionSetList.add(s);
          }
        }
      }
    }

    ait = g.achievedBy.iterator();
    while (ait.hasNext())
    {
      PGAction a = (PGAction) ait.next();
      if (!(a instanceof PGNoOp) && a.layer <= layer && a.layer >= 0)
      {
        Set newnewGoalSet = new HashSet(newGoalSet);
        newnewGoalSet.removeAll(a.achieves);
        List l = searchLevel(newnewGoalSet, layer);
        Iterator lit = l.iterator();
        while (lit.hasNext())
        {
          Set s = (HashSet) lit.next();
          if (noMutexesTest(a,s,layer))
          {
            s.add(a);
            actionSetList.add(s);
          }
        }
      }
    }


    return actionSetList;
  }

  //******************************************************
  // Useful Methods
  //******************************************************

  public int getLayer(Action a)
  {
    PGAction pg = (PGAction) actionMap.get(a);
    return pg.layer;
  }

  //******************************************************
  // protected Classes
  //******************************************************
  protected class Node
  {
    public int layer;
    public Set mutexes;

    public Map mutexTable;

    public Node()
    {
    }

    public void reset()
    {
      layer = -1;
      mutexes = new HashSet();
      mutexTable = new Hashtable();
    }

    public void setMutex(Node n, int l)
    {
      n.mutexTable.put(this, new Integer(l));
      this.mutexTable.put(n, new Integer(l));
    }

    public boolean mutexWith(Node n, int l)
    {
      /*
       if (this == n) return false;
       Iterator mit = mutexes.iterator();
       while (mit.hasNext())
       {
         Mutex m = (Mutex) mit.next();
         if (m.contains(n))
         {
           return m.layer >= l;
         }
       }
       return false;
       */
      Object o = mutexTable.get(n);
      if (o == null) return false;
      Integer i = (Integer) o;
      return i.intValue() >= l;
    }
  }

  protected class PGAction extends Node
    {
    public Action action;
    public int counter, difficulty;

    public Set conditions = new HashSet();
    public Set achieves = new HashSet();
    public Set deletes = new HashSet();

    public PGAction()
    {

    }

    public PGAction(Action a)
    {
      action = a;
    }

    public Set getComparators()
    {
      return action.getComparators();
    }

    public Set getOperators()
    {
      return action.getOperators();
    }

    public void reset()
    {
      super.reset();
      counter = 0;
      difficulty = 0;
    }

    public String toString()
    {
      return action.toString();
    }
    }

  protected class PGNoOp extends PGAction
  {
    public PGProposition proposition;

    public PGNoOp(PGProposition p)
    {
      proposition = p;
    }

    public String toString()
    {
      return ("No-Op "+proposition);
    }

    public Set getComparators()
    {
      return new HashSet();
    }

    public Set getOperators()
    {
      return new HashSet();
    }
  }

  protected class PGProposition extends Node
    {
    public Proposition proposition;

    public Set achieves = new HashSet();
    public Set achievedBy = new HashSet();
    public Set deletedBy = new HashSet();

    public PGProposition(Proposition p)
    {
      proposition = p;
    }

    public String toString()
    {
      return proposition.toString();
    }
    }

  protected class MutexPair
  {
    public Node node1, node2;
    public MutexPair(Node n1, Node n2)
    {
      node1 = n1;
      node2 = n2;
    }
  }


  //******************************************************
  // Debugging Classes
  //******************************************************
  public void printGraph()
  {
    for (int i = 0; i <= num_layers; ++i)
    {
      System.out.println("-----Layer "+i+"----------------------------------------");
      printLayer(i);
    }
    System.out.println("-----End -----------------------------------------------");
  }

  public void printLayer(int i)
  {
    System.out.println("Facts:");
    Iterator pit = propositions.iterator();
    while (pit.hasNext())
    {
      PGProposition p = (PGProposition) pit.next();
      if (p.layer <= i && p.layer >= 0)
      {
        System.out.println("\t"+p);
        System.out.println("\t\tmutex with");
        Iterator mit = p.mutexTable.keySet().iterator();
        while (mit.hasNext())
        {
          PGProposition pm = (PGProposition) mit.next();
          Integer il = (Integer) p.mutexTable.get(pm);
          if (il.intValue() >= i)
          {
            System.out.println("\t\t\t"+pm);
          }
        }
      }
    }
    if (i == num_layers) return;
    System.out.println("Actions:");
    Iterator ait = actions.iterator();
    while (ait.hasNext())
    {
      PGAction a = (PGAction) ait.next();
      if (a.layer <= i && a.layer >= 0)
      {
        System.out.println("\t"+a);
        System.out.println("\t\tmutex with");
        Iterator mit = a.mutexTable.keySet().iterator();
        while (mit.hasNext())
        {
          PGAction am = (PGAction) mit.next();
          Integer il = (Integer) a.mutexTable.get(am);
          if (il.intValue() >= i)
          {
            System.out.println("\t\t\t"+am);
          }
        }
      }
    }
  }

}
TOP

Related Classes of javaff.planning.PlanningGraph

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.