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
184print_model(Model, Options) :-
185 model_hook(Model, Options),
186 !.
187print_model(_:Model, Options) :-
188 ( option(width(Width), Options)
189 -> true
190 ; catch(tty_size(_, Width), _, Width = 80)
191 ),
192 layout(Model, Width, Layout),
193 compound_name_arguments(Array, v, Model),
194 format('{ ', []),
195 print_table(0, Array, Layout.put(_{ sep:',',
196 end:'\n}',
197 prefix:' ',
198 options:Options
199 })).
200
201print_table(I, Array, Layout) :-
202 Cols = Layout.cols,
203 Rows = Layout.rows,
204 Row is I // Cols,
205 Col is I mod Cols,
206 Index is Row + Col * Rows + 1,
207
208 209 210 ( NIndex is Row + (Col+1) * Rows + 1,
211 functor(Array, _, LastIndex),
212 NIndex =< LastIndex
213 -> NL = false,
214 Last = false
215 ; NL = true,
216 ( Row+1 =:= Rows
217 -> Last = true
218 ; Last = false
219 )
220 ),
221
222 223 224 225 ( arg(Index, Array, Atom)
226 -> ( NL == false,
227 Last == false
228 -> format('~|~@~w~t~*+',
229 [print_model_term(Atom, Layout.options),
230 Layout.sep, Layout.col_width])
231 ; Last == false
232 -> format('~@~w', [print_model_term(Atom, Layout.options), Layout.sep])
233 ; format('~@~w', [print_model_term(Atom, Layout.options), Layout.end])
234 ),
235 Print = true
236 ; true
237 ),
238
239 240 241 ( Last == true
242 -> true
243 ; ( Print == true, NL == true
244 -> format('~n~w', [Layout.prefix])
245 ; true
246 ),
247 I2 is I+1,
248 print_table(I2, Array, Layout)
249 ).
250
251layout(Atoms, Width, _{cols:Cols, rows:Rows, col_width:ColWidth}) :-
252 length(Atoms, L),
253 longest(Atoms, Longest),
254 Cols0 is max(1, Width // (Longest + 3)),
255 Rows is ceiling(L / Cols0),
256 Cols is ceiling(L/Rows),
257 ColWidth is min(Longest+3, Width // Cols).
258
259longest(List, Longest) :-
260 longest(List, 0, Longest).
261
262longest([], M, M) :- !.
263longest([H|T], Sofar, M) :-
264 write_length(H, Length,
265 [ portray(true),
266 numbervars(true),
267 quoted(true)
268 ]),
269 Length >= Sofar,
270 !,
271 longest(T, Length, M).
272longest([_|T], S, M) :-
273 longest(T, S, M)