org.sosy_lab.cpachecker.core.counterexample.RichModel.java Source code

Java tutorial

Introduction

Here is the source code for org.sosy_lab.cpachecker.core.counterexample.RichModel.java

Source

/*
 *  CPAchecker is a tool for configurable software verification.
 *  This file is part of CPAchecker.
 *
 *  Copyright (C) 2007-2014  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.core.counterexample;

import static com.google.common.base.Preconditions.checkState;

import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.annotation.Nullable;

import org.sosy_lab.common.Appender;
import org.sosy_lab.common.Appenders;
import org.sosy_lab.cpachecker.cfa.model.CFAEdge;
import org.sosy_lab.solver.AssignableTerm;
import org.sosy_lab.cpachecker.cpa.arg.ARGPath;
import org.sosy_lab.cpachecker.cpa.arg.ARGState;
import org.sosy_lab.solver.Model;

import com.google.common.collect.ForwardingMap;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Multimap;

/**
 * This class represents an assignment of concrete values to program variables
 * along a path. Each variable can have several assignments with different
 * SSA indices if it gets re-assigned along the path.
 * The value of each variable can be an arbitrary object, but usually
 * this is a {@link Number}.
 *
 * Unlike {@link Model} class, RichModel contains extra meta-information:
 * {@link CFAPathWithAssumptions} and a multimap from {@link CFAEdge} to objects
 * stored.
 */
public class RichModel extends ForwardingMap<AssignableTerm, Object> implements Appender {

    private final Map<AssignableTerm, Object> mModel;

    private final CFAPathWithAssumptions assignments;
    private final Multimap<CFAEdge, AssignableTerm> assignableTermsPerCFAEdge;

    @Override
    protected Map<AssignableTerm, Object> delegate() {
        return mModel;
    }

    public static RichModel empty() {
        return new RichModel();
    }

    private RichModel() {
        mModel = ImmutableMap.of();
        assignments = new CFAPathWithAssumptions();
        assignableTermsPerCFAEdge = ImmutableListMultimap.of();
    }

    public RichModel(Map<AssignableTerm, Object> content) {
        mModel = ImmutableMap.copyOf(content);
        assignments = new CFAPathWithAssumptions();
        assignableTermsPerCFAEdge = ImmutableListMultimap.of();
    }

    private RichModel(Map<AssignableTerm, Object> content, CFAPathWithAssumptions pAssignments) {
        mModel = ImmutableMap.copyOf(content);
        assignments = pAssignments;
        assignableTermsPerCFAEdge = ImmutableListMultimap.of();
    }

    public static RichModel of(Model model) {
        return new RichModel(model.getData());
    }

    /**
     * Return a new model that is equal to the current one,
     * but additionally has information about when each variable was assigned.
     */
    public RichModel withAssignmentInformation(CFAPathWithAssumptions pAssignments) {
        checkState(assignments.isEmpty());
        return new RichModel(mModel, pAssignments);
    }

    /**
     * Return a path that indicates which variables where assigned which values at
     * what edge. Note that not every value for every variable is available.
     */
    @Nullable
    public CFAPathWithAssumptions getCFAPathWithAssignments() {
        return assignments;
    }

    /**
     * Returns a collection of {@link AssignableTerm}} terms that were assigned a the given
     * {@link CFAEdge} edge.
     *
     * @param pEdge All terms that were assigned at this edge are returned-
     * @return A collection of terms assigned at the given edge.
     */
    public Collection<AssignableTerm> getAllAssignedTerms(CFAEdge pEdge) {
        return assignableTermsPerCFAEdge.get(pEdge);
    }

    @Nullable
    public Map<ARGState, CFAEdgeWithAssumptions> getExactVariableValues(ARGPath pPath) {

        if (assignments.isEmpty()) {
            return null;
        }

        return assignments.getExactVariableValues(pPath);
    }

    @Nullable
    public CFAPathWithAssumptions getExactVariableValuePath(List<CFAEdge> pPath) {

        if (assignments.isEmpty()) {
            return null;
        }

        return assignments.getExactVariableValues(pPath);
    }

    @Override
    public void appendTo(Appendable output) throws IOException {
        Model.appendModel(output, mModel);
    }

    @Override
    public String toString() {
        return Appenders.toString(this);
    }
}