org.sosy_lab.cpachecker.cpa.invariants.formula.ReplaceVisitor.java Source code

Java tutorial

Introduction

Here is the source code for org.sosy_lab.cpachecker.cpa.invariants.formula.ReplaceVisitor.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.cpa.invariants.formula;

import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;

/**
 * Instances of this class are invariants formula visitors used to replace
 * parts of the visited formulae with other formulae.
 *
 * @param <T> the type of the constants used in the formulae.
 */
public class ReplaceVisitor<T>
        implements NumeralFormulaVisitor<T, NumeralFormula<T>>, BooleanFormulaVisitor<T, BooleanFormula<T>> {

    /**
     * Predicate indicating which numeral formula to replace.
     */
    private final Predicate<? super NumeralFormula<T>> toReplaceN;

    /**
     * This function receives a formula to be replaced and produces the replacement.
     */
    private final Function<? super NumeralFormula<T>, ? extends NumeralFormula<T>> replacementN;

    /**
     * Predicate indicating which boolean formula to replace.
     */
    private final Predicate<? super BooleanFormula<T>> toReplaceB;

    /**
     * This function receives a formula to be replaced and produces the replacement.
     */
    private final Function<? super BooleanFormula<T>, ? extends BooleanFormula<T>> replacementB;

    private final RecursiveNumeralFormulaVisitor<T> recursiveNumeralFormulaVisitor;

    private final RecursiveBooleanFormulaVisitor<T> recursiveBooleanFormulaVisitor;

    /**
     * Creates a new replace visitor for replacing occurrences of the first given
     * formula by the second given formula in visited formulae.
     *
     * @param pToReplace the formula to be replaced.
     * @param pReplacement the replacement formula.
     */
    public ReplaceVisitor(NumeralFormula<T> pToReplace, NumeralFormula<T> pReplacement) {
        this(pToReplace == null ? Predicates.<NumeralFormula<T>>alwaysFalse()
                : Predicates.<NumeralFormula<T>>equalTo(pToReplace), Functions.constant(pReplacement),
                Predicates.<BooleanFormula<T>>alwaysFalse(), Functions.<BooleanFormula<T>>identity());
    }

    /**
     * Creates a new replace visitor for replacing matches of given predicate
     * by the given formula in visited formulae.
     *
     * @param pToReplace the predicate indicating what to replace.
     * @param pReplacement the replacement formula.
     */
    public ReplaceVisitor(Predicate<? super NumeralFormula<T>> pToReplace,
            Function<NumeralFormula<T>, NumeralFormula<T>> pReplacement) {
        this(pToReplace, pReplacement, Predicates.<BooleanFormula<T>>alwaysFalse(),
                Functions.<BooleanFormula<T>>identity());
    }

    /**
     * Creates a new replace visitor for replacing occurrences of the first given
     * formula by the second given formula in visited formulae.
     *
     * @param pToReplace the formula to be replaced.
     * @param pReplacement the replacement formula.
     */
    public ReplaceVisitor(BooleanFormula<T> pToReplace, BooleanFormula<T> pReplacement) {
        this(Predicates.<NumeralFormula<T>>alwaysFalse(), Functions.<NumeralFormula<T>>identity(),
                pToReplace == null ? Predicates.<BooleanFormula<T>>alwaysFalse()
                        : Predicates.<BooleanFormula<T>>equalTo(pToReplace),
                Functions.constant(pReplacement));
    }

    private ReplaceVisitor(Predicate<? super NumeralFormula<T>> pToReplaceN,
            Function<? super NumeralFormula<T>, ? extends NumeralFormula<T>> pReplacementN,
            Predicate<? super BooleanFormula<T>> pToReplaceB,
            Function<? super BooleanFormula<T>, ? extends BooleanFormula<T>> pReplacementB) {
        Preconditions.checkNotNull(pToReplaceN);
        Preconditions.checkNotNull(pReplacementN);
        Preconditions.checkNotNull(pToReplaceB);
        Preconditions.checkNotNull(pToReplaceB);
        this.toReplaceN = pToReplaceN;
        this.replacementN = pReplacementN;
        this.toReplaceB = pToReplaceB;
        this.replacementB = pReplacementB;
        this.recursiveNumeralFormulaVisitor = new RecursiveNumeralFormulaVisitor<T>() {

            @Override
            protected NumeralFormula<T> visitPost(NumeralFormula<T> pFormula) {
                if (toReplaceN.apply(pFormula)) {
                    return replacementN.apply(pFormula);
                }
                return pFormula;
            }

        };
        this.recursiveBooleanFormulaVisitor = new RecursiveBooleanFormulaVisitor<T>(
                this.recursiveNumeralFormulaVisitor) {

            @Override
            protected BooleanFormula<T> visitPost(BooleanFormula<T> pFormula) {
                if (toReplaceB.apply(pFormula)) {
                    return replacementB.apply(pFormula);
                }
                return pFormula;
            }
        };
    }

    @Override
    public BooleanFormula<T> visitFalse() {
        return this.recursiveBooleanFormulaVisitor.visitFalse();
    }

    @Override
    public BooleanFormula<T> visitTrue() {
        return this.recursiveBooleanFormulaVisitor.visitTrue();
    }

    @Override
    public BooleanFormula<T> visit(Equal<T> pEqual) {
        return pEqual.accept(this.recursiveBooleanFormulaVisitor);
    }

    @Override
    public BooleanFormula<T> visit(LessThan<T> pLessThan) {
        return pLessThan.accept(this.recursiveBooleanFormulaVisitor);
    }

    @Override
    public BooleanFormula<T> visit(LogicalAnd<T> pAnd) {
        return pAnd.accept(this.recursiveBooleanFormulaVisitor);
    }

    @Override
    public BooleanFormula<T> visit(LogicalNot<T> pNot) {
        return pNot.accept(this.recursiveBooleanFormulaVisitor);
    }

    @Override
    public NumeralFormula<T> visit(Add<T> pAdd) {
        return pAdd.accept(this.recursiveNumeralFormulaVisitor);
    }

    @Override
    public NumeralFormula<T> visit(BinaryAnd<T> pAnd) {
        return pAnd.accept(this.recursiveNumeralFormulaVisitor);
    }

    @Override
    public NumeralFormula<T> visit(BinaryNot<T> pNot) {
        return pNot.accept(this.recursiveNumeralFormulaVisitor);
    }

    @Override
    public NumeralFormula<T> visit(BinaryOr<T> pOr) {
        return pOr.accept(this.recursiveNumeralFormulaVisitor);
    }

    @Override
    public NumeralFormula<T> visit(BinaryXor<T> pXor) {
        return pXor.accept(this.recursiveNumeralFormulaVisitor);
    }

    @Override
    public NumeralFormula<T> visit(Constant<T> pConstant) {
        return pConstant.accept(this.recursiveNumeralFormulaVisitor);
    }

    @Override
    public NumeralFormula<T> visit(Divide<T> pDivide) {
        return pDivide.accept(this.recursiveNumeralFormulaVisitor);
    }

    @Override
    public NumeralFormula<T> visit(Exclusion<T> pExclusion) {
        return pExclusion.accept(this.recursiveNumeralFormulaVisitor);
    }

    @Override
    public NumeralFormula<T> visit(Modulo<T> pModulo) {
        return pModulo.accept(this.recursiveNumeralFormulaVisitor);
    }

    @Override
    public NumeralFormula<T> visit(Multiply<T> pMultiply) {
        return pMultiply.accept(this.recursiveNumeralFormulaVisitor);
    }

    @Override
    public NumeralFormula<T> visit(ShiftLeft<T> pShiftLeft) {
        return pShiftLeft.accept(this.recursiveNumeralFormulaVisitor);
    }

    @Override
    public NumeralFormula<T> visit(ShiftRight<T> pShiftRight) {
        return pShiftRight.accept(this.recursiveNumeralFormulaVisitor);
    }

    @Override
    public NumeralFormula<T> visit(Union<T> pUnion) {
        return pUnion.accept(this.recursiveNumeralFormulaVisitor);
    }

    @Override
    public NumeralFormula<T> visit(Variable<T> pVariable) {
        return pVariable.accept(this.recursiveNumeralFormulaVisitor);
    }

    @Override
    public NumeralFormula<T> visit(IfThenElse<T> pIfThenElse) {
        return pIfThenElse.accept(this.recursiveNumeralFormulaVisitor);
    }

    @Override
    public NumeralFormula<T> visit(Cast<T> pCast) {
        return pCast.accept(this.recursiveNumeralFormulaVisitor);
    }

}