34
35:- module(interface,
36 [ bind_interface/2
37 ]). 38
39:- use_module(library(lists)). 40:- use_module(library(apply)). 41:- use_module(library(error)). 42:- reexport(library(compound_expand)). 43:- init_expansors. 44
45:- multifile
46 '$interface'/1,
47 '$interface'/2,
48 '$implementation'/2. 49
50direct_interface(M, F/A) :-
51 \+ ( current_predicate(M:F/A),
52 functor(H, F, A),
53 predicate_property(M:H, defined),
54 \+ predicate_property(M:H, imported_from(_))
55 ).
56
57end_interface(Interface, DIL) -->
58 [interface:'$interface'(Interface, DIL)],
59 findall((:- dynamic Interface:F/A),
60 member(F/A, DIL)).
61
62term_expansion_decl(implements(Alias), Clauses) :-
63 '$current_source_module'(Implementation),
64 Implementation:use_module(Alias, []), 65 absolute_file_name(Alias, File, [file_type(prolog), access(read)]),
66 module_property(Interface, file(File)),
67 term_expansion_decl(implements_mod(Interface), Clauses).
68term_expansion_decl(implements_mod(Interface), Clauses) :-
69 '$current_source_module'(Implementation),
70 '$interface'(Interface, PIL),
71 phrase(( [interface:'$implementation'(Implementation, Interface)],
72 findall((:- meta_predicate Implementation:Spec),
73 ( member(F/A, PIL),
74 functor(Pred, F, A),
75 predicate_property(Interface:Pred, meta_predicate(Spec))
76 )),
77 findall((:- export(PI)), member(PI, PIL))
78 ), Clauses).
79term_expansion_decl(interfaces(Alias), Clauses) :-
80 '$current_source_module'(Interface),
81 Interface:use_module(Alias, []),
82 absolute_file_name(Alias, File, [file_type(prolog), access(read)]),
83 module_property(Implementation, file(File)),
84 term_expansion_decl(interfaces_mod(Implementation), Clauses).
85term_expansion_decl(interfaces_mod(Implementation), Clauses) :-
86 '$current_source_module'(Interface),
87 module_property(Implementation, exports(PIL)),
88 phrase(( findall((:- export(PI)), member(PI, PIL)),
89 end_interface(Interface, PIL)
90 ), Clauses).
91term_expansion_decl(interface, interface:'$interface'(Interface)) :-
92 '$current_source_module'(Interface).
93
94term_expansion((:- Decl), Clauses) :-
95 term_expansion_decl(Decl, Clauses).
96term_expansion(end_of_file, Clauses) :-
97 '$current_source_module'(Interface),
98 '$interface'(Interface),
99 module_property(Interface, file(File)),
100 prolog_load_context(source, File),
101 module_property(Interface, exports(PIL)),
102 include(direct_interface(Interface), PIL, DIL),
103 phrase(end_interface(Interface, DIL), Clauses, [end_of_file]).
104
105prolog:called_by(Pred, Interface, Context, PredL) :-
106 '$interface'(Interface, DIL),
107 member(F/A, DIL),
108 functor(Pred, F, A),
109 findall(@(Implementation:Pred, Context),
110 interface:'$implementation'(Implementation, Interface),
111 PredL),
112 PredL \= [].
118bind_interface(Interface, Implementation) :-
119 ( '$interface'(Interface, DIL)
120 ->true
121 ; existence_error(interface, Interface)
122 ),
123 ( '$implementation'(Implementation, Interface)
124 ->true
125 ; ( '$implementation'(Implementation, _)
126 ->existence_error(implementation, Implementation)
127 ; existence_error(binding, Interface->Implementation)
128 )
129 ),
130 forall(( member(F/A, DIL),
131 functor(H, F, A)
132 ),
133 ( retractall(Interface:H),
134 Implementation:assertz((Interface:H :- H))))