Beispiel #1
0
 @Override
 public void visit(Rewrite node) {
   node.getLeft().accept(this);
   current = right;
   node.getRight().accept(this);
   current = left;
 }
Beispiel #2
0
 @Override
 public Void visit(Rewrite rew, Void _) {
     // builder.append('(');
     visitNodeOrKList(rew.getLeft());
     builder.append(" => ");
     visitNodeOrKList(rew.getRight());
     // builder.append(')');
     return null;
 }
Beispiel #3
0
  @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));
  }