org.sosy_lab.cpachecker.cpa.value.symbolic.util.SymbolicValues.java Source code

Java tutorial

Introduction

Here is the source code for org.sosy_lab.cpachecker.cpa.value.symbolic.util.SymbolicValues.java

Source

/*
 * CPAchecker is a tool for configurable software verification.
 *  This file is part of CPAchecker.
 *
 *  Copyright (C) 2007-2015  Dirk Beyer
 *  All rights reserved.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *
 *  CPAchecker web page:
 *    http://cpachecker.sosy-lab.org
 */
package org.sosy_lab.cpachecker.cpa.value.symbolic.util;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.sosy_lab.cpachecker.cpa.constraints.ConstraintsCPA.ComparisonType;
import org.sosy_lab.cpachecker.cpa.value.symbolic.type.BinarySymbolicExpression;
import org.sosy_lab.cpachecker.cpa.value.symbolic.type.ConstantSymbolicExpression;
import org.sosy_lab.cpachecker.cpa.value.symbolic.type.SymbolicIdentifier;
import org.sosy_lab.cpachecker.cpa.value.symbolic.type.SymbolicValue;
import org.sosy_lab.cpachecker.cpa.value.symbolic.type.UnarySymbolicExpression;
import org.sosy_lab.cpachecker.cpa.value.symbolic.util.AliasCreator.Environment;
import org.sosy_lab.cpachecker.cpa.value.type.Value;
import org.sosy_lab.cpachecker.util.states.MemoryLocation;

import com.google.common.base.Optional;

/**
 * Util class for {@link SymbolicValue}.
 * Before using this class, {@link #initialize(ComparisonType)} has to be called at least once.
 */
public class SymbolicValues {

    private static AliasCreator aliasCreator;
    private static SymbolicIdentifierLocator identifierLocator;

    public static void initialize(final ComparisonType pLessOrEqualComparison) {
        switch (pLessOrEqualComparison) {
        case SUBSET:
            aliasCreator = new IdentityAliasCreator();
            break;
        case ALIASED_SUBSET:
            aliasCreator = new RealAliasCreator();
            break;
        default:
            throw new AssertionError("Unhandled comparison type " + pLessOrEqualComparison);
        }

        identifierLocator = SymbolicIdentifierLocator.getInstance();
    }

    /**
     * Returns whether the given constraints represent the same C code (string wise).
     * This is the case if two constraints are completely equal after replacing symbolic expressions
     * with the program variables they represent.
     *
     * <p>Example: <code>s1 < 5</code> is equal to <code>s2 + 2 < 5</code> in respect to its meaning
     * with <code>s1</code> and <code>s2</code> being symbolic identifiers, if both constraints
     * represent <code>a < 5</code> with <code>a</code> being a program variable.</p>
     *
     * @param pValue1 the first symbolic value
     * @param pValue2 the second symbolic value
     * @return <code>true</code> if both symbolic values represent the same C code
     */
    public static boolean representSameCCodeExpression(final SymbolicValue pValue1, final SymbolicValue pValue2) {

        if (!pValue1.getClass().equals(pValue2.getClass())) {
            final Optional<MemoryLocation> val1RepLoc = pValue1.getRepresentedLocation();
            final Optional<MemoryLocation> val2RepLoc = pValue2.getRepresentedLocation();

            return (val1RepLoc.isPresent() || val2RepLoc.isPresent()) && val1RepLoc.equals(val2RepLoc);
        }

        final Optional<MemoryLocation> maybeRepLocVal1 = pValue1.getRepresentedLocation();
        final Optional<MemoryLocation> maybeRepLocVal2 = pValue2.getRepresentedLocation();

        if (maybeRepLocVal1.isPresent() || maybeRepLocVal2.isPresent()) {
            return maybeRepLocVal1.equals(maybeRepLocVal2);
        }
        assert maybeRepLocVal1.equals(maybeRepLocVal2);

        if (pValue1 instanceof SymbolicIdentifier || pValue1 instanceof ConstantSymbolicExpression) {
            assert pValue2 instanceof SymbolicIdentifier || pValue2 instanceof ConstantSymbolicExpression;

            return maybeRepLocVal1.equals(maybeRepLocVal2);

        } else if (pValue1 instanceof UnarySymbolicExpression) {
            assert pValue2 instanceof UnarySymbolicExpression;

            final SymbolicValue val1Op = ((UnarySymbolicExpression) pValue1).getOperand();
            final SymbolicValue val2Op = ((UnarySymbolicExpression) pValue2).getOperand();

            return representSameCCodeExpression(val1Op, val2Op);

        } else if (pValue1 instanceof BinarySymbolicExpression) {
            assert pValue2 instanceof BinarySymbolicExpression;

            final SymbolicValue val1Op1 = ((BinarySymbolicExpression) pValue1).getOperand1();
            final SymbolicValue val1Op2 = ((BinarySymbolicExpression) pValue1).getOperand2();
            final SymbolicValue val2Op1 = ((BinarySymbolicExpression) pValue2).getOperand1();
            final SymbolicValue val2Op2 = ((BinarySymbolicExpression) pValue2).getOperand2();

            return representSameCCodeExpression(val1Op1, val2Op1) && representSameCCodeExpression(val1Op2, val2Op2);

        } else {
            throw new AssertionError("Unhandled symbolic value type " + pValue1.getClass());
        }
    }

    public static boolean representSameSymbolicMeaning(final SymbolicValue pValue1, final SymbolicValue pValue2) {

        if (!pValue1.getClass().equals(pValue2.getClass())) {
            return false;
        }

        if (pValue1 instanceof SymbolicIdentifier) {
            assert pValue2 instanceof SymbolicIdentifier;

            return ((SymbolicIdentifier) pValue1).getId() == ((SymbolicIdentifier) pValue2).getId();

        } else if (pValue1 instanceof ConstantSymbolicExpression) {
            assert pValue2 instanceof ConstantSymbolicExpression;

            final Value innerVal1 = ((ConstantSymbolicExpression) pValue1).getValue();
            final Value innerVal2 = ((ConstantSymbolicExpression) pValue2).getValue();

            if (innerVal1 instanceof SymbolicValue && innerVal2 instanceof SymbolicValue) {
                return representSameSymbolicMeaning((SymbolicValue) innerVal1, (SymbolicValue) innerVal2);

            } else {
                return innerVal1.equals(innerVal2);
            }

        } else if (pValue1 instanceof UnarySymbolicExpression) {
            assert pValue2 instanceof UnarySymbolicExpression;

            final SymbolicValue val1Op = ((UnarySymbolicExpression) pValue1).getOperand();
            final SymbolicValue val2Op = ((UnarySymbolicExpression) pValue2).getOperand();

            return representSameSymbolicMeaning(val1Op, val2Op);

        } else if (pValue1 instanceof BinarySymbolicExpression) {
            assert pValue2 instanceof BinarySymbolicExpression;

            final SymbolicValue val1Op1 = ((BinarySymbolicExpression) pValue1).getOperand1();
            final SymbolicValue val1Op2 = ((BinarySymbolicExpression) pValue1).getOperand2();
            final SymbolicValue val2Op1 = ((BinarySymbolicExpression) pValue2).getOperand1();
            final SymbolicValue val2Op2 = ((BinarySymbolicExpression) pValue2).getOperand2();

            return representSameSymbolicMeaning(val1Op1, val2Op1) && representSameSymbolicMeaning(val1Op2, val2Op2);

        } else {
            throw new AssertionError("Unhandled symbolic value type " + pValue1.getClass());
        }
    }

    public static Collection<SymbolicIdentifier> getContainedSymbolicIdentifiers(final SymbolicValue pValue) {
        return pValue.accept(identifierLocator);
    }

    public static Collection<SymbolicIdentifier> getContainedSymbolicIdentifiers(
            final Collection<? extends SymbolicValue> pValues) {
        Collection<SymbolicIdentifier> ret = new HashSet<>();

        for (SymbolicValue v : pValues) {
            ret.addAll(v.accept(identifierLocator));
        }

        return ret;
    }

    public static Set<Environment> getPossibleAliases(final Collection<? extends SymbolicValue> pFirstValues,
            final Collection<? extends SymbolicValue> pSecondValues) {
        return aliasCreator.getPossibleAliases(pFirstValues, pSecondValues);
    }
}