Implementing user-defined arithmetic functions

偶尔善良 提交于 2019-12-22 07:09:07

问题


How can I add a function (e.g., hammingweight) and use it in expressions occuring in the right-hand side is some (is)/2 goal?

Could something like goal_expansion or term_expansion help here?

I acknowledge that this is not a big feature, but it could increase readability of some of my Prolog programs.

Writing a custom (is)/2 predicate (implementing a custom expression evaluator) is do-able, but I would like to keep runtime overhead low, as I don't want to sacrifice readability for runtime overhead in this case.


回答1:


There is no such provision in ISO Prolog, neither to extend (is)/2 nor to rely on goal expansion. And, looking at the various implementation specific features that are offered by some implementations to this end, there is no generally agreed upon way to do this. So implementing your own (my_is)/2 seems to be the best way to go.

Also note, that this would not only affect (is)/2 but also all other built-ins that use evaluable functors. In particular, all arithmetic comparison built-ins (8.7 Arithmetic comparison) (see this overview) would be affected.




回答2:


My simple minded (~20 LOC) syntax sugar, lifter, it's based on goal_expansion.

With lifter, the clause

longer(A,B) :-
    length(A,º) > length(B,º).

is expanded to

longer(A, B) :-
    length(A, C),
    length(B, D),
    C > D.



回答3:


You can use Logtalk's term-expansion mechanism, which is portable and works with its twelve supported Prolog compilers (*). Logtalk compiling and loading and loading predicates accept Prolog files and will output the corresponding Prolog expanded files. For example, assuming that the file you want to expand is named source.pl and that your term_expansion/2 and goal_expansion/2 predicate definitions are in a file named expansions.pl, you can do something like:

% first, load the expansion hooks:
| ?- [expansions].
...

% second, expand a file using those hooks:
| ?- logtalk_compile(source, [hook(user)]).
...

You will get the expanded file, which will be (by default) named source_pl.pl (in a directory that will depend on the value of the scratch_directory Logtalk flag). If the expansions are contained in a Prolog module, use above the module name instead of user. If the source.pl file contains a module instead of plain Prolog code, you'll need to define some clauses for the term_expansion/2 predicate to avoid Logtalk compiling the module as an object. But in the simpler case where you're not using modules, the two queries above should suffice.

One feature of Logtalk's term-expansion mechanism that might be useful is that you can mark a term or a goal to not be expanded or further expanded by wrapping it with the {}/1 control construct.

(*) Note that term-expansion mechanism are not standard, not provided by all Prolog implementations, and with significant differences between implementations.



来源:https://stackoverflow.com/questions/28854812/implementing-user-defined-arithmetic-functions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!