All Downloads are FREE. Search and download functionalities are using the official Maven repository.

hu.bme.mit.theta.solver.javasmt.JavaSMTDeclTransformer Maven / Gradle / Ivy

/*
 *  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.javasmt;

import com.google.common.collect.ImmutableList;
import hu.bme.mit.theta.common.Tuple2;
import hu.bme.mit.theta.core.decl.ConstDecl;
import hu.bme.mit.theta.core.decl.Decl;
import hu.bme.mit.theta.core.type.Type;
import hu.bme.mit.theta.core.type.functype.FuncType;
import org.sosy_lab.java_smt.api.Formula;
import org.sosy_lab.java_smt.api.FormulaType;
import org.sosy_lab.java_smt.api.SolverContext;

import java.util.List;

import static com.google.common.base.Preconditions.checkArgument;

final class JavaSMTDeclTransformer {

    private final JavaSMTTransformationManager transformer;
    private final JavaSMTSymbolTable symbolTable;
    private final SolverContext context;

    private int symbolCount;

    JavaSMTDeclTransformer(final JavaSMTTransformationManager transformer, final JavaSMTSymbolTable symbolTable,
                           final SolverContext context) {
        this.transformer = transformer;
        this.symbolTable = symbolTable;
        this.context = context;
        this.symbolCount = 0;
    }

    public Formula toSymbol(final Decl decl) {
        if (decl instanceof ConstDecl) {
            return transformConst((ConstDecl) decl);
        } else {
            throw new UnsupportedOperationException("Cannot transform declaration: " + decl);
        }
    }

    private Formula transformConst(final ConstDecl decl) {
        final Formula symbol;

        if (symbolTable.definesConstAsFormula(decl)) {
            symbol = symbolTable.getSymbolAsFormula(decl);
        } else {
            final Type type = decl.getType();

            final Tuple2, Type> extractedTypes = extractTypes(type);
            final List paramTypes = extractedTypes.get1();
            final Type returnType = extractedTypes.get2();

            final FormulaType returnSort = transformer.toSort(returnType);
            final List> paramSorts = paramTypes.stream()
                    .map(transformer::toSort)
                    .toList();


            if (!paramSorts.isEmpty()) {
                throw new JavaSMTSolverException("Function consts not yet supported.");
            }

            // Enums can't be yet handled by formulamanager directly
            if (returnSort.isEnumerationType()) {
                symbol = context.getFormulaManager().getEnumerationFormulaManager().makeVariable(symbolNameFor(decl), (FormulaType.EnumerationFormulaType) returnSort);
            } else {
                symbol = context.getFormulaManager().makeVariable(returnSort, symbolNameFor(decl));
            }

            symbolTable.put(decl, symbol);
        }

        return symbol;
    }

    private Tuple2, Type> extractTypes(final Type type) {
        if (type instanceof FuncType funcType) {

            final Type paramType = funcType.getParamType();
            final Type resultType = funcType.getResultType();

            checkArgument(!(paramType instanceof FuncType), "Parameter type most not be function");

            final Tuple2, Type> subResult = extractTypes(resultType);
            final List paramTypes = subResult.get1();
            final Type newResultType = subResult.get2();
            final List newParamTypes = ImmutableList.builder().add(paramType)
                    .addAll(paramTypes).build();
            return Tuple2.of(newParamTypes, newResultType);
        } else {
            return Tuple2.of(ImmutableList.of(), type);
        }
    }

    private String symbolNameFor(final Decl decl) {
        return String.format("%s_%d", decl.getName(), symbolCount++);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy