首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Prolog中的“泛型编程”

Prolog中的“泛型编程”
EN

Stack Overflow用户
提问于 2019-09-22 02:14:36
回答 2查看 169关注 0票数 5

据我所知,Prolog没有任何内置的generic programming机制。可以使用统一来模拟泛型,但这需要在运行时进行类型检查:

代码语言:javascript
复制
:- initialization(main).
:- set_prolog_flag(double_quotes, chars).

% this is a "generic" predicate, where A and B have the same type
add(A,B,C) :-
    generic_types([A:Type,B:Type]),
    (Type = number,
    C is A + B;Type=var,C = A+B).

main :-
    add(A,B,C),
    add(3,4,D),
    writeln(C),
    writeln(D).

generic_types([]).
generic_types([A:B|C]) :-
    member(B,[var,nonvar,float,rational,number,atom,atomic,compound,callable,ground,acyclic_term]),
    call(B,A),
    generic_types(C).
has_type(Type,A) :-
    call(Type,A).

有没有可能在运行时不检查每个变量的类型就编写“泛型”谓词?

EN

回答 2

Stack Overflow用户

发布于 2021-05-03 03:02:21

通过Logtalk在Prolog中提供了一些形式的泛型编程,Logtalk扩展了Prolog,可以与大多数Prolog系统一起使用。

假设您希望根据前两个参数的类型使用不同的add/3谓词定义,我们可以从定义一个声明谓词的协议开始:

代码语言:javascript
复制
:- protocol(math_protocol).

    :- public(add/3).

:- end_protocol.

根据您的示例代码,我们现在可以为谓词定义不同的实现:

代码语言:javascript
复制
:- object(number,
    implements(math_protocol)).

    add(A, B, C) :-
        C is A + B.

:- end_object.


:- object(var,
    implements(math_protocol)).

    add(A, B, C) :-
        C = A + B.

:- end_object.

我们可以修改numbervar对象来执行类型检查。例如:

代码语言:javascript
复制
:- object(number,
    implements(math_protocol)).

    add(A, B, C) :-
        number(A),
        number(B),
        C is A + B.

:- end_object.

或者,我们可以在执行类型检查的类型上定义一个对象参数,然后委托对该类型的实际操作。例如:

代码语言:javascript
复制
:- object(math(_Type_),
    implements(math_protocol)).

    add(A, B, C) :-
        call(_Type_, A),
        call(_Type_, B),
        _Type_::add(A, B, C).

:- end_object.

在这种情况下,示例调用将是:

代码语言:javascript
复制
?- math(number)::add(2, 3, Sum).
Sum = 5
yes

但请注意,这些替代方案仍将在运行时执行类型检查。

可以修改参数对象以查找参数的类型,如示例代码中所示。但是,如果没有内置的Prolog谓词来允许查询term类型,效率就会很低(但是,没有相应的标准,而且通常也不可用)。

票数 2
EN

Stack Overflow用户

发布于 2021-05-02 17:07:38

您可以通过向谓词显式添加type参数来模拟参数多态性:

代码语言:javascript
复制
add(int, A, B, C) :-
    C is A + B.
add(var, A, B, C) :-
    C #= A + B.


?- add(var, 2, 3, 5).
true.

?- add(var, A, 3, 5).
A = 2.

?- add(int, A, 3, 5).
ERROR: Arguments are not sufficiently instantiated
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58042928

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档