Search code examples
prologcategorieslogtalk

Category method provided by the object


Let say I have :

:- category(multi).

    :- public([set/2, set/3]).
    %% set(r,c,v).
    set([],_). %% multi-ix/value set    
    set([[Row, Col]|RCs], Value) :- \+ is_list(Value), set(Row, Col, Value), set(RCs, Value).
    set([[Row, Col]|RCs], [V|Vs]) :- set(Row, Col, V), set(RCs, Vs).

:- end_category.


 *     Declared static predicate called but not defined: set/3

set/3 is provided by the Object... how to make it works..?


Solution

  • Simply call the set/3 predicate in self (i.e. in the context of the object that receives the set/2 message):

    :- category(multi).
    
        :- public([set/2, set/3]).
        %% set(r,c,v).
        set([],_). %% multi-ix/value set    
        set([[Row, Col]|RCs], Value) :- \+ is_list(Value), ::set(Row, Col, Value), set(RCs, Value).
        set([[Row, Col]|RCs], [V|Vs]) :- ::set(Row, Col, V), set(RCs, Vs).
    
    :- end_category.
    

    Assuming, for example, the following object importing the category:

    :- object(proto,
        imports(multi)).
    
        set(1, 1, 42).
    
    :- end_object.
    

    You can then use queries such as:

    ?- proto::set([[1,1]], V).
    V = 42 ;
    V = [42|_].
    

    P.S. The is_list/1 predicate is not a standard built-in predicate. But the same functionality is available from the list library object. For example, after loading basic_types(loader), you can use in the category:

    :- uses(list, [valid/1 as is_list/1]).
    

    Or, in alternative, use the type object provided by the same library:

    :- uses(type, [valid(list,Term) as is_list(Term)]).