34
35:- module(shrink,
36 [ shrink/2,
37 expand/2
38 ]). 39
40:- use_module(library(apply)). 41:- use_module(library(lists)). 42:- use_module(library(neck)). 43:- init_expansors. 44
45:- meta_predicate
46 shrink(1, -),
47 expand(1, -). 48
49esc_max_size(16).
50
52
53escaped_atom(B) :-
54 esc_max_size(N),
55 between(1, N, X),
56 length(L, X),
57 maplist(=(&), L),
58 atomic_list_concat(L, B).
59
60shrink(GenTerm, Shrink) :- shrink_expand(shrink, GenTerm, Shrink).
61
62expand(GenTerm, Expand) :- shrink_expand(expand, GenTerm, Expand).
63
64shrink_expand_args(shrink, S2, S, S2, S).
65shrink_expand_args(shrnkt, S2, S, S2, S).
66shrink_expand_args(expand, S2, S, S, S2).
67shrink_expand_args(expndt, S2, S, S, S2).
68
69shrink_expand(Cmd, GenTerm, S) :-
70 SL = s(''),
71 call(GenTerm, S2),
72 SL = s(S1),
73 shrink_expand_args(Cmd, S2, S, S3, S4),
74 once(diff_term(Cmd, S1, S3, S4)),
75 nb_setarg(1, SL, S3).
82skip_comp(T) :- var(T).
83skip_comp(B) :-
84 escaped_atom(B),
85 necki,
86 !,
87 fail.
88skip_comp([]).
89skip_comp('[|]').
90skip_comp(Atom) :-
91 atom(Atom),
92 current_op(_, _, Atom),
93 atom_length(Atom, L),
94 L =< 3.
95skip_comp(Atom) :-
96 atomic(Atom),
97 write_length(Atom, L,
98 [ quoted(true),
99 backquoted_string(true)
100 ]),
101 L =< 2.
102
103:- meta_predicate
104 diff_term(+, ?, ?, ?). 105
106diff_term(Cmd, A, B, D) :-
107 diff_term(Cmd, =@=, A, B, D).
108
109cmd_into(shrink, shrnkt).
110cmd_into(shrnkt, shrnkt).
111cmd_into(expand, expndt).
112cmd_into(expndt, expndt).
113
114diff_term(_, _, _, T, T) :- skip_comp(T), !.
115diff_term(shrink, O, A, B, C) :- diff_term_into(shrink, O, A, B, C), !.
116diff_term(expand, O, A, B, C) :- diff_term_into(expand, O, A, B, C), !.
117diff_term(shrnkt, O, A, B, C) :- diff_term_shrnkt(O, A, B, [], C), !.
118diff_term(expndt, _, A, B, C) :- diff_term_expndt( A, B, C), !.
119diff_term(Cmd, O, A, B, D) :- diff_term_args(Cmd, O, A, B, D), !.
120diff_term(_, _, _, T, T).
121
122diff_term_args(Cmd, _, A, X, Y) :-
123 compound(A),
124 A =.. L1,
125 length(L1, N1),
126 cmd_into(Cmd, Into),
127 shrink_expand_args(Into, X, Y, B, D),
128 compound(B),
129 B =.. L2,
130 length(L2, N2),
131 N is min(N1, N2),
132 length(C1, N),
133 length(C2, N),
134 append(C1, _, L1),
135 append(C2, R2, L2),
136 shrink_expand_args(Into, C2, C3, D2, D3),
137 138 139 maplist(diff_term(Into, ==), C1, D2, D3),
140 append(C3, R2, L3),
141 D =.. L3,
142 !.
143
144escape_atom(B, C) :-
145 escaped_atom(B),
146 atom_concat(&, B, C),
147 neck.
148
149diff_term_shrnkt(_, _, B, _, C) :- escape_atom(B, C), !.
150diff_term_shrnkt(=@=, A, B, L, &) :- A-L =@= B-L.
151diff_term_shrnkt(==, A, B, L, &) :- A-L == B-L.
152
153simplify_term(M:A, M:B, A, B).
154simplify_term( A, B, A, B).
155
156diff_term_expndt(A, A, B) :-
157 B == (&).
158diff_term_expndt(_, C, B) :-
159 escape_atom(C, B).
160
161diff_term_into(Cmd, O, P, Q, R) :-
162 once(( var(R)
163 ; R \= (_:_)
164 )),
165 once(simplify_term(P, Q, A, B)),
166 cmd_into(Cmd, Into),
167 diff_term(Into, O, A, B, R)