mercredi 31 octobre 2018

Prolog if-then-else constructs: -> vs *-> vs. if_/3

As noted in another StackOverflow answer that I can't seem to find anymore, this pattern emerges frequently in practical Prolog code:

pred(X) :-
    guard(X),
    ...
pred(X) :-
    \+ guard(X),
    ...

and many people try to condense this to

pred(X) :-
    (guard(X) ->
    ...
    ;
    ...).

However as we all know, the arrow structure destroys choice points and isn't logical.

In Ulrich Neumerkel's Indexing dif/2, a predicate called if_/3 is proposed that is monotonic and logical, however in the paper he mentions another construct which caught my eye:

The *-> construct functions exactly like the unsugared guard clause example above, and thus it seems perfect for my uses as I don't want to have a reified condition which is required by if_/3 and I don't care about extra choice points that much. If I'm not mistaken, it offers the same semantics as if_/3 but without the requirement of adding the "reification" to the condition predicate.

However in the SWI documentation for it, it claims that "this construct is rarely used," which seems weird to me. *-> seems to me like it's strictly better than -> when you're trying to do pure logical programming. Is there any reason to avoid this structure, or is there an even better alternative to the entire guard clause / negated guard clause pattern?

Aucun commentaire:

Enregistrer un commentaire