Ejemplo n.º 1
0
  private BooleanFormula makeSsaNondetFlagMerger(int iSmaller, int iBigger) {
    Formula pInitialValue = fmgr.makeNumber(nondetFormulaType, 0);
    assert iSmaller < iBigger;

    List<BooleanFormula> lResult = new ArrayList<>();
    FormulaType<Formula> type = fmgr.getFormulaType(pInitialValue);

    for (int i = iSmaller + 1; i <= iBigger; ++i) {
      Formula currentVar = fmgr.makeVariable(type, NONDET_FLAG_VARIABLE, i);
      lResult.add(fmgr.assignment(currentVar, pInitialValue));
    }

    return bfmgr.and(lResult);
  }
    /**
     * 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;
    }