/* File: flrcontrol.P
**
** Author(s): Michael Kifer
** Guizhen Yang
**
** Contact: flora-users@lists.sourceforge.net
**
** Copyright (C) The Research Foundation of SUNY, 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: flrcontrol.P,v 1.17 2003/06/18 07:01:20 kifer Exp $
**
*/
:- compiler_options([xpp_on]).
#include "flora_terms.flh"
#include "flora_porting.flh"
:- import flora_commit_storage/0 from flrutils.
/***************************************************************************
if-then-else statement
***************************************************************************/
FLLIBIFTHENELSE(Cond,Then,_Else) :-
call(Cond),
call(Then).
FLLIBIFTHENELSE(Cond,_Then,Else) :-
FLORA_TNOT(Cond),
call(Else).
/***************************************************************************
if-then statement
The semantics is such that the entire statement succeeds when the
condition part fails.
***************************************************************************/
FLLIBIFTHEN(Cond,Then) :-
call(Cond),
call(Then).
FLLIBIFTHEN(Cond,_Then) :-
FLORA_TNOT(Cond).
%% UNLESS ... DO ... is like IF...THEN true ELSE ...
FLLIBUNLESSDO(Cond,_Action) :- call(Cond).
FLLIBUNLESSDO(Cond,Action) :- FLORA_TNOT(Cond), call(Action).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% while-do and do-until loops commit storage after each iteration
%%%% so they are not backtrackable (backtracking over updates can occur
%%%% only within the condition or action parts, but not after an iteration
%%%% is finished)
%%%% These loops fail only if Action fails.
%%%% Variables that were unbound at the time of the call stay unbound
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% This should fail ONLY if Cond is true, but Action fails.
%% We use catch/throw to achieve this
FLLIBWHILEDO(Cond,Action) :-
FLORA_SYMBOL('catch')((call(Cond),
(call(Action) -> flora_commit_storage, fail
; throw(quitLoop)
)
; true
),
quitLoop, % catcher
fail). % fail, if condition was thrown
%% Fails only if Action becomes false before Cond becomes true
FLLIBDOUNTIL(Action,Cond) :-
call(Action),
flora_commit_storage,
call(Cond).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% while-loop and loop-until
%%%% These loops are fully backtrackable, but they are more expensive,
%%%% since they are recursive.
%%%% These loops fail only if Action fails.
%%%% Variables that were unbound at the time of the call stay unbound
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FLLIBWHILELOOP(Cond,Action) :-
%% Must copy_term Action&Cond together so the variables
%% will be preserved
copy_term((Action,Cond),(Action1,Cond1)),
(call(Cond1) ->
(call(Action1), !, FLLIBWHILELOOP(Cond,Action)
; fail
)
; true
).
/*
FLORA_SYMBOL('catch')(
(call(Cond1) ->
(call(Action1), ! ; throw(quitLoop)),
FLLIBWHILELOOP(Cond,Action)
; true
),
quitLoop, % catcher
fail % fail if action failed
).
*/
%% Cond shouldn't be tabled!!! Otherwise "not" barks!!!
%% We can't use FLORA_TNOT instead of "not" because FLORA_TNOT
%% would table Cond and cause more iterations than necessary.
%% We could call abolish_all_tables from within FLORA_TNOT,
%% but this is dangerous:
%% If there is a recursive dependency on Cond then abolishing tables
%% while computing them can crash XSB
FLLIBLOOPUNTIL(Action,Cond) :-
%% Must copy_term Action&Cond together so the variables
%% will be preserved
copy_term((Action,Cond),(Action1,Cond1)),
FLORA_SYMBOL('catch')(
((call(Action1), ! ; throw(quitLoop)),
(not(call(Cond1))
-> FLLIBLOOPUNTIL(Action,Cond)
; true
)
),
quitLoop, % catcher
fail % fail if action failed
).
%% These exist in order to be able to hide the calls
%% to catch/throw in the debugger
FLORA_SYMBOL('catch')(X,Y,Z) :- catch(X,Y,Z).
syntax highlighted by Code2HTML, v. 0.9.1