hu.bme.mit.theta.solver.z3.Z3ExprTransformer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of theta-solver-z3 Show documentation
Show all versions of theta-solver-z3 Show documentation
Solver Z3 subproject in the Theta model checking framework
/*
* Copyright 2024 Budapest University of Technology and Economics
*
* 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.
*/
package hu.bme.mit.theta.solver.z3;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.ImmutableList;
import com.microsoft.z3.*;
import com.microsoft.z3.BitVecExpr;
import com.microsoft.z3.BoolExpr;
import com.microsoft.z3.Context;
import com.microsoft.z3.FPExpr;
import com.microsoft.z3.FPSort;
import hu.bme.mit.theta.common.DispatchTable;
import hu.bme.mit.theta.common.Tuple2;
import hu.bme.mit.theta.common.dsl.Env;
import hu.bme.mit.theta.core.decl.ConstDecl;
import hu.bme.mit.theta.core.decl.Decl;
import hu.bme.mit.theta.core.decl.ParamDecl;
import hu.bme.mit.theta.core.dsl.DeclSymbol;
import hu.bme.mit.theta.core.type.Expr;
import hu.bme.mit.theta.core.type.Type;
import hu.bme.mit.theta.core.type.anytype.IteExpr;
import hu.bme.mit.theta.core.type.anytype.RefExpr;
import hu.bme.mit.theta.core.type.arraytype.*;
import hu.bme.mit.theta.core.type.booltype.*;
import hu.bme.mit.theta.core.type.bvtype.*;
import hu.bme.mit.theta.core.type.enumtype.EnumEqExpr;
import hu.bme.mit.theta.core.type.enumtype.EnumLitExpr;
import hu.bme.mit.theta.core.type.enumtype.EnumNeqExpr;
import hu.bme.mit.theta.core.type.enumtype.EnumType;
import hu.bme.mit.theta.core.type.fptype.*;
import hu.bme.mit.theta.core.type.functype.FuncAppExpr;
import hu.bme.mit.theta.core.type.functype.FuncLitExpr;
import hu.bme.mit.theta.core.type.functype.FuncType;
import hu.bme.mit.theta.core.type.inttype.*;
import hu.bme.mit.theta.core.type.rattype.*;
import hu.bme.mit.theta.core.utils.BvUtils;
import hu.bme.mit.theta.core.utils.ExprUtils;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.stream.Stream;
import static hu.bme.mit.theta.core.utils.ExprUtils.extractFuncAndArgs;
final class Z3ExprTransformer {
private static final int CACHE_SIZE = 1000;
private final Z3TransformationManager transformer;
private final Context context;
private final Cache, com.microsoft.z3.Expr> exprToTerm;
private final DispatchTable table;
private final Env env;
public Z3ExprTransformer(final Z3TransformationManager transformer, final Context context) {
this.context = context;
this.transformer = transformer;
this.env = new Env();
exprToTerm = CacheBuilder.newBuilder().maximumSize(CACHE_SIZE).build();
table = DispatchTable.builder()
// General
.addCase(RefExpr.class, this::transformRef)
.addCase(IteExpr.class, this::transformIte)
// Boolean
.addCase(FalseExpr.class, this::transformFalse)
.addCase(TrueExpr.class, this::transformTrue)
.addCase(NotExpr.class, this::transformNot)
.addCase(ImplyExpr.class, this::transformImply)
.addCase(IffExpr.class, this::transformIff)
.addCase(XorExpr.class, this::transformXor)
.addCase(AndExpr.class, this::transformAnd)
.addCase(OrExpr.class, this::transformOr)
.addCase(ExistsExpr.class, this::transformExists)
.addCase(ForallExpr.class, this::transformForall)
// Rationals
.addCase(RatLitExpr.class, this::transformRatLit)
.addCase(RatAddExpr.class, this::transformRatAdd)
.addCase(RatSubExpr.class, this::transformRatSub)
.addCase(RatPosExpr.class, this::transformRatPos)
.addCase(RatNegExpr.class, this::transformRatNeg)
.addCase(RatMulExpr.class, this::transformRatMul)
.addCase(RatDivExpr.class, this::transformRatDiv)
.addCase(RatEqExpr.class, this::transformRatEq)
.addCase(RatNeqExpr.class, this::transformRatNeq)
.addCase(RatGeqExpr.class, this::transformRatGeq)
.addCase(RatGtExpr.class, this::transformRatGt)
.addCase(RatLeqExpr.class, this::transformRatLeq)
.addCase(RatLtExpr.class, this::transformRatLt)
.addCase(RatToIntExpr.class, this::transformRatToInt)
// Integers
.addCase(IntLitExpr.class, this::transformIntLit)
.addCase(IntAddExpr.class, this::transformIntAdd)
.addCase(IntSubExpr.class, this::transformIntSub)
.addCase(IntPosExpr.class, this::transformIntPos)
.addCase(IntNegExpr.class, this::transformIntNeg)
.addCase(IntMulExpr.class, this::transformIntMul)
.addCase(IntDivExpr.class, this::transformIntDiv)
.addCase(IntModExpr.class, this::transformIntMod)
.addCase(IntRemExpr.class, this::transformIntRem)
.addCase(IntEqExpr.class, this::transformIntEq)
.addCase(IntNeqExpr.class, this::transformIntNeq)
.addCase(IntGeqExpr.class, this::transformIntGeq)
.addCase(IntGtExpr.class, this::transformIntGt)
.addCase(IntLeqExpr.class, this::transformIntLeq)
.addCase(IntLtExpr.class, this::transformIntLt)
.addCase(IntToRatExpr.class, this::transformIntToRat)
// Bitvectors
.addCase(BvLitExpr.class, this::transformBvLit)
.addCase(BvConcatExpr.class, this::transformBvConcat)
.addCase(BvExtractExpr.class, this::transformBvExtract)
.addCase(BvZExtExpr.class, this::transformBvZExt)
.addCase(BvSExtExpr.class, this::transformBvSExt)
.addCase(BvAddExpr.class, this::transformBvAdd)
.addCase(BvSubExpr.class, this::transformBvSub)
.addCase(BvPosExpr.class, this::transformBvPos)
.addCase(BvSignChangeExpr.class, this::transformBvSignChange)
.addCase(BvNegExpr.class, this::transformBvNeg)
.addCase(BvMulExpr.class, this::transformBvMul)
.addCase(BvUDivExpr.class, this::transformBvUDiv)
.addCase(BvSDivExpr.class, this::transformBvSDiv)
.addCase(BvSModExpr.class, this::transformBvSMod)
.addCase(BvURemExpr.class, this::transformBvURem)
.addCase(BvSRemExpr.class, this::transformBvSRem)
.addCase(BvAndExpr.class, this::transformBvAnd)
.addCase(BvOrExpr.class, this::transformBvOr)
.addCase(BvXorExpr.class, this::transformBvXor)
.addCase(BvNotExpr.class, this::transformBvNot)
.addCase(BvShiftLeftExpr.class, this::transformBvShiftLeft)
.addCase(BvArithShiftRightExpr.class, this::transformBvArithShiftRight)
.addCase(BvLogicShiftRightExpr.class, this::transformBvLogicShiftRight)
.addCase(BvRotateLeftExpr.class, this::transformBvRotateLeft)
.addCase(BvRotateRightExpr.class, this::transformBvRotateRight)
.addCase(BvEqExpr.class, this::transformBvEq)
.addCase(BvNeqExpr.class, this::transformBvNeq)
.addCase(BvUGeqExpr.class, this::transformBvUGeq)
.addCase(BvUGtExpr.class, this::transformBvUGt)
.addCase(BvULeqExpr.class, this::transformBvULeq)
.addCase(BvULtExpr.class, this::transformBvULt)
.addCase(BvSGeqExpr.class, this::transformBvSGeq)
.addCase(BvSGtExpr.class, this::transformBvSGt)
.addCase(BvSLeqExpr.class, this::transformBvSLeq)
.addCase(BvSLtExpr.class, this::transformBvSLt)
// Floating points
.addCase(FpLitExpr.class, this::transformFpLit)
.addCase(FpAddExpr.class, this::transformFpAdd)
.addCase(FpSubExpr.class, this::transformFpSub)
.addCase(FpPosExpr.class, this::transformFpPos)
.addCase(FpNegExpr.class, this::transformFpNeg)
.addCase(FpMulExpr.class, this::transformFpMul)
.addCase(FpDivExpr.class, this::transformFpDiv)
.addCase(FpEqExpr.class, this::transformFpEq)
.addCase(FpAssignExpr.class, this::transformFpAssign)
.addCase(FpGeqExpr.class, this::transformFpGeq)
.addCase(FpLeqExpr.class, this::transformFpLeq)
.addCase(FpGtExpr.class, this::transformFpGt)
.addCase(FpLtExpr.class, this::transformFpLt)
.addCase(FpNeqExpr.class, this::transformFpNeq)
.addCase(FpAbsExpr.class, this::transformFpAbs)
.addCase(FpRoundToIntegralExpr.class, this::transformFpRoundToIntegral)
.addCase(FpMaxExpr.class, this::transformFpMax)
.addCase(FpMinExpr.class, this::transformFpMin)
.addCase(FpSqrtExpr.class, this::transformFpSqrt)
.addCase(FpRemExpr.class, this::transformFpRem)
.addCase(FpIsNanExpr.class, this::transformFpIsNan)
.addCase(FpIsInfiniteExpr.class, this::transformFpIsInfinite)
.addCase(FpFromBvExpr.class, this::transformFpFromBv)
.addCase(FpToBvExpr.class, this::transformFpToBv)
.addCase(FpToFpExpr.class, this::transformFpToFp)
// Functions
.addCase(FuncAppExpr.class, this::transformFuncApp)
// Arrays
.addCase(ArrayReadExpr.class, this::transformArrayRead)
.addCase(ArrayWriteExpr.class, this::transformArrayWrite)
.addCase(ArrayEqExpr.class, this::transformArrayEq)
.addCase(ArrayNeqExpr.class, this::transformArrayNeq)
.addCase(ArrayLitExpr.class, this::transformArrayLit)
.addCase(ArrayInitExpr.class, this::transformArrayInit)
// Enums
.addCase(EnumLitExpr.class, this::transformEnumLit)
.addCase(EnumEqExpr.class, this::transformEnumEq)
.addCase(EnumNeqExpr.class, this::transformEnumNeq)
.build();
}
////
/*
* General
*/
public com.microsoft.z3.Expr toTerm(final Expr> expr) {
try {
return exprToTerm.get(expr, () -> table.dispatch(expr));
} catch (final ExecutionException e) {
throw new AssertionError("Unhandled case: " + expr, e);
}
}
private com.microsoft.z3.Expr transformRef(final RefExpr> expr) {
final Decl> decl = expr.getDecl();
if (decl instanceof ConstDecl) {
final com.microsoft.z3.FuncDecl funcDecl = transformer.toSymbol(decl);
return context.mkConst(funcDecl);
} else if (decl instanceof ParamDecl) {
final com.microsoft.z3.FuncDecl funcDecl = (com.microsoft.z3.FuncDecl) env.eval(
DeclSymbol.of(decl));
return context.mkConst(funcDecl);
} else {
throw new UnsupportedOperationException(
"Cannot transform reference for declaration: " + decl);
}
}
/*
* Booleans
*/
private com.microsoft.z3.Expr transformIte(final IteExpr> expr) {
final BoolExpr condTerm = (BoolExpr) toTerm(expr.getCond());
final com.microsoft.z3.Expr thenTerm = toTerm(expr.getThen());
final com.microsoft.z3.Expr elzeTerm = toTerm(expr.getElse());
return context.mkITE(condTerm, thenTerm, elzeTerm);
}
private com.microsoft.z3.Expr transformFalse(final FalseExpr expr) {
return context.mkFalse();
}
private com.microsoft.z3.Expr transformTrue(final TrueExpr expr) {
return context.mkTrue();
}
private com.microsoft.z3.Expr transformNot(final NotExpr expr) {
final BoolExpr opTerm = (BoolExpr) toTerm(expr.getOp());
return context.mkNot(opTerm);
}
private com.microsoft.z3.Expr transformImply(final ImplyExpr expr) {
final BoolExpr leftOpTerm = (BoolExpr) toTerm(expr.getLeftOp());
final BoolExpr rightOpTerm = (BoolExpr) toTerm(expr.getRightOp());
return context.mkImplies(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformIff(final IffExpr expr) {
final BoolExpr leftOpTerm = (BoolExpr) toTerm(expr.getLeftOp());
final BoolExpr rightOpTerm = (BoolExpr) toTerm(expr.getRightOp());
return context.mkIff(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformXor(final XorExpr expr) {
final BoolExpr leftOpTerm = (BoolExpr) toTerm(expr.getLeftOp());
final BoolExpr rightOpTerm = (BoolExpr) toTerm(expr.getRightOp());
return context.mkXor(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformAnd(final AndExpr expr) {
final BoolExpr[] opTerms = expr.getOps().stream()
.map(e -> (BoolExpr) toTerm(e))
.toArray(BoolExpr[]::new);
return context.mkAnd(opTerms);
}
private com.microsoft.z3.Expr transformOr(final OrExpr expr) {
final BoolExpr[] opTerms = expr.getOps().stream()
.map(e -> (BoolExpr) toTerm(e))
.toArray(BoolExpr[]::new);
return context.mkOr(opTerms);
}
private com.microsoft.z3.Expr transformExists(final ExistsExpr expr) {
env.push();
final com.microsoft.z3.Expr[] paramTerms = transformParamDecls(expr.getParamDecls());
final BoolExpr opTerm = (BoolExpr) toTerm(expr.getOp());
final BoolExpr result = context.mkExists(paramTerms, opTerm, 1, null, null, null, null);
env.pop();
return result;
}
private com.microsoft.z3.Expr transformForall(final ForallExpr expr) {
env.push();
final com.microsoft.z3.Expr[] paramTerms = transformParamDecls(expr.getParamDecls());
final BoolExpr opTerm = (BoolExpr) toTerm(expr.getOp());
final BoolExpr result = context.mkForall(paramTerms, opTerm, 1, null, null, null, null);
env.pop();
return result;
}
private com.microsoft.z3.Expr[] transformParamDecls(final List> paramDecls) {
final com.microsoft.z3.Expr[] paramTerms = new com.microsoft.z3.Expr[paramDecls.size()];
int i = 0;
for (final ParamDecl> paramDecl : paramDecls) {
final com.microsoft.z3.FuncDecl paramSymbol = transformParamDecl(paramDecl);
paramTerms[i] = context.mkConst(paramSymbol);
env.define(DeclSymbol.of(paramDecl), paramSymbol);
i++;
}
return paramTerms;
}
/*
* Rationals
*/
private com.microsoft.z3.FuncDecl transformParamDecl(final ParamDecl> paramDecl) {
final Type type = paramDecl.getType();
if (type instanceof FuncType, ?>) {
throw new UnsupportedOperationException("Only simple types are supported");
} else {
final com.microsoft.z3.Sort sort = transformer.toSort(type);
return context.mkConstDecl(paramDecl.getName(), sort);
}
}
private com.microsoft.z3.Expr transformRatLit(final RatLitExpr expr) {
var num = context.mkReal(expr.getNum().toString());
var denom = context.mkReal(expr.getDenom().toString());
return context.mkDiv(num, denom);
}
private com.microsoft.z3.Expr transformRatAdd(final RatAddExpr expr) {
final com.microsoft.z3.ArithExpr[] opTerms = expr.getOps().stream()
.map(e -> (com.microsoft.z3.ArithExpr) toTerm(e))
.toArray(com.microsoft.z3.ArithExpr[]::new);
return context.mkAdd(opTerms);
}
private com.microsoft.z3.Expr transformRatSub(final RatSubExpr expr) {
final com.microsoft.z3.ArithExpr leftOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getLeftOp());
final com.microsoft.z3.ArithExpr rightOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getRightOp());
return context.mkSub(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformRatPos(final RatPosExpr expr) {
return toTerm(expr.getOp());
}
private com.microsoft.z3.Expr transformRatNeg(final RatNegExpr expr) {
final com.microsoft.z3.ArithExpr opTerm = (com.microsoft.z3.ArithExpr) toTerm(expr.getOp());
return context.mkUnaryMinus(opTerm);
}
private com.microsoft.z3.Expr transformRatMul(final RatMulExpr expr) {
final com.microsoft.z3.ArithExpr[] opTerms = expr.getOps().stream()
.map(e -> (com.microsoft.z3.ArithExpr) toTerm(e))
.toArray(com.microsoft.z3.ArithExpr[]::new);
return context.mkMul(opTerms);
}
private com.microsoft.z3.Expr transformRatDiv(final RatDivExpr expr) {
final com.microsoft.z3.ArithExpr leftOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getLeftOp());
final com.microsoft.z3.ArithExpr rightOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getRightOp());
return context.mkDiv(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformRatEq(final RatEqExpr expr) {
final com.microsoft.z3.Expr leftOpTerm = toTerm(expr.getLeftOp());
final com.microsoft.z3.Expr rightOpTerm = toTerm(expr.getRightOp());
return context.mkEq(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformRatNeq(final RatNeqExpr expr) {
final com.microsoft.z3.Expr leftOpTerm = toTerm(expr.getLeftOp());
final com.microsoft.z3.Expr rightOpTerm = toTerm(expr.getRightOp());
return context.mkNot(context.mkEq(leftOpTerm, rightOpTerm));
}
private com.microsoft.z3.Expr transformRatGeq(final RatGeqExpr expr) {
final com.microsoft.z3.ArithExpr leftOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getLeftOp());
final com.microsoft.z3.ArithExpr rightOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getRightOp());
return context.mkGe(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformRatGt(final RatGtExpr expr) {
final com.microsoft.z3.ArithExpr leftOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getLeftOp());
final com.microsoft.z3.ArithExpr rightOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getRightOp());
return context.mkGt(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformRatLeq(final RatLeqExpr expr) {
final com.microsoft.z3.ArithExpr leftOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getLeftOp());
final com.microsoft.z3.ArithExpr rightOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getRightOp());
return context.mkLe(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformRatLt(final RatLtExpr expr) {
final com.microsoft.z3.ArithExpr leftOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getLeftOp());
final com.microsoft.z3.ArithExpr rightOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getRightOp());
return context.mkLt(leftOpTerm, rightOpTerm);
}
/*
* Integers
*/
private com.microsoft.z3.Expr transformRatToInt(final RatToIntExpr expr) {
final com.microsoft.z3.RealExpr opTerm = (com.microsoft.z3.RealExpr) toTerm(expr.getOp());
return context.mkReal2Int(opTerm);
}
private com.microsoft.z3.Expr transformIntLit(final IntLitExpr expr) {
return context.mkInt(expr.getValue().toString());
}
private com.microsoft.z3.Expr transformIntAdd(final IntAddExpr expr) {
final com.microsoft.z3.ArithExpr[] opTerms = expr.getOps().stream()
.map(e -> (com.microsoft.z3.ArithExpr) toTerm(e))
.toArray(com.microsoft.z3.ArithExpr[]::new);
return context.mkAdd(opTerms);
}
private com.microsoft.z3.Expr transformIntSub(final IntSubExpr expr) {
final com.microsoft.z3.ArithExpr leftOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getLeftOp());
final com.microsoft.z3.ArithExpr rightOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getRightOp());
return context.mkSub(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformIntPos(final IntPosExpr expr) {
return toTerm(expr.getOp());
}
private com.microsoft.z3.Expr transformIntNeg(final IntNegExpr expr) {
final com.microsoft.z3.ArithExpr opTerm = (com.microsoft.z3.ArithExpr) toTerm(expr.getOp());
return context.mkUnaryMinus(opTerm);
}
private com.microsoft.z3.Expr transformIntMul(final IntMulExpr expr) {
final com.microsoft.z3.ArithExpr[] opTerms = expr.getOps().stream()
.map(e -> (com.microsoft.z3.ArithExpr) toTerm(e))
.toArray(com.microsoft.z3.ArithExpr[]::new);
return context.mkMul(opTerms);
}
private com.microsoft.z3.Expr transformIntDiv(final IntDivExpr expr) {
final com.microsoft.z3.IntExpr leftOpTerm = (com.microsoft.z3.IntExpr) toTerm(
expr.getLeftOp());
final com.microsoft.z3.IntExpr rightOpTerm = (com.microsoft.z3.IntExpr) toTerm(
expr.getRightOp());
return context.mkDiv(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformIntMod(final IntModExpr expr) {
final com.microsoft.z3.IntExpr leftOpTerm = (com.microsoft.z3.IntExpr) toTerm(
expr.getLeftOp());
final com.microsoft.z3.IntExpr rightOpTerm = (com.microsoft.z3.IntExpr) toTerm(
expr.getRightOp());
return context.mkMod(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformIntRem(final IntRemExpr expr) {
final com.microsoft.z3.IntExpr leftOpTerm = (com.microsoft.z3.IntExpr) toTerm(
expr.getLeftOp());
final com.microsoft.z3.IntExpr rightOpTerm = (com.microsoft.z3.IntExpr) toTerm(
expr.getRightOp());
return context.mkRem(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformIntEq(final IntEqExpr expr) {
final com.microsoft.z3.Expr leftOpTerm = toTerm(expr.getLeftOp());
final com.microsoft.z3.Expr rightOpTerm = toTerm(expr.getRightOp());
return context.mkEq(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformIntNeq(final IntNeqExpr expr) {
final com.microsoft.z3.Expr leftOpTerm = toTerm(expr.getLeftOp());
final com.microsoft.z3.Expr rightOpTerm = toTerm(expr.getRightOp());
return context.mkNot(context.mkEq(leftOpTerm, rightOpTerm));
}
private com.microsoft.z3.Expr transformIntGeq(final IntGeqExpr expr) {
final com.microsoft.z3.ArithExpr leftOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getLeftOp());
final com.microsoft.z3.ArithExpr rightOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getRightOp());
return context.mkGe(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformIntGt(final IntGtExpr expr) {
final com.microsoft.z3.ArithExpr leftOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getLeftOp());
final com.microsoft.z3.ArithExpr rightOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getRightOp());
return context.mkGt(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformIntLeq(final IntLeqExpr expr) {
final com.microsoft.z3.ArithExpr leftOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getLeftOp());
final com.microsoft.z3.ArithExpr rightOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getRightOp());
return context.mkLe(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformIntLt(final IntLtExpr expr) {
final com.microsoft.z3.ArithExpr leftOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getLeftOp());
final com.microsoft.z3.ArithExpr rightOpTerm = (com.microsoft.z3.ArithExpr) toTerm(
expr.getRightOp());
return context.mkLt(leftOpTerm, rightOpTerm);
}
/*
* Bitvectors
*/
private com.microsoft.z3.Expr transformIntToRat(final IntToRatExpr expr) {
final com.microsoft.z3.IntExpr opTerm = (com.microsoft.z3.IntExpr) toTerm(expr.getOp());
return context.mkInt2Real(opTerm);
}
private com.microsoft.z3.Expr transformBvLit(final BvLitExpr expr) {
return context.mkBV(BvUtils.neutralBvLitExprToBigInteger(expr).toString(),
expr.getType().getSize());
}
private com.microsoft.z3.Expr transformBvEq(final BvEqExpr expr) {
final com.microsoft.z3.Expr leftOpTerm = toTerm(expr.getLeftOp());
final com.microsoft.z3.Expr rightOpTerm = toTerm(expr.getRightOp());
return context.mkEq(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformBvNeq(final BvNeqExpr expr) {
final com.microsoft.z3.Expr leftOpTerm = toTerm(expr.getLeftOp());
final com.microsoft.z3.Expr rightOpTerm = toTerm(expr.getRightOp());
return context.mkNot(context.mkEq(leftOpTerm, rightOpTerm));
}
private com.microsoft.z3.Expr transformBvConcat(final BvConcatExpr expr) {
final BitVecExpr[] opTerms = expr.getOps().stream()
.map(e -> (BitVecExpr) toTerm(e))
.toArray(BitVecExpr[]::new);
return Stream.of(opTerms).skip(1).reduce(opTerms[0], context::mkConcat);
}
private com.microsoft.z3.Expr transformBvExtract(final BvExtractExpr expr) {
final BitVecExpr bitvecTerm = (BitVecExpr) toTerm(expr.getBitvec());
final int from = expr.getFrom().getValue().intValue();
final int until = expr.getUntil().getValue().intValue();
return context.mkExtract(until - 1, from, bitvecTerm);
}
private com.microsoft.z3.Expr transformBvZExt(final BvZExtExpr expr) {
final BitVecExpr bitvecTerm = (BitVecExpr) toTerm(expr.getOp());
final int extendWith = expr.getExtendType().getSize() - expr.getOp().getType().getSize();
return context.mkZeroExt(extendWith, bitvecTerm);
}
private com.microsoft.z3.Expr transformBvSExt(final BvSExtExpr expr) {
final BitVecExpr bitvecTerm = (BitVecExpr) toTerm(expr.getOp());
final int extendWith = expr.getExtendType().getSize() - expr.getOp().getType().getSize();
return context.mkSignExt(extendWith, bitvecTerm);
}
private com.microsoft.z3.Expr transformBvAdd(final BvAddExpr expr) {
final BitVecExpr[] opTerms = expr.getOps().stream()
.map(e -> (BitVecExpr) toTerm(e))
.toArray(BitVecExpr[]::new);
return Stream.of(opTerms).skip(1).reduce(opTerms[0], context::mkBVAdd);
}
private com.microsoft.z3.Expr transformBvSub(final BvSubExpr expr) {
final BitVecExpr leftOpTerm = (BitVecExpr) toTerm(expr.getLeftOp());
final BitVecExpr rightOpTerm = (BitVecExpr) toTerm(expr.getRightOp());
return context.mkBVSub(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformBvPos(final BvPosExpr expr) {
return toTerm(expr.getOp());
}
private com.microsoft.z3.Expr transformBvSignChange(final BvSignChangeExpr expr) {
return toTerm(expr.getOp());
}
private com.microsoft.z3.Expr transformBvNeg(final BvNegExpr expr) {
final BitVecExpr opTerm = (BitVecExpr) toTerm(expr.getOp());
return context.mkBVNeg(opTerm);
}
private com.microsoft.z3.Expr transformBvMul(final BvMulExpr expr) {
final BitVecExpr[] opTerms = expr.getOps().stream()
.map(e -> (BitVecExpr) toTerm(e))
.toArray(BitVecExpr[]::new);
return Stream.of(opTerms).skip(1).reduce(opTerms[0], context::mkBVMul);
}
private com.microsoft.z3.Expr transformBvUDiv(final BvUDivExpr expr) {
final BitVecExpr leftOpTerm = (BitVecExpr) toTerm(expr.getLeftOp());
final BitVecExpr rightOpTerm = (BitVecExpr) toTerm(expr.getRightOp());
return context.mkBVUDiv(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformBvSDiv(final BvSDivExpr expr) {
final BitVecExpr leftOpTerm = (BitVecExpr) toTerm(expr.getLeftOp());
final BitVecExpr rightOpTerm = (BitVecExpr) toTerm(expr.getRightOp());
return context.mkBVSDiv(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformBvSMod(final BvSModExpr expr) {
final BitVecExpr leftOpTerm = (BitVecExpr) toTerm(expr.getLeftOp());
final BitVecExpr rightOpTerm = (BitVecExpr) toTerm(expr.getRightOp());
return context.mkBVSMod(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformBvURem(final BvURemExpr expr) {
final BitVecExpr leftOpTerm = (BitVecExpr) toTerm(expr.getLeftOp());
final BitVecExpr rightOpTerm = (BitVecExpr) toTerm(expr.getRightOp());
return context.mkBVURem(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformBvSRem(final BvSRemExpr expr) {
final BitVecExpr leftOpTerm = (BitVecExpr) toTerm(expr.getLeftOp());
final BitVecExpr rightOpTerm = (BitVecExpr) toTerm(expr.getRightOp());
return context.mkBVSRem(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformBvAnd(final BvAndExpr expr) {
final BitVecExpr[] opTerms = expr.getOps().stream()
.map(e -> (BitVecExpr) toTerm(e))
.toArray(BitVecExpr[]::new);
return Stream.of(opTerms).skip(1).reduce(opTerms[0], context::mkBVAND);
}
private com.microsoft.z3.Expr transformBvOr(final BvOrExpr expr) {
final BitVecExpr[] opTerms = expr.getOps().stream()
.map(e -> (BitVecExpr) toTerm(e))
.toArray(BitVecExpr[]::new);
return Stream.of(opTerms).skip(1).reduce(opTerms[0], context::mkBVOR);
}
private com.microsoft.z3.Expr transformBvXor(final BvXorExpr expr) {
final BitVecExpr[] opTerms = expr.getOps().stream()
.map(e -> (BitVecExpr) toTerm(e))
.toArray(BitVecExpr[]::new);
return Stream.of(opTerms).skip(1).reduce(opTerms[0], context::mkBVXOR);
}
private com.microsoft.z3.Expr transformBvNot(final BvNotExpr expr) {
final BitVecExpr opTerm = (BitVecExpr) toTerm(expr.getOp());
return context.mkBVNot(opTerm);
}
private com.microsoft.z3.Expr transformBvShiftLeft(final BvShiftLeftExpr expr) {
final BitVecExpr leftOpTerm = (BitVecExpr) toTerm(expr.getLeftOp());
final BitVecExpr rightOpTerm = (BitVecExpr) toTerm(expr.getRightOp());
return context.mkBVSHL(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformBvArithShiftRight(final BvArithShiftRightExpr expr) {
final BitVecExpr leftOpTerm = (BitVecExpr) toTerm(expr.getLeftOp());
final BitVecExpr rightOpTerm = (BitVecExpr) toTerm(expr.getRightOp());
return context.mkBVASHR(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformBvLogicShiftRight(final BvLogicShiftRightExpr expr) {
final BitVecExpr leftOpTerm = (BitVecExpr) toTerm(expr.getLeftOp());
final BitVecExpr rightOpTerm = (BitVecExpr) toTerm(expr.getRightOp());
return context.mkBVLSHR(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformBvRotateLeft(final BvRotateLeftExpr expr) {
final BitVecExpr leftOpTerm = (BitVecExpr) toTerm(expr.getLeftOp());
final BitVecExpr rightOpTerm = (BitVecExpr) toTerm(expr.getRightOp());
return context.mkBVRotateLeft(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformBvRotateRight(final BvRotateRightExpr expr) {
final BitVecExpr leftOpTerm = (BitVecExpr) toTerm(expr.getLeftOp());
final BitVecExpr rightOpTerm = (BitVecExpr) toTerm(expr.getRightOp());
return context.mkBVRotateRight(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformBvUGeq(final BvUGeqExpr expr) {
final BitVecExpr leftOpTerm = (BitVecExpr) toTerm(expr.getLeftOp());
final BitVecExpr rightOpTerm = (BitVecExpr) toTerm(expr.getRightOp());
return context.mkBVUGE(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformBvUGt(final BvUGtExpr expr) {
final BitVecExpr leftOpTerm = (BitVecExpr) toTerm(expr.getLeftOp());
final BitVecExpr rightOpTerm = (BitVecExpr) toTerm(expr.getRightOp());
return context.mkBVUGT(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformBvULeq(final BvULeqExpr expr) {
final BitVecExpr leftOpTerm = (BitVecExpr) toTerm(expr.getLeftOp());
final BitVecExpr rightOpTerm = (BitVecExpr) toTerm(expr.getRightOp());
return context.mkBVULE(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformBvULt(final BvULtExpr expr) {
final BitVecExpr leftOpTerm = (BitVecExpr) toTerm(expr.getLeftOp());
final BitVecExpr rightOpTerm = (BitVecExpr) toTerm(expr.getRightOp());
return context.mkBVULT(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformBvSGeq(final BvSGeqExpr expr) {
final BitVecExpr leftOpTerm = (BitVecExpr) toTerm(expr.getLeftOp());
final BitVecExpr rightOpTerm = (BitVecExpr) toTerm(expr.getRightOp());
return context.mkBVSGE(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformBvSGt(final BvSGtExpr expr) {
final BitVecExpr leftOpTerm = (BitVecExpr) toTerm(expr.getLeftOp());
final BitVecExpr rightOpTerm = (BitVecExpr) toTerm(expr.getRightOp());
return context.mkBVSGT(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformBvSLeq(final BvSLeqExpr expr) {
final BitVecExpr leftOpTerm = (BitVecExpr) toTerm(expr.getLeftOp());
final BitVecExpr rightOpTerm = (BitVecExpr) toTerm(expr.getRightOp());
return context.mkBVSLE(leftOpTerm, rightOpTerm);
}
/*
* Floating points
*/
private com.microsoft.z3.Expr transformBvSLt(final BvSLtExpr expr) {
final BitVecExpr leftOpTerm = (BitVecExpr) toTerm(expr.getLeftOp());
final BitVecExpr rightOpTerm = (BitVecExpr) toTerm(expr.getRightOp());
return context.mkBVSLT(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformFpLit(final FpLitExpr expr) {
return context.mkFP(context.mkBV(expr.getHidden() ? 1 : 0, 1),
(BitVecExpr) toTerm(expr.getExponent()), (BitVecExpr) toTerm(expr.getSignificand()));
}
private com.microsoft.z3.Expr transformFpAdd(final FpAddExpr expr) {
final FPExpr[] opTerms = expr.getOps().stream()
.map(e -> (FPExpr) toTerm(e))
.toArray(FPExpr[]::new);
return Stream.of(opTerms).skip(1).reduce(opTerms[0],
(op1, op2) -> context.mkFPAdd(transformFpRoundingMode(expr.getRoundingMode()), op1,
op2));
}
private com.microsoft.z3.Expr transformFpSub(final FpSubExpr expr) {
final FPExpr leftOpTerm = (FPExpr) toTerm(expr.getLeftOp());
final FPExpr rightOpTerm = (FPExpr) toTerm(expr.getRightOp());
return context.mkFPSub(transformFpRoundingMode(expr.getRoundingMode()), leftOpTerm,
rightOpTerm);
}
private com.microsoft.z3.Expr transformFpPos(final FpPosExpr expr) {
return toTerm(expr.getOp());
}
private com.microsoft.z3.Expr transformFpNeg(final FpNegExpr expr) {
final FPExpr opTerm = (FPExpr) toTerm(expr.getOp());
return context.mkFPNeg(opTerm);
}
private com.microsoft.z3.Expr transformFpAbs(final FpAbsExpr expr) {
final FPExpr opTerm = (FPExpr) toTerm(expr.getOp());
return context.mkFPAbs(opTerm);
}
private com.microsoft.z3.Expr transformFpIsNan(final FpIsNanExpr expr) {
final FPExpr opTerm = (FPExpr) toTerm(expr.getOp());
return context.mkFPIsNaN(opTerm);
}
private com.microsoft.z3.Expr transformFpIsInfinite(final FpIsInfiniteExpr expr) {
final FPExpr opTerm = (FPExpr) toTerm(expr.getOp());
return context.mkFPIsInfinite(opTerm);
}
private com.microsoft.z3.Expr transformFpSqrt(final FpSqrtExpr expr) {
final FPExpr opTerm = (FPExpr) toTerm(expr.getOp());
return context.mkFPSqrt(transformFpRoundingMode(expr.getRoundingMode()), opTerm);
}
private com.microsoft.z3.Expr transformFpRoundToIntegral(final FpRoundToIntegralExpr expr) {
final FPExpr opTerm = (FPExpr) toTerm(expr.getOp());
return context.mkFPRoundToIntegral(transformFpRoundingMode(expr.getRoundingMode()), opTerm);
}
private com.microsoft.z3.Expr transformFpMul(final FpMulExpr expr) {
final FPExpr[] opTerms = expr.getOps().stream()
.map(e -> (FPExpr) toTerm(e))
.toArray(FPExpr[]::new);
return Stream.of(opTerms).skip(1).reduce(opTerms[0],
(op1, op2) -> context.mkFPMul(transformFpRoundingMode(expr.getRoundingMode()), op1,
op2));
}
private com.microsoft.z3.Expr transformFpDiv(final FpDivExpr expr) {
final FPExpr leftOpTerm = (FPExpr) toTerm(expr.getLeftOp());
final FPExpr rightOpTerm = (FPExpr) toTerm(expr.getRightOp());
return context.mkFPDiv(transformFpRoundingMode(expr.getRoundingMode()), leftOpTerm,
rightOpTerm);
}
private com.microsoft.z3.Expr transformFpRem(final FpRemExpr expr) {
final FPExpr leftOpTerm = (FPExpr) toTerm(expr.getLeftOp());
final FPExpr rightOpTerm = (FPExpr) toTerm(expr.getRightOp());
return context.mkFPRem(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformFpEq(final FpEqExpr expr) {
final com.microsoft.z3.Expr leftOpTerm = toTerm(expr.getLeftOp());
final com.microsoft.z3.Expr rightOpTerm = toTerm(expr.getRightOp());
return context.mkFPEq((FPExpr) leftOpTerm, (FPExpr) rightOpTerm);
}
private com.microsoft.z3.Expr transformFpAssign(final FpAssignExpr expr) {
final com.microsoft.z3.Expr leftOpTerm = toTerm(expr.getLeftOp());
final com.microsoft.z3.Expr rightOpTerm = toTerm(expr.getRightOp());
return context.mkEq(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformFpNeq(final FpNeqExpr expr) {
final com.microsoft.z3.Expr leftOpTerm = toTerm(expr.getLeftOp());
final com.microsoft.z3.Expr rightOpTerm = toTerm(expr.getRightOp());
return context.mkNot(context.mkFPEq((FPExpr) leftOpTerm, (FPExpr) rightOpTerm));
}
private com.microsoft.z3.Expr transformFpGeq(final FpGeqExpr expr) {
final com.microsoft.z3.Expr leftOpTerm = toTerm(expr.getLeftOp());
final com.microsoft.z3.Expr rightOpTerm = toTerm(expr.getRightOp());
return context.mkFPGEq((FPExpr) leftOpTerm, (FPExpr) rightOpTerm);
}
private com.microsoft.z3.Expr transformFpLeq(final FpLeqExpr expr) {
final com.microsoft.z3.Expr leftOpTerm = toTerm(expr.getLeftOp());
final com.microsoft.z3.Expr rightOpTerm = toTerm(expr.getRightOp());
return context.mkFPLEq((FPExpr) leftOpTerm, (FPExpr) rightOpTerm);
}
private com.microsoft.z3.Expr transformFpGt(final FpGtExpr expr) {
final com.microsoft.z3.Expr leftOpTerm = toTerm(expr.getLeftOp());
final com.microsoft.z3.Expr rightOpTerm = toTerm(expr.getRightOp());
return context.mkFPGt((FPExpr) leftOpTerm, (FPExpr) rightOpTerm);
}
private com.microsoft.z3.Expr transformFpLt(final FpLtExpr expr) {
final com.microsoft.z3.Expr leftOpTerm = toTerm(expr.getLeftOp());
final com.microsoft.z3.Expr rightOpTerm = toTerm(expr.getRightOp());
return context.mkFPLt((FPExpr) leftOpTerm, (FPExpr) rightOpTerm);
}
private com.microsoft.z3.FPRMExpr transformFpRoundingMode(final FpRoundingMode roundingMode) {
switch (roundingMode) {
case RNE:
return context.mkFPRoundNearestTiesToEven();
case RNA:
return context.mkFPRoundNearestTiesToAway();
case RTP:
return context.mkFPRoundTowardPositive();
case RTN:
return context.mkFPRoundTowardNegative();
case RTZ:
return context.mkFPRoundTowardZero();
default:
throw new UnsupportedOperationException();
}
}
private com.microsoft.z3.Expr transformFpMax(final FpMaxExpr expr) {
final FPExpr leftOpTerm = (FPExpr) toTerm(expr.getLeftOp());
final FPExpr rightOpTerm = (FPExpr) toTerm(expr.getRightOp());
return context.mkFPMax(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformFpMin(final FpMinExpr expr) {
final FPExpr leftOpTerm = (FPExpr) toTerm(expr.getLeftOp());
final FPExpr rightOpTerm = (FPExpr) toTerm(expr.getRightOp());
return context.mkFPMin(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformFpFromBv(final FpFromBvExpr expr) {
final BitVecExpr val = (BitVecExpr) toTerm(expr.getOp());
final FPSort fpSort = context.mkFPSort(expr.getFpType().getExponent(),
expr.getFpType().getSignificand());
return context.mkFPToFP(transformFpRoundingMode(expr.getRoundingMode()), val, fpSort,
expr.isSigned()); // TODO: is this OK? FP2FP when BV2FP is used?
}
private com.microsoft.z3.Expr transformFpToBv(final FpToBvExpr expr) {
boolean sgn = expr.getSgn();
int size = expr.getSize();
final FPExpr op = (FPExpr) toTerm(expr.getOp());
return context.mkFPToBV(transformFpRoundingMode(expr.getRoundingMode()), op, size, sgn);
}
/*
* Arrays
*/
private com.microsoft.z3.Expr transformFpToFp(final FpToFpExpr expr) {
final FPExpr op = (FPExpr) toTerm(expr.getOp());
return context.mkFPToFP(transformFpRoundingMode(expr.getRoundingMode()), op,
new FPSort(context, expr.getExpBits(), expr.getSignBits()));
}
private com.microsoft.z3.Expr transformArrayRead(final ArrayReadExpr, ?> expr) {
final com.microsoft.z3.ArrayExpr arrayTerm = (com.microsoft.z3.ArrayExpr) toTerm(
expr.getArray());
final com.microsoft.z3.Expr indexTerm = toTerm(expr.getIndex());
return context.mkSelect(arrayTerm, indexTerm);
}
private com.microsoft.z3.Expr transformArrayWrite(final ArrayWriteExpr, ?> expr) {
final com.microsoft.z3.ArrayExpr arrayTerm = (com.microsoft.z3.ArrayExpr) toTerm(
expr.getArray());
final com.microsoft.z3.Expr indexTerm = toTerm(expr.getIndex());
final com.microsoft.z3.Expr elemTerm = toTerm(expr.getElem());
return context.mkStore(arrayTerm, indexTerm, elemTerm);
}
private com.microsoft.z3.Expr transformArrayEq(final ArrayEqExpr, ?> expr) {
final com.microsoft.z3.Expr leftOpTerm = toTerm(expr.getLeftOp());
final com.microsoft.z3.Expr rightOpTerm = toTerm(expr.getRightOp());
return context.mkEq(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformArrayNeq(final ArrayNeqExpr, ?> expr) {
final com.microsoft.z3.Expr leftOpTerm = toTerm(expr.getLeftOp());
final com.microsoft.z3.Expr rightOpTerm = toTerm(expr.getRightOp());
return context.mkNot(context.mkEq(leftOpTerm, rightOpTerm));
}
/*
* Functions
*/
private com.microsoft.z3.Expr transformArrayLit(final ArrayLitExpr, ?> expr) {
com.microsoft.z3.ArrayExpr running = context.mkConstArray(
transformer.toSort(expr.getType().getIndexType()), toTerm(expr.getElseElem()));
for (Tuple2 extends Expr>, ? extends Expr>> elem : expr.getElements()) {
running = context.mkStore(running, toTerm(elem.get1()), toTerm(elem.get2()));
}
return running;
}
private com.microsoft.z3.Expr transformArrayInit(final ArrayInitExpr, ?> expr) {
com.microsoft.z3.ArrayExpr running = context.mkConstArray(
transformer.toSort(expr.getType().getIndexType()), toTerm(expr.getElseElem()));
for (Tuple2 extends Expr>, ? extends Expr>> elem : expr.getElements()) {
running = context.mkStore(running, toTerm(elem.get1()), toTerm(elem.get2()));
}
return running;
}
private com.microsoft.z3.Expr transformFuncApp(final FuncAppExpr, ?> expr) {
final Tuple2, List>> funcAndArgs = extractFuncAndArgs(expr);
final Expr> func = funcAndArgs.get1();
final List> args = funcAndArgs.get2();
if (func instanceof RefExpr) {
final RefExpr> ref = (RefExpr>) func;
final Decl> decl = ref.getDecl();
final com.microsoft.z3.FuncDecl funcDecl = transformer.toSymbol(decl);
final com.microsoft.z3.Expr[] argTerms = args.stream()
.map(this::toTerm)
.toArray(com.microsoft.z3.Expr[]::new);
return context.mkApp(funcDecl, argTerms);
} else if (func instanceof FuncLitExpr, ?>) {
Expr> replaced = func;
int i = 0;
while (replaced instanceof FuncLitExpr, ?>) {
final ParamDecl> param = ((FuncLitExpr, ?>) replaced).getParam();
final Expr> funcExpr = ((FuncLitExpr, ?>) replaced).getResult();
replaced = ExprUtils.changeDecls(funcExpr, Map.of(param, ((RefExpr>) args.get(i++)).getDecl()));
}
return toTerm(replaced);
} else {
throw new UnsupportedOperationException(
"Higher order functions are not supported: " + func);
}
}
private com.microsoft.z3.Expr transformEnumLit(final EnumLitExpr expr) {
EnumType enumType = expr.getType();
return ((EnumSort) transformer.toSort(enumType)).getConst(enumType.getIntValue(expr.getValue()));
}
private com.microsoft.z3.Expr transformEnumEq(final EnumEqExpr expr) {
final com.microsoft.z3.Expr leftOpTerm = toTerm(expr.getLeftOp());
final com.microsoft.z3.Expr rightOpTerm = toTerm(expr.getRightOp());
return context.mkEq(leftOpTerm, rightOpTerm);
}
private com.microsoft.z3.Expr transformEnumNeq(final EnumNeqExpr expr) {
final com.microsoft.z3.Expr leftOpTerm = toTerm(expr.getLeftOp());
final com.microsoft.z3.Expr rightOpTerm = toTerm(expr.getRightOp());
return context.mkNot(context.mkEq(leftOpTerm, rightOpTerm));
}
public void reset() {
exprToTerm.invalidateAll();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy