org.sosy_lab.solver.mathsat5.Mathsat5UnsafeFormulaManager.java Source code

Java tutorial

Introduction

Here is the source code for org.sosy_lab.solver.mathsat5.Mathsat5UnsafeFormulaManager.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.solver.mathsat5;

import static com.google.common.base.Preconditions.checkArgument;
import static org.sosy_lab.solver.mathsat5.Mathsat5NativeApi.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.sosy_lab.solver.api.Formula;
import org.sosy_lab.solver.basicimpl.AbstractUnsafeFormulaManager;

import com.google.common.collect.ImmutableList;
import com.google.common.primitives.Longs;

class Mathsat5UnsafeFormulaManager extends AbstractUnsafeFormulaManager<Long, Long, Long> {

    private final long msatEnv;
    private final Mathsat5FormulaCreator creator;

    public Mathsat5UnsafeFormulaManager(Mathsat5FormulaCreator pCreator) {
        super(pCreator);
        this.msatEnv = pCreator.getEnv();
        this.creator = pCreator;
    }

    @Override
    public boolean isAtom(Long t) {
        return msat_term_is_atom(msatEnv, t);
    }

    @Override
    public int getArity(Long pT) {
        return msat_term_arity(pT);
    }

    @Override
    public Formula getArg(Formula pF, int pN) {
        long f = Mathsat5FormulaManager.getMsatTerm(pF);
        long arg = msat_term_get_arg(f, pN);
        if (msat_is_fp_roundingmode_type(msatEnv, msat_term_get_type(arg))) {
            // We have terms that are of type fp_roundingmode
            // (for example, arguments to floating-point arithmetic operators),
            // but we do not want to work with them.
            // So we just return an untyped formula here.
            return new Mathsat5Formula(arg) {
            };
        }
        return super.getArg(pF, pN);
    }

    @Override
    public Long getArg(Long t, int n) {
        return msat_term_get_arg(t, n);
    }

    @Override
    public boolean isVariable(Long t) {
        return msat_term_is_constant(msatEnv, t);
    }

    @Override
    public boolean isUF(Long t) {
        return msat_term_is_uf(msatEnv, t);
    }

    @Override
    public String getName(Long t) {
        if (isUF(t)) {
            return msat_decl_get_name(msat_term_get_decl(t));
        } else if (isVariable(t)) {
            return msat_term_repr(t);
        } else {
            throw new IllegalArgumentException("Can't get the name from the given formula!");
        }
    }

    @Override
    public Long replaceArgs(Long t, List<Long> newArgs) {
        long tDecl = msat_term_get_decl(t);
        return msat_make_term(msatEnv, tDecl, Longs.toArray(newArgs));
    }

    @Override
    public Long replaceArgsAndName(Long t, String newName, List<Long> newArgs) {
        if (isUF(t)) {
            long decl = msat_term_get_decl(t);
            int arity = msat_decl_get_arity(decl);
            long retType = msat_decl_get_return_type(decl);
            long[] argTypes = new long[arity];
            for (int i = 0; i < arity; i++) {
                argTypes[i] = msat_decl_get_arg_type(decl, i);
            }
            long funcType = msat_get_function_type(msatEnv, argTypes, argTypes.length, retType);
            long funcDecl = msat_declare_function(msatEnv, newName, funcType);
            return msat_make_uf(msatEnv, funcDecl, Longs.toArray(newArgs));
        } else if (isVariable(t)) {
            checkArgument(newArgs.isEmpty());
            return creator.makeVariable(msat_term_get_type(t), newName);
        } else {
            throw new IllegalArgumentException("Can't set the name from the given formula!");
        }
    }

    @Override
    protected List<Long> splitNumeralEqualityIfPossible(Long pF) {
        if (msat_term_is_equal(msatEnv, pF) && getArity(pF) == 2) {
            long arg0 = msat_term_get_arg(pF, 0);
            long arg1 = msat_term_get_arg(pF, 1);
            long type = msat_term_get_type(arg0);
            if (msat_is_bv_type(msatEnv, type)) {
                return ImmutableList.of(msat_make_bv_uleq(msatEnv, arg0, arg1),
                        msat_make_bv_uleq(msatEnv, arg1, arg0));
            } else if (msat_is_integer_type(msatEnv, type) || msat_is_rational_type(msatEnv, type)) {
                return ImmutableList.of(msat_make_leq(msatEnv, arg0, arg1), msat_make_leq(msatEnv, arg1, arg0));
            }
        }
        return ImmutableList.of(pF);
    }

    @Override
    public boolean isNumber(Long pT) {
        return msat_term_is_number(msatEnv, pT);
    }

    @Override
    protected Long substitute(Long expr, List<Long> substituteFrom, List<Long> substituteTo) {
        checkArgument(substituteFrom.size() == substituteTo.size());
        Map<Long, Long> replacements = new HashMap<>();
        for (int i = 0; i < substituteFrom.size(); i++) {
            replacements.put(substituteFrom.get(i), substituteTo.get(i));
        }
        return recSubstitute(expr, replacements);
    }

    private long recSubstitute(Long expr, Map<Long, Long> memoization) {

        Long out = memoization.get(expr);

        if (out == null) {
            int arity = getArity(expr);
            long[] updatedChildren = new long[arity];
            for (int childIdx = 0; childIdx < arity; childIdx++) {
                long child = getArg(expr, childIdx);
                updatedChildren[childIdx] = recSubstitute(child, memoization);
            }

            long decl = msat_term_get_decl(expr);
            out = msat_make_term(msatEnv, decl, updatedChildren);

            memoization.put(expr, out);
        }

        return out;
    }

    @Override
    protected boolean isQuantification(Long pT) {
        return false;
    }

    @Override
    protected boolean isFreeVariable(Long pT) {
        return isVariable(pT);
    }

    @Override
    protected boolean isBoundVariable(Long pT) {
        return false;
    }

    @Override
    protected Long getQuantifiedBody(Long pT) {
        throw new UnsupportedOperationException();
    }

    @Override
    protected Long replaceQuantifiedBody(Long pF, Long pBody) {
        throw new UnsupportedOperationException();
    }

}