1 :- module(ast_to_difference_logic, [rewrite_to_idl/2,
2 rewrite_to_idl_no_zero/2,
3 rewrite_inequality_to_idl_disj_no_zero/2,
4 remove_zero_var/2,
5 remove_idl_origin_from_info/2,
6 get_int_value/2]).
7
8 :- use_module(library(lists), [maplist/3, select/3]).
9 :- use_module(probsrc(preferences)).
10 :- use_module(probsrc(b_ast_cleanup), [clean_up_pred/3]).
11
12 add_original_constraint_to_info(_, [], []).
13 add_original_constraint_to_info(Constraint, [DLConstraint|T], [NDLConstraint|NT]) :-
14 DLConstraint = b(Node,Type,Info),
15 NDLConstraint = b(Node,Type,[idl_origin(Constraint)|Info]),
16 add_original_constraint_to_info(Constraint, T, NT).
17
18 rewrite_to_idl_no_zero(Constraint, ConjList) :-
19 rewrite_to_idl(Constraint, TConjList),
20 maplist(remove_zero_var, TConjList, ConjList).
21
22 remove_zero_var(b(less_equal(Sub,Cst),pred,Info), b(less_equal(NSub,Cst),pred,Info)) :-
23 Sub = b(minus(_,_),integer,_),
24 remove_zero_var_from_sub(Sub, NSub).
25 remove_zero_var(b(negation(Term),pred,Info), New) :-
26 !,
27 remove_zero_var(Term, NewTerm),
28 New = b(negation(NewTerm),pred,Info).
29 remove_zero_var(b(conjunct(C1,C2),pred,Info), Out) :-
30 !,
31 remove_zero_var(C1, NC1),
32 remove_zero_var(C2, NC2),
33 Out = b(conjunct(NC1,NC2),pred,Info).
34 remove_zero_var(b(disjunct(C1,C2),pred,Info), Out) :-
35 !,
36 remove_zero_var(C1, NC1),
37 remove_zero_var(C2, NC2),
38 Out = b(disjunct(NC1,NC2),pred,Info).
39 remove_zero_var(Term, Term).
40
41 remove_zero_var_from_sub(b(minus(b(identifier('_zero'),integer,_),Rhs),integer,Info), NSub) :-
42 !,
43 NSub = b(unary_minus(Rhs),integer,Info).
44 remove_zero_var_from_sub(b(minus(Lhs, b(identifier('_zero'),integer,_)),integer,_), NSub) :-
45 !,
46 NSub = Lhs.
47 remove_zero_var_from_sub(Sub, Sub).
48
49 is_idl_candidate(negation(Pred)) :-
50 Pred = b(Node,_,_),
51 is_idl_candidate(Node).
52 is_idl_candidate(less(_,_)).
53 is_idl_candidate(less_equal(_,_)).
54 is_idl_candidate(greater(_,_)).
55 is_idl_candidate(greater_equal(_,_)).
56 is_idl_candidate(equal(_,_)).
57 is_idl_candidate(not_equal(_,_)).
58
59 %% rewrite_to_idl(+Constraint, -ConjList).
60 % Returns a list of conjuncts.
61 % The constraint is normalized by AST cleanup and only <, <= or its negations or =, negated /= are used on the top level.
62 rewrite_to_idl(Constraint, ConjList) :-
63 Constraint = b(Node,pred,_),
64 is_idl_candidate(Node),
65 temporary_set_preference(normalize_ast_sort_commutative, true),
66 clean_up_pred(Constraint, _, Clean),
67 reset_temporary_preference(normalize_ast_sort_commutative),
68 rewrite_to_idl_clean(Clean, TConjList),
69 add_original_constraint_to_info(Constraint, TConjList, ConjList).
70
71 remove_idl_origin_from_info(b(Node,Type,Info), NewNode) :-
72 select(idl_origin(_), Info, NInfo),
73 !,
74 NewNode = b(Node,Type,NInfo).
75 remove_idl_origin_from_info(Ast, Ast).
76
77 %% rewrite_inequality_to_idl_disj_no_zero(+Inequality, -DLConstraint).
78 rewrite_inequality_to_idl_disj_no_zero(Inequality, DLConstraint) :-
79 ( Inequality = b(not_equal(Lhs,Rhs),pred,ConjInfo)
80 ; Inequality = b(negation(b(equal(Lhs,Rhs),pred,ConjInfo)),pred,[])
81 ),
82 rewrite_to_idl_pos(b(equal(Lhs,Rhs),pred,ConjInfo), ConjList),!,
83 ConjList = [TArg1,TArg2],
84 remove_zero_var(TArg1, Arg1),
85 remove_zero_var(TArg2, Arg2),
86 NArg1 = b(negation(Arg1),pred,[]),
87 NArg2 = b(negation(Arg2),pred,[]),
88 DLConstraint = b(disjunct(NArg1,NArg2),pred,[idl_origin(Inequality)]).
89
90 rewrite_to_idl_clean(b(negation(Inequality),pred,_), Out) :-
91 % not(x/=y) -> x=y
92 Inequality = b(not_equal(Lhs,Rhs),pred,EqInfo),
93 !,
94 Equality = b(equal(Lhs,Rhs),pred,EqInfo),
95 rewrite_to_idl_pos(Equality, Out).
96 rewrite_to_idl_clean(b(negation(Constraint),pred,Info), Out) :-
97 !,
98 rewrite_to_idl_pos(Constraint, ConjList),
99 % negation of /= is covered above, other operators provide singleton list
100 ConjList = [DLConstraint],
101 Out = [b(negation(DLConstraint),pred,Info)].
102 rewrite_to_idl_clean(Constraint, DLConstraint) :-
103 rewrite_to_idl_pos(Constraint, DLConstraint).
104
105 % TO DO: do not use b/3 on top level of first argument
106 rewrite_to_idl_pos(Constraint, [NConstraint]) :-
107 % c <= x-y -> y-x <= -c
108 Constraint = b(less_equal(Constant,Rhs),pred,Info),
109 get_int_value(Constant, CVal),
110 rewrite_to_difference(Rhs, TRhs),
111 switch_arguments_in_difference(TRhs, NRhs),
112 !,
113 NCVal is CVal * -1,
114 NConstraint = b(less_equal(NRhs,b(integer(NCVal),integer,[])),pred,Info).
115 rewrite_to_idl_pos(Constraint, [NConstraint]) :-
116 % x+-y <= c -> x-y <= c | x-y <= c -> x-y <= c
117 % x <= c -> x-_zero <= c | -x <= c -> _zero-x <= c
118 Constraint = b(less_equal(Lhs,Constant),pred,Info),
119 get_int_value(Constant, _),
120 rewrite_to_difference(Lhs, NLhs),
121 !,
122 NConstraint = b(less_equal(NLhs,Constant),pred,Info).
123 rewrite_to_idl_pos(Constraint, [NConstraint]) :-
124 % x <= y -> x-y <= 0
125 Constraint = b(less_equal(Id1,Id2),pred,Info),
126 Id1 = b(identifier(_),_,_),
127 Id2 = b(identifier(_),_,_),
128 !,
129 NLhs = b(minus(Id1,Id2),integer,[]),
130 NConstraint = b(less_equal(NLhs,b(integer(0),integer,[])),pred,Info).
131 rewrite_to_idl_pos(Constraint, [NConstraint]) :-
132 % -x <= y -> y-x <= 0
133 Constraint = b(less_equal(Id1,Id2),pred,Info),
134 Id1 = b(unary_minus(b(identifier(_),_,_)),integer,[]),
135 Id2 = b(identifier(_),_,_),
136 !,
137 NLhs = b(minus(Id2,Id1),integer,[]),
138 NConstraint = b(less_equal(NLhs,b(integer(0),integer,[])),pred,Info).
139 rewrite_to_idl_pos(Constraint, [NConstraint]) :-
140 % c <= y -> _zero-y <= -c | c <= -y -> y-_zero <= -c
141 Constraint = b(less_equal(Constant,Id2),pred,Info),
142 get_int_value(Constant, CVal),
143 ( Id2 = b(identifier(Id2Name),integer,Id2Info)
144 -> NegId2 = b(unary_minus(b(identifier(Id2Name),integer,Id2Info)),integer,[])
145 ; Id2 = b(unary_minus(NegId2),integer,[])
146 ),
147 rewrite_to_difference(NegId2, Diff),
148 !,
149 NCVal is CVal * -1,
150 NConstraint = b(less_equal(Diff,b(integer(NCVal),integer,[])),pred,Info).
151 rewrite_to_idl_pos(Constraint, [NConstraint]) :-
152 % c1 <= y-c2 -> _zero-y <= -c2-c1 | c1 <= -y-c2 -> y-_zero <= -c2-c1
153 Constraint = b(less_equal(Constant1,AddOrSub),pred,Info),
154 get_int_value(Constant1, CVal1),
155 get_args_of_add_or_minus_to_addition(AddOrSub, Id2, Constant2),
156 get_int_value(Constant2, CVal2),
157 ( Id2 = b(identifier(Id2Name),integer,Id2Info)
158 -> NegId2 = b(unary_minus(b(identifier(Id2Name),integer,Id2Info)),integer,[])
159 ; Id2 = b(unary_minus(NegId2),integer,[])
160 ),
161 rewrite_to_difference(NegId2, Diff),
162 !,
163 NCVal is CVal2 + CVal1 * -1,
164 NConstraint = b(less_equal(Diff,b(integer(NCVal),integer,[])),pred,Info).
165 rewrite_to_idl_pos(Constraint, [NConstraint]) :-
166 % x <= y-c -> x-y <= -c | x <= y+c -> x-y <= c
167 Constraint = b(less_equal(Id1,AddOrSub),pred,Info),
168 Id1 = b(identifier(_),_,_),
169 get_args_of_add_or_minus_to_addition(AddOrSub, Id2, Constant),
170 !,
171 NLhs = b(minus(Id1,Id2),integer,[]),
172 NConstraint = b(less_equal(NLhs,Constant),pred,Info).
173 rewrite_to_idl_pos(Constraint, [NConstraint]) :-
174 % x - c <= y -> x-y <= c | x + c <= y -> x-y <= -c
175 Constraint = b(less_equal(AddOrSub,Id2),pred,Info),
176 Id2 = b(identifier(_),_,_),
177 get_args_of_add_or_minus_to_addition(AddOrSub, Id1, Constant),
178 get_int_value(Constant, CVal),
179 !,
180 NLhs = b(minus(Id1,Id2),integer,[]),
181 NCVal is CVal * -1,
182 NConstraint = b(less_equal(NLhs,b(integer(NCVal),integer,[])),pred,Info).
183 rewrite_to_idl_pos(Constraint, [NConstraint]) :-
184 % x - c1 <= c2 -> x-_zero <= c2+c1 | x + c1 <= c2 -> x-_zero <= c2-c1
185 Constraint = b(less_equal(AddOrSub,Constant2),pred,Info),
186 get_int_value(Constant2, CVal2),
187 get_args_of_add_or_minus_to_addition(AddOrSub, Id1, Constant1),
188 get_int_value(Constant1, CVal1),
189 !,
190 rewrite_to_difference(Id1, Diff),
191 NCVal is CVal2 + CVal1 * -1,
192 NConstraint = b(less_equal(Diff,b(integer(NCVal),integer,[])),pred,Info).
193 rewrite_to_idl_pos(Constraint, [NConstraint]) :-
194 % x+c1 <= y-c2 -> x-y <= -c2-c1 | x + c1 <= y+c2 -> x-y <= c2-c1
195 % x-c1 <= y-c2 -> x-y <= -c2+c1 | x-c1 <= y+c2 -> x-y <= c2+c1
196 Constraint = b(less_equal(AddOrSub1,AddOrSub2),pred,Info),
197 get_args_of_add_or_minus_to_addition(AddOrSub1, Id1, Constant1),
198 get_args_of_add_or_minus_to_addition(AddOrSub2, Id2, Constant2),
199 get_int_value(Constant1, CVal1),
200 get_int_value(Constant2, CVal2),
201 !,
202 NLhs = b(minus(Id1,Id2),integer,[]),
203 NCVal is CVal2 + CVal1 * -1,
204 NConstraint = b(less_equal(NLhs,b(integer(NCVal),integer,[])),pred,Info).
205 rewrite_to_idl_pos(Constraint, [NConstraint]) :-
206 % c < x-y -> y-x <= -c-1
207 Constraint = b(less(Constant,Rhs),pred,Info),
208 get_int_value(Constant, CVal),
209 rewrite_to_difference(Rhs, TRhs),
210 switch_arguments_in_difference(TRhs, NRhs),
211 !,
212 NCVal is CVal * -1 - 1,
213 NConstraint = b(less_equal(NRhs,b(integer(NCVal),integer,[])),pred,Info).
214 rewrite_to_idl_pos(Constraint, [NConstraint]) :-
215 % x+-y < c -> x-y <= c-1 | x-y < c -> x-y <= c-1
216 % x < c -> x-_zero <= -c-1 | -x < c -> _zero-x <= -c-1
217 Constraint = b(less(Lhs,Constant),pred,Info),
218 get_int_value(Constant, CVal),
219 rewrite_to_difference(Lhs, NLhs),
220 !,
221 NCVal is CVal - 1,
222 NConstraint = b(less_equal(NLhs,b(integer(NCVal),integer,[])),pred,Info).
223 rewrite_to_idl_pos(Constraint, [NConstraint]) :-
224 % x < y -> x-y <= -1
225 Constraint = b(less(Id1,Id2),pred,Info),
226 Id1 = b(identifier(_),_,_),
227 Id2 = b(identifier(_),_,_),
228 !,
229 NLhs = b(minus(Id1,Id2),integer,[]),
230 NConstraint = b(less_equal(NLhs,b(integer(-1),integer,[])),pred,Info).
231 rewrite_to_idl_pos(Constraint, [NConstraint]) :-
232 % -x < y -> y-x <= -1
233 Constraint = b(less(Id1,Id2),pred,Info),
234 Id1 = b(unary_minus(b(identifier(_),_,_)),integer,[]),
235 Id2 = b(identifier(_),_,_),
236 !,
237 NLhs = b(minus(Id2,Id1),integer,[]),
238 NConstraint = b(less_equal(NLhs,b(integer(-1),integer,[])),pred,Info).
239 rewrite_to_idl_pos(Constraint, [NConstraint]) :-
240 % c < y -> _zero-y <= -c-1 | c < -y -> y-_zero <= -c-1
241 Constraint = b(less(Constant,Id2),pred,Info),
242 get_int_value(Constant, CVal),
243 ( Id2 = b(identifier(Id2Name),integer,Id2Info)
244 -> NegId2 = b(unary_minus(b(identifier(Id2Name),integer,Id2Info)),integer,[])
245 ; Id2 = b(unary_minus(NegId2),integer,[])
246 ),
247 rewrite_to_difference(NegId2, Diff),
248 !,
249 NCVal is CVal * -1 - 1,
250 NConstraint = b(less_equal(Diff,b(integer(NCVal),integer,[])),pred,Info).
251 rewrite_to_idl_pos(Constraint, [NConstraint]) :-
252 % c1 < y-c2 -> _zero-y <= -c2-c1-1 | c1 <= -y-c2 -> y-_zero <= -c2-c1-1
253 Constraint = b(less(Constant1,AddOrSub),pred,Info),
254 get_int_value(Constant1, CVal1),
255 get_args_of_add_or_minus_to_addition(AddOrSub, Id2, Constant2),
256 get_int_value(Constant2, CVal2),
257 ( Id2 = b(identifier(Id2Name),integer,Id2Info)
258 -> NegId2 = b(unary_minus(b(identifier(Id2Name),integer,Id2Info)),integer,[])
259 ; Id2 = b(unary_minus(NegId2),integer,[])
260 ),
261 rewrite_to_difference(NegId2, Diff),
262 !,
263 NCVal is CVal2 + CVal1 * -1 - 1,
264 NConstraint = b(less_equal(Diff,b(integer(NCVal),integer,[])),pred,Info).
265 rewrite_to_idl_pos(Constraint, [NConstraint]) :-
266 % x < y-c -> x-y <= -c-1 | x < y+c -> x-y <= c-1
267 Constraint = b(less(Id1,AddOrSub),pred,Info),
268 Id1 = b(identifier(_),_,_),
269 get_args_of_add_or_minus_to_addition(AddOrSub, Id2, Constant),
270 get_int_value(Constant, CVal),
271 !,
272 NLhs = b(minus(Id1,Id2),integer,[]),
273 NCVal is CVal - 1,
274 NConstraint = b(less_equal(NLhs,b(integer(NCVal),integer,[])),pred,Info).
275 rewrite_to_idl_pos(Constraint, [NConstraint]) :-
276 % x-c < y -> x-y <= c-1 | x+c < y -> x-y <= -c-1
277 Constraint = b(less(AddOrSub,Id2),pred,Info),
278 Id2 = b(identifier(_),_,_),
279 get_args_of_add_or_minus_to_addition(AddOrSub, Id1, Constant),
280 get_int_value(Constant, CVal),
281 !,
282 NLhs = b(minus(Id1,Id2),integer,[]),
283 NCVal is CVal * -1 - 1,
284 NConstraint = b(less_equal(NLhs,b(integer(NCVal),integer,[])),pred,Info).
285 rewrite_to_idl_pos(Constraint, [NConstraint]) :-
286 % x - c1 < c2 -> x-_zero <= c2+c1-1 | x + c1 < c2 -> x-_zero <= c2-c1-1
287 Constraint = b(less(AddOrSub,Constant2),pred,Info),
288 get_int_value(Constant2, CVal2),
289 get_args_of_add_or_minus_to_addition(AddOrSub, Id1, Constant1),
290 rewrite_to_difference(Id1, Diff),
291 get_int_value(Constant1, CVal1),
292 !,
293 rewrite_to_difference(Id1, Diff),
294 NCVal is CVal2 + CVal1 * -1 - 1,
295 NConstraint = b(less_equal(Diff,b(integer(NCVal),integer,[])),pred,Info).
296 rewrite_to_idl_pos(Constraint, [NConstraint]) :-
297 % x+c1 < y-c2 -> x-y <= -c2-c1-1 | x+c1 < y+c2 -> x-y <= c2-c1-1
298 % x-c1 < y-c2 -> x-y <= -c2+c1-1 | x-c1 < y+c2 -> x-y <= c2+c1-1
299 Constraint = b(less(AddOrSub1,AddOrSub2),pred,Info),
300 get_args_of_add_or_minus_to_addition(AddOrSub1, Id1, Constant1),
301 get_args_of_add_or_minus_to_addition(AddOrSub2, Id2, Constant2),
302 get_int_value(Constant1, CVal1),
303 get_int_value(Constant2, CVal2),
304 !,
305 NLhs = b(minus(Id1,Id2),integer,[]),
306 NCVal is CVal2 + CVal1 * -1 - 1,
307 NConstraint = b(less_equal(NLhs,b(integer(NCVal),integer,[])),pred,Info).
308 rewrite_to_idl_pos(Constraint, ConjList) :-
309 % c = _ -> rewrite(_ = c)
310 Constraint = b(equal(Constant,Rhs),pred,Info),
311 get_int_value(Constant, _),
312 \+ get_int_value(Rhs, _),
313 !,
314 rewrite_to_idl_pos(b(equal(Rhs,Constant),pred,Info), ConjList).
315 rewrite_to_idl_pos(Constraint, [NC1,NC2]) :-
316 % x-y = c -> x-y <= c & y-x <= -c | x+-y = c -> x-y <= c & y-x <= -c
317 Constraint = b(equal(Lhs,Constant),pred,Info),
318 get_int_value(Constant, CVal),
319 !,
320 rewrite_to_difference(Lhs, Diff),
321 switch_arguments_in_difference(Diff, SDiff),
322 NCVal is CVal * -1,
323 NC1 = b(less_equal(Diff,Constant),pred,Info),
324 NC2 = b(less_equal(SDiff,b(integer(NCVal),integer,[])),pred,Info).
325 rewrite_to_idl_pos(Constraint, NConstraint) :-
326 % x = y-c -> rewrite(x-y = -c) | x = y+c -> rewrite(x-y = c)
327 Constraint = b(equal(Id1,AddOrSub),pred,Info),
328 Id1 = b(identifier(_),_,_),
329 get_args_of_add_or_minus_to_addition(AddOrSub, Id2, Constant),
330 !,
331 NLhs = b(minus(Id1,Id2),integer,[]),
332 rewrite_to_idl_pos(b(equal(NLhs,Constant),pred,Info), NConstraint).
333 rewrite_to_idl_pos(Constraint, NConstraint) :-
334 % x-c1 = y-c2 -> rewrite(x-y = -c2+c1) | x-c1 = y+c2 -> rewrite(x-y = c1+c2)
335 % x+c1 = y-c2 -> rewrite(x-y = -c2-c1) | x+c1 = y+c2 -> rewrite(x-y = c1-c2)
336 Constraint = b(equal(AddOrSub1,AddOrSub2),pred,Info),
337 get_args_of_add_or_minus_to_addition(AddOrSub1, Id1, Constant1),
338 get_args_of_add_or_minus_to_addition(AddOrSub2, Id2, Constant2),
339 get_int_value(Constant1, CVal1),
340 get_int_value(Constant2, CVal2),
341 !,
342 NCVal is CVal2 + CVal1 * -1,
343 NLhs = b(minus(Id1,Id2),integer,[]),
344 rewrite_to_idl_pos(b(equal(NLhs,b(integer(NCVal),integer,[])),pred,Info), NConstraint).
345 rewrite_to_idl_pos(Constraint, NConstraint) :-
346 % x = y -> rewrite(x-y = 0)
347 Constraint = b(equal(Id1,Id2),pred,Info),
348 Id1 = b(identifier(_),_,_),
349 Id2 = b(identifier(_),_,_),
350 !,
351 Constraint2 = b(equal(b(minus(Id1,Id2),integer,[]),b(integer(0),integer,[])),pred,Info),
352 rewrite_to_idl_pos(Constraint2, NConstraint).
353 rewrite_to_idl_pos(Constraint, NConstraint) :-
354 % -x = -y -> rewrite(y-x = 0)
355 Constraint = b(equal(Id1,Id2),pred,Info),
356 Id1 = b(unary_minus(b(identifier(_),_,_)),integer,[]),
357 Id2 = b(unary_minus(PosId2),integer,[]),
358 !,
359 Constraint2 = b(equal(b(minus(PosId2,Id1),integer,[]),b(integer(0),integer,[])),pred,Info),
360 rewrite_to_idl_pos(Constraint2, NConstraint).
361 rewrite_to_idl_pos(Constraint, NConstraint) :-
362 % x-c = y -> rewrite(x-y = c) | x+c = y -> rewrite(x-y = -c)
363 Constraint = b(equal(AddOrSub,Id2),pred,Info),
364 get_args_of_add_or_minus_to_addition(AddOrSub, Id1, Constant),
365 Id2 = b(identifier(_),_,_),
366 get_int_value(Constant, CVal),
367 !,
368 NCVal is CVal * -1,
369 Constraint2 = b(equal(b(minus(Id1,Id2),integer,[]),b(integer(NCVal),integer,[])),pred,Info),
370 rewrite_to_idl_pos(Constraint2, NConstraint).
371 rewrite_to_idl_pos(Constraint, NConstraint) :-
372 % c1 = y-c2 -> rewrite(y = c1+c2) | c1 = y+c2 -> rewrite(y = c1-c2)
373 Constraint = b(equal(Constant1,AddOrSub),pred,Info),
374 get_args_of_add_or_minus_to_addition(AddOrSub, Id2, Constant2),
375 get_int_value(Constant1, CVal1),
376 get_int_value(Constant2, CVal2),
377 !,
378 NCVal is CVal1 + CVal2 * -1,
379 Constraint2 = b(equal(Id2,b(integer(NCVal),integer,[])),pred,Info),
380 rewrite_to_idl_pos(Constraint2, NConstraint).
381 rewrite_to_idl_pos(Constraint, NConstraint) :-
382 % x-c1 = c2 -> rewrite(x = c2+c1) | x+c1 = c2 -> rewrite(x = c2-c1)
383 Constraint = b(equal(AddOrSub,Constant2),pred,Info),
384 get_args_of_add_or_minus_to_addition(AddOrSub, Id1, Constant1),
385 get_int_value(Constant1, CVal1),
386 get_int_value(Constant2, CVal2),
387 !,
388 NCVal is CVal2 + CVal1 * -1,
389 Constraint2 = b(equal(Id1,b(integer(NCVal),integer,[])),pred,Info),
390 rewrite_to_idl_pos(Constraint2, NConstraint).
391 rewrite_to_idl_pos(Constraint, NConstraint) :-
392 % x = c -> rewrite(x-_zero = c) | -x = c -> rewrite(_zero-x = c)
393 Constraint = b(equal(Id1,Constant),pred,Info),
394 Id1 = b(identifier(_),_,_),
395 get_int_value(Constant, _),
396 !,
397 rewrite_to_difference(Id1, Diff),
398 Constraint2 = b(equal(Diff,Constant),pred,Info),
399 rewrite_to_idl_pos(Constraint2, NConstraint).
400
401 get_args_of_add_or_minus_to_addition(b(add(Id,Constant),integer,_), Id, Constant) :-
402 Id = b(identifier(_),integer,_),
403 get_int_value(Constant, _).
404 get_args_of_add_or_minus_to_addition(b(minus(Id,Constant),integer,_), Id, b(integer(NCVal),integer,[])) :-
405 % x-c -> x+-c
406 Id = b(identifier(_),integer,_),
407 get_int_value(Constant, CVal),
408 NCVal is CVal * -1.
409
410 switch_arguments_in_difference(b(minus(Lhs,Rhs),integer,Info), b(minus(Rhs,Lhs),integer,Info)).
411
412 %% rewrite_to_difference(+IdOrDiff, -Diff).
413 % Possibly introduce artificial variable _zero.
414 rewrite_to_difference(Id, Diff) :-
415 % x -> x-_zero
416 Id = b(identifier(_),integer,_),
417 !,
418 Diff = b(minus(Id,b(identifier('_zero'),integer,[])),integer,[]).
419 rewrite_to_difference(UId, Diff) :-
420 % -x -> _zero-x
421 UId = b(unary_minus(b(identifier(IdName),integer,IdInfo)),integer,_),
422 !,
423 Diff = b(minus(b(identifier('_zero'),integer,[]),b(identifier(IdName),integer,IdInfo)),integer,[]).
424 rewrite_to_difference(Add, Diff) :-
425 % x+-y -> x-y
426 Add = b(add(b(identifier(V1),integer,Info1),b(unary_minus(Id2),integer,_)),integer,InfoAdd),
427 Id2 = b(identifier(_),integer,_),
428 Diff = b(minus(b(identifier(V1),integer,Info1),Id2),integer,InfoAdd).
429 rewrite_to_difference(Diff, Diff) :-
430 % difference of positive integer ids
431 Diff = b(minus(b(identifier(_),integer,_),b(identifier(_),integer,_)),_,_).
432
433 %% get_int_value(+IntegerAst, -Value).
434 get_int_value(b(integer(Value),integer,_), Value).
435 get_int_value(b(value(int(Value)),integer,_), Value).