@Override
  public BooleanFormula visitAtom(BooleanFormula pAtom, FunctionDeclaration<BooleanFormula> pDecl) {
    NonLinearMultiplicationTransformation multiplicationTransformation =
        new NonLinearMultiplicationTransformation(fmgrView, fmgr);
    BooleanFormula result = (BooleanFormula) fmgrView.visit(pAtom, multiplicationTransformation);

    BooleanFormulaManagerView booleanFormulaManager = fmgrView.getBooleanFormulaManager();
    BooleanFormula additionalAxioms =
        booleanFormulaManager.and(multiplicationTransformation.getAdditionalAxioms());
    return fmgrView.makeAnd(result, additionalAxioms);
  }
    @Override
    public Formula visitFunction(
        Formula pF, List<Formula> pArgs, FunctionDeclaration<?> pFunctionDeclaration) {

      List<Formula> newArgs = Lists.transform(pArgs, f -> fmgrView.visit(f, this));

      if ((pFunctionDeclaration.getKind().equals(UF)
              && pFunctionDeclaration.getName().equalsIgnoreCase("Integer__*_"))
          || (pFunctionDeclaration.getKind().equals(MUL)
              && !isConstant(newArgs.get(0))
              && !isConstant(newArgs.get(1)))) {
        assert newArgs.size() == 2;
        return transformNonLinearMultiplication(
            newArgs.get(0), newArgs.get(1), pFunctionDeclaration.getType());

      } else {
        return fmgr.makeApplication(pFunctionDeclaration, newArgs);
      }
    }