|
| 1 | +/* |
| 2 | + * Copyright (C) 2024 Matthias Heizmann ([email protected]>) |
| 3 | + * Copyright (C) 2024 University of Freiburg |
| 4 | + * |
| 5 | + * This file is part of the ULTIMATE ModelCheckerUtils Library. |
| 6 | + * |
| 7 | + * The ULTIMATE ModelCheckerUtils Library is free software: you can redistribute it and/or modify |
| 8 | + * it under the terms of the GNU Lesser General Public License as published |
| 9 | + * by the Free Software Foundation, either version 3 of the License, or |
| 10 | + * (at your option) any later version. |
| 11 | + * |
| 12 | + * The ULTIMATE ModelCheckerUtils Library is distributed in the hope that it will be useful, |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | + * GNU Lesser General Public License for more details. |
| 16 | + * |
| 17 | + * You should have received a copy of the GNU Lesser General Public License |
| 18 | + * along with the ULTIMATE ModelCheckerUtils Library. If not, see <http://www.gnu.org/licenses/>. |
| 19 | + * |
| 20 | + * Additional permission under GNU GPL version 3 section 7: |
| 21 | + * If you modify the ULTIMATE ModelCheckerUtils Library, or any covered work, by linking |
| 22 | + * or combining it with Eclipse RCP (or a modified version of Eclipse RCP), |
| 23 | + * containing parts covered by the terms of the Eclipse Public License, the |
| 24 | + * licensors of the ULTIMATE ModelCheckerUtils Library grant you additional permission |
| 25 | + * to convey the resulting work. |
| 26 | + */ |
| 27 | +package de.uni_freiburg.informatik.ultimate.lib.smtlibutils; |
| 28 | + |
| 29 | +import java.math.BigDecimal; |
| 30 | +import java.math.BigInteger; |
| 31 | + |
| 32 | +import de.uni_freiburg.informatik.ultimate.logic.ConstantTerm; |
| 33 | +import de.uni_freiburg.informatik.ultimate.logic.Rational; |
| 34 | +import de.uni_freiburg.informatik.ultimate.logic.Term; |
| 35 | +import de.uni_freiburg.informatik.ultimate.logic.TermTransformer; |
| 36 | + |
| 37 | +/** |
| 38 | + * {@link ConstantTerm}s that have numeric sort (Int, Real) can represent their value either as {@link BigInteger}, |
| 39 | + * {@link BigDecimal}, or {@link Rational}. This class helps us to establish a normal form in which values are always |
| 40 | + * represented by {@link Rational}s. |
| 41 | + * |
| 42 | + * @author Matthias Heizmann ([email protected]>) |
| 43 | + * |
| 44 | + */ |
| 45 | +public class ConstantTermNormalizer extends TermTransformer { |
| 46 | + |
| 47 | + @Override |
| 48 | + protected void convert(final Term term) { |
| 49 | + if (term instanceof ConstantTerm) { |
| 50 | + final Term res; |
| 51 | + final ConstantTerm ct = (ConstantTerm) term; |
| 52 | + res = convertConstantTerm(term, ct); |
| 53 | + setResult(res); |
| 54 | + } else { |
| 55 | + super.convert(term); |
| 56 | + } |
| 57 | + } |
| 58 | + |
| 59 | + private static Term convertConstantTerm(final Term term, final ConstantTerm ct) { |
| 60 | + if (!ct.getSort().isNumericSort()) { |
| 61 | + // do nothing, only applicable to numeric sorts |
| 62 | + return ct; |
| 63 | + } |
| 64 | + if (ct.getValue() instanceof BigInteger) { |
| 65 | + final Rational rat = Rational.valueOf((BigInteger) ct.getValue(), BigInteger.ONE); |
| 66 | + return rat.toTerm(term.getSort()); |
| 67 | + } else if (ct.getValue() instanceof BigDecimal) { |
| 68 | + final BigDecimal decimal = (BigDecimal) ct.getValue(); |
| 69 | + Rational rat; |
| 70 | + if (decimal.scale() <= 0) { |
| 71 | + final BigInteger num = decimal.toBigInteger(); |
| 72 | + rat = Rational.valueOf(num, BigInteger.ONE); |
| 73 | + } else { |
| 74 | + final BigInteger num = decimal.unscaledValue(); |
| 75 | + final BigInteger denom = BigInteger.TEN.pow(decimal.scale()); |
| 76 | + rat = Rational.valueOf(num, denom); |
| 77 | + } |
| 78 | + return rat.toTerm(term.getSort()); |
| 79 | + } else if (ct.getValue() instanceof Rational) { |
| 80 | + // do nothing, already in normal form |
| 81 | + return ct; |
| 82 | + } else { |
| 83 | + throw new AssertionError("Value has to be either BigInteger, Decimal, or Rational"); |
| 84 | + } |
| 85 | + } |
| 86 | + |
| 87 | +} |
0 commit comments