@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);
  }
  /**
   * For each interpolant, we strengthen the corresponding state by conjunctively adding the
   * interpolant to its state formula. This is all implemented in {@link
   * ImpactUtility#strengthenStateWithInterpolant(BooleanFormula, ARGState, AbstractionFormula)}.
   */
  @Override
  protected boolean performRefinementForState(BooleanFormula itp, ARGState s)
      throws SolverException, InterruptedException {
    checkArgument(!bfmgr.isTrue(itp));
    checkArgument(!bfmgr.isFalse(itp));

    boolean stateChanged = impact.strengthenStateWithInterpolant(itp, s, lastAbstraction);

    // Get the abstraction formula of the current state
    // (whether changed or not) to have it ready for the next call to this method).
    lastAbstraction = getPredicateState(s).getAbstractionFormula();

    return !stateChanged; // Careful: this method requires negated return value.
  }
  /**
   * Get the predicates out of an interpolant.
   *
   * @param pInterpolant The interpolant formula.
   * @return A set of predicates.
   */
  private final Collection<AbstractionPredicate> convertInterpolant(
      final BooleanFormula pInterpolant) {

    BooleanFormula interpolant = pInterpolant;

    if (bfmgr.isTrue(interpolant)) {
      return Collections.<AbstractionPredicate>emptySet();
    }

    Collection<AbstractionPredicate> preds;

    if (atomicPredicates) {
      preds = predAbsMgr.getPredicatesForAtomsOf(interpolant);

    } else {
      preds = ImmutableList.of(predAbsMgr.getPredicateFor(interpolant));
    }

    assert !preds.isEmpty()
        : "Interpolant without relevant predicates: "
            + pInterpolant
            + "; simplified to "
            + interpolant;

    logger.log(Level.FINEST, "Got predicates", preds);

    return preds;
  }
  @Override
  public Region fromFormula(
      BooleanFormula pF, FormulaManagerView fmgr, Function<BooleanFormula, Region> atomToRegion) {
    cleanupReferences();

    BooleanFormulaManagerView bfmgr = fmgr.getBooleanFormulaManager();
    if (bfmgr.isFalse(pF)) {
      return makeFalse();
    }

    if (bfmgr.isTrue(pF)) {
      return makeTrue();
    }

    try (FormulaToRegionConverter converter = new FormulaToRegionConverter(fmgr, atomToRegion)) {
      return wrap(bfmgr.visit(pF, converter));
    }
  }
  @Override
  protected boolean performRefinementForState(BooleanFormula pInterpolant, ARGState pState)
      throws InterruptedException, SolverException {
    checkState(newPredicates != null);
    checkArgument(!bfmgr.isTrue(pInterpolant));

    predicateCreation.start();
    newPredicates.putAll(extractLocation(pState), convertInterpolant(pInterpolant));
    predicateCreation.stop();

    return false;
  }
    /**
     * Transform a non linear multiplication operation into a new linear {@link Formula} and adds it
     * to {@link #additionalAxioms}. The returned {@link Formula} represents the multiplication
     * opertion's result if that {@link Formula} is satisfied.
     *
     * @return a {@link Formula} representing the result of the multiplication operation
     */
    private Formula transformNonLinearMultiplication(
        Formula a, Formula b, FormulaType<?> formulaType) {
      BooleanFormulaManagerView bfmgr = fmgrView.getBooleanFormulaManager();

      Formula multAux =
          fmgr.makeVariable(
              formulaType,
              TERMINATION_AUX_VARS_PREFIX + "MULT_AUX_VAR_" + ID_GENERATOR.getFreshId());

      List<BooleanFormula> cases = Lists.newArrayList();
      Formula one = fmgrView.makeNumber(formulaType, 1);
      Formula minusOne = fmgrView.makeNumber(formulaType, -1);
      Formula zero = fmgrView.makeNumber(formulaType, 0);

      BooleanFormula aIsZero = fmgrView.makeEqual(a, zero);
      BooleanFormula bIsZero = fmgrView.makeEqual(b, zero);
      BooleanFormula factorIsZero = fmgrView.makeOr(aIsZero, bIsZero);
      cases.add(fmgrView.makeAnd(factorIsZero, fmgrView.makeEqual(multAux, zero)));

      BooleanFormula aIsOne = fmgrView.makeEqual(a, one);
      BooleanFormula bIsOne = fmgrView.makeEqual(b, one);
      cases.add(fmgrView.makeAnd(bIsOne, fmgrView.makeEqual(multAux, a)));
      cases.add(fmgrView.makeAnd(aIsOne, fmgrView.makeEqual(multAux, b)));

      // 0 < a < 1,  0 < b < 1, -1 < a < 0, -1 < b < 0, a > 1, ...
      BooleanFormula zeroLessALessOne =
          bfmgr.and(fmgrView.makeLessThan(zero, a, true), fmgrView.makeLessThan(a, one, true));
      BooleanFormula zeroLessBLessOne =
          bfmgr.and(fmgrView.makeLessThan(zero, b, true), fmgrView.makeLessThan(b, one, true));
      BooleanFormula minusOneLessALessZero =
          bfmgr.and(fmgrView.makeLessThan(minusOne, a, true), fmgrView.makeLessThan(a, zero, true));
      BooleanFormula minusOneLessBLessZero =
          bfmgr.and(fmgrView.makeLessThan(minusOne, b, true), fmgrView.makeLessThan(b, zero, true));
      BooleanFormula aGreaterOne = bfmgr.and(fmgrView.makeGreaterThan(a, one, true));
      BooleanFormula bGreaterOne = bfmgr.and(fmgrView.makeGreaterThan(b, one, true));
      BooleanFormula aLessMinuseOne = bfmgr.and(fmgrView.makeLessThan(a, one, true));
      BooleanFormula bLessMinuseOne = bfmgr.and(fmgrView.makeLessThan(b, one, true));

      // 0 < multAux < 1, -1 < multAux < 0, multAux > 1, ...
      BooleanFormula zeroLessResultLessOne =
          bfmgr.and(
              fmgrView.makeLessThan(zero, multAux, true),
              fmgrView.makeLessThan(multAux, one, true));
      BooleanFormula minusOneLessResultLessZero =
          bfmgr.and(
              fmgrView.makeLessThan(minusOne, multAux, true),
              fmgrView.makeLessThan(multAux, zero, true));
      BooleanFormula resultGreaterOne = bfmgr.and(fmgrView.makeGreaterThan(multAux, one, true));
      BooleanFormula resultLessMinuseOne = bfmgr.and(fmgrView.makeLessThan(multAux, one, true));
      BooleanFormula positiveResult = fmgrView.makeGreaterThan(multAux, zero, true);
      BooleanFormula negativeResult = fmgrView.makeLessThan(multAux, zero, true);

      cases.add(bfmgr.and(zeroLessALessOne, zeroLessBLessOne, zeroLessResultLessOne));
      cases.add(bfmgr.and(zeroLessALessOne, minusOneLessBLessZero, minusOneLessResultLessZero));
      cases.add(bfmgr.and(zeroLessALessOne, bGreaterOne, positiveResult));
      cases.add(bfmgr.and(zeroLessALessOne, bLessMinuseOne, negativeResult));
      cases.add(bfmgr.and(minusOneLessALessZero, zeroLessBLessOne, minusOneLessResultLessZero));
      cases.add(bfmgr.and(minusOneLessALessZero, minusOneLessBLessZero, zeroLessResultLessOne));
      cases.add(bfmgr.and(minusOneLessALessZero, bGreaterOne, negativeResult));
      cases.add(bfmgr.and(minusOneLessALessZero, bLessMinuseOne, positiveResult));
      cases.add(bfmgr.and(aGreaterOne, zeroLessBLessOne, positiveResult));
      cases.add(bfmgr.and(aGreaterOne, minusOneLessBLessZero, negativeResult));
      cases.add(bfmgr.and(aGreaterOne, bGreaterOne, resultGreaterOne));
      cases.add(bfmgr.and(aGreaterOne, bLessMinuseOne, resultLessMinuseOne));
      cases.add(bfmgr.and(aLessMinuseOne, zeroLessBLessOne, negativeResult));
      cases.add(bfmgr.and(aLessMinuseOne, minusOneLessBLessZero, positiveResult));
      cases.add(bfmgr.and(aLessMinuseOne, bGreaterOne, resultLessMinuseOne));
      cases.add(bfmgr.and(aLessMinuseOne, bLessMinuseOne, resultGreaterOne));

      additionalAxioms.add(bfmgr.or(cases));
      return multAux;
    }
Ejemplo n.º 7
0
 public static <T> MergeResult<T> trivial(T result, BooleanFormulaManagerView bfmgr) {
   BooleanFormula trueFormula = bfmgr.makeTrue();
   return new MergeResult<>(result, trueFormula, trueFormula, trueFormula);
 }