/** 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; } }
/** Partially evaluate the right-hand side and the conditions for each rule. */ private static Definition evaluateDefinition(TermContext termContext) { Definition definition = termContext.global().getDefinition(); /* replace the unevaluated rules defining functions with their partially evaluated counterparts */ ArrayList<Rule> partiallyEvaluatedRules = new ArrayList<>(); /* iterate until a fixpoint is reached, because the evaluation with functions uses Term#substituteAndEvalaute */ while (true) { boolean change = false; partiallyEvaluatedRules.clear(); for (Rule rule : Iterables.concat( definition.functionRules().values(), definition.anywhereRules().values())) { Rule freshRule = rule.getFreshRule(termContext); Rule evaluatedRule = evaluateRule(freshRule, termContext); partiallyEvaluatedRules.add(evaluatedRule); if (!evaluatedRule.equals(freshRule)) { change = true; } } if (!change) { break; } definition.functionRules().clear(); definition.anywhereRules().clear(); definition.addRuleCollection(partiallyEvaluatedRules); } /* replace the unevaluated rules and macros with their partially evaluated counterparts */ partiallyEvaluatedRules.clear(); Iterable<Rule> rules = Iterables.concat( definition.rules(), definition.macros(), definition.patternRules().values(), definition.patternFoldingRules()); for (Rule rule : rules) { partiallyEvaluatedRules.add(evaluateRule(rule, termContext)); } definition.rules().clear(); definition.macros().clear(); definition.patternRules().clear(); definition.patternFoldingRules().clear(); definition.addRuleCollection(partiallyEvaluatedRules); return definition; }