-
-
Notifications
You must be signed in to change notification settings - Fork 176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Built-in predicate request: function_property/2 #1181
Comments
Update An additional property, that enables e.g. more sophisticated linter checks, is
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 SWI-Prolog? |
Thanks. The template property seems useful. As is, SWI-Prolog provides current_arithmetic_function/1, to query existing functions. Reasoning about their types seems useful. But, it is more complicated, in particular when ration numbers are involved. The type for e.g., ** is hard to predict. If there is a correct rational, this is returned, but if the result is not rational, it becomes a float, so we have rat**rat -> rat|float. |
Wondering about the possible trouble of having:
Does this problem exists for types other than |
A more concise (but also ambiguous) alternative would be to simply use in this case: template(number ** number, number) |
Possibly. Roughly SWI-Prolog only knows rationals and floats. Any function (except for casting) with at least one float argument will produce a float result. If all arguments are rational the result is rational if well defined. Well, we do not consider special cases such as sin(0) -> 0. I'm now on holiday. I think it makes sense to add this as a library, or possibly add the type info to the built-in functions. Note that for several Prolog systems, evaluation simply calls predicates with an extra argument and values are not even limited to numners. |
At didoudiaz/gprolog#40 Daniel makes a good point that using instead |
What about functions that do not change the type, e.g., +(X) simply returns X. should that have
|
See a proposal in https://github.com/SWI-Prolog/swipl-devel/blob/master/library/prolog_evaluable.pl I think the first argument should not be required to be instantiated, so we can enumerate evaluable functions, consistent with predicate_property/2 and most (all?) other built-in *_property/2 predicates. We might also consider to add a property |
Similar concerns by other Prolog system implementers (notably, for ECLiPSe). Currently, the |
The
Please see the discussion on didoudiaz/gprolog#40. There, the idea is to allow enumeration using a second Genuine question: did you (or anyone else) ever found a sensible use case for being able to enumerate predicates using |
A |
As with the other *_property predicates, there is no domain error on unknown properties, simply failure. That allows implementations to add other properties.
That is SWI's current_arithmetic_function/1. I'd be happy to deprecate that in favor of
Yes. Only in IDEs though, i.e., completing predicate/function names. I also used it to create the rough Prolog template predicate 😄 Its more consistent and I think the implementation should not be a big issue for most systems.
I'm in favor of that. |
The current tests actually throw a domain error on unknown properties. Your argument here is a reasonable one. But so is detecting typos/errors in property names; if not done by the compiler, that would need to be done by a linter.
The
In the case of IDEs as in your code completion example, I always use an explicit table for built-ins. A main reason to do that in general (instead of enumerating them) is to only list documented built-ins instead of all of them.
Good. But its exact meaning needs to be well specified. Notably, if it simply means that the evaluable functor is specified by the ISO standard (light requirement) or that the implementation actually follows the standard specification (stricter requirement). |
IMO, both extensibility and consistency with the predicate_property/2 asks for silent failure. Note that the current spec already has properties that only have meaning in some systems. A linter is better in dealing with typos.
? All functions are supposed to be documented, no? For predicates one typically enumerates over properties such as
Good question. Also a bit grey area and, at least for SWI-Prolog, depending on flags such as |
Note that the ISO Prolog standard specifies domain errors for the
A good argument here is that a failure would mask invalid properties. If a property only was meaning in system A, there's no sound reason in general to assume its value should be either true or false in system B.
My experience is that most systems provide more built-ins that those that are documented. Either because they are really internal predicates and not meant to be called by the user or because they are not ready or part of a stable API. On the plus side, the set of built-ins are is infrequently updated.
Issues like these indeed make me a bit reluctant to support this |
True. It is pretty impractical though. Same holds for e.g.
Demanding this property might indeed not be a good idea. I just did add it to the library as I think it is useful for IDEs and linters. I'm also unsure about the template. As is, we have e.g.
Some alternatives are Another issue is supporting partial evaluation. For that, we need to know whether a function is pure, e.g., its result only depends on its arguments. SWI-Prolog has a few exceptions: |
I don't think there's a real problem here. When writing portable code, we should only use standard properties. In this case, a catch is not required and the domain errors will alert to any mistake. If we're using non-standard properties, i.e. writing non-portable code, again a catch is not required and if you make a typo, a domain error again will alert you.
This is what LVM and Trealla Prolog currently implement.
One step at the time. It will take some time to find a consensual and useful spec for the |
Latest versions of LVM and Trealla Prolog implement a
function_property/2
built-in predicate, which provides similar functionality to the de facto standardpredicate_property/2
built-in predicate, allowing checking or enumerating the properties of a given arithmetic function. Thefunction_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 thestatic
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:Would it be possible to add this predicate to SWI-Prolog?
The text was updated successfully, but these errors were encountered: