<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> <HTML> <HEAD> <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <META name="GENERATOR" content="hevea 1.06-7 of 2001-11-14"> <TITLE> Prolog control constructs </TITLE> </HEAD> <BODY TEXT=black BGCOLOR=white> <A HREF="manual021.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A> <A HREF="manual020.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A> <HR> <TABLE CELLPADDING=0 CELLSPACING=0 WIDTH="100%"> <TR><TD BGCOLOR="#66dbff"><DIV ALIGN=center><TABLE> <TR><TD><FONT SIZE=4><B><A NAME="htoc60">6.2</A></B></FONT></TD> <TD WIDTH="100%" ALIGN=center><FONT SIZE=4><B>Prolog control constructs</B></FONT></TD> </TR></TABLE></DIV></TD> </TR></TABLE><UL> <LI><A HREF="manual022.html#toc40"> <TT>true/0</TT>, <TT>fail/0</TT>, <TT>!/0</TT></A> <LI><A HREF="manual022.html#toc41"> <TT>(',')/2</TT> - conjunction, <TT>(;)/2</TT> - disjunction, <TT>(->)/2</TT> - if-then</A> <LI><A HREF="manual022.html#toc42"> <TT>call/1</TT></A> <LI><A HREF="manual022.html#toc43"> <TT>catch/3</TT>, <TT>throw/1</TT></A> </UL> <BR> <A NAME="toc40"></A><TABLE CELLPADDING=0 CELLSPACING=0 WIDTH="100%"> <TR><TD BGCOLOR="#98e7ff"><DIV ALIGN=center><TABLE> <TR><TD><B><A NAME="htoc61">6.2.1</A></B></TD> <TD WIDTH="100%" ALIGN=center><B><TT>true/0</TT>, <TT>fail/0</TT>, <TT>!/0</TT></B></TD> </TR></TABLE></DIV></TD> </TR></TABLE> <A NAME="true/0"></A> <BR> <B>Templates</B> <DL COMPACT=compact><DT><DD><TT> true<BR> fail<BR> !</TT></DL> <B>Description</B><BR> <BR> <TT>true</TT> always succeeds.<BR> <BR> <TT>fail</TT> always fails (enforces backtracking).<BR> <BR> <TT>!</TT> always succeeds and the for side-effect of removing all choice-points created since the invocation of the predicate activating it.<BR> <BR> <B>Errors</B><BR> <BR> None.<BR> <BR> <B>Portability</B><BR> <BR> ISO control constructs.<BR> <BR> <A NAME="toc41"></A><TABLE CELLPADDING=0 CELLSPACING=0 WIDTH="100%"> <TR><TD BGCOLOR="#98e7ff"><DIV ALIGN=center><TABLE> <TR><TD><B><A NAME="htoc62">6.2.2</A></B></TD> <TD WIDTH="100%" ALIGN=center><B><TT>(',')/2</TT> - conjunction, <TT>(;)/2</TT> - disjunction, <TT>(->)/2</TT> - if-then</B></TD> </TR></TABLE></DIV></TD> </TR></TABLE> <BR> <B>Templates</B> <DL COMPACT=compact><DT><DD><TT> ','(+callable_term, +callable_term)<BR> ;(+callable_term, +callable_term)<BR> ->(+callable_term, +callable_term)</TT></DL> <B>Description</B><BR> <BR> <TT>Goal1 , Goal2</TT> executes <TT>Goal1</TT> and, in case of success, executes <TT>Goal2</TT>.<BR> <BR> <TT>Goal1 ; Goal2</TT> first creates a choice-point and executes <TT>Goal1</TT>. On backtracking <TT>Goal2</TT> is executed.<BR> <BR> <TT>Goal1 -> Goal2</TT> first executes <TT>Goal1</TT> and, in case of success, removes all choice-points created by <TT>Goal1</TT> and executes <TT>Goal2</TT>. This control construct acts like an if-then (<TT>Goal1</TT> is the test part and <TT>Goal2</TT> the then part). Note that if <TT>Goal1</TT> fails <TT>->/2</TT> fails also. <TT>->/2</TT> is often combined with <TT>;/2</TT> to define an if-then-else as follows: <TT>Goal1 -> Goal2 ; Goal3</TT>. Note that <TT>Goal1 -> Goal2</TT> is the first argument of the <TT>(;)/2</TT> and <TT>Goal3</TT> (the else part) is the second argument. Such an if-then-else control construct first creates a choice-point for the else-part (intuitively associated to <TT>;/2</TT>) and then executes <TT>Goal1</TT>. In case of success, all choice-points created by <TT>Goal1</TT> together with the choice-point for the else-part are removed and <TT>Goal2</TT> is executed. If <TT>Goal1</TT> fails then <TT>Goal3</TT> is executed.<BR> <BR> <TT>','</TT>, <TT>;</TT> and <TT>-></TT> are predefined infix operators (section <A HREF="manual037.html#op/3:(Term-input/output)">7.14.10</A>).<BR> <BR> <B>Errors</B><BR> <TABLE CELLSPACING=2 CELLPADDING=0> <TR><TD BGCOLOR=black COLSPAN=3><TABLE BORDER=0 WIDTH="100%" CELLSPACING=0 CELLPADDING=1><TR><TD></TD></TR></TABLE></TD> </TR> <TR><TD VALIGN=top ALIGN=left><TT>Goal1</TT> or <TT>Goal2</TT> is a variable</TD> <TD VALIGN=top ALIGN=center NOWRAP> </TD> <TD VALIGN=top ALIGN=left><TT>instantiation_error</TT></TD> </TR> <TR><TD BGCOLOR=black COLSPAN=3><TABLE BORDER=0 WIDTH="100%" CELLSPACING=0 CELLPADDING=1><TR><TD></TD></TR></TABLE></TD> </TR> <TR><TD VALIGN=top ALIGN=left><TT>Goal1</TT> is neither a variable nor a callable term</TD> <TD VALIGN=top ALIGN=center NOWRAP> </TD> <TD VALIGN=top ALIGN=left><TT>type_error(callable, Goal1)</TT></TD> </TR> <TR><TD BGCOLOR=black COLSPAN=3><TABLE BORDER=0 WIDTH="100%" CELLSPACING=0 CELLPADDING=1><TR><TD></TD></TR></TABLE></TD> </TR> <TR><TD VALIGN=top ALIGN=left><TT>Goal2</TT> is neither a variable nor a callable term</TD> <TD VALIGN=top ALIGN=center NOWRAP> </TD> <TD VALIGN=top ALIGN=left><TT>type_error(callable, Goal2)</TT></TD> </TR> <TR><TD BGCOLOR=black COLSPAN=3><TABLE BORDER=0 WIDTH="100%" CELLSPACING=0 CELLPADDING=1><TR><TD></TD></TR></TABLE></TD> </TR> <TR><TD VALIGN=top ALIGN=left>The predicate indicator <TT>Pred</TT> of <TT>Goal1</TT> or <TT>Goal2</TT> does not correspond to an existing procedure and the value of the <TT>unknown</TT> Prolog flag is <TT>error</TT> (section <A HREF="manual045.html#set-prolog-flag/2">7.22.1</A>)</TD> <TD VALIGN=top ALIGN=center NOWRAP> </TD> <TD VALIGN=top ALIGN=left><TT>existence_error(procedure, Pred)</TT></TD> </TR> <TR><TD BGCOLOR=black COLSPAN=3><TABLE BORDER=0 WIDTH="100%" CELLSPACING=0 CELLPADDING=1><TR><TD></TD></TR></TABLE></TD> </TR></TABLE><BR> <B>Portability</B><BR> <BR> ISO control constructs.<BR> <BR> <A NAME="toc42"></A><TABLE CELLPADDING=0 CELLSPACING=0 WIDTH="100%"> <TR><TD BGCOLOR="#98e7ff"><DIV ALIGN=center><TABLE> <TR><TD><B><A NAME="htoc63">6.2.3</A></B></TD> <TD WIDTH="100%" ALIGN=center><TT><B>call/1</B></TT></TD> </TR></TABLE></DIV></TD> </TR></TABLE> <A NAME="call/1"></A> <BR> <B>Templates</B> <DL COMPACT=compact><DT><DD><TT> call(+callable_term)</TT></DL> <B>Description</B><BR> <BR> <TT>call(Goal)</TT> executes <TT>Goal</TT>. <TT>call/1</TT> succeeds if <TT>Goal</TT> represents a goal which is true. When <TT>Goal</TT> contains a cut symbol <TT>!</TT> (section <A HREF="#true/0">6.2.1</A>) as a subgoal, the effect of <TT>!</TT> does not extend outside <TT>Goal</TT>. <BR> <BR> <B>Errors</B><BR> <TABLE CELLSPACING=2 CELLPADDING=0> <TR><TD BGCOLOR=black COLSPAN=3><TABLE BORDER=0 WIDTH="100%" CELLSPACING=0 CELLPADDING=1><TR><TD></TD></TR></TABLE></TD> </TR> <TR><TD VALIGN=top ALIGN=left><TT>Goal</TT> is a variable</TD> <TD VALIGN=top ALIGN=center NOWRAP> </TD> <TD VALIGN=top ALIGN=left><TT>instantiation_error</TT></TD> </TR> <TR><TD BGCOLOR=black COLSPAN=3><TABLE BORDER=0 WIDTH="100%" CELLSPACING=0 CELLPADDING=1><TR><TD></TD></TR></TABLE></TD> </TR> <TR><TD VALIGN=top ALIGN=left><TT>Goal</TT> is neither a variable nor a callable term</TD> <TD VALIGN=top ALIGN=center NOWRAP> </TD> <TD VALIGN=top ALIGN=left><TT>type_error(callable, Goal)</TT></TD> </TR> <TR><TD BGCOLOR=black COLSPAN=3><TABLE BORDER=0 WIDTH="100%" CELLSPACING=0 CELLPADDING=1><TR><TD></TD></TR></TABLE></TD> </TR> <TR><TD VALIGN=top ALIGN=left>The predicate indicator <TT>Pred</TT> of <TT>Goal</TT> does not correspond to an existing procedure and the value of the <TT>unknown</TT> Prolog flag is <TT>error</TT> (section <A HREF="manual045.html#set-prolog-flag/2">7.22.1</A>)</TD> <TD VALIGN=top ALIGN=center NOWRAP> </TD> <TD VALIGN=top ALIGN=left><TT>existence_error(procedure, Pred)</TT></TD> </TR> <TR><TD BGCOLOR=black COLSPAN=3><TABLE BORDER=0 WIDTH="100%" CELLSPACING=0 CELLPADDING=1><TR><TD></TD></TR></TABLE></TD> </TR></TABLE><BR> <B>Portability</B><BR> <BR> ISO control construct.<BR> <BR> <A NAME="toc43"></A><TABLE CELLPADDING=0 CELLSPACING=0 WIDTH="100%"> <TR><TD BGCOLOR="#98e7ff"><DIV ALIGN=center><TABLE> <TR><TD><B><A NAME="htoc64">6.2.4</A></B></TD> <TD WIDTH="100%" ALIGN=center><B><TT>catch/3</TT>, <TT>throw/1</TT></B></TD> </TR></TABLE></DIV></TD> </TR></TABLE> <A NAME="catch/3"></A> <BR> <B>Templates</B> <DL COMPACT=compact><DT><DD><TT> catch(?callable_term, ?term, ?term)<BR> throw(+nonvar)</TT></DL> <B>Description</B><BR> <BR> <TT>catch(Goal, Catcher, Recovery)</TT> is similar to <TT>call(Goal)</TT> (section <A HREF="#call/1">6.2.3</A>). If this succeeds or fails, so does the call to <TT>catch/3</TT>. If however, during the execution of <TT>Goal</TT>, there is a call to <TT>throw(Ball)</TT>, the current flow of control is interrupted, and control returns to a call of <TT>catch/3</TT> that is being executed. This can happen in one of two ways: <UL><LI>implicitly, when an error condition for a built-in predicate is satisfied.<BR> <BR> <LI>explicitly, when the program executes a call of <TT>throw/1</TT> because the program wishes to abandon the current processing, and instead to take an alternative action.</UL> <TT>throw(Ball)</TT> causes the normal flow of control to be transferred back to an existing call of <TT>catch/3</TT>. When a call to <TT>throw(Ball)</TT> happens, <TT>Ball</TT> is copied and the stack is unwound back to the call to <TT>catch/3</TT>, whereupon the copy of <TT>Ball</TT> is unified with <TT>Catcher</TT>. If this unification succeeds, then <TT>catch/3</TT> executes the goal <TT>Recovery</TT> using <TT>call/1</TT> (section <A HREF="#call/1">6.2.3</A>) in order to determine the success or failure of <TT>catch/3</TT>. Otherwise, in case the unification fails, the stack keeps unwinding, looking for an earlier invocation of <TT>catch/3</TT>. <TT>Ball</TT> may be any non-variable term.<BR> <BR> <B>Errors</B><BR> <TABLE CELLSPACING=2 CELLPADDING=0> <TR><TD BGCOLOR=black COLSPAN=3><TABLE BORDER=0 WIDTH="100%" CELLSPACING=0 CELLPADDING=1><TR><TD></TD></TR></TABLE></TD> </TR> <TR><TD VALIGN=top ALIGN=left><TT>Goal</TT> is a variable</TD> <TD VALIGN=top ALIGN=center NOWRAP> </TD> <TD VALIGN=top ALIGN=left><TT>instantiation_error</TT></TD> </TR> <TR><TD BGCOLOR=black COLSPAN=3><TABLE BORDER=0 WIDTH="100%" CELLSPACING=0 CELLPADDING=1><TR><TD></TD></TR></TABLE></TD> </TR> <TR><TD VALIGN=top ALIGN=left><TT>Goal</TT> is neither a variable nor a callable term</TD> <TD VALIGN=top ALIGN=center NOWRAP> </TD> <TD VALIGN=top ALIGN=left><TT>type_error(callable, Goal)</TT></TD> </TR> <TR><TD BGCOLOR=black COLSPAN=3><TABLE BORDER=0 WIDTH="100%" CELLSPACING=0 CELLPADDING=1><TR><TD></TD></TR></TABLE></TD> </TR> <TR><TD VALIGN=top ALIGN=left>The predicate indicator <TT>Pred</TT> of <TT>Goal</TT> does not correspond to an existing procedure and the value of the <TT>unknown</TT> Prolog flag is <TT>error</TT> (section <A HREF="manual045.html#set-prolog-flag/2">7.22.1</A>)</TD> <TD VALIGN=top ALIGN=center NOWRAP> </TD> <TD VALIGN=top ALIGN=left><TT>existence_error(procedure, Pred)</TT></TD> </TR> <TR><TD BGCOLOR=black COLSPAN=3><TABLE BORDER=0 WIDTH="100%" CELLSPACING=0 CELLPADDING=1><TR><TD></TD></TR></TABLE></TD> </TR> <TR><TD VALIGN=top ALIGN=left><TT>Ball</TT> is a variable</TD> <TD VALIGN=top ALIGN=center NOWRAP> </TD> <TD VALIGN=top ALIGN=left><TT>instantiation_error</TT></TD> </TR> <TR><TD BGCOLOR=black COLSPAN=3><TABLE BORDER=0 WIDTH="100%" CELLSPACING=0 CELLPADDING=1><TR><TD></TD></TR></TABLE></TD> </TR></TABLE><BR> If <TT>Ball</TT> does not unify with the <TT>Catcher</TT> argument of any call of <TT>catch/3</TT>, a system error message is displayed and <TT>throw/1</TT> fails.<BR> <BR> When <TT>catch/3</TT> calls <TT>Recovery</TT> it uses <TT>call/1</TT> (section <A HREF="#call/1">6.2.3</A>), an <TT>instantiation_error</TT>, a <TT>type_error</TT> or an <TT>existence_error</TT> can then occur depending on <TT>Recovery</TT>. <BR> <BR> <B>Portability</B><BR> <BR> ISO control constructs.<BR> <BR> <HR SIZE=2> Copyright (C) 1999-2002 Daniel Diaz <BR> <BR> Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved. <BR> <BR> <A HREF="index.html#copyright">More about the copyright</A> <HR> <A HREF="manual021.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A> <A HREF="manual020.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A> </BODY> </HTML>