/* * tuProlog - Copyright (C) 2001-2002 aliCE team at deis.unibo.it * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package alice.tuprolog; import java.util.LinkedList; import java.util.List; import java.util.NoSuchElementException; /** * * @author Alex Benini */ public class EngineManager { private Prolog mediator; private TheoryManager theoryManager; private PrimitiveManager primitiveManager; private LibraryManager libraryManager; /* Current environment */ Engine env; /* Last environment used */ private Engine last_env; /* Stack environments of nested solving */ private LinkedList<Engine> stackEnv = new LinkedList<Engine>(); private SolveInfo sinfo; /** * Configure this Manager */ void initialize(Prolog vm) { mediator = vm; theoryManager = vm.getTheoryManager(); primitiveManager = vm.getPrimitiveManager(); libraryManager = vm.getLibraryManager(); } void spy(String action, Engine env) { mediator.spy(action,env); } void warn(String message) { mediator.warn(message); } /** * Solves a query * * @param g the term representing the goal to be demonstrated * @return the result of the demonstration * @see SolveInfo */ public SolveInfo solve(Term query) { try { query.resolveTerm(); libraryManager.onSolveBegin(query); primitiveManager.identifyPredicate(query); // theoryManager.transBegin(); freeze(); env = new Engine(this, query); sinfo = env.solve(); defreeze(); if (!sinfo.hasOpenAlternatives()) solveEnd(); return sinfo; } catch (Exception ex) { ex.printStackTrace(); return new SolveInfo(query); } } /** * Gets next solution * * @return the result of the demonstration * @throws NoMoreSolutionException if no more solutions are present * @see SolveInfo **/ public synchronized SolveInfo solveNext() throws NoMoreSolutionException { if (hasOpenAlternatives()) { refreeze(); sinfo = env.solveNext(); defreeze(); if (!sinfo.hasOpenAlternatives()) solveEnd(); return sinfo; } else throw new NoMoreSolutionException(); } /** * Halts current solve computation */ public void solveHalt() { env.mustStop(); } /** * Accepts current solution */ public void solveEnd() { // theoryManager.transEnd(sinfo.isSuccess()); // theoryManager.optimize(); libraryManager.onSolveEnd(); } private void freeze() { if (env == null) return; try { if (stackEnv.getLast() == env) return; } catch(NoSuchElementException e) {} stackEnv.addLast(env); } private void refreeze() { freeze(); env = last_env; } private void defreeze() { last_env = env; if (stackEnv.isEmpty()) return; env = stackEnv.removeLast(); } /* * Utility functions for Finite State Machine */ List<ClauseInfo> find(Term t) { return theoryManager.find(t); } void identify(Term t) { primitiveManager.identifyPredicate(t); } // void saveLastTheoryStatus() { // theoryManager.transFreeze(); // } void pushSubGoal(SubGoalTree goals) { env.currentContext.goalsToEval.pushSubGoal(goals); } void cut() { env.choicePointSelector.cut(env.currentContext.choicePointAfterCut); } ExecutionContext getCurrentContext() { return (env == null) ? null : env.currentContext; } /** * Asks for the presence of open alternatives to be explored * in current demonstration process. * * @return true if open alternatives are present */ boolean hasOpenAlternatives() { if (sinfo == null) return false; return sinfo.hasOpenAlternatives(); } /** * Checks if the demonstration process was stopped by an halt command. * * @return true if the demonstration was stopped */ boolean isHalted() { if (sinfo == null) return false; return sinfo.isHalted(); } }