package tcra.exercises.resolve_random_access_capability_private;

import java.util.List;
import java.util.Vector;

import tcra.math.Assertion;
import tcra.math.MathInteger;
import tcra.math.MathString;
import tcra.math.MathType;

public class ResolveRandomAccessCapability_PostRemoveAssertion
       implements Assertion
{

   @SuppressWarnings("unchecked")
   public boolean check(List<MathType> state)
   {
      MathString<MathType> lb_self   =
                                   (MathString<MathType>)state.get(0);
      MathInteger          lb_index  = (MathInteger)state.get(2);
      MathString<MathType> self      =
                                   (MathString<MathType>)state.get(3);
      MathInteger          remove    = (MathInteger)state.get(4);
      MathInteger          index     = (MathInteger)state.get(5);
      
      Vector<MathString<MathType>> split =
                           (Vector<MathString<MathType>>)lb_self.split(
                                                lb_index.getValue()-2);
      MathString<MathType> alpha = split.get(0);
      MathString<MathType> beta  = split.get(1);
      
      Vector<MathString<MathType>> split2 =
                           (Vector<MathString<MathType>>)beta.split(0);
      beta = split2.get(1);
      
      if(!split2.get(0).compareElement(0,remove)) return false;
      if(lb_index.getValue() != alpha.length()+1) return false;
      if(!self.equals(alpha.concat(beta))) return false;
      if(!index.equals(lb_index))          return false;
      
      return true;
   } // end ctor
   
   public String toString()
   {
      return("∃ α, β: Str(Integer) ∋ "+
             "#S = α * &lt;I&gt; * β and<br>"+
             "|α| + 1 = k and S = α * β;");
   } // end toString()
   
   @SuppressWarnings("unchecked")
   public String toInstanceString(List<MathType> state)
   {
      MathString<MathType> lb_self   =
                                   (MathString<MathType>)state.get(0);
      MathInteger          lb_index  = (MathInteger)state.get(2);
      MathString<MathType> self      =
                                   (MathString<MathType>)state.get(3);
      MathInteger          remove    = (MathInteger)state.get(4);
      
      Vector<MathString<MathType>> split =
                          (Vector<MathString<MathType>>)lb_self.split(
                                               lb_index.getValue()-2);
      MathString<MathType> alpha = split.get(0);
      MathString<MathType> beta  = split.get(1);
         
      Vector<MathString<MathType>> split2 =
                          (Vector<MathString<MathType>>)beta.split(0);
      beta = split2.get(1);
      
      return("∃ α, β: Str(Integer) ∋" +
             lb_self.toHTMLString()+ " = " +alpha.toHTMLString()+
             " * &lt;" +
             remove.toHTMLString()+ "&gt; * " +beta.toHTMLString()+
             " and<br>" +
             "|" +alpha.toHTMLString()+ "| + 1 = " +
             lb_index.toHTMLString()+
             " and " +self.toHTMLString()+ " = " +
             alpha.toHTMLString()+ " * " +
             beta.toHTMLString());
   } // end toInstanceString()
} // end class
