private Stream<? extends Sentence> genKore(Sort sort) { if (sort.equals(Sorts.K())) { return Stream.of(Rule(KRewrite(KApply(KLabel("is" + sort.toString()), KVariable("K")), BooleanUtils.TRUE), BooleanUtils.TRUE, BooleanUtils.TRUE)); } else { List<Sentence> res = new ArrayList<>(); res.add(Rule(KRewrite(KApply(KLabel("is" + sort.toString()), KVariable(sort.name(), Att().add(Sort.class, sort))), BooleanUtils.TRUE), BooleanUtils.TRUE, BooleanUtils.TRUE)); res.add(Rule(KRewrite(KApply(KLabel("is" + sort.toString()), KVariable("K")), BooleanUtils.FALSE), BooleanUtils.TRUE, BooleanUtils.TRUE, Att().add("owise"))); return res.stream(); } }
@Test public void testSimpleClosure() { K term = cell("<k>", false, true, KApply(KLabel("_+_"), KVariable("I"), KVariable("J"))); K expected = ccell("<k>", KSequence(KApply(KLabel("_+_"), KVariable("I"), KVariable("J")), KVariable("DotVar0"))); Assert.assertEquals(expected, new CloseCells(cfgInfo, sortInfo, labelInfo).close(term)); }
private K addFreshCell(K body) { if (freshVars.size() == 0) { return body; } KApply cellTerm = IncompleteCellUtils.make(KLabels.GENERATED_COUNTER_CELL, false, KRewrite(FRESH, KApply(KLabel("_+Int_"), FRESH, KToken(Integer.toString(freshVars.size()), Sorts.Int()))), false); return KApply(KLabels.CELLS, body, cellTerm); }
Production prod = Production(KLabel("is" + sort.toString()), Sorts.Bool(), Seq(Terminal("is" + sort.toString()), Terminal("("), NonTerminal(Sorts.K()), Terminal(")")), Att().add(Attribute.FUNCTION_KEY).add(Attribute.PREDICATE_KEY, Sort.class, sort)); res.add(prod); java.util.Set<Sort> nonProtectingSubsorts = new HashSet<>(); List<NonTerminal> nts = stream(p.items()).filter(pi -> pi instanceof NonTerminal).map(pi -> (NonTerminal) pi).collect(Collectors.toList()); for (NonTerminal nt : nts) { KVariable v = KVariable("K" + i++, Att().add(Sort.class, nt.sort())); klist.add(v); if (!mutable(mod.sortAttributesFor()).getOrDefault(sort, Att()).contains("flatPredicate")) { side.add(KApply(KLabel("is" + nt.sort().toString()), v)); requires = sideCondition.get(); Rule r = Rule(KRewrite(KApply(KLabel("is" + sort.toString()), KApply(p.klabel().get(), KList(klist))), BooleanUtils.TRUE), requires, BooleanUtils.TRUE); res.add(r); res.add(Rule(KRewrite(KApply(KLabel("is" + sort.toString()), KApply(KLabel("#KToken"), KToken(s.toString(), Sorts.KString()), KVariable("_"))), BooleanUtils.TRUE), BooleanUtils.TRUE, BooleanUtils.TRUE)); res.add(Rule(KRewrite(KApply(KLabel("is" + sort.toString()), KVariable("K")), BooleanUtils.FALSE), BooleanUtils.TRUE, BooleanUtils.TRUE, Att().add("owise"))); return res.stream();
children.add(addInjections(child, expectedSort)); return KApply(kapp.klabel(), KList(children), att); } else if (term instanceof KRewrite) { KRewrite rew = (KRewrite) term; return KRewrite(addInjections(rew.left(), actualSort), addInjections(rew.right(), actualSort), att); } else if (term instanceof KVariable) { return KVariable(((KVariable) term).name(), att); } else if (term instanceof KToken) { return KToken(((KToken) term).s(), ((KToken) term).sort(), att); } else if (term instanceof InjectedKLabel) { return InjectedKLabel(((InjectedKLabel) term).klabel(), att); } else if (term instanceof KSequence) { KSequence kseq = (KSequence)term; return KSequence(children, att); } else if (term instanceof KAs) { KAs kas = (KAs)term; return KAs(addInjections(kas.pattern(), actualSort), kas.alias(), att); } else { throw KEMException.internalError("Invalid category of k found.", term);
private KApply cell(String s, Map<String, String> att, K body) { K cellAtt = att.entrySet().stream() .map(e -> KApply(KLabel("#cellProperty"), KToken(e.getKey(), Sort("#CellName")), KToken(StringUtil.enquoteKString(e.getValue()), Sort("KString")))) .reduce(KApply(KLabel("#cellPropertyListTerminator")), (k1, k2) -> KApply(KLabel("#cellPropertyList"), k2, k1)); return KApply(KLabel("#configCell"), KToken(s, Sort("#CellName")), cellAtt, body, KToken(s, Sort("#CellName"))); } }
@Test public void testRewriteWithCellVariable() { K term = cell("<T>", KRewrite(KVariable("KCell", Att().add(Sort.class, Sort("KCell"))), cell("<k>", intToToken(1)))); K expected = cell("<T>", cell("<ts>", cell("<t>", KRewrite(KVariable("KCell", Att().add(Sort.class, Sort("KCell"))), cell("<k>", intToToken(1)))))); Assert.assertEquals(expected, pass.concretizeCell(term)); }
@Test public void testFragmentBag() { K term = cell("<top>", KVariable("F"),cell("<t>", KRewrite(KVariable("Rest"),KSequence(KVariable("F"),KVariable("Rest"))))); K expected = cell("<top>", app("_ThreadCellBag_", KVariable("_0"), cell("<t>", KRewrite(KVariable("Rest"), KSequence(app("<top>-fragment",KVariable("_0"),KVariable("_1")),KVariable("Rest"))))), KVariable("_1")); KExceptionManager kem = new KExceptionManager(new GlobalOptions()); Assert.assertEquals(expected, new SortCells(bagCfgInfo, bagLabelInfo).sortCells(term)); Assert.assertEquals(0, kem.getExceptions().size()); }
} else if (expectedSort.equals(Sorts.K())) { if (actualSort.equals(Sorts.KItem())) { return KSequence(visitChildren(term, Sorts.KItem(), actualSort)); } else { return KSequence(KApply(KLabel("inj", actualSort, Sorts.KItem()), KList(visitChildren(term, Sorts.KItem(), actualSort)), Att.empty().add(Sort.class, Sorts.KItem()))); String hookAtt = mod.sortAttributesFor().get(expectedSort).getOrElse(() -> Att()).getOptional("hook").orElse(""); if (hookAtt.equals("MAP.Map") || hookAtt.equals("SET.Set") || hookAtt.equals("LIST.List")) { for (KLabel collectionLabel : collectionFor.keySet()) { Optional<String> wrapElement = mod.attributesFor().apply(collectionLabel).getOptional("wrapElement"); if (wrapElement.isPresent()) { KLabel wrappedLabel = KLabel(wrapElement.get()); KLabel elementLabel = KLabel(mod.attributesFor().apply(collectionLabel).get("element")); KApply k = (KApply)term; if (k.klabel().equals(wrappedLabel)) { if (collectionIsMap(collectionLabel)) { return KApply(elementLabel, KList(k.klist().items().get(0), visitChildren(k, expectedSort, actualSort)), Att.empty().add(Sort.class, expectedSort)); } else { return KApply(elementLabel, KList(visitChildren(k, expectedSort, actualSort)), Att.empty().add(Sort.class, expectedSort)); return KApply(KLabel("inj", actualSort, expectedSort), KList(visitChildren(term, expectedSort, actualSort)), Att.empty().add(Sort.class, expectedSort));
K concretize(K term) { if (term instanceof KApply) { KApply app = (KApply) term; KApply newTerm = KApply(app.klabel(), KList(app.klist().stream() .map(this::concretize).collect(Collectors.toList()))); if (cfg.isParentCell(newTerm.klabel())) { return concretizeCell(newTerm); } else { return newTerm; } } else if (term instanceof KRewrite) { KRewrite rew = (KRewrite) term; return KRewrite(concretize(rew.left()), concretize(rew.right())); } else if (term instanceof KSequence) { return KSequence(((KSequence) term).stream() .map(this::concretize).collect(Collectors.toList())); } else { return term; } }
list = klist(); jj_consume_token(RPAREN); {if (true) return KApply(label, list);} break; case KLABELLABEL: label = klabel(); jj_consume_token(RPAREN); {if (true) return InjectedKLabel(label);} break; case TOKENLABEL: sort = StringUtil.unquoteCString(token.image); jj_consume_token(RPAREN); {if (true) return KToken(value, Sort(sort));} break; case KVARIABLE: jj_consume_token(KVARIABLE); {if (true) return KVariable(token.image);} break; default:
@Test public void testCloseList() { K term = KApply(KLabels.CELLS, cell("<list>", true, false, intToToken(1)), cell("<list>", false, true, intToToken(2)), cell("<list>", true, true, intToToken(3))); K expected = KApply(KLabels.CELLS, ccell("<list>", KApply(KLabel("_List_"), KVariable("DotVar0"), intToToken(1))), ccell("<list>", KApply(KLabel("_List_"), intToToken(2), KVariable("DotVar1"))), ccell("<list>", KApply(KLabel("_List_"), KVariable("DotVar2"), KApply(KLabel("_List_"), intToToken(3), KVariable("DotVar3"))))); Assert.assertEquals(expected, new CloseCells(cfgInfo, sortInfo, labelInfo).close(term)); }
@Test public void testCloseCellTerm() { K term = KRewrite(cells(), cells(cell("<thread>", true, false, cell("<k>", intToToken(1))), cell("<thread>", false, true, cell("<k>", intToToken(2))), cell("<thread>", true, true, cell("<env>", intToToken(2))))); K expected = KRewrite(cells(), cells(ccell("<thread>", ccell("<k>", intToToken(1)), ccell("<env>", KApply(KLabel(".Map")))), ccell("<thread>", ccell("<k>", intToToken(2)), ccell("<env>", KApply(KLabel(".Map")))), ccell("<thread>", ccell("<env>", intToToken(2)), ccell("<k>", stringToToken("defaultK"))))); Assert.assertEquals(expected, new CloseCells(cfgInfo, sortInfo, labelInfo).close(term)); }
private Rule getExitCodeRule(Definition parsedDefinition) { Module mainMod = parsedDefinition.mainModule(); Set<Production> exitProds = stream(mainMod.productions()).filter(p -> p.att().contains("exit")).collect(Collectors.toSet()); if (exitProds.size() == 0) { return null; } else if (exitProds.size() > 1) { throw KEMException.compilerError("Found more than one or zero productions with 'exit' attribute. Exactly one production, a cell, must have this attribute, designating the exit code of krun. Found:\n" + exitProds); } Production exitProd = exitProds.iterator().next(); return Rule(IncompleteCellUtils.make(exitProd.klabel().get(), false, KApply(KLabel("#SemanticCastToInt"), KVariable("_")), false), BooleanUtils.TRUE, BooleanUtils.TRUE); }
private K addSideCondition(K requires) { Optional<KApply> sideCondition = freshVars.stream().map(k -> { Optional<Sort> s = k.att().getOptional(Sort.class); if (!s.isPresent()) { throw KEMException.compilerError("Fresh constant used without a declared sort.", k); } return KApply(KLabel("#match"), k, KApply(KLabel("#fresh"), KToken(StringUtil.enquoteKString(s.get().toString()), Sorts.String()))); }).reduce(BooleanUtils::and); if (!sideCondition.isPresent()) { return requires; } else if (requires.equals(BooleanUtils.TRUE) && sideCondition.isPresent()) { return sideCondition.get(); } else { // we order the lookup after the requires clause so that the fresh constant // matching side condition occurs last. This is necessary in order to // ensure that fresh constants in rule RHSs are consecutive return BooleanUtils.and(requires, sideCondition.get()); } }
@Override public K apply(KApply k0) { if (hasCells(k0)) { ArrayList<K> klist0 = new ArrayList<K>(Collections.nCopies(k0.klist().size(), null)); for (int idx = 0; idx < k0.klist().size(); idx++) { K item0 = k0.klist().items().get(idx); klist0.set(idx, item0); if (item0 instanceof KApply) { KApply k = (KApply) item0; if (k.klabel().name().equals("#cells")) { if (cellFragmentVarsCell.contains(k)) { Sort cellFragmentSort = nthArgSort(k0.klabel(), idx); if (cellFragmentSort == null) { throw new IllegalArgumentException("Not found " + idx + "th argument sort of " + k0.klabel()); } if (cellFragmentSort.name().endsWith("Fragment")) { Sort cellSort = Sort(cellFragmentSort.name().substring(0,cellFragmentSort.name().indexOf("Fragment"))); KLabel cellLabel = cfg.cfg.getCellLabel(cellSort); klist0.set(idx, KApply(cellLabel, KList(item0), Att().add("dummy_cell"))); } } } } } return KApply(k0.klabel(), KList(klist0), k0.att()); } return super.apply(k0); } @Override
private Rule funRule(KLabel fun, K k, Att att) { K resolved = transform(k); K withAnonVars = new ResolveAnonVar().resolveK(resolved); List<K> klist = new ArrayList<>(); klist.add(RewriteToTop.toLeft(withAnonVars)); klist.addAll(closure(k)); return Rule(KRewrite(KApply(fun, KList(klist)), RewriteToTop.toRight(withAnonVars)), BooleanUtils.TRUE, BooleanUtils.TRUE, att); }