:- module(dictoo_lib, [ oo/1, oo_bind/2, is_oo/1, is_oo/2, % '$was_dictoo'/2, is_oo_invokable/2, oo_call/4, oo_call_dot_hook/4, oo_jpl_call/3, oo_derefed/2, oo_derefed/3, oo_deref/3, oo_put_attr/3, oo_put_attrs/2, oo_get_attr/3, oo_get_attrs/2, oo_inner_class_begin/1, oo_inner_class_end/1, oo_class_field/1, oo_class_begin/1, oo_class_end/1, oo_set/3, oo_put_dict/4, oo_get_dict/3 ]). /** Utility LOGICMOO DICTOO Dict-like OO Syntax Pack Now everyone can get dictoo! Dict-like OO Syntax - allows dictionary to be used in object orientated ways, common interface for hashmaps, dictionaries trees, object-orientated objects used in the same ways. - @author Douglas R. Miles - @license LGPL Author: Douglas R. Miles E-mail: logicmoo@gmail.com WWW: [http://www.logicmoo.org] Copyright (C): 2017 */ :- set_module(class(library)). :- set_prolog_flag(generate_debug_info, false). :- reexport(library(gvar_lib)). :- use_module(library(dicts)). :- if(\+ current_module(attvar_serializer)). :- use_module(library(logicmoo/attvar_serializer)). :- endif. :- multifile(dot_cfg:using_dot_type/2). :- dynamic(dot_cfg:using_dot_type/2). :- nodebug(dictoo(core)). :- nodebug(dictoo(decl)). :- nodebug(dictoo(syntax)). :- nodebug(dictoo(goal_expand)). %:- autoload(library(jpl),[jpl_set/3,jpl_get/3,jpl_call/4]). :- autoload(library(backcomp),[string_to_atom/2]). % :- use_module(atts). :- meta_predicate(fail_on_missing(*)). % fail_on_missing(G):-current_predicate(G),!,call(G). fail_on_missing(G):- notrace(catch(G,error(existence_error(_,_),_),fail)). oo_get_attr(MVar,Attr,Value):- % notrace ((strip_module(MVar,M,Var),oo_call(M,Var,Attr,Value))). oo_put_attr(MVar,Attr,Value):- notrace((strip_module(MVar,M,Var),oo_put_dict(M,Attr,Var,Value))). oo_get_attrs(V,Att3s):- var(V),!,get_attrs(V,Att3s),!. oo_get_attrs('$VAR'(Name),_):- atom(Name),!,fail. oo_get_attrs('$VAR'(Att3s),Att3):-!,Att3s=Att3. oo_get_attrs('aVar'(Att3s),Att3):-!,Att3s=Att3. oo_get_attrs('aVar'(_,Att3s),Att3):-!,Att3s=Att3. % oo_get_attrs(V,Value):- trace_or_throw(oo_get_attrs(V,Value)). put_atts_list([KV|Attrs],Var):-!, get_kv(KV,K,V),oo_set(Var,K,V),put_atts_list(Attrs,Var). put_atts_list([],_):-!. %:- if(exists_source(library(atts))). %:- user:use_module(library(atts)). oo_put_attrs(V,Attrs):- must_be(nonvar,Attrs),is_list(Attrs),!,put_atts_list(Attrs,V). %:- endif. oo_put_attrs(V,Att3s):- var(V),!,put_attrs(V,Att3s),!. oo_put_attrs(VAR,Att3s):- VAR='$VAR'(Name), atom(Name),!,setarg(1,VAR, att(vn, Name, Att3s)). oo_put_attrs(VAR,Att3s):- VAR='$VAR'(_Att3),!,setarg(1,VAR, Att3s). oo_put_attrs(VAR,Att3s):- VAR='aVar'(_Att3),!,setarg(1,VAR, Att3s). oo_put_attrs(VAR,Att3s):- VAR='aVar'(_,_),!,setarg(2,VAR, Att3s). oo_put_attrs(V,Att3s):- trace_or_throw(oo_put_attrs(V,Att3s)). % '$was_dictoo'(_,_). %% is_oo(+Self) is det. %% is_oo(+Module,+Self) is det. % % Tests to see if Self % Has Member Functions % is_oo(S):- ((strip_module(S,M,O),is_oo(M,O))). %is_oo(_,_):- !. % assume we''ll take care of dicts as well is_oo(M,O):- (var(O)->attvar(O); (is_dvar(O)->true; (((((((O='$was_dictoo'(MM,_),ignore(M=MM)); is_dict(O); O=jclass(_); O=jpl(_); O= class(_); O='&'(_) ; O='&'(_,_) ; functor(O,'.',2); is_logtalk_object(O); (oo_deref(M,O,DREF)->O\==DREF); fail_on_missing(jpl_is_ref(O)); fail_on_missing(cli_is_object(O)); fail_on_missing(cli_is_struct(O)))))))))),!. :- if((false,exists_source(library(multivar)))). :- use_module(library(multivar)). oo(O):- call(ignore,xvarx(O)),put_attr(O,oo,binding(O,_Value)). :- else. oo(O):- do_but_warn(put_attr(O,oo,binding(O,_Value))). :- endif. do_but_warn(G):- call(G),dmsg(do_but_warn(G)). oo_bind(O,Value):- oo(O),put_attr(O,oo,binding(O,Value)). oo:attr_unify_hook(B,Value):- B = binding(_Var,Prev)->Prev.equals(Value);true. oo_get_extender(_,_):-fail. oo_put_extender(_,_):-fail. new_oo(_M,Self,NewSelf):- oo(Self)->NewSelf=Self. logtalk_ready :- current_predicate(logtalk:current_logtalk_flag/2). is_logtalk_object(O):- logtalk_ready, call(call,logtalk:current_object(O)). nb_setattr(Att,Key,Value):-nb_setattr(Att,Att,Key,Value). nb_setattr(att(Key,_OldValue,_),Atts,Key,Value):-!,nb_setarg(2,Atts,Value). nb_setattr(att(_,_,[]),Att,Key,Value):-!,nb_setarg(3,Att,att(Key,Value,[])). nb_setattr(att(_,_,Att),_,Key,Value):-nb_setattr(Att,Att,Key,Value). b_setattr(Att,Key,Value):-b_setattr(Att,Att,Key,Value). b_setattr(att(Key,_OldValue,_),Atts,Key,Value):-!,setarg(2,Atts,Value). b_setattr(att(_,_,[]),Att,Key,Value):-!,setarg(3,Att,att(Key,Value,[])). b_setattr(att(_,_,Att),_,Key,Value):-b_setattr(Att,Att,Key,Value). oo_set(UDT,Key,Value):- attvar(UDT),!,get_attrs(UDT,Atts),nb_setattr(Atts,Atts,Key,Value). oo_set(UDT,Key,Value):- var(UDT),!,do_but_warn(put_attr(UDT,Key,Value)),!. oo_set(UDT,Key,Value):- oo_derefed(UDT,DREF),!,oo_set(DREF,Key,Value). oo_set(UDT,Key,Value):- is_dict(UDT),!,nb_set_dict(Key,UDT,Value). %oo_set(UDT,Key,Value):- is_rbtree(UDT),!,nb_rb_insert(UDT, Key, Value),!. oo_set(UDT,Key,Value):- is_rbtree(UDT),!,rb_insert(UDT,Key,Value,NewUDT),nb_copy(2,NewUDT,UDT). oo_set(UDT,Key,Value):- is_assoc(UDT),!, put_assoc(Key,UDT,Value,NewUDT),nb_copy(NewUDT,UDT). oo_set(UDT,Key,Value):- UDT=..[U,D|T], oo_nb_set_varholder(U,D,T,UDT,Key,Value). oo_set(UDT,Key,Value):- is_list(UDT),!,((member(KV,UDT),get_kv(KV,K,_),Key==K,nb_set_kv(KV,K,Value))->true;(nb_copy([Key-Value|UDT],UDT))). oo_set(UDT,Key,Value):- fail_on_missing(jpl_is_ref(UDT)),fail_on_missing(jpl_set(UDT,Key,Value)). %oo_set(UDT,Key,Value):- trace_or_throw(oo_set(UDT,Key,Value)). oo_nb_set_varholder('$VAR',Name,[],UDT,Key,Value):- atom(Name),!,nb_setarg(1,UDT,att(vn, Name, att(Key,Value, []))). oo_nb_set_varholder('$VAR',Att3,[],UDT,Key,Value):- nb_setarg(1,UDT,att(Key,Value,Att3)). oo_nb_set_varholder('aVar',Att3,[],UDT,Key,Value):- nb_setarg(1,UDT,att(Key,Value,Att3)). oo_nb_set_varholder('aVar',_D,[Att3],UDT,Key,Value):- nb_setarg(2,UDT,att(Key,Value,Att3)). oo_nb_set_varholder('att',_D,_T,UDT,Key,Value):- !,nb_setattr(UDT,Key,Value). oo_b_set_varholder('$VAR',Name,[],UDT,Key,Value):- atom(Name),!,setarg(1,UDT,att(vn, Name, att(Key,Value, []))). oo_b_set_varholder('$VAR',Att3,[],UDT,Key,Value):- setarg(1,UDT,att(Key,Value,Att3)). oo_b_set_varholder('aVar',Att3,[],UDT,Key,Value):- setarg(1,UDT,att(Key,Value,Att3)). oo_b_set_varholder('aVar',_D,[Att3],UDT,Key,Value):- setarg(2,UDT,att(Key,Value,Att3)). oo_b_set_varholder('att',_D,_T,UDT,Key,Value):- !,b_setattr(UDT,Key,Value). b_copy(NewMap,Map):-functor(NewMap,F,A),functor(Map,F,A),b_copy(A,NewMap,Map). b_copy(A,NewMap,Map):- arg(A,NewMap,E),setarg(A,NewMap,E), (A==1-> true ; Am1 is A-1, (b_copy(Am1,NewMap,Map))). nb_copy(NewMap,Map):-functor(NewMap,F,A),functor(Map,F,A),nb_copy(A,NewMap,Map). nb_copy(2,NewUDT,UDT):- !, arg(1,NewUDT,Arg1),nb_setarg(1,UDT,Arg1),arg(2,NewUDT,Arg2),nb_setarg(2,UDT,Arg2). nb_copy(A,NewMap,Map):- arg(A,NewMap,E),nb_setarg(A,NewMap,E), (A==1-> true ; Am1 is A-1, (b_copy(Am1,NewMap,Map))). %get_kv(KV,K,V):-compound(KV),(KV=..[_,K,V]->true;KV=..[K,V]). %% get_kv( ?KV, ?X, ?Y) is semidet. % % Get Kv. % get_kv(X=Y,X,Y):- !. get_kv(X-Y,X,Y):- !. get_kv(KV,X,Y):- functor(KV,_,1),KV=..[X,Y],!. get_kv(KV,X,Y):- arg(1,KV,X),arg(2,KV,Y),!. % @TODO WRONG?! set_kv(KV,K,V):- b_put_kv(KV,K,V). nb_set_kv(KV,K,V):- nb_put_kv(KV,K,V). b_put_kv(KV,_,V):- functor(KV,_,A),setarg(A,KV,V). nb_put_kv(KV,_,V):- functor(KV,_,A),nb_setarg(A,KV,V). % oo_get_attr(V,A,Value):- trace_or_throw(oo_get_attr(V,A,Value)). oo_put_dict5(M,Key,UDT,Value, NewUDT):- is_dict(UDT),!,M:put_dict(Key,UDT,Value, NewUDT). oo_put_dict5(M,Key,UDT,Value, NewUDT):- oo_copy_term(UDT,NewUDT),oo_put_dict(M,Key,NewUDT,Value). oo_copy_term(UDT,NewUDT):- copy_term(UDT,NewUDT). oo_put_dict( M,Key,UDT,Value):- var(UDT),!,(attvar(UDT)-> M:put_attr(UDT,Key,Value);do_but_warn(put_attr(UDT,Key,Value))). oo_put_dict( M,Key,UDT,Value):- \+ compound(UDT),!,oo_derefed(M,UDT,DREF),!,oo_put_dict(M,DREF,Key,Value). oo_put_dict(_M,Key,UDT,Value):- compound_name_arity(UDT,att,3),nb_setattr(UDT,Key,Value). oo_put_dict( M,Key,UDT,Value):- is_dict(UDT),!,M:m_put_dict(Key,UDT,Value). oo_put_dict(_M,Key,UDT,Value):- is_rbtree(UDT),!,rb_insert(UDT,Key,Value,NewUDT),arg(1,NewUDT,Arg1),setarg(1,UDT,Arg1),arg(2,NewUDT,Arg2),setarg(2,UDT,Arg2). oo_put_dict(_M,Key,UDT,Value):- is_assoc(UDT),!,put_assoc(Key,UDT,Value,NewUDT),b_copy(NewUDT,UDT). oo_put_dict(_M,Key,UDT,Value):- is_list(UDT),!,((member(KV,UDT),get_kv(KV,K,_),Key==K,set_kv(KV,K,Value))->true;(b_copy([Key-Value|UDT],UDT))). % todo index these by sending in the UDT on two args oo_put_dict(_M,Key,UDT,Value):- UDT=..[U,D|T], oo_b_set_varholder(U,D,T,UDT,Key,Value). oo_put_dict( M,Key,REF,Value):- oo_derefed(M,REF,DREF),!,oo_put_dict(M,DREF,Key,Value). oo_put_dict( M,Key,UDT,Value):- M:oo_set(UDT,Key,Value),!. oo_put_dict( M,Key,UDT,Value):- trace_or_throw(oo_put_dict(M,Key,UDT,Value)). oo_get(UDT,Key,Value):- oo_get_dict(Key,UDT,Value). oo_get_dict(Key,UDT,Value):- strip_module(UDT,M,Self), oo_get_dict(M,Key,Self, Value). oo_get_dict(M,Key,Self, Value):- oo_call(M,Self,Key,Value). m_put_dict(Key,Map,Value):- ((get_dict(Key,Map,_),b_set_dict(Key,Map,Value))->true; (oo_put_extender(Map,Ext),oo_put_attr(Ext,Key,Value))). oo_jpl_call(A,B,C):- (integer(B);B==length; B= (_-_)),!,fail_on_missing(jpl_get(A,B,C)). oo_jpl_call(A,B,C):- (compound(B)->compound_name_arguments(B,H,L);(H=B,L=[])),fail_on_missing(jpl_call(A,H,L,C)),!. oo_jpl_call(A,B,C):- catch(fail_on_missing(jpl_get(A,B,C)),E,(debug(dictoo(_),'~N~w,~n',[E:jpl_get(A,B,C)]),fail)). to_atomic_name(DMemb,Memb):- compound(DMemb),!,compound_name_arity(DMemb,Memb,0). to_atomic_name(Memb,Memb):- var(Memb),!. to_atomic_name(SMemb,Memb):- string_to_atom(SMemb,Memb). member_func_unify(X,Y):- to_atomic_name(X,X1),to_atomic_name(Y,Y1),X1=Y1. %% is_oo_invokable(+Self,-DeRef) is det. % % DeRef''s an OO Whatnot and ckecks if invokable % is_oo_invokable(Was,Was):- is_oo(Was),!. % is_oo_invokable(Was,Was):- M:nb_current('$oo_stack',[Was|_]) is_oo_invokable(Was,Ref):- strip_module(Was,M,Self),oo_deref(M,Self,Ref),!,((Self\==Ref,M:Self\==Ref,Self\==M:Ref);is_oo(M,Ref)). :- module_transparent(oo_call/4). :- module_transparent(oo_call_dot_hook/4). :- thread_initialization(nb_setval('$oo_stack',[])). oo_call_dot_hook(M,Self, Func, Value):- is_dict(Self), M:dot_dict(Self, Func, Value),!. oo_call_dot_hook(M,A,B,C):- (M:nb_current('$oo_stack',Was)->true;Was=[]),b_setval('$oo_stack',['.'(A,B,C)|Was]),oo_call(M,A,B,C). oo_call(M,DVAR, Memb,Value):- dvar_name(M,DVAR,_,NameSpace), dot_cfg:dictoo_decl(= ,_SM,_CM,From,DVAR,DMemb,Value,Call),member_func_unify(DMemb,Memb),!, sanity(ground(NameSpace)), show_call(dictoo(core), From:Call). %oo_call(M,DVAR,Memb,Value):- Memb==value, dvar_name(M,DVAR,_,GVar), atom(GVar), var(Value),M:nb_current_value(GVar,Value),!. %oo_call(M,DVAR,Memb,Value):- Memb==value, dvar_name(M,DVAR,_,GVar), atom(GVar),!,must( M:nb_link_value(GVar,Value)),!, on_bind(Value,gvar_put(M, GVar, Value)),!. oo_call(_M,Self,Memb,Value):- notrace((atom(Memb),attvar(Self))),get_attr(Self, Memb, Value),!. oo_call(M,Self,Memb,Value):- var(Self),atom(Memb),!, % trace, on_bind(Self,oo_call(M,Self,Memb,Value)). oo_call(M,Self,Memb,Value):- var(Self),!, % trace, on_bind(Self,oo_call(M,Self,Memb,Value)). oo_call(_M,'$VAR'(Name),N,V):- atom(Name),!,N=vn,V=Name. oo_call(_M,'$VAR'(Att3),A,Value):- !, put_attrs(NewVar,Att3),get_attr(NewVar,A,Value). oo_call(_M,'aVar'(Att3),A,Value):- !, put_attrs(NewVar,Att3),get_attr(NewVar,A,Value). oo_call(_M,'aVar'(_,Att3),A,Value):- !, put_attrs(NewVar,Att3),get_attr(NewVar,A,Value). oo_call(M,Map,Key,Value):-is_dict(Map),!,(get_dict(Key,Map,Value)->true;(oo_get_extender(Map,Ext),oo_call(M,Ext,Key,Value))). oo_call(M,Map,Key,Value):-is_rbtree(Map),!,(rb_in(Key,Value,Map)->true;(oo_get_extender(Map,Ext),oo_call(M,Ext,Key,Value))). oo_call(M,Map,Key,Value):-is_assoc(Map),!,(get_assoc(Key,Value,Map)->true;(oo_get_extender(Map,Ext),oo_call(M,Ext,Key,Value))). oo_call(M,Map,Key,Value):-is_list(Map),!,((member(KV,Map),get_kv(KV,K,V),Key==K,V=Value)->true;(oo_get_extender(Map,Ext),oo_call(M,Ext,Key,Value))). oo_call(_M,Self,Memb,Value):- strip_module(Memb,M,Prop),Memb\==Prop,catch(oo_call(M,Self,Prop,Value),_E,fail). oo_call(M,'$was_dictoo'(CM,Self),Memb,Value):- var(Self),new_oo(M,Self,NewSelf),!,M:oo_call(CM,NewSelf,Memb,Value). oo_call(M,DVAR,add(Memb,V),'$was_dictoo'(M,DVAR)):- dvar_name(M,DVAR,_,GVar), notrace((atom(GVar),M:nb_current_value(GVar,Self))), is_dict(Self),!, M:m_put_dict(Memb,Self,V,NewSelf), M:nb_set_value(GVar,NewSelf). oo_call(M,DVAR,Memb,Value):- dvar_name(M,DVAR,_,GVar), atom(GVar), gvar_call(M, GVar, Memb, Value),!. oo_call(M,DVAR,Memb,Value):- dvar_name(M,DVAR,_,GVar), is_gvar(M,GVar,_Name),gvar_call(M,GVar,Memb,Value),!. oo_call(M,'&'(Self,_),Memb,Value):- gvar_call(M,Self,Memb,Value),!. oo_call(M,'&'(_,Self),Memb,Value):- oo_call(M,Self,Memb,Value),!. oo_call(M,Self,set(Memb,Value),'&'(Self)):- is_dict(Self),!,M:nb_set_dict(Memb,Self,Value). oo_call(M,Self,Memb,Value):- notrace(is_dict(Self)),!, M:dot_dict(Self, Memb, Value). oo_call(M,'&'(Self),Memb,Value):- !,oo_call(M,Self,Memb,Value). oo_call(M,jpl(Self),Memb,Value):- !, M:oo_jpl_call(Self, Memb, Value). oo_call(M,jclass(Self),Memb,Value):- !, M:oo_jpl_call(Self, Memb, Value). oo_call(M,class(Self),Memb,Value):- M:fail_on_missing(cli_call(Self, Memb, Value)),!. oo_call(M,DVAR,Memb,Value):- dvar_name(M,DVAR,_,GVar), atom(GVar), (M:nb_current_value(GVar,Self)),oo_call(M,Self,Memb,Value), M:nb_set_value(GVar,Self). oo_call(M,Self,Memb,Value):- fail_on_missing(jpl_is_ref(Self)),!,M:oo_jpl_call(Self, Memb, Value). oo_call(M,Self,Memb,Value):- notrace(fail_on_missing(cli_is_object(Self))),!,fail_on_missing(M:cli_call(Self, Memb, Value)). oo_call(M,Self,Memb,Value):- notrace(fail_on_missing(cli_is_struct(Self))),!,fail_on_missing(M:cli_call(Self, Memb, Value)). oo_call(M,Class,Inner,Value):- show_success(is_oo_class(inner(Class,Inner))),!,oo_call(M,inner(Class,Inner),Value,_). oo_call(M,'&'(_,DeRef),Memb,Value):- oo_call(M,DeRef,Memb,Value). %oo_call(M,Self,deref,Value):- var(Self),nonvar(Value),!,oo_call(M,Value,deref,Self). %oo_call(M,Self,deref,Self):-!. % oo_call(M,Self,Memb,Value):- nonvar(Value),trace_or_throw(oo_call(M,Self,Memb,Value)). oo_call(M,Self,Memb,Value):- oo_derefed(M,Self,NewSelf),!,oo_call(M,NewSelf,Memb,Value). % oo_call(M,Self,Memb,Value):- gvar_interp(M,Self,Self,Memb,Value). oo_call(M,DVAR,Memb,Value):- dvar_name(M,DVAR,_,NameSpace), nonvar(NameSpace), dot_cfg:dictoo_decl(= ,_SM,_CM,From,DVAR,Unk,Value,Call),!, throw(M:dot_cfg=dictoo_decl(= ,From,NameSpace,Memb-->Unk,Value,Call)),fail. oo_call(_,M:Self,Memb,Value):- !,oo_call(M,Self,Memb,Value). oo_call(_,_Self,_Memb,_Value):- !,fail. oo_call(_,Self,Memb,Value):- Value =.. ['.', Self,Memb],!. oo_call(M,Self,Memb,Value):- throw(oo_call(M,Self,Memb,Value)). oo_call(M,Self,Memb,Value):- var(Value),!,on_bind(Value, oo_put_dict(M,Memb,Self, Value)). oo_call(M,Self,Memb,Value):- var(Memb),!,on_bind(Memb, oo_put_dict(M,Memb,Self, Value)). oo_call(_,Self,Memb,Value):- var(Value),!,Value='&'(Self,Memb). oo_call(M,Self,Memb,Value):- throw(oo_call(M,Self,Memb,Value)). /* oo_call(M,Self,Memb,Value):- nb_link_value(Self,construct(Self,Memb,Value)),!,oo_call(M,Self,Memb,Value). oo_call(M,Self,Memb,Value):- to_member_path(Memb,[F|Path]),append(Path,[Value],PathWValue), Call =.. [F,Self|PathWValue], oo_call(M,Call). to_member_path(C,[F|ARGS]):-compound(C),!,compound_name_args(C,F,ARGS). to_member_path(C,[C]). */ bb_key(Module:Key, Atom) :- atom(Module), !, atomic(Key), atomic_list_concat([Module, Key], :, Atom). bb_key(Key, Atom) :- atomic(Key), prolog_load_context(module, Module), atomic_list_concat([Module, Key], :, Atom). oo_derefed(MObj,RObj):- strip_module(MObj,M,Obj),oo_derefed(M,Obj,RObj). oo_derefed( M,Obj,RObj):- oo_deref(M,Obj,RObj),!,RObj\==Obj. oo_derefed(_M,Obj,RObj):- atom(Obj),!,oo_new(_,RObj),nb_setval(Obj,RObj). oo_deref(M,Obj,RObj):- var(Obj),!,M:once(get_attr(Obj,oo,binding(_,RObj));Obj=RObj),!. oo_deref(_,Value,Value):- \+ compound(Value),!. % oo_deref(M,'$'(GVar),'&'(GVar,Value)):- atom(GVar),M:nb_current_value(GVar,Value),!. %oo_deref(M,'$'(GVar),'&'(GVar,Value)):- atom(GVar),(M:nb_current_value(GVar,Value)->true;(Value=[],M:nb_setvar(GVar,Value))). oo_deref(M,DVAR,Value):- dvar_name(M,DVAR,_,GVar), atom(GVar),notrace((M:nb_current_value(GVar,ValueM))),!,oo_deref(M,ValueM,Value). oo_deref(M,inline_cl_eval(Call),Result):-is_list(Call),!,M:fail_on_missing(cl_eval(Call,Result)). oo_deref(M,inline_cl_eval(Call),Result):-!,nonvar(Call),oo_deref(M,Call,CallE),!,M:call(CallE,Result). %oo_deref(M,Value,Value):- M:fail_on_missing(jpl_is_ref(Value)),!. % %oo_deref(M,[A|B],Result):-!, maplist(oo_deref(M),[A|B],Result). % %oo_deref(M,Call,Result):- call(Call,Result),!. %oo_deref(_,Value,Value):- is_logtalk_object(Value). %oo_deref(M,Head,HeadE):- Head=..B,maplist(oo_deref(M),B,A),HeadE=..A,!. oo_deref(_,Value,Value). oo_get_dict(M,Key,Dict, Value, NewDict, NewDict) :- is_dict(Dict),!, M:get_dict(Key,Dict, Value, NewDict, NewDict). oo_get_dict(M,Key,Dict, Value, NewDict, NewDict) :- oo_get_dict(M,Key,Dict, Value), oo_put_dict5(M,Key,Dict, NewDict, NewDict). %! eval_oo_function(M,+Func, +Tag, +UDT,-Value) % % Test for predefined functions on Objects or evaluate a user-defined % function. eval_oo_function(_M,Func, Tag, UDT,Value) :- is_dict(UDT),!, '$dicts':eval_dict_function(Func, Tag, UDT,Value). eval_oo_function(M,get(Key), _, UDT,Value) :- !, oo_get_dict(M,Key,UDT,Value). eval_oo_function(M,put(Key,Value), _, UDT,NewUDT) :- !, ( atomic(Key) -> oo_put_dict5(M,Key,UDT,Value, NewUDT) ; put_oo_path(M,Key,UDT,Value, NewUDT) ). eval_oo_function(M,put(New), _Tag, UDT,NewUDT) :- !, % put_dict(New, Dict, NewDict). oo_put_dict(M,New, UDT,NewUDT). eval_oo_function(M,Func, Tag, UDT,Value) :- M:call(Tag:Func, UDT,Value). %! put_oo_path(M,+KeyPath, +UDT,+Value, -NewUDT) % % Add/replace a value according to a path definition. Path % segments are separated using '/'. put_oo_path(M,Key,UDT,Value, NewUDT) :- atom(Key), !, oo_put_dict5(M,Key,UDT,Value, NewUDT). put_oo_path(M,Path, UDT,Value, NewUDT) :- get_oo_path(M,Path, UDT,_Old, NewUDT,Value). get_oo_path(_M,Path, _, _, _, _) :- var(Path), !, '$instantiation_error'(Path). get_oo_path(M,Path/Key,UDT,Old, NewUDT,New) :- !, get_oo_path(M,Path, UDT,OldD, NewUDT,NewD), ( oo_get_dict(M,Key,OldD, Old, NewD, New), is_oo(M,Old) -> true ; Old = _{}, oo_put_dict5(M,Key,OldD, New, NewD) ). get_oo_path(M,Key,UDT,Old, NewUDT,New) :- oo_get_dict(M,Key,UDT,Old, NewUDT,New), is_oo(M,Old), !. get_oo_path(M,Key,UDT,_{}, NewUDT,New) :- oo_put_dict5(M,Key,UDT,New, NewUDT). :- dynamic(is_oo_class/1). :- dynamic(is_oo_class_field/2). :- multifile(dot_cfg:dictoo_decl/8). :- dynamic(dot_cfg:dictoo_decl/8). :- discontiguous(dot_cfg:dictoo_decl/8). % is_oo_hooked(M,Self,_Func,_Value):- M:is_oo(M,Self),!. is_oo_hooked(M,Self,_Func,_Value):- M:is_oo_invokable(Self,_),!. % $current_file.value = X :- prolog_load_context(file,X). % dot_cfg:dictoo_decl(= ,mpred_gvars,current_file,value,A,prolog_load_context(file, A)). is_oo_hooked(M, IVar, Memb, Value):- compound(IVar), IVar = ($(Var)), dot_cfg:dictoo_decl(= ,_SM,_CM,M,Var, Memb, Value,_Body). % is_oo_hooked(M, IVar, value, Ref):- atom(IVar),IVar=Var,dot_cfg:dictoo_decl(= ,SM,CM,M,IVar,value,_Value,_Body),!,must(Ref=IVar). %is_oo_hooked(M,Var,_,Ref):- dot_cfg:dictoo_decl(= ,SM,CM,M,Var,value,_Value,_Body),Ref=Var. oo_class_begin(Name):-asserta(is_oo_class(Name)). oo_class_end(Name):- is_oo_class(Name),!,retract(is_oo_class(Name)),assertz(is_oo_class(Name)). oo_inner_class(Name,Inner):-asserta(is_oo_class(inner(Name,Inner))). oo_inner_class_begin(Inner):- is_oo_class(Name),!,oo_class_begin(inner(Name,Inner)). oo_inner_class_end(Inner):- is_oo_class(inner(Name,Inner)),!,oo_class_end(inner(Name,Inner)). oo_class_field(Inner):- is_oo_class(Name),!,asserta(is_oo_class_field(Name,Inner)). :- multifile(gvs:dot_overload_hook/4). :- dynamic(gvs:dot_overload_hook/4). :- module_transparent(gvs:dot_overload_hook/4). gvs:dot_overload_hook(M,NewName, Memb, Value):- dot_cfg:using_dot_type(_,M) -> show_call(dictoo(overload),oo_call_dot_hook(M,NewName, Memb, Value)). :- multifile(gvs:is_dot_hook/4). :- dynamic(gvs:is_dot_hook/4). :- module_transparent(gvs:is_dot_hook/4). gvs:is_dot_hook(M,Self,Func,Value):- dot_cfg:using_dot_type(_,M) -> is_oo_hooked(M,Self,Func,Value),!. :- gvar_file_predicates_are_exported, gvar_file_predicates_are_transparent.