/*
* Copyright (C) 2013 University of Freiburg
*
* This file is part of SMTInterpol.
*
* SMTInterpol is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SMTInterpol is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with SMTInterpol. If not, see <http://www.gnu.org/licenses/>.
*/
package de.uni_freiburg.informatik.ultimate.smtinterpol.util;
import de.uni_freiburg.informatik.ultimate.logic.ConstantTerm;
import de.uni_freiburg.informatik.ultimate.logic.FunctionSymbol;
import de.uni_freiburg.informatik.ultimate.logic.Rational;
import de.uni_freiburg.informatik.ultimate.logic.Sort;
import de.uni_freiburg.informatik.ultimate.logic.Term;
import de.uni_freiburg.informatik.ultimate.smtinterpol.convert.SMTAffineTerm;
/**
* Helper class to factor out coercions needed in IRA-Logics
* @author Juergen Christ
*/
public final class Coercion {
private Coercion() {
// Hide constructor
}
public static Term toInt(Term t) {
assert t.getSort().getName().equals("Real");
if (t instanceof ConstantTerm) {
final Rational val = SMTAffineTerm.create(t).getConstant();
assert val.isIntegral();
return val.toTerm(t.getTheory().getSort("Int"));
}
return t.getTheory().term("to_int", t);
}
public static Term toReal(Term t) {
assert t.getSort().getName().equals("Int");
if (t instanceof ConstantTerm) {
final SMTAffineTerm tmp = SMTAffineTerm.create(t);
assert tmp.getConstant().isIntegral();
return tmp.getConstant().toTerm(t.getTheory().getSort("Real"));
}
return t.getTheory().term("to_real", t);
}
public static Term coerce(Term t, Sort s) {
if (t.getSort() == s) {
return t;
}
if (s.getName().equals("Int")) {
return toInt(t);
}
if (s.getName().equals("Real")) {
return toReal(t);
}
throw new InternalError("Should only be called with numeric sort!");
}
/// BE CAREFUL: args might be modified!!!
public static Term buildApp(FunctionSymbol fsymb, Term[] args) {
final Sort[] paramSorts = fsymb.getParameterSorts();
if (fsymb.getTheory().getLogic().isIRA()) {
for (int i = 0; i < args.length; ++i) {
if (args[i].getSort() != paramSorts[i]) {
args[i] = coerce(args[i], paramSorts[i]);
}
}
}
return fsymb.getTheory().term(fsymb, args);
}
public static Term buildEq(Term lhs, Term rhs) {
if (lhs.getSort() != rhs.getSort()) {
assert lhs.getTheory().getLogic().isIRA();
if (!lhs.getSort().getName().equals("Real")) {
lhs = toReal(lhs);
}
if (!rhs.getSort().getName().equals("Real")) {
rhs = toReal(rhs);
}
}
return lhs.getTheory().term("=", lhs, rhs);
}
public static Term buildDistinct(Term lhs, Term rhs) {
if (lhs.getSort() != rhs.getSort()) {
assert lhs.getTheory().getLogic().isIRA();
if (!lhs.getSort().getName().equals("Real")) {
lhs = toReal(lhs);
}
if (!rhs.getSort().getName().equals("Real")) {
rhs = toReal(rhs);
}
}
return lhs.getTheory().distinct(lhs, rhs);
}
}