Используйте предикат "univ" Prolog с методом объекта Logtalk в качестве параметра
Как использовать " Univ" (=../2
) предикат пролога с методом объекта 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-пролога. predsort/3
( предсортировка / 3 документа).
1 ответ
Решение
Стандарт =../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.