/* File: flranswer.P ** ** Author(s): Guizhen Yang ** Michael Kifer ** ** Contact: flora-users@lists.sourceforge.net ** ** Copyright (C) The Research Foundation of SUNY, 1999-2001 ** ** FLORA-2 is free software; you can redistribute it and/or modify it under the ** terms of the GNU Library General Public License as published by the Free ** Software Foundation; either version 2 of the License, or (at your option) ** any later version. ** ** FLORA-2 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 Library General Public License for ** more details. ** ** You should have received a copy of the GNU Library General Public License ** along with FLORA-2; if not, write to the Free Software Foundation, ** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** $Id: flranswer.P,v 1.19 2003/06/18 07:01:21 kifer Exp $ ** */ :- compiler_options([xpp_on]). #include "char_defs.h" #include "flag_defs_xsb.h" #include "standard.h" #include "flora_terms.flh" :- import cputime/1 from standard. :- import windows_os/0 from xsb_configuration. :- import length/2 from basics. :- import stat_flag/2 from machine. :- import shell/5 from shell. :- import flora_stdfdbk_string/2, flora_stdfdbk_string/1, flora_stdfdbk_nl/0, flora_stdfdbk_line/1 from flrprint. :- import flora_commit_storage/0, flora_reclaim_storage_space/0 from flrutils. :- import flora_display_feedback/1 from flrdisplay. :- dynamic flora_switch(_). /********************************************************************/ fllibshellans(Gs,NVs) :- flora_switch(all), !, flora_print_all(Gs,NVs). fllibshellans(Gs,NVs) :- flora_print_one(Gs,NVs). /********************************************************************/ fllibprogramans(Gs,NVs) :- flora_print_all(Gs,NVs). /* The business of getting just one answer from a program query * needs to be rethought. */ /* flora_switch(all), !, flora_print_all(Gs,NVs). fllibprogramans(Gs,NVs) :- flora_print_one(Gs,NVs). */ /******************************************************************** NVs is a list of output variables Gs is a list of goals to evaluate ********************************************************************/ flora_print_all(Gs,NVs) :- cputime(T0), ( NVs == [] -> flora_if_then_else(flora_call(Gs),flora_write_Yes,flora_write_No) ; flora_findall(NVs,Gs,TempL), cputime(T1), T is T1-T0, flora_reclaim_storage_space, sort(TempL,L), length(L,N), ( N == 0 -> flora_write_No ; flora_write_matches(L), ( flora_switch(chatter) -> flora_stdfdbk_string('~n~w solution(s) in ~w seconds', [N,T]), ( windows_os, flora_stdfdbk_nl, ! ; flora_stdfdbk_string(' on '), shell(hostname,block,STDFDBK,block,_) ) ; true ), flora_write_Yes ) ). /********************************************************************/ flora_print_one(Gs,NVs) :- ( NVs == [] -> flora_if_then_else(flora_call(Gs), flora_write_Yes,flora_write_No) ; ( flora_call(Gs), flora_write_pairs(NVs), flora_fail_unless_return ; flora_write_No ), flora_reclaim_storage_space ). /********************************************************************/ flora_if_then_else(Condition,Then,_Else) :- call(Condition), call(Then). flora_if_then_else(_Condition,_Then,Else) :- call(Else). /********************************************************************/ %% If the user types RETURN, then succeed. Otherwise, assume the user wants %% more answers, so fail in order to provide another answer. flora_fail_unless_return :- get0(C), (C =:= CH_NEWLINE; C =:= CH_EOF_P), !, flora_write_Yes. flora_fail_unless_return :- flora_fail_unless_return, fail. /********************************************************************/ flora_write_Yes :- flora_stdfdbk_line('~nYes~n'). flora_write_No :- flora_stdfdbk_line('~nNo~n'). /********************************************************************/ %% Hookup to the Flora debugger %% flora_call is a wrapper around XSB call %% Used only in top-level queries flora_call(Goal) :- flora_handle_trace, call(Goal), flora_commit_storage, flora_handle_end_of_call. flora_call(_Goal) :- flora_handle_notrace, fail. /********************************************************************/ flora_findall(NVs,Gs,TempL) :- findall(NVs,flora_call(Gs),TempL). /********************************************************************/ flora_write_matches([]). flora_write_matches([M|Ms]) :- flora_write_pairs(M), flora_stdfdbk_nl, flora_write_matches(Ms). flora_write_pairs([]). flora_write_pairs([N=V|NVs]) :- flora_stdfdbk_nl, flora_stdfdbk_string('~w = ',[N]), flora_display_feedback(V), flora_write_pairs(NVs). /************************************************************************** The predicates below are debugger related. We keep them here rather than in syslib/flrdebugger.P because these predicates are used in every top-level query call, and the debugger would have to be loaded all the time. We don't want this. **************************************************************************/ flora_handle_trace :- ( flora_switch(trace) -> (stat_flag(TRACE,Trace), Trace == 0 -> trace ; true ) ; true ). /********************************************************************/ flora_handle_notrace :- ( stat_flag(TRACE,Trace), Trace > 0 -> notrace ; true ). /********************************************************************/ %% This turns off trace, so that flora internal stuff done after a %% subgoal call won''t be traced. However, on backtracking, this turns %% trace on and fails, thereby allowing to backtrack over the previous %% subgoal. flora_handle_end_of_call :- flora_handle_notrace. flora_handle_end_of_call :- flora_handle_trace, fail. /********************************************************************/