ciao icon indicating copy to clipboard operation
ciao copied to clipboard

Built-in predicate request: function_property/2

Open pmoura opened this issue 2 years ago • 2 comments

Latest versions of LVM and Trealla Prolog implement a function_property/2 built-in predicate, which provides similar functionality to the de facto standard predicate_property/2 built-in predicate, allowing checking or enumerating the properties of a given arithmetic function. The function_property/2 predicate allows clean checking if an arithmetic function is defined, simplifying e.g. portability linter checks for arithmetic expressions. The first argument is a function template (e.g. abs(_)) and the second argument is the property. Four properties are specified:

  • built_in (function is a defined built-in arithmetic function)
  • foreign (function is a defined arithmetic function implemented using the FLI)
  • static (function is a static arithmetic function)
  • dynamic (function is a dynamic arithmetic function)

The dynamic is meant for Prolog systems that allow runtime definition of new arithmetic functions (e.g. LVM). Built-in and foreign functions usually also have the static property.

The predicate spec is:

Template: function_property(Function, Property) Modes and number of proofs: function_property(+callable, ?function_property) - zero_or_more

Exceptions:

  • Function is a variable: instantiation_error
  • Function is neither a variable nor a callable term: type_error(callable, Function)
  • Property is neither a variable nor an atom: type_error(atom, Property)
  • Property is an atom but not a valid function property: domain_error(function_property, Property)

Examples:

Check that popcount/1 is a built-in arithmetic function:

?- function_property(popcount(_), built_in).
true.

Would it be possible to add this predicate to Ciao Prolog?

pmoura avatar Jun 08 '23 14:06 pmoura

Update

An additional property, that enables e.g. more sophisticated linter checks, is template/2. It allows querying function arguments types and return types. For example:

?- function_property(abs(_), Property).
   Property = built_in ;
   Property = static ;
   Property = template(abs(integer), integer) ;
   Property = template(abs(float), float) ;
   false.

For some Prolog systems, the necessary internal tables to implement this property seems to already be there. For other, it would be more work. And in the case of Ciao?

pmoura avatar Jun 09 '23 09:06 pmoura

Thanks Paulo for the suggestion. Exposing some engine table and information definitely seems useful in some scenarios. We'd need to think about this more carefully:

  • function_property seems a very broad name (for us it would only mean arithmetic functions, arith_function_property/2 is longer but would be more accurate?)
  • we rely on fsyntax (functional notation) to write code in functional style (which relaxed our needs to extend is/2 to use concise syntax)
  • extending is/2 would be a nightmare for our static analyzer (many is/2 calls may call arbitrary code)

My first thought is that probably adding a limited function_property/2 predicate in a specific module for portability may not be actually bad.

jfmc avatar Jun 09 '23 12:06 jfmc