/** Partially evaluate the right-hand side and the conditions of a specified rule. */
  private static Rule evaluateRule(Rule rule, TermContext termContext) {
    try {
      // TODO(AndreiS): some evaluation is required in the LHS as well
      // TODO(YilongL): cannot simply uncomment the following code because it
      // may evaluate the LHS using the rule itself
      // Term leftHandSide = rule.leftHandSide().evaluate(termContext);

      Rule origRule = rule;
      Term rightHandSide = rule.rightHandSide().evaluate(termContext);
      List<Term> requires = new ArrayList<>();
      for (Term term : rule.requires()) {
        requires.add(term.evaluate(termContext));
      }
      List<Term> ensures = new ArrayList<>();
      for (Term term : rule.ensures()) {
        ensures.add(term.evaluate(termContext));
      }
      ConjunctiveFormula lookups = ConjunctiveFormula.of(termContext);
      for (Equality equality : rule.lookups().equalities()) {
        lookups =
            lookups.add(
                equality.leftHandSide().evaluate(termContext),
                equality.rightHandSide().evaluate(termContext));
      }

      Map<CellLabel, Term> rhsOfWriteCell = null;
      if (rule.isCompiledForFastRewriting()) {
        rhsOfWriteCell = new HashMap<>();
        for (Map.Entry<CellLabel, Term> entry : rule.rhsOfWriteCell().entrySet()) {
          rhsOfWriteCell.put(entry.getKey(), entry.getValue().evaluate(termContext));
        }
      }

      Rule newRule =
          new Rule(
              rule.label(),
              rule.leftHandSide(),
              rightHandSide,
              requires,
              ensures,
              rule.freshConstants(),
              rule.freshVariables(),
              lookups,
              rule.isCompiledForFastRewriting(),
              rule.lhsOfReadCell(),
              rhsOfWriteCell,
              rule.cellsToCopy(),
              rule.matchingInstructions(),
              rule,
              termContext);
      return newRule.equals(rule) ? origRule : newRule;
    } catch (KEMException e) {
      e.exception.addTraceFrame(
          "while compiling rule at location " + rule.getSource() + rule.getLocation());
      throw e;
    }
  }
Exemple #2
0
 @Override
 public void visit(Rule rule) {
   rule.leftHandSide().accept(this);
   rule.rightHandSide().accept(this);
   rule.lookups().accept(this);
   for (Term term : rule.requires()) {
     term.accept(this);
   }
   for (Term term : rule.ensures()) {
     term.accept(this);
   }
   for (Variable variable : rule.freshVariables()) {
     variable.accept(this);
   }
 }
Exemple #3
0
  private void narrowByRule(ConstrainedTerm constrainedTerm, Rule rule) {
    stopwatch.reset();
    stopwatch.start();

    constrainedTermResults = new ArrayList<ConstrainedTerm>();

    SymbolicConstraint leftHandSideConstraint =
        new SymbolicConstraint(constrainedTerm.termContext());
    leftHandSideConstraint.addAll(rule.requires());
    for (Variable variable : rule.freshVariables()) {
      leftHandSideConstraint.add(variable, IntToken.fresh());
    }

    ConstrainedTerm leftHandSide =
        new ConstrainedTerm(
            rule.leftHandSide(),
            rule.lookups().getSymbolicConstraint(constrainedTerm.termContext()),
            leftHandSideConstraint,
            constrainedTerm.termContext());

    for (SymbolicConstraint constraint : constrainedTerm.unify(leftHandSide)) {
      constraint.addAll(rule.ensures());
      /* rename rule variables in the constraints */
      Map<Variable, Variable> freshSubstitution = constraint.rename(rule.variableSet());

      Term result = rule.rightHandSide();
      /* rename rule variables in the rule RHS */
      result = result.substituteWithBinders(freshSubstitution, constrainedTerm.termContext());
      /* apply the constraints substitution on the rule RHS */
      result =
          result.substituteWithBinders(constraint.substitution(), constrainedTerm.termContext());
      /* evaluate pending functions in the rule RHS */
      result = result.evaluate(constrainedTerm.termContext());
      /* eliminate anonymous variables */
      constraint.eliminateAnonymousVariables();

      /* compute all results */
      constrainedTermResults.add(
          new ConstrainedTerm(result, constraint, constrainedTerm.termContext()));
    }

    stopwatch.stop();
  }
Exemple #4
0
  // apply rule by matching
  private void rewriteByRule(Term term, Rule rule) {
    stopwatch.reset();
    stopwatch.start();

    termResults = new ArrayList<Term>();

    TermContext context = TermContext.of(definition);
    ConstrainedTerm constrainedTerm = new ConstrainedTerm(term, context);

    SymbolicConstraint leftHandSideConstraint = new SymbolicConstraint(context);
    leftHandSideConstraint.addAll(rule.requires());
    for (Variable variable : rule.freshVariables()) {
      leftHandSideConstraint.add(variable, IntToken.fresh());
    }

    ConstrainedTerm leftHandSide =
        new ConstrainedTerm(
            rule.leftHandSide(),
            rule.lookups().getSymbolicConstraint(context),
            leftHandSideConstraint,
            context);

    for (SymbolicConstraint constraint : constrainedTerm.unify(leftHandSide)) {
      if (!constraint.isMatching(leftHandSide)) {
        continue;
      }

      constraint.orientSubstitution(leftHandSide.variableSet());

      Term result = rule.rightHandSide();
      /* apply the constraints substitution on the rule RHS */
      result = result.substituteAndEvaluate(constraint.substitution(), context);

      /* compute all results */
      termResults.add(result);
    }

    stopwatch.stop();
  }