@Override public void visit(Rewrite node) { node.getLeft().accept(this); current = right; node.getRight().accept(this); current = left; }
@Override public Void visit(Rewrite rew, Void _) { // builder.append('('); visitNodeOrKList(rew.getLeft()); builder.append(" => "); visitNodeOrKList(rew.getRight()); // builder.append(')'); return null; }
@Override public ASTNode transform(Rule node) throws TransformerException { final boolean heating = node.containsAttribute(MetaK.Constants.heatingTag); final boolean cooling = node.containsAttribute(MetaK.Constants.coolingTag); if (!(heating || cooling)) return node; if (!(node.getBody() instanceof Rewrite)) { GlobalSettings.kem.register( new KException( KException.ExceptionType.ERROR, KException.KExceptionGroup.CRITICAL, "Heating/Cooling rules should have rewrite at the top.", getName(), node.getFilename(), node.getLocation())); } KSequence kSequence; Rewrite rewrite = (Rewrite) node.getBody(); if (heating) { if (!(rewrite.getRight() instanceof KSequence)) { GlobalSettings.kem.register( new KException( KException.ExceptionType.ERROR, KException.KExceptionGroup.CRITICAL, "Heating rules should have a K sequence in the rhs.", getName(), node.getFilename(), node.getLocation())); } kSequence = (KSequence) rewrite.getRight(); } else { if (!(rewrite.getLeft() instanceof KSequence)) { GlobalSettings.kem.register( new KException( KException.ExceptionType.ERROR, KException.KExceptionGroup.CRITICAL, "Cooling rules should have a K sequence in the lhs.", getName(), node.getFilename(), node.getLocation())); } kSequence = (KSequence) rewrite.getLeft(); } List<Term> kSequenceContents = kSequence.getContents(); if (kSequenceContents.size() != 2) { GlobalSettings.kem.register( new KException( KException.ExceptionType.ERROR, KException.KExceptionGroup.CRITICAL, "Heating/Cooling rules should have exactly 2 items in their K Sequence.", getName(), node.getFilename(), node.getLocation())); } final Term freezer = kSequenceContents.get(1); if (!(freezer instanceof Freezer)) { kSequenceContents = new ArrayList<Term>(kSequenceContents); kSequenceContents.set(1, new ContextsToHeating(context).freeze(freezer)); kSequence = kSequence.shallowCopy(); kSequence.setContents(kSequenceContents); rewrite = rewrite.shallowCopy(); if (heating) { rewrite.replaceChildren(rewrite.getLeft(), kSequence, context); } else { rewrite.replaceChildren(kSequence, rewrite.getRight(), context); } node = node.shallowCopy(); node.setBody(rewrite); } return node; }
@Override public ASTNode visit(org.kframework.kil.Rule node, Void _void) { try { assert node.getBody() instanceof org.kframework.kil.Rewrite; JavaBackendRuleData ruleData = node.getAttribute(JavaBackendRuleData.class); if (ruleData == null) { ruleData = new JavaBackendRuleData(); } concreteCollectionSize = ruleData.getConcreteDataStructureSize(); org.kframework.kil.Rewrite rewrite = (org.kframework.kil.Rewrite) node.getBody(); Term leftHandSide = (Term) this.visitNode(rewrite.getLeft()); Term rightHandSide = (Term) this.visitNode(rewrite.getRight()); List<Term> requires = new ArrayList<>(); if (node.getRequires() != null) { transformConjunction(requires, (Term) this.visitNode(node.getRequires())); } List<Term> ensures = new ArrayList<>(); if (node.getEnsures() != null) { transformConjunction(ensures, (Term) this.visitNode(node.getEnsures())); } ConjunctiveFormula lookups = ConjunctiveFormula.of(termContext); for (org.kframework.kil.BuiltinLookup lookup : ruleData.getLookups()) { Variable base = (Variable) this.visitNode(lookup.base()); Term key = (Term) this.visitNode(lookup.key()); if (lookup instanceof org.kframework.kil.SetLookup) { if (lookup.choice()) { lookups = lookups.add(DataStructures.choice(base, termContext), key); } else { lookups = lookups.add(DataStructures.lookup(base, key, termContext), BoolToken.TRUE); } } else { Term value = (Term) this.visitNode(lookup.value()); if (lookup instanceof org.kframework.kil.MapLookup) { if (lookup.choice()) { lookups = lookups.add(DataStructures.choice(base, termContext), key); } lookups = lookups.add(DataStructures.lookup(base, key, termContext), value); } else { // ListLookup lookups = lookups.add(DataStructures.lookup(base, key, termContext), value); } } } // TODO(AndreiS): check !Variable only appears in the RHS Set<Variable> freshConstants = node.getBody() .variables() .stream() .filter(v -> v.isFreshConstant()) .map(v -> (Variable) this.visitNode(v)) .collect(Collectors.toSet()); Set<Variable> freshVariables = node.getBody() .variables() .stream() .filter(v -> v.isFreshVariable()) .map(v -> (Variable) this.visitNode(v)) .collect(Collectors.toSet()); assert leftHandSide.kind() == rightHandSide.kind() || leftHandSide.kind().isComputational() && rightHandSide.kind().isComputational(); concreteCollectionSize = Collections.emptyMap(); java.util.Map<CellLabel, Term> lhsOfReadCell = null; java.util.Map<CellLabel, Term> rhsOfWriteCell = null; if (ruleData.isCompiledForFastRewriting()) { lhsOfReadCell = Maps.newHashMap(); for (java.util.Map.Entry<String, org.kframework.kil.Term> entry : ruleData.getLhsOfReadCell().entrySet()) { lhsOfReadCell.put(CellLabel.of(entry.getKey()), (Term) this.visitNode(entry.getValue())); } rhsOfWriteCell = Maps.newHashMap(); for (java.util.Map.Entry<String, org.kframework.kil.Term> entry : ruleData.getRhsOfWriteCell().entrySet()) { rhsOfWriteCell.put(CellLabel.of(entry.getKey()), (Term) this.visitNode(entry.getValue())); } } java.util.Set<CellLabel> cellsToCopy = null; if (ruleData.getCellsToCopy() != null) { cellsToCopy = Sets.newHashSet(); for (String cellLabelName : ruleData.getCellsToCopy()) { cellsToCopy.add(CellLabel.of(cellLabelName)); } } Rule rule = new Rule( node.getLabel(), leftHandSide, rightHandSide, requires, ensures, freshConstants, freshVariables, lookups, ruleData.isCompiledForFastRewriting(), lhsOfReadCell, rhsOfWriteCell, cellsToCopy, ruleData.getMatchingInstructions(), node, termContext); if (freshRules) { return rule.getFreshRule(termContext); } return rule; } catch (KEMException e) { e.exception.addTraceFrame( "while compiling rule at " + node.getSource() + node.getLocation() + " to backend"); throw e; } }
@Override public ASTNode transform(org.kframework.kil.Rule node) throws TransformerException { assert node.getBody() instanceof org.kframework.kil.Rewrite; org.kframework.kil.Rewrite rewrite = (org.kframework.kil.Rewrite) node.getBody(); Term leftHandSide = (Term) rewrite.getLeft().accept(this); Term rightHandSide = (Term) rewrite.getRight().accept(this); Collection<Term> requires = new ArrayList<Term>(); Collection<Variable> freshVariables = new ArrayList<Variable>(); // TODO: Deal with Ensures if (node.getRequires() != null) { Term term = (Term) node.getRequires().accept(this); if (term instanceof KItem && ((KItem) term).kLabel().toString().equals("'_andBool_")) { for (Term item : ((KItem) term).kList().getItems()) { if (item instanceof KItem && ((KItem) item).kLabel().toString().equals("'fresh(_)")) { freshVariables.add((Variable) ((KItem) item).kList().get(0)); } else { requires.add(item); } } } else { if (term instanceof KItem && ((KItem) term).kLabel().toString().equals("'fresh(_)")) { freshVariables.add((Variable) ((KItem) term).kList().get(0)); } else { requires.add(term); } } } SymbolicConstraint lookups = new SymbolicConstraint(new TermContext(definition)); for (org.kframework.kil.BuiltinLookup lookup : node.getLookups()) { Variable base = (Variable) lookup.base().accept(this); Term key = (Term) lookup.key().accept(this); if (lookup instanceof org.kframework.kil.SetLookup) { lookups.add(new SetLookup(base, key), BoolToken.TRUE); } else { Term value = (Term) lookup.value().accept(this); if (lookup instanceof org.kframework.kil.MapLookup) { lookups.add(new MapLookup(base, key), value); } else { // ListLookup lookups.add(new ListLookup(base, key), value); } } } assert leftHandSide.kind() == rightHandSide.kind() || ((leftHandSide.kind() == Kind.KITEM || leftHandSide.kind() == Kind.K || leftHandSide.kind() == Kind.KLIST) && (rightHandSide.kind() == Kind.KITEM || rightHandSide.kind() == Kind.K || rightHandSide.kind() == Kind.KLIST)); Rule rule = new Rule( leftHandSide, rightHandSide, requires, freshVariables, lookups, node.getAttributes()); return rule.getFreshRule(new TermContext(definition)); }