33
34:- module(scasp_model,
35 [ canonical_model/2, 36 unqualify_model/3, 37 print_model/2 38 ]). 39:- use_module(library(apply)). 40:- use_module(library(lists)). 41:- use_module(library(pairs)). 42
43:- use_module(common). 44:- use_module(modules). 45:- use_module(output). 46
47:- meta_predicate
48 canonical_model(:, -),
49 print_model(:, +). 50
51:- multifile
52 model_hook/2. 53
58
60
61canonical_model(M:Model, CanModel) :-
62 flatten(Model, FlatModel),
63 exclude(nonmodel_term, FlatModel, Model1),
64 sort(Model1, Unique),
65 maplist(raise_negation, Unique, Raised),
66 filter_shown(M, Raised, Filtered),
67 sort_model(Filtered, Sorted),
68 simplify_model(Sorted, CanModel).
69
70nonmodel_term(abducible(_)).
71nonmodel_term(proved(_)).
72nonmodel_term(chs(_)).
73nonmodel_term(o_nmr_check).
74nonmodel_term(not(X)) :-
75 nonvar(X),
76 !,
77 nonmodel_term(X).
78nonmodel_term(Term) :-
79 functor(Term, Name, _),
80 ( sub_atom(Name, 0, _, _, 'o_')
81 -> true
82 ; sub_atom(Name, _, _, 0, '$')
83 ).
84
91
92filter_shown(M, Model, Shown) :-
93 maplist(tag_module(M), Model, Tagged),
94 maplist(arg(1), Tagged, Modules),
95 sort(Modules, Unique),
96 include(has_shown, Unique, Filter),
97 ( Filter == []
98 -> Shown = Model
99 ; convlist(do_show(Filter), Tagged, Shown)
100 ).
101
102tag_module(M, Term, t(Q, Unqualified, Term)) :-
103 model_term_module(M:Term, Q),
104 unqualify_model_term(Q, Term, Unqualified).
105
106has_shown(Module) :-
107 clause(Module:pr_show_predicate(_), _),
108 !.
109
110do_show(Filter, t(M,Unqualified,Term), Term) :-
111 ( memberchk(M, Filter)
112 -> M:pr_show_predicate(Unqualified)
113 ; true
114 ).
115
126
127sort_model(ModelIn, Sorted) :-
128 map_list_to_pairs(literal_key, ModelIn, Pairs),
129 keysort(Pairs, KSorted),
130 pairs_values(KSorted, Sorted).
131
132literal_key(Term, Literal-Flags) :-
133 literal_key(Term, Literal, 0, Flags).
134
135literal_key(not(X), Key, F0, F) =>
136 literal_key(X, Key, F0, F1),
137 F is F1+0x1.
138literal_key(-(X), Key, F0, F) =>
139 literal_key(X, Key, F0, F1),
140 F is F1+0x2.
141literal_key(X, Key, F0, F) =>
142 Key = X,
143 F = F0.
144
148
149simplify_model([not(X0),-X1|T0], M), X0 == X1 =>
150 M = [-X1|M0],
151 simplify_model(T0, M0).
152simplify_model([X0, not(-(X1))|T0], M), X0 == X1 =>
153 M = [X0|M0],
154 simplify_model(T0, M0).
155simplify_model([H|T0], M) =>
156 M = [H|M0],
157 simplify_model(T0, M0).
158simplify_model([], M) =>
159 M = [].
160
164
165unqualify_model(Model0, Module, Model) :-
166 maplist(unqualify_model_term(Module), Model0, Model).
167
183
184:- if(\+current_predicate(tty_size/2)). 185tty_size(25,80).
186:- endif. 187
188print_model(Model, Options) :-
189 model_hook(Model, Options),
190 !.
191print_model(_:Model, Options) :-
192 ( option(width(Width), Options)
193 -> true
194 ; catch(tty_size(_, Width), _, Width = 80)
195 ),
196 layout(Model, Width, Layout),
197 compound_name_arguments(Array, v, Model),
198 format('{ ', []),
199 print_table(0, Array, Layout.put(_{ sep:',',
200 end:'\n}',
201 prefix:' ',
202 options:Options
203 })).
204
205print_table(I, Array, Layout) :-
206 Cols = Layout.cols,
207 Rows = Layout.rows,
208 Row is I // Cols,
209 Col is I mod Cols,
210 Index is Row + Col * Rows + 1,
211
212 213 214 ( NIndex is Row + (Col+1) * Rows + 1,
215 functor(Array, _, LastIndex),
216 NIndex =< LastIndex
217 -> NL = false,
218 Last = false
219 ; NL = true,
220 ( Row+1 =:= Rows
221 -> Last = true
222 ; Last = false
223 )
224 ),
225
226 227 228 229 ( arg(Index, Array, Atom)
230 -> ( NL == false,
231 Last == false
232 -> format('~|~@~w~t~*+',
233 [print_model_term(Atom, Layout.options),
234 Layout.sep, Layout.col_width])
235 ; Last == false
236 -> format('~@~w', [print_model_term(Atom, Layout.options), Layout.sep])
237 ; format('~@~w', [print_model_term(Atom, Layout.options), Layout.end])
238 ),
239 Print = true
240 ; true
241 ),
242
243 244 245 ( Last == true
246 -> true
247 ; ( Print == true, NL == true
248 -> format('~n~w', [Layout.prefix])
249 ; true
250 ),
251 I2 is I+1,
252 print_table(I2, Array, Layout)
253 ).
254
255layout(Atoms, Width, _{cols:Cols, rows:Rows, col_width:ColWidth}) :-
256 length(Atoms, L),
257 longest(Atoms, Longest),
258 Cols0 is max(1, Width // (Longest + 3)),
259 Rows is ceiling(L / Cols0),
260 Cols is ceiling(L/Rows),
261 ColWidth is min(Longest+3, Width // Cols).
262
263longest(List, Longest) :-
264 longest(List, 0, Longest).
265
266longest([], M, M) :- !.
267longest([H|T], Sofar, M) :-
268 write_length(H, Length,
269 [ portray(true),
270 numbervars(true),
271 quoted(true)
272 ]),
273 Length >= Sofar,
274 !,
275 longest(T, Length, M).
276longest([_|T], S, M) :-
277 longest(T, S, M)