Package org.jakstab.analysis.composite

Source Code of org.jakstab.analysis.composite.DualCompositeState

/*
* DualCompositeState.java - This file is part of the Jakstab project.
* Copyright 2007-2012 Johannes Kinder <jk@jakstab.org>
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, see <http://www.gnu.org/licenses/>.
*/
package org.jakstab.analysis.composite;

import java.util.Collections;
import java.util.Set;

import org.jakstab.analysis.AbstractState;
import org.jakstab.analysis.UnderApproximateState;
import org.jakstab.rtl.expressions.RTLExpression;
import org.jakstab.rtl.expressions.RTLNumber;
import org.jakstab.util.FastSet;
import org.jakstab.util.Logger;
import org.jakstab.util.Tuple;

/**
* A composite state containing both over- and under-approximate states.
*
* @author Johannes Kinder
*
*/
public class DualCompositeState extends CompositeState {

  @SuppressWarnings("unused")
  private static final Logger logger = Logger.getLogger(DualCompositeState.class);

  public DualCompositeState(AbstractState[] components) {
    super(components);
  }

  public Set<Tuple<RTLNumber>> projection(RTLExpression... expressions) {

    Set<Tuple<RTLNumber>> result = new FastSet<Tuple<RTLNumber>>();
   
    for (int i=0; i<components.length; i++) {
      if (!(components[i] instanceof UnderApproximateState))
        continue;
      // Concretize this component state and then take the union with existing ones
      Set<Tuple<RTLNumber>> concreteTuples = components[i].projectionFromConcretization(expressions);
      //logger.info(concreteTuples);
      /* Return value of null here represents the bottom element, so it has no effect in union */
      if (concreteTuples == null) continue;
      /* Else take the union */
      else {
        result.addAll(concreteTuples);
      }
    }
    //logger.debug("Under-approximation projects " + Arrays.toString(expressions) + " to " + result);
    assert result != null;
    return result;
  }

  @Override
  public Set<Tuple<RTLNumber>> projectionFromConcretization(
      RTLExpression... expressions) {

    Set<Tuple<RTLNumber>> result = null;
    for (int i=0; i<components.length; i++) {
      if (components[i] instanceof UnderApproximateState)
        continue;
      // Concretize this component state and then intersect it with existing ones
      Set<Tuple<RTLNumber>> concreteTuples = components[i].projectionFromConcretization(expressions);
      //logger.info(concreteTuples);
      /* Return value of null represents the whole set of tuples of numbers (usually b/c the function
       * is not implemented), so intersection has no effect */
      if (concreteTuples == null) continue;
      /* If we are currently at the whole set, the new tuple set is the intersection */
      else if (result == null) result = concreteTuples;
      /* Else intersect */
      else {
        // result.retainAll(concreteTuples);
        // intersect manually b/c of possible null components (wildcards for more tuples)
        //   Note: A tuple with a null component expands to a set of tuples
        //   with all possible values for that component
        //
        Set<Tuple<RTLNumber>> newResult = new FastSet<Tuple<RTLNumber>>();
        // for all tuples in result
        for (Tuple<RTLNumber> rTuple : result) {
          // for all tuples we got from the current substate
          cTuplesLoop: for (Tuple<RTLNumber> cTuple : concreteTuples) {
            // array for building new tuple
            RTLNumber[] numbers = new RTLNumber[expressions.length];
            // match components of both tuples against each other
            for (int j=0; j<expressions.length; j++) {
              RTLNumber cNumber = cTuple.get(j);
              RTLNumber rNumber = rTuple.get(j);
              // if the component is no wildcard and not equal, don't match, try next new tuple for match
              if (cNumber != RTLNumber.WILDCARD && rNumber != null && !cNumber.equals(rNumber)) {
                continue cTuplesLoop;
              } else {
                // handle wildcards on both sides:
                if (rNumber == RTLNumber.WILDCARD) numbers[j] = cNumber;
                else numbers[j] = rNumber;
              }
            }
            // We passed all components - so add matching tuple
            newResult.add(Tuple.create(numbers));
            // We still need to continue with the next tuple, since wildcards
            // could allow more possibilities
          }
          // cTuplesLoop finished without finding a match
        }
        result = newResult;
      }
     
    }
    //logger.info("Project " + Arrays.toString(expressions) + " to " + result);
    //assert result != null;
   
    // result can be null when using DummyAnalysis.
    if (result == null) result = Collections.emptySet();
    return result;
  }

}
TOP

Related Classes of org.jakstab.analysis.composite.DualCompositeState

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.