@@ -0,0 +1,2285 @@
+package wyautl.util;%0A%0Aimport wyautl.core.Automaton;%0Aimport wyautl.core.Schema;%0Aimport wyautl.rw.Activation;%0Aimport wyautl.rw.InferenceRule;%0Aimport wyautl.rw.ReductionRule;%0Aimport wyautl.rw.RewriteRule;%0Aimport wyautl.rw.RewriteState;%0Aimport wyautl.rw.RewriteStep;%0Aimport wyautl.rw.Rewriter;%0A%0Apublic class Rewriters %7B%0A%09%0A%09/**%0A%09 * Fully reduce an automaton in place. This is assuming that the given rules%0A%09 * are confluent, as it makes no effort to avoid infinite rewrite loops.%0A%09 * %0A%09 * @param automaton%0A%09 * @param rules%0A%09 */%0A%09public static Automaton reduce(Automaton automaton, Schema schema, ReductionRule... rules) %7B%0A%09%09Rewriter rewriter = new SingleStepRewriter(automaton,schema,rules);%09%09%09%09%0A%09%09return rewriteAll(rewriter,ReductionRule.class);%0A%09%7D%0A%09%09%0A%09public static Automaton infer(Automaton automaton, Schema schema, InferenceRule%5B%5D inferences,%0A%09%09%09ReductionRule%5B%5D reductions, int maxSteps) %7B%0A%09%09RewriteRule%5B%5D rules = new RewriteRule%5Binferences.length + reductions.length%5D;%0A%09%09System.arraycopy(inferences, 0, rules, 0, inferences.length);%0A%09%09System.arraycopy(reductions, 0, rules, inferences.length, reductions.length);%0A%09%09Rewriter rewriter = new SingleStepRewriter(automaton, schema, rules);%0A%09%09rewriter = new CachingRewriter(rewriter);%0A%09%09automaton = rewriteAll(rewriter, ReductionRule.class);%0A%09%09int r;%0A%09%09while (maxSteps %3E 0 && (r = selectFirstUnvisited(InferenceRule.class, rewriter)) != -1) %7B%0A%09%09%09RewriteStep step = rewriter.apply(r);%0A%09%09%09automaton = rewriteAll(rewriter, ReductionRule.class);%0A%09%09%09maxSteps = maxSteps - 1;%0A%09%09%7D%0A%09%09if(maxSteps == 0) %7B%0A%09%09%09return null;%0A%09%09%7D else %7B%0A%09%09%09return automaton;%0A%09%09%7D%0A%09%7D%0A%09%0A%09private static %3CT extends RewriteRule%3E Automaton rewriteAll(Rewriter rewriter, Class%3CT%3E kind) %7B%09%09%09%09%09%0A%09%09int r;%0A%09%09Automaton automaton = rewriter.state().automaton();%0A%09%09while((r = selectFirstUnvisited(kind,rewriter)) != -1) %7B%0A%09%09%09RewriteStep step = rewriter.apply(r);%0A%09%09%09automaton = step.after().automaton();%0A%09%09%7D%0A%09%09return automaton;%0A%09%7D%0A%09%0A%09private static %3CT extends RewriteRule%3E int selectFirstUnvisited(Class%3CT%3E kind, Rewriter rewriter) %7B%0A%09%09RewriteState state = rewriter.state();%0A%09%09for(int i=0;i!=state.size();++i) %7B%0A%09%09%09if(state.step(i) == null) %7B%0A%09%09%09%09Activation activation = state.activation(i);%0A%09%09%09%09if(kind.isInstance(activation.rule())) %7B%0A%09%09%09%09%09return i;%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D%0A%09%09return -1;%0A%09%7D%0A%7D%0A

Add simple utility functions for rewriting #13