@Override public CyclicStackItem<P> enter(Pda<S, P> pda, S state, CyclicStackItem<P> previous) { P item; if ((item = pda.getPush(state)) != null) return previous.push(item); if ((item = pda.getPop(state)) != null) return previous.pop(item); if (previous == null) return new CyclicStackItem<P>(); return previous; }
protected <S, P> TraceItem<S, P> traceToWithPruningStack( Pda<S, P> pda, Iterable<S> starts, Iterator<P> stack, Predicate<S> matches, Predicate<S> canPass) { StackItem<P> stackItem = createStack(stack); List<TraceItem<S, P>> current = Lists.newArrayList(); Set<S> visited = Sets.newLinkedHashSet(starts); TraceItem<S, P> result = null; for (S start : starts) { TraceItem<S, P> item = new TraceItem<S, P>(null, start, stackItem); // if (matches.apply(start)) // result = item; current.add(item); } int counter = stackItem.size() * -1; while (current.size() > 0 && counter < visited.size()) { List<TraceItem<S, P>> newCurrent = Lists.newArrayList(); for (TraceItem<S, P> trace : current) for (S follower : pda.getFollowers(trace.state)) { if (matches.apply(follower)) { TraceItem<S, P> found = new TraceItem<S, P>(trace, follower, trace.stackitem); if (found.stackitem == null) return found; if (result == null || result.stackitem.size() > found.stackitem.size()) { result = found; counter = result.stackitem.size() * -1; } else if (result.stackitem.size() == found.stackitem.size() && result.size() > found.size()) { result = found; counter = result.stackitem.size() * -1; } } if (canPass.apply(follower)) { P push = pda.getPush(follower); visited.add(follower); if (push != null) { StackItem<P> pushed = trace.stackitem.push(push); newCurrent.add(new TraceItem<S, P>(trace, follower, pushed)); } else { P pop = pda.getPop(follower); if (pop != null) { if (trace.stackitem != null && pop == trace.stackitem.peek()) { StackItem<P> popped = trace.stackitem.pop(); newCurrent.add(new TraceItem<S, P>(trace, follower, popped)); } } else newCurrent.add(new TraceItem<S, P>(trace, follower, trace.stackitem)); } } } current = newCurrent; counter++; } return result; }
protected <S, P, T, D extends Pda<S, P>> S clone( S state, Pda<S, P> src, D target, Function<S, T> tokens, PdaFactory<D, S, P, T> fact, Identity<S> identity) { if (state == src.getStart()) return target.getStart(); if (state == src.getStop()) return target.getStop(); P push = src.getPush(state); if (push != null) return identity.get(fact.createPush(target, tokens.apply(state))); P pop = src.getPop(state); if (pop != null) return identity.get(fact.createPop(target, tokens.apply(state))); return identity.get(fact.createState(target, tokens.apply(state))); }
protected <S, R, P> TraversalItem<S, R> newItem( Pda<S, P> pda, MappedComparator<S, Integer> comp, Map<S, Integer> distances, S next, R item) { List<S> followers = Lists.newArrayList(); for (S f : pda.getFollowers(next)) if (distances.containsKey(f)) followers.add(f); Collections.sort(followers, comp); return new TraversalItem<S, R>(next, followers, item); }
protected <S, P> void filterUnambiguousPaths( final Pda<S, P> pda, S state, Map<S, Integer> dist, Map<S, List<S>> followers) { if (followers.containsKey(state)) return; List<S> f = Lists.newArrayList(pda.getFollowers(state)); if (f.size() <= 1) { followers.put(state, f); if (f.size() == 1) filterUnambiguousPaths(pda, f.get(0), dist, followers); return; } int closestDist = dist.get(f.get(0)); S closest = f.get(0); for (int i = 1; i < f.size(); i++) { int d = dist.get(f.get(i)); if (d < closestDist) { closestDist = d; closest = f.get(i); } } IsPop<S, P> isPop = new IsPop<S, P>(pda); Set<S> closestPops = nfaUtil.findFirst(pda, Collections.singleton(closest), isPop); Iterator<S> it = f.iterator(); while (it.hasNext()) { S next = it.next(); if (next != closest) { Set<S> nextPops = nfaUtil.findFirst(pda, Collections.singleton(next), isPop); if (!closestPops.equals(nextPops)) it.remove(); } } followers.put(state, f); for (S follower : f) filterUnambiguousPaths(pda, follower, dist, followers); }
public <S, P, D extends Pda<S, P>> Map<P, Pair<S, S>> collectPopsAndPushs(Pda<S, P> pda) { Map<P, Pair<S, S>> result = Maps.newLinkedHashMap(); for (S s : nfaUtil.collect(pda)) { P push = pda.getPush(s); if (push != null) { Pair<S, S> o = result.get(push); Pair<S, S> n = Tuples.create(s, o == null ? null : o.getSecond()); result.put(push, n); } P pop = pda.getPop(s); if (pop != null) { Pair<S, S> o = result.get(pop); Pair<S, S> n = Tuples.create(o == null ? null : o.getFirst(), s); result.put(pop, n); } } return result; }
public <S, P, R> List<R> collectReachable(Pda<S, P> pda, final Function<S, R> function) { final List<R> result = Lists.newArrayList(); Iterator<P> stack = Collections.<P>emptyList().iterator(); Predicate<S> matches = Predicates.<S>alwaysFalse(); Predicate<S> canPass = new Predicate<S>() { @Override public boolean apply(S input) { R r = function.apply(input); if (r != null) { result.add(r); return false; } else { return true; } } }; trace(pda, Collections.singleton(pda.getStart()), stack, matches, canPass); return result; }
@Override public boolean apply(S input) { return pda.getPop(input) != null; }
public <S, P> List<S> shortestStackpruningPathTo(Pda<S, P> pda, Iterator<P> stack, S matches) { return shortestStackpruningPathTo( pda, pda.getStart(), stack, Predicates.equalTo(matches), Predicates.<S>alwaysTrue()); }
public <S, P> List<S> shortestPathToFinalState(Pda<S, P> pda, Iterator<P> stack) { return shortestPathTo( pda, pda.getStart(), stack, Predicates.equalTo(pda.getStop()), Predicates.<S>alwaysTrue()); }
public <S, P> List<S> shortestPathTo( Pda<S, P> pda, Iterator<P> stack, Predicate<S> matches, Predicate<S> canPass) { return shortestPathTo(pda, pda.getStart(), stack, matches, canPass); }
public <S, P> List<S> shortestPathTo(Pda<S, P> pda, Iterator<P> stack, Predicate<S> matches) { return shortestPathTo(pda, pda.getStart(), stack, matches, Predicates.<S>alwaysTrue()); }
public <S, P> Nfa<S> filterUnambiguousPaths(Pda<S, P> pda) { Map<S, List<S>> followers = Maps.newLinkedHashMap(); Map<S, Integer> distanceMap = nfaUtil.distanceToFinalStateMap(pda); filterUnambiguousPaths(pda, pda.getStart(), distanceMap, followers); return new NfaUtil.NFAImpl<S>(pda.getStart(), pda.getStop(), followers); }
public <S, P, R, D extends Pda<S, P>> D filterEdges( Pda<S, P> pda, Traverser<? super Pda<S, P>, S, R> traverser, PdaFactory<D, S, P, S> factory) { HashStack<TraversalItem<S, R>> trace = new HashStack<TraversalItem<S, R>>(); R previous = traverser.enter(pda, pda.getStart(), null); if (previous == null) return factory == null ? null : factory.create(pda.getStart(), pda.getStop()); Map<S, Integer> distances = new NfaUtil().distanceToFinalStateMap(pda); MappedComparator<S, Integer> distanceComp = new MappedComparator<S, Integer>(distances); trace.push(newItem(pda, distanceComp, distances, pda.getStart(), previous)); Multimap<S, S> edges = LinkedHashMultimap.create(); HashSet<S> states = Sets.newLinkedHashSet(); HashSet<Pair<S, R>> success = Sets.newLinkedHashSet(); states.add(pda.getStart()); states.add(pda.getStop()); ROOT: while (!trace.isEmpty()) { TraversalItem<S, R> current = trace.peek(); while (current.followers.hasNext()) { S next = current.followers.next(); R item = traverser.enter(pda, next, current.data); if (item != null) { if ((next == pda.getStop() && traverser.isSolution(item)) || success.contains(Tuples.create(next, item))) { S s = null; for (TraversalItem<S, R> i : trace) { if (s != null) edges.put(s, i.state); states.add(i.state); success.add(Tuples.create(i.state, i.data)); s = i.state; } edges.put(s, next); } else { if (trace.push(newItem(pda, distanceComp, distances, next, item))) continue ROOT; } } } trace.pop(); } if (factory == null) return null; D result = factory.create(pda.getStart(), pda.getStop()); Map<S, S> old2new = Maps.newLinkedHashMap(); old2new.put(pda.getStart(), result.getStart()); old2new.put(pda.getStop(), result.getStop()); for (S old : states) { if (old == pda.getStart() || old == pda.getStop()) continue; else if (pda.getPop(old) != null) old2new.put(old, factory.createPop(result, old)); else if (pda.getPush(old) != null) old2new.put(old, factory.createPush(result, old)); else old2new.put(old, factory.createState(result, old)); } for (S old : states) { List<S> followers = Lists.newArrayList(); for (S f : edges.get(old)) followers.add(old2new.get(f)); factory.setFollowers(result, old2new.get(old), followers); } return result; }
public <S, P, T, D extends Pda<S, P>> D expand( Pda<S, P> pda, Function<S, Pda<S, P>> expand, Function<S, T> tokens, PdaFactory<D, S, P, T> fact) { D result = fact.create(tokens.apply(pda.getStart()), tokens.apply(pda.getStop())); Identity<S> identity = new Identity<S>(); Map<S, S> idstates = Maps.newIdentityHashMap(); Multimap<S, S> followers = LinkedHashMultimap.create(); for (S s_old : nfaUtil.collect(pda)) { S s_new = idstates.get(s_old); if (s_new == null) { Pda<S, P> sub = expand.apply(s_old); if (sub != null) { S s_start = identity.get(fact.createPush(result, tokens.apply(s_old))); S s_stop = identity.get(fact.createPop(result, tokens.apply(s_old))); idstates.put(s_old, s_start); idstates.put(sub.getStart(), s_start); idstates.put(sub.getStop(), s_stop); followers.putAll(s_start, sub.getFollowers(sub.getStart())); followers.putAll(s_stop, pda.getFollowers(s_old)); for (S f_old : nfaUtil.collect(sub)) if (f_old != sub.getStart() && f_old != sub.getStop()) { S f_new = idstates.get(f_old); if (f_new == null) { idstates.put(f_old, f_new = clone(f_old, sub, result, tokens, fact, identity)); followers.putAll(f_new, pda.getFollowers(f_old)); } } } else { idstates.put(s_old, s_new = clone(s_old, pda, result, tokens, fact, identity)); followers.putAll(s_new, pda.getFollowers(s_old)); } } } for (Map.Entry<S, Collection<S>> entry : followers.asMap().entrySet()) { Set<S> f = Sets.newLinkedHashSet(); for (S s : entry.getValue()) f.add(idstates.get(s)); fact.setFollowers(result, entry.getKey(), f); } return result; }