gpt4 book ai didi

generics - 序言中的 "Generic programming"

转载 作者:行者123 更新时间:2023-12-03 16:50:40 29 4
gpt4 key购买 nike

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

:- 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).

是否可以编写“通用”谓词而不在运行时检查每个变量的类型?

最佳答案

通过 Logtalk 在 Prolog 中提供了一些形式的通用编程,它扩展了 Prolog 并且可以与大多数 Prolog 系统一起使用。
鉴于您想要 add/3 的不同定义根据前两个参数的类型来使用谓词,我们可以从定义一个声明谓词的协议(protocol)开始:

:- protocol(math_protocol).

:- public(add/3).

:- end_protocol.
根据您的示例代码,我们现在可以为谓词定义不同的实现:
:- 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对象也执行类型检查。例如:
:- object(number,
implements(math_protocol)).

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

:- end_object.
或者,我们可以在执行类型检查的类型上定义一个对象参数,然后委托(delegate)对该类型的实际操作。例如:
:- object(math(_Type_),
implements(math_protocol)).

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

:- end_object.
在这种情况下,示例调用将是:
?- math(number)::add(2, 3, Sum).
Sum = 5
yes
但请注意,这些替代方案仍将在运行时执行类型检查。
可以修改参数对象以查找示例代码中的参数类型。但是,如果没有允许查询术语类型的内置 Prolog 谓词,这是非常低效的(它没有标准,而且通常也不可用)。

关于generics - 序言中的 "Generic programming",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58042928/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com