package org.archstudio.prolog.archstudio.ops; import java.util.Iterator; import java.util.List; import java.util.Map; import org.archstudio.prolog.engine.PrologUtils; import org.archstudio.prolog.engine.ProofContext; import org.archstudio.prolog.engine.UnificationEngine; import org.archstudio.prolog.op.Executable; import org.archstudio.prolog.term.ComplexTerm; import org.archstudio.prolog.term.Term; import org.archstudio.prolog.term.VariableTerm; import com.google.common.collect.AbstractIterator; public class Precedes extends ComplexTerm implements Executable { public Precedes(String name, List<? extends Term> terms) { super(name, 2, terms); } @Override public Iterable<Map<VariableTerm, Term>> execute(final ProofContext proofContext, final UnificationEngine unificationEngine, final Term source, final Map<VariableTerm, Term> variables) { return new Iterable<Map<VariableTerm, Term>>() { @Override public Iterator<Map<VariableTerm, Term>> iterator() { return new AbstractIterator<Map<VariableTerm, Term>>() { Iterator<Map<VariableTerm, Term>> term0Variables = null; Integer term0Index = Integer.MAX_VALUE; Iterator<Map<VariableTerm, Term>> term1Variables = null; @Override protected Map<VariableTerm, Term> computeNext() { while (true) { if (term0Variables == null) { ComplexTerm t = PrologUtils.resolveComplexTerm(proofContext, getTerm(0), variables); term0Variables = t.execute(proofContext, unificationEngine, t, variables).iterator(); } if ((term1Variables == null || !term1Variables.hasNext()) && term0Variables.hasNext()) { Map<VariableTerm, Term> variables = term0Variables.next(); term0Index = getIndex(getTerm(0), variables); if (term0Index == null) { continue; } ComplexTerm t = PrologUtils.resolveComplexTerm(proofContext, getTerm(1), variables); term1Variables = t.execute(proofContext, unificationEngine, t, variables).iterator(); } if (term1Variables != null && term1Variables.hasNext()) { Map<VariableTerm, Term> variables = term1Variables.next(); Integer term1Index = getIndex(getTerm(1), variables); if (term1Index == null) { continue; } if (term0Index < term1Index) { return variables; } continue; } return endOfData(); } } private Integer getIndex(Term term, Map<VariableTerm, Term> variables) { return proofContext.getIndex(PrologUtils.resolveComplexTerm(proofContext, term, variables)); } }; } }; } }