Koryonik
Koryonik

Reputation: 2758

Use "univ" Prolog predicate with a Logtalk object method as parameter

How to use the 'Univ' ( =../2 ) prolog predicate with a Logtalk object method as parameter ?

Consider this code :

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.

I'll obtain :

?- {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

What workaround to use for a good interpretation / compilation ? It seems issue is the same with swi-prolog building predicate like predsort/3 (predsort/3 doc).

Upvotes: 0

Views: 150

Answers (1)

Paulo Moura
Paulo Moura

Reputation: 18663

The standard =../2 predicate expects, when constructing a term from a list, that the first list argument be an atom but bar::baz is a compound term with functor ::/2 (which is both defined as a predicate - for top-level queries - and as an operator when Logtalk is loaded). The solution is to write instead:

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.

With this changes, you get:

?- {univ}.
% [ /Users/pmoura/Desktop/univ.lgt loaded ]
% (0 warnings)
true.

?- run.
baz(foo(testfoo))
predicatetestfoo

bar::baz(foo(testfoo))
predicatetestfoo

true.

Upvotes: 2

Related Questions