package tarau.jinni; import java.util.Vector; import java.util.Enumeration; import java.util.Stack; /** Basic toplevel Prolog Engine. Loads and executes Prolog programs and spawns threads executing on new Prolog Engine objects as well as networking threads and synchronized local and remote Linda transactions */ public class Prog extends Source implements Runnable { // CONSTRUCTORS /** Creates a Prog starting execution with argument "goal" */ public Prog(Clause goal,Prog parent) { super(parent); this.parent=parent; goal=goal.ccopy(); this.trail=new Trail(); this.orStack=new Stack(); if(null!=goal) orStack.push(new Unfolder(goal,this)); if(null==Init.default_db) IO.assertion("null Init.bboard"); if(null==Init.builtinDict) IO.assertion("null Init.builtinDict"); } // INSTANCE FIELDS private Trail trail; private Stack orStack; private Prog parent; public final Trail getTrail() { return trail; } public final Prog getParent() { return parent; } // CLASS FIELDS public static int tracing=1; // INSTANCE METHODS public Term getElement() { if(null==orStack) return null; Clause answer=null; while(!orStack.isEmpty()) { Unfolder I=(Unfolder)orStack.pop(); answer=I.getAnswer(); if(null!=answer) break; Clause goal=(Clause)I.getElement(); if(null!=goal) { if( I.notLastClause() ) orStack.push(I); else I.stop(); if(null==answer)orStack.push(new Unfolder(goal,this)); } } Term head; if(null==answer) { head=null; stop(); } else head=answer.getHead(); return head; } public void stop() { if(null!=trail) { trail.unwind(0); trail=null; } orStack=null; } /** Computes a copy of the first solution X of Goal G. */ static public Term firstSolution(Term X, Term G) { Prog p=new_engine(X,G); Term A=ask_engine(p); if(A!=null) { A=new Fun("the",A); p.stop(); } else A=Const.aNo; return A; } static public Prog new_engine(Term X,Term G) { Clause C=new Clause(X,G); Prog p=new Prog(C,null); return p; } static public Term ask_engine(Prog p) { return p.getElement(); } public void run() { for(;;) { Term Answer=getElement(); if(null==Answer) break; } } }