如何使用' Univ' (=../2
)prolog谓词,使用Logtalk对象方法作为参数?
考虑以下代码:
baz(foo(X)) :-
write(predicate), write(X), nl.
run :-
Term =.. [baz, foo(testfoo)],
write(Term), nl, Term,nl,
TermLgt =.. [bar::baz, foo(testfoo2)],
write(TermLgt), nl, Term,nl.
:- object(bar).
:- public(baz/1).
baz(foo(X)) :-
write(method), write(X), nl.
:- end_object.
:- object(main).
:- public(run/0).
run :-
Term =.. [baz, foo(testfoo)],
write(Term), nl, Term,nl,
TermLgt =.. [bar::baz, foo(testfoo2)],
write(TermLgt), nl, Term,nl.
:- end_object.
我将获得:
?- {myfile}.
% (0 warnings)
true.
?- run.
baz(foo(testfoo))
predicatetestfoo
ERROR: =../2: Type error: `atom' expected, found `bar::baz' (a compound)
?- main::run.
baz(foo(testfoo))
ERROR: Undefined procedure: baz/1
ERROR: However, there are definitions for:
ERROR: baz/1
用于良好解释/编译的解决方法是什么?似乎问题与swi-prolog构建谓词相同,如predsort/3
(predsort/3 doc)。
答案 0 :(得分:2)
标准=../2
谓词在从列表构造术语时期望第一个列表参数是原子,但bar::baz
是带有仿函数::/2
的复合词(两者都是定义为谓词 - 用于顶级查询 - 并在加载Logtalk时作为运算符)。解决方案是改为编写:
baz(foo(X)) :-
write(predicate), write(X), nl.
run :-
Term =.. [baz, foo(testfoo)],
write(Term), nl, call(Term), nl,
TermLgt =.. [::, bar, Term],
write(TermLgt), nl, call(Term), nl.
:- object(bar).
:- public(baz/1).
baz(foo(X)) :-
write(method), write(X), nl.
:- end_object.
:- object(main).
:- public(run/0).
run :-
Term =.. [baz, foo(testfoo)],
write(Term), nl, Term,nl,
TermLgt =.. [::, bar, Term],
write(TermLgt), nl, Term,nl.
:- end_object.
通过此更改,您将获得:
?- {univ}.
% [ /Users/pmoura/Desktop/univ.lgt loaded ]
% (0 warnings)
true.
?- run.
baz(foo(testfoo))
predicatetestfoo
bar::baz(foo(testfoo))
predicatetestfoo
true.