据我所知,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).有没有可能在运行时不检查每个变量的类型就编写“泛型”谓词?
发布于 2021-05-03 03:02:21
通过Logtalk在Prolog中提供了一些形式的泛型编程,Logtalk扩展了Prolog,可以与大多数Prolog系统一起使用。
假设您希望根据前两个参数的类型使用不同的add/3谓词定义,我们可以从定义一个声明谓词的协议开始:
:- 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.我们可以修改number和var对象来执行类型检查。例如:
:- object(number,
implements(math_protocol)).
add(A, B, C) :-
number(A),
number(B),
C is A + B.
:- end_object.或者,我们可以在执行类型检查的类型上定义一个对象参数,然后委托对该类型的实际操作。例如:
:- 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谓词来允许查询term类型,效率就会很低(但是,没有相应的标准,而且通常也不可用)。
发布于 2021-05-02 17:07:38
您可以通过向谓词显式添加type参数来模拟参数多态性:
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 instantiatedhttps://stackoverflow.com/questions/58042928
复制相似问题