How do you do a Nested if-else statement in Prolog?

17,131

In nested if-then-else, it is common to omit redundant parentheses, yielding:

min(List1, List2, Output) :-
    length(List1, N),
    length(List2, M),
    (   N < M -> Output = true
    ;   N =:= M -> Output = equal
    ;   Output = other
    ).

In Prolog, it is good practice to use pattern matching when possible, because this yields more general, more declarative and more readable programs than using if-then-else. For this particular case of conditions, check out the compare/3 library predicate. compare/3 lets you reify the relation of the two lengths into an atom, and you can use that atom to describe the three conditions with pattern matching:

lists_output(List1, List2, Output) :-
        length(List1, L1),
        length(List2, L2),
        compare(Order, L1, L2),
        order_output(Order, Output).

order_output(<, true).
order_output(=, equal).
order_output(>, other).

Sample queries and results:

?- lists_output([_,_], [_,_,_], Output).
Output = true.

?- lists_output([_,_,_], [_,_,_], Output).
Output = equal.

?- lists_output([_,_,_,_], [_,_,_], Output).
Output = other.
Share:
17,131
Bramble
Author by

Bramble

Updated on June 21, 2022

Comments

  • Bramble
    Bramble almost 2 years

    If I have this function:

    min(List1, List2, Output) :-
       length(List1, N),
       length(List2, M),
       (   N < M ->
           Output = 'true'
       ;   Output = 'false'
       ).
    

    but what if I wanted to also check if N == M? Maybe like this:

    min(List1, List2, Output) :-
       length(List1, N),
       length(List2, M),
       (   N < M ->
           Output = 'true'
       ;   (  N = M ->
              Output = 'equal'
           ;  Output = 'other'
           )
       ).
    

    Doesn't seem to work.

  • Admin
    Admin over 13 years
    Quite nice, I like this style, it's neater. I wonder if the operator precedence rules for ->, ;, etc. are common amongst other PROLOG implementations such that this isn't SWI-PROLOG specific (probably the case)?
  • Fred Foo
    Fred Foo over 13 years
    @Sharky, I don't have an ISO standard ready, but I've seen this style before and @mat's code works perfectly in SICStus 3.12.
  • false
    false about 12 years
    @larsmans: The example uses only ISO's predefined operators. See iso-prolog for how to get the standard for USD 30!