/** 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; } }
@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); } }
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(); }
@Override public KRunProofResult<Set<org.kframework.kil.Term>> prove(Module module) throws KRunExecutionException { TermContext termContext = TermContext.of(globalContext); List<Rule> rules = new ArrayList<Rule>(); for (org.kframework.kil.ModuleItem moduleItem : module.getItems()) { if (!(moduleItem instanceof org.kframework.kil.Rule)) { continue; } Rule rule = transformer.transformAndEval((org.kframework.kil.Rule) moduleItem); Rule freshRule = rule.getFreshRule(termContext); rules.add(freshRule); } CounterGetter counterGetter = new CounterGetter(context); counterGetter.visitNode(module); BigInteger counter = counterGetter.counter.add(BigInteger.ONE); SymbolicRewriter symbolicRewriter = executor.getSymbolicRewriter(); List<ConstrainedTerm> proofResults = new ArrayList<>(); for (org.kframework.kil.ModuleItem moduleItem : module.getItems()) { if (!(moduleItem instanceof org.kframework.kil.Rule) || moduleItem.containsAttribute(Attribute.TRUSTED_KEY)) { continue; } termContext.setCounter(counter); Rule rule = transformer.transformAndEval((org.kframework.kil.Rule) moduleItem); ConstrainedTerm initialTerm = new ConstrainedTerm( rule.leftHandSide(), ConjunctiveFormula.of(termContext).addAll(rule.requires())); ConstrainedTerm targetTerm = new ConstrainedTerm( rule.rightHandSide(), ConjunctiveFormula.of(termContext).addAll(rule.ensures())); proofResults.addAll(symbolicRewriter.proveRule(initialTerm, targetTerm, rules)); } return new KRunProofResult<>( proofResults.isEmpty(), Collections.<org.kframework.kil.Term>emptySet()); }