/** * When a cell fragment variable occurs as an argument to the appropriate cell fragment sort * predict, we specialize the expansion by splitting it into a conjunction of individual sort * predicate tests on the variables the cell fragment variable splits into, rather than just using * the generic replacement term. This is a very special case of statically simplifying predicate * applications. */ @Test public void testPredicateExpansion() { Rule term = new Rule( KRewrite( cell( "<t>", cell("<env>"), KVariable("X"), KVariable("Y", Att().add(Attribute.SORT_KEY, "OptCell"))), KVariable("X")), app("isThreadCellFragment", KVariable("X")), BooleanUtils.TRUE, Att()); K expectedBody = KRewrite( cell( "<t>", KVariable("X"), cell("<env>"), KVariable("Y", Att().add(Attribute.SORT_KEY, "OptCell"))), cell("<t>-fragment", KVariable("X"), app("noEnvCell"), app(".OptCell"))); Rule expected = new Rule( expectedBody, BooleanUtils.and(BooleanUtils.TRUE, app("isKCell", KVariable("X"))), BooleanUtils.TRUE, Att()); KExceptionManager kem = new KExceptionManager(new GlobalOptions()); Assert.assertEquals(expected, new SortCells(cfgInfo, labelInfo).sortCells(term)); Assert.assertEquals(0, kem.getExceptions().size()); }
K addSideCondition(K requires) { Optional<KApply> sideCondition = state.stream().reduce(BooleanUtils::and); if (!sideCondition.isPresent()) { return requires; } else if (requires.equals(BooleanUtils.TRUE) && sideCondition.isPresent()) { return sideCondition.get(); } else { return BooleanUtils.and(requires, sideCondition.get()); } }
/** * Adds lookups to the side condition in sorted order in which they must be performed. Lookups are * sorted based on dependencies between each other, but non-lookup operations appear in no * particular order with respect to the lookups. * * @param requires Previous side condition, if any. * @return Side condition generated by this compiler pass + previous side condition. */ K addSideCondition(K requires) { Optional<KApply> sideCondition = getSortedLookups().reduce(BooleanUtils::and); if (!sideCondition.isPresent()) { return requires; } else if (requires.equals(BooleanUtils.TRUE) && sideCondition.isPresent()) { return sideCondition.get(); } else { // we order lookups before the requires clause so that the fresh constant // matching side condition remains last. This is necessary in order to // ensure that fresh constants in rule RHSs are consecutive return BooleanUtils.and(sideCondition.get(), requires); } }