public static Definition expandAndEvaluate(TermContext termContext, KExceptionManager kem) { Definition expandedDefinition = new MacroExpander(termContext, kem).processDefinition(); termContext.global().setDefinition(expandedDefinition); Definition evaluatedDefinition = evaluateDefinition(termContext); termContext.global().setDefinition(evaluatedDefinition); return evaluatedDefinition; }
@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()); }
/** 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; }
@Inject public KILtoBackendJavaKILTransformer( Context context, @FreshRules boolean freshRules, GlobalContext globalContext, IndexingTable.Data data, KExceptionManager kem) { super("Transform KIL into java backend KIL", context); this.freshRules = freshRules; this.globalContext = globalContext; // TODO(YilongL): remove the call to "freshCounter(0)" once // macro expansion doesn't trigger the fresh constants generation this.termContext = TermContext.builder(globalContext).freshCounter(0).build(); this.indexingData = data; this.kem = kem; }
// 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(); }