[Oops, I replied to Ulrich earlier but forgot to Cc: it to the list.]
Hi Ulrich,
On Sat, Dec 21, 2002 at 11:43:52AM +0100, Ulrich Scholz wrote:
> ECLiPSe provides iterators like foreach and friends - and they do their job.
> What is missing is a case statement. Sometimes you just have 20+ different
> mutually exclusive cases and you want to be sure that one of them is taken
> (else-case).
There are standard methods for doing (more or less) this in standard Prolog,
though there is no direct analogue of (say) C's case statement with a
default option --- though what you do get is more flexible.
One way is just to chain if-then-else statements. This makes it clear which
case to use if more than one matches, and provides a default case. E.g.
( <condition 1> ->
<code to execute when condition 1 holds>
; <condition 2> ->
<code to execute when condition 2 (but not condition 1) holds>
...
;
<code to execute when none of the conditions hold>
)
If you like cuts (and I'm not a fan of cuts; I've seen even experienced
Prolog programmers get tripped up by them) then you can also write the above
as:
foo(...) :-
<condition 1>,
!,
<code to execute when condition 1 holds>
foo(...) :-
<condition 2>,
!,
<code to execute when condition 2 (but not condition 1) holds>
...
foo(...) :-
<code to execute when none of the conditions hold>
Note that if the conditions are simple unifications of clause head
variables, one can simply put the relevant term(s) in the head. But please,
if you're using cuts, don't put output unifications in the head of the
clause! Use explicit unification in the body somewhere after the cut;
otherwise you may get unexpected results in certain cases. (A standard
example of this is the following implementation of min/3 for finding the
smaller of two numbers:
min(A, B, A) :-
A =< B,
!.
min(A, B, B).
min(2, 4, X) yields X = 2 as expected, yet min(2, 4, 4) succeeds, which is
clearly wrong!)
If your conditions are all mutually exclusive, are of various simple forms,
and you don't need a default case, then ECLiPSe can often detect this and
generate more efficient code that just jumps to the right clause (and you
won't need the cuts). See the User Manual / The Compiler / Writing
Efficient Code for more details (though be aware that the current compiler
sometimes chooses the wrong argument to index on if it has a choice, so it
pays to keep an eye open for stray choice points being introduced).
Cheers,
Warwick