
/**
 * Strips3.java
 * Apply a Strips operator
 *
 * Created: Mon Jan 15 20:13:17 2001
 *
 * @author 
 * @version
 */

import java.util.*;
import StripsFn;

public class Strips3 extends StripsFn{
  private Strips_op op;
  private HashMap context;
  private MStringVector prestate; //state after preconds met
  private HashMap pcon; //context after preconds met
  private Vector preplan; //plan to achieve preconds
  private MStringVector astate; //state after applying op
  private Vector aplan; //plan to apply op

  //constructor
  public Strips3 (Vector opl,MStringVector is, MStringVector gs, Strips_op o, HashMap con){
    oplis=opl;
    initstate=is;
    op=o;
    context=con;

  } 

  //run problem solver

  public boolean run(){
    //commentary
    System.out.println("-------------------");
    System.out.println("Strips3");
    System.out.println(initstate);
    System.out.println(op.getAct_list());
    System.out.println(context);
    
    boolean preres = meet_preconditions(); //try to meet preconditions
    if (!preres){
      result=false; //failed
    }
    else{ //OK, apply the op
      apply_op();
      result=true;
      plan=preplan;
      plan.addAll(aplan); //plan is plan for meeting preconds + op's act
    }
    return result;
  }

  private boolean meet_preconditions(){
    MStringVector preconds=op.getPreconds();
    boolean preres=true; //set to false if we fail to match a precond
    prestate=initstate; //state having met some preconds
    pcon=context; //context after having matched some preconds
    preplan=new Vector(); //plan for preconds, initially empty

    Iterator pit=preconds.iterator();
    String p; //will be next precond

    while (pit.hasNext()&& preres){ //iterate over preconds
      p=(String) pit.next(); //next precond
      boolean matchres=initstate.match(p,pcon);//match precond in initstate
      if (matchres) { //this precond met 
        pcon=initstate.getContext(); //update context from match
      }
      else { //precond p not met - call Strips1 to deal with it

        MString pm=new MString(p); //substitute back in the precondn
        String ps=pm.msubst(pcon); //to form the goal for Strips1

        Strips1 strips1 =new Strips1(oplis,prestate,new MStringVector(ps));
        boolean strips1res=strips1.run();

        if (strips1res){ //Strips1 succeeded - back for more preconds
          preplan.addAll(strips1.getPlan()); //save the strips1 plan
          prestate=strips1.getNewstate(); 
        }
        else {
          preres=false; //Strips1 failed - give up
        }
      }
    }
    return preres;
  }
  
  // apply an operator
  // delete items from op's delete list from prestate
  // then add items from add list

  private void apply_op(){
    aplan=op.getAct_list().msubst(pcon); //the plan - subst in action list
    System.out.println("Applying op "+aplan);
    Vector dels=op.getDel_list().msubst(pcon); //get deletions and substitute context
    Vector adds=op.getAdd_list().msubst(pcon); //ditto for additions
    /* diagnostics
       System.out.println("Applying op: deleting "+dels+"adding "+adds);
       String del=(String) dels.elementAt(0);
       System.out.println(del.length());
       System.out.println(del);
       for (Iterator it=prestate.iterator();it.hasNext();){
       String el= (String)it.next();
       System.out.println(el.length());
       System.out.println(el);
       boolean r=el.equals(del);
       }
    */
      
    prestate.removeAll(dels);
    prestate.addAll(adds);
    newstate=prestate;
    System.out.println("New state "+newstate);
    
  }

}
        
