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