Warning for predicate clause with a different arity than all the others?

Is there a directive or some other idiom or technique to force all the clauses for a particular predicate to have the exact same arity? I find myself chasing bugs fairly often where I forgot to put the correct number of arguments in one of the clauses and that causes the predicate to fail unexpectedly; especially with the termination clause in a list processing predicate (e.g. - the final clause when tearing apart a list that checks for the empty set and succeeds to end processing).

If there was a directive that would warn you about predicates that have clauses where the head does not have the same number of arguments for all clauses, that would be useful. For example:

:- enforce_arity dubious_predicate/3.

Not that I am aware of.

However for this problem there are two things that I typically make use of to help.

  1. When using gtrace the predicates that are dead code show up in a different color.

  2. Add a final clause to toss out a warning message: e.g.

prolog_number_term(Sign,Whole_number_part,Fractional_number_part,Exponent,_Prolog_number_term) -->
        format("Need to add case for predicate: prolog_number_term/5 for parameters: Sign: ~w, Whole_number_part: ~w, Fractional_number_part: ~w, Exponent: ~w ~n",[Sign,Whole_number_part,Fractional_number_part,Exponent])


Another option used in mainly the functional languages is to use Algebraic Data Types and then there is a phase in the parsing that checks that all of the cases are covered and throws out warning messages when one or more are missing. Doesn’t work for type string but does work with Enum. Some of the languages even give example patterns of what will cover the remaining cases.

1 Like

Not really. In many cases you will get a discontiguous warning, but not if you use the wrong arith as first or last clause. list_undefined/0, called by make/0 will typically find resulting undefined predicates. gxref/0 will find not called predicates and the built-in editor will (as @EricGT points out for gtrace) show the not called code in red.

Some people consider using different arities as dubious coding. I think Ciao has a warning for it. Others don’t. I consider it generally a good way to deal with defaults.

Note that a test is fairly easy to write using current_predicate/2. Your proposed directive is not that hard either: just assert the fact and use term_expansion/2 to verify every clause you find.

As far as I’m concerned the available tools suffice. If there is a wide feeling this is not the case we can reconsider.


I only use it by mistake except for the other small case where I want to provide “default” arguments for some predicates that have a large number of arguments.