org.sosy_lab.cpachecker.util.predicates.invariants.ExpressionTreeInvariantSupplier.java Source code

Java tutorial

Introduction

Here is the source code for org.sosy_lab.cpachecker.util.predicates.invariants.ExpressionTreeInvariantSupplier.java

Source

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

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

import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;

import org.sosy_lab.cpachecker.cfa.CFA;
import org.sosy_lab.cpachecker.cfa.model.CFANode;
import org.sosy_lab.cpachecker.core.algorithm.invariants.ExpressionTreeSupplier;
import org.sosy_lab.cpachecker.core.algorithm.invariants.LazyLocationMapping;
import org.sosy_lab.cpachecker.core.algorithm.invariants.ReachedSetBasedExpressionTreeSupplier;
import org.sosy_lab.cpachecker.core.reachedset.AggregatedReachedSets;
import org.sosy_lab.cpachecker.core.reachedset.UnmodifiableReachedSet;
import org.sosy_lab.cpachecker.util.expressions.And;
import org.sosy_lab.cpachecker.util.expressions.ExpressionTree;
import org.sosy_lab.cpachecker.util.expressions.ExpressionTrees;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class ExpressionTreeInvariantSupplier implements ExpressionTreeSupplier {

    private final AggregatedReachedSets aggregatedReached;
    private final CFA cfa;

    private Set<UnmodifiableReachedSet> lastUsedReachedSets = Collections.emptySet();
    private ExpressionTreeSupplier lastInvariantSupplier = TrivialInvariantSupplier.INSTANCE;

    private final Map<UnmodifiableReachedSet, ExpressionTreeSupplier> singleInvariantSuppliers = new HashMap<>();

    public ExpressionTreeInvariantSupplier(AggregatedReachedSets pAggregated, CFA pCFA) {
        aggregatedReached = pAggregated;
        cfa = pCFA;
        updateInvariants(); // at initialization we want to update the invariants the first time
    }

    @Override
    public ExpressionTree<Object> getInvariantFor(CFANode pNode) {
        return lastInvariantSupplier.getInvariantFor(pNode);
    }

    public void updateInvariants() {
        Set<UnmodifiableReachedSet> newReached = aggregatedReached.snapShot();
        if (!newReached.equals(lastUsedReachedSets)) {
            // if we have a former aggregated supplier we do only replace the changed parts
            Set<UnmodifiableReachedSet> oldElements = Sets.difference(lastUsedReachedSets, newReached);
            Set<UnmodifiableReachedSet> newElements = Sets.difference(newReached, lastUsedReachedSets);

            oldElements.forEach(r -> singleInvariantSuppliers.remove(r));
            newElements.forEach(r -> singleInvariantSuppliers.put(r,
                    new ReachedSetBasedExpressionTreeSupplier(new LazyLocationMapping(r), cfa)));

            lastUsedReachedSets = newReached;
            lastInvariantSupplier = new AggregatedExpressionTreeSupplier(
                    ImmutableSet.copyOf(singleInvariantSuppliers.values()));
        }
    }

    private static class AggregatedExpressionTreeSupplier implements ExpressionTreeSupplier {

        private final Collection<ExpressionTreeSupplier> invariantSuppliers;

        private AggregatedExpressionTreeSupplier(ImmutableCollection<ExpressionTreeSupplier> pInvariantSuppliers) {
            invariantSuppliers = checkNotNull(pInvariantSuppliers);
        }

        @Override
        public ExpressionTree<Object> getInvariantFor(CFANode pNode) {
            return invariantSuppliers.stream().map(s -> s.getInvariantFor(pNode)).reduce(ExpressionTrees.getTrue(),
                    And::of);
        }
    }
}