package tarau.jinni; /** Lazy List: produces Cons-like sequences, based on a Source. Saving a lazy list to the database does not make too much sense as it will be discarded when backtracking over its creation point. Note that a Lazy List has its own trail, and is only discarded when backtracking over its creation point. */ public class LazyList extends Cons { public LazyList(Term head,Source source,Trail trail) { super(head,new Var()); this.source=source; this.bound=false; this.trail=trail; } private Source source; private boolean bound; private Trail trail; /** * advances the Lazy List, pulling out elements of the Source * as needed */ private final void advance() { if(bound) return; Term nextHead=source.getElement(); Const thisTail; if(null==nextHead) { thisTail=getNull(); } else { thisTail=new LazyList(nextHead.copy(),source,trail); } ((Var)getArg(1)).unify(thisTail,trail); bound=true; } /** * Advances the tail of a lazy list. * Note that they inherit getHead() from Cons. */ public Term getTail() { advance(); return super.getTail(); } /** * this permissive definition for bind_to allows a Lazy * List to Unify with any 2 arg constructor chain */ boolean bind_to(Term that,Trail trail) { return that instanceof Fun && 2==that.getArity(); } public Const getNull() { return Const.aNil; } protected void undo() { //if(source.getPersistent()) return; trail.unwind(0); source.stop(); source=null; } }