LoopInvariantProposer.java :  » Testing » KeY » de » uka » ilkd » key » proof » Java Open Source

Java Open Source » Testing » KeY 
KeY » de » uka » ilkd » key » proof » LoopInvariantProposer.java
// This file is part of KeY - Integrated Deductive Software Design
// Copyright (C) 2001-2007 Universitaet Karlsruhe, Germany
//                         Universitaet Koblenz-Landau, Germany
//                         Chalmers University of Technology, Sweden
//
// The KeY system is protected by the GNU General Public License. 
// See LICENSE.TXT for details.
//
//

package de.uka.ilkd.key.proof;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import de.uka.ilkd.key.collection.ListOfString;
import de.uka.ilkd.key.java.*;
import de.uka.ilkd.key.java.annotation.Annotation;
import de.uka.ilkd.key.java.annotation.LoopInvariantAnnotation;
import de.uka.ilkd.key.java.reference.*;
import de.uka.ilkd.key.java.statement.LoopStatement;
import de.uka.ilkd.key.java.statement.MethodFrame;
import de.uka.ilkd.key.java.visitor.JavaASTVisitor;
import de.uka.ilkd.key.logic.*;
import de.uka.ilkd.key.logic.op.*;
import de.uka.ilkd.key.pp.*;
import de.uka.ilkd.key.rule.*;

public class LoopInvariantProposer implements InstantiationProposer {

    /**
     * An instance of LoopInvariantProposer
     */
    public static final LoopInvariantProposer DEFAULT = new LoopInvariantProposer();

    
    /**
     * Returns a proposal for the instantiation of <code>var</code> 
     * iff <code>app</code> is a TacletApp for a loop invariant taclet
     * and <code>var</code> is the SchemaVariable representing the invariant 
     * and the loop on which the taclet matches contains a loop invariant
     * annotation. Otherwise null is returned.
     */
    public String getProposal(TacletApp app, 
                SchemaVariable var, 
            Services services, 
            Node undoAnchor,
            ListOfString previousProposals){
  
        final Object inst = tryToInstantiate(app, var, services);
  final LogicPrinter lp = new LogicPrinter(new ProgramPrinter(null), 
             NotationInfo.createInstance(),
             services);
  String proposal;        
  try {
      if (inst instanceof Term){
    lp.printTerm((Term) inst);
    proposal = lp.toString();
      }  else if (inst instanceof ListOfTerm){
    lp.printTerm((ListOfTerm) inst);
    proposal = lp.toString();
            } else if (inst instanceof SetOfLocationDescriptor) {
                lp.printLocationDescriptors((SetOfLocationDescriptor) inst);
                proposal = lp.toString();
            } else if (var.name().toString().equals("#modifies")) {
    lp.printLocationDescriptors(
                        SetAsListOfLocationDescriptor.EMPTY_SET
                        .add(EverythingLocationDescriptor.INSTANCE));
                proposal = lp.toString();
      } else { 
    proposal = null;
      }
  } catch (IOException e){
      proposal = null;
  }
        
  return proposal;
    }

    /**
     * returns true if the rulesets contain the rule set loop invariant   
     */
    public static boolean inLoopInvariantRuleSet(IteratorOfRuleSet ruleSets) {    
        while (ruleSets.hasNext()) {
            if (ruleSets.next().name().toString().equals("loop_invariant_proposal")) {
                return true;
            }
        }
        return false;
    }
    
    
    private static Term getSelfTerm(Term term, Services services) {
        final Services serv = services;
        
  //ignore updates
  while(term.op() instanceof IUpdateOperator) {
      term = term.sub(((IUpdateOperator)term.op()).targetPos());
  }
  
  //the remaining term should contain a program 
  //(because this method is only called for apps of taclets 
  //in "loop_invariant_proposal")
  final ProgramElement pe = term.javaBlock().program();
    
  //fetch "self" from innermost non-static method-frame
  Term result = new JavaASTVisitor(pe) {
      private Term result;
      protected void doAction(ProgramElement node) {
    node.visit(this);
      }
      protected void doDefaultAction(SourceElement node) {
    if(node instanceof MethodFrame && result == null) {
        MethodFrame mf = (MethodFrame) node;
        ExecutionContext ec 
          = (ExecutionContext) mf.getExecutionContext();
        ReferencePrefix rp = ec.getRuntimeInstance();
                    if(!(rp instanceof TypeReference) && rp !=null) {
                        result = serv.getTypeConverter().convertToLogicElement(rp);
                    }
    }
      }
      public Term run() {
    walk(pe);
    return result;
      }
  }.run();
    
  return result;
    }
    
    
    /**
     * Returns an instantiation of <code>var</code> 
     * iff <code>app</code> is a TacletApp for a loop invariant taclet
     * and <code>var</code> is the SchemaVariable representing the invariant 
     * and the loop on which the taclet matches contains a loop invariant
     * annotation. Otherwise null is returned.
     * Depending if the var looked for is a list schemavariable or a normal sv
     * a list of terms or a term is returned
     */
    public Object tryToInstantiate(TacletApp app, SchemaVariable var, Services services){  
        Object inst = null;
        if (app instanceof PosTacletApp && 
      inLoopInvariantRuleSet(app.taclet().ruleSets())) {
      final PosInOccurrence pos = ((PosTacletApp) app).posInOccurrence();
      final LoopInvariantAnnotation firstLoopInvAnnot = 
                getFirstLoopInvariantAnnotation(pos.subTerm());
      if(firstLoopInvAnnot == null) {
    return null;
      }

      //prepare replacing the loop invariant's "self"-variable 
      //by the current "self" term
      final Term selfTerm = getSelfTerm(pos.subTerm(), services);
      Map map = new HashMap();
      map.put(TermBuilder.DF.var(firstLoopInvAnnot.getSelfVar()), 
                    selfTerm);
      OpReplacer or = new OpReplacer(map);
      
      //determine instantiation
            final String varName = var.name().toString();
            if (varName.equals("inv") 
              && firstLoopInvAnnot.invariant() != null) {
    inst = or.replace(firstLoopInvAnnot.invariant());
      } else if(varName.equals("#modifies")
        && firstLoopInvAnnot.assignable() != null) {
    inst = or.replace(firstLoopInvAnnot.assignable());
      } else if(var.name().toString().equals("post")
        && firstLoopInvAnnot.post() != null) {
    inst = or.replace(firstLoopInvAnnot.post());
      } else if(varName.equals("variant")
        && firstLoopInvAnnot.variant() != null) {
    inst = or.replace(firstLoopInvAnnot.variant());
      } else if(varName.equals("#old")) {
    inst = convertToListOfTerm(firstLoopInvAnnot.olds());
      }
  }
        
  return inst;
    }


    private LoopInvariantAnnotation getFirstLoopInvariantAnnotation(Term t) {
        final Annotation[] a = getFirstLoopStatement(t).getAnnotations();
        
        for(int i = 0; i<a.length; i++){
            if(a[i] instanceof LoopInvariantAnnotation){
                return (LoopInvariantAnnotation) a[i];
            }
        }
        return null;        
    }
    
    private ListOfTerm convertToListOfTerm(ArrayOfTerm array){
  ListOfTerm result =  SLListOfTerm.EMPTY_LIST;
  for (int i = array.size() - 1; i>=0; i--) {
      result = result.prepend(array.getTerm(i));      
  }
  return result;
    }

    private LoopStatement getFirstLoopStatement(Term t){
  while(t.op() instanceof IUpdateOperator){
      t = ( (IUpdateOperator)t.op () ).target ( t );
  }
  return getLoopHelp(t.javaBlock().program());
    }

    private LoopStatement getLoopHelp(ProgramElement pe){
  if(pe instanceof LoopStatement){
      return (LoopStatement) pe;
  }
  if(pe instanceof StatementContainer){
      return getLoopHelp(((StatementContainer) pe).getStatementAt(0));
  }
  //shouldn't happen.
  return null;
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.