1 % (c) 2014-2022 Lehrstuhl fuer Softwaretechnik und Programmiersprachen,
2 % Heinrich Heine Universitaet Duesseldorf
3 % This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html)
4
5 :- module(smtlib2_translation,[smt_type_to_prob_type/3,
6 smt_term_to_prob_term/3,
7 smt_type_to_prob_type_maplist/3,
8 smt_term_to_prob_term_maplist/3,
9 bool_to_pred/2,
10 typing_constraint/2,
11 is_function_constraint/3]).
12
13 :- use_module(probsrc(module_information),[module_info/2]).
14 :- module_info(group,smtlib).
15 :- module_info(description,'The SMT-LIB 2 Interpreter - Translation from SMT-LIB 2 to B').
16
17 :- use_module(library(lists)).
18
19 :- use_module(probsrc(bsyntaxtree),[get_texpr_type/2,
20 get_texpr_expr/2,
21 safe_create_texpr/3,
22 create_forall/3,
23 create_exists/3,
24 create_couple/2,
25 create_implication/3,
26 conjunct_predicates/2,
27 replace_id_by_expr/4]).
28
29 :- use_module(smtlib_solver(smtlib2_environment)).
30
31 chain(Op,[A,B],BPred) :- !,
32 Pred =.. [Op,A,B],
33 BPred = b(Pred,pred,[]).
34 chain(Op,[First,Second|Further],TermOut) :-
35 chain(Op,[First,Second],Pred),
36 chain(Op,[Second|Further],FurtherPred),
37 conjunct_predicates([Pred,FurtherPred],TermOut).
38
39 interleave(_Op,[A],TermOut) :- !, TermOut=A.
40 interleave(Op,[First|Further],TermOut) :-
41 interleave(Op,Further,FurtherPred),
42 get_texpr_type(FurtherPred,FurtherType),
43 Pred =.. [Op,First,FurtherPred],
44 safe_create_texpr(Pred,FurtherType,TermOut).
45
46 :- use_module(probsrc(preferences), [get_preference/2]).
47 :- use_module(probsrc(error_manager),[add_error/3]).
48 smt_type_to_prob_type(sort('Int'),_,integer) :- !.
49 smt_type_to_prob_type(sort('Bool'),_,boolean) :- !.
50 smt_type_to_prob_type(sort('Array',[From,sort('Bool')]),E,Out) :-
51 get_preference(smtlib2b_arrays_as_sets,true),
52 !, % we could translate arrays to Bool as sets
53 smt_type_to_prob_type(From,E,FromType),
54 Out = set(FromType).
55 smt_type_to_prob_type(sort('Array',[From,To]),E,Out) :- !,
56 %format('Sort Array ~w to ~w~n',[From,To]),nl,
57 smt_type_to_prob_type(From,E,FromType),
58 smt_type_to_prob_type(To,E,ToType),
59 Out = set(couple(FromType,ToType)).
60 smt_type_to_prob_type(sort('BitVec',[_Length]),_E,Out) :- !,
61 Out = set(couple(integer,integer)).
62 smt_type_to_prob_type(sort('Set',[Sub]),E,Out) :- !,
63 smt_type_to_prob_type(Sub,E,SubType),
64 Out = set(SubType).
65 smt_type_to_prob_type(sort(X),E,global(X)) :-
66 is_custom_type(E,X), !.
67 smt_type_to_prob_type(X,_,_) :- !,
68 add_error(smtlib2_translation,'Unsupported sort in smt_type_to_prob_type:',X), fail.
69
70 % special versions for maplist that keeps first argument indexing
71 smt_term_to_prob_term_maplist(E,I,O) :-
72 smt_term_to_prob_term(I,E,O).
73 smt_type_to_prob_type_maplist(E,I,O) :-
74 smt_type_to_prob_type(I,E,O).
75
76 smt_term_to_prob_term(attributed_term(Term,_Attr),Env,Out) :- !,
77 smt_term_to_prob_term(Term,Env,Out).
78 smt_term_to_prob_term(id_term(id('not'),[Arg]),Env,Out) :- !,
79 smt_term_to_prob_term(Arg,Env,BArg),
80 get_texpr_type(BArg,Type),
81 (Type = pred
82 -> Out = b(negation(BArg),pred,[])
83 ; Out = b(equal(BArg,b(boolean_false,boolean,[])),pred,[])).
84 smt_term_to_prob_term(id_term(id('-'),[SingleArg]),Env,Out) :- !,
85 % special case for unary minus: can not be interleaved
86 smt_term_to_prob_term(SingleArg,Env,BArg),
87 Out = b(unary_minus(BArg),integer,[]).
88 smt_term_to_prob_term(id_term(id('='),Args),Env,Out) :- !,
89 maplist(smt_term_to_prob_term_maplist(Env),Args,BArgs),
90 maplist(get_texpr_type,BArgs,Types),
91 (member(pred,Types)
92 -> maplist(bool_to_pred,BArgs,BArgsPreds),
93 chain(equivalence,BArgsPreds,Out)
94 ; chain(equal,BArgs,Out)).
95 smt_term_to_prob_term(id_term(id('ite'),[Test,If,Then]),Env,Out) :- !,
96 smt_term_to_prob_term(Test,Env,BTestT),
97 smt_term_to_prob_term(If,Env,BIfT),
98 smt_term_to_prob_term(Then,Env,BThenT),
99 bool_to_pred(BTestT,BTest),
100 to_bool_if_necessary(BIfT,BIf),
101 to_bool_if_necessary(BThenT,BThen),
102 get_texpr_type(BIf,Type),
103 Out = b(if_then_else(BTest,BIf,BThen),Type,[]).
104 % set logic
105 smt_term_to_prob_term(id_term(id(member),[Element,Set]),Env,Out) :- !,
106 smt_term_to_prob_term(Set,Env,BSet),
107 smt_term_to_prob_term(Element,Env,BElement),
108 Out = b(member(BElement,BSet),pred,[]).
109 smt_term_to_prob_term(id_term(id(card),[Set]),Env,Out) :- !,
110 smt_term_to_prob_term(Set,Env,BSet),
111 Out = b(card(BSet),integer,[]).
112 smt_term_to_prob_term(id_term(id(singleton),[Element]),Env,Out) :- !,
113 smt_term_to_prob_term(Element,Env,BElement),
114 get_texpr_type(BElement,ElementType),
115 Out = b(set_extension([BElement]),set(ElementType),[]).
116 smt_term_to_prob_term(id_term(id(union),[SetA,SetB]),Env,Out) :- !,
117 smt_term_to_prob_term(SetA,Env,BSetA),
118 smt_term_to_prob_term(SetB,Env,BSetB),
119 get_texpr_type(BSetB,Type),
120 Out = b(union(BSetA,BSetB),Type,[]).
121 smt_term_to_prob_term(id_term(id(intersection),[SetA,SetB]),Env,Out) :- !,
122 smt_term_to_prob_term(SetA,Env,BSetA),
123 smt_term_to_prob_term(SetB,Env,BSetB),
124 get_texpr_type(BSetB,Type),
125 Out = b(intersection(BSetA,BSetB),Type,[]).
126 smt_term_to_prob_term(id_term(id(subset),[SetA,SetB]),Env,Out) :- !,
127 smt_term_to_prob_term(SetA,Env,BSetA),
128 smt_term_to_prob_term(SetB,Env,BSetB),
129 Out = b(subset(BSetA,BSetB),pred,[]).
130 % array logics
131 smt_term_to_prob_term(id_term(id('store'),[Array,Index,Element]),Env,Out) :- !,
132 smt_term_to_prob_term(Array,Env,BArray),
133 get_texpr_type(BArray,ArrayType),
134 ArrayType = set(CoupleType),
135 smt_term_to_prob_term(Index,Env,BIndex),
136 smt_term_to_prob_term(Element,Env,BElement),
137 % TO DO: generate union or set_difference depending on Element=true or false when smtlib2b_arrays_as_sets
138 % store(X,Index,El) = IF El=TRUE THEN X \/ {Index} ELSE X \ {Index} END
139 SetEx = b(set_extension([b(couple(BIndex,BElement),CoupleType,[])]),ArrayType,[]),
140 Out = b(overwrite(BArray,SetEx),ArrayType,[]).
141 smt_term_to_prob_term(id_term(id('select'),[Array,Index]),Env,Out) :- !,
142 smt_term_to_prob_term(Array,Env,BArray),
143 smt_term_to_prob_term(Index,Env,BIndex),
144 get_texpr_type(BArray,ArrayType),
145 %format('select of array ~w (type: ~w) at index ~w~n',[Array,ArrayType,Index]),
146 (ArrayType = set(couple(_From,To)) % Array was translated as total function From --> To
147 -> Out = b(function(BArray,BIndex),To,[])
148 ; ArrayType = set(_From), % Array was translated as set (smtlib2b_arrays_as_sets=true)
149 MEM = b(member(BIndex,BArray),pred,[]),
150 Out = b(convert_bool(MEM),boolean,[])
151 ).
152 % bitvector logics
153 smt_term_to_prob_term(id_term(id('concat'),[A,B]),Env,Out) :- !,
154 smt_term_to_prob_term(A,Env,BA),
155 smt_term_to_prob_term(B,Env,BB),
156 bvwidth(BA,WidthA),
157 bvwidth(BB,WidthB),
158 WidthBP1 = b(add(WidthB,Int1),integer,[]),
159 Int0 = b(integer(0),integer,[]),
160 Int1 = b(integer(1),integer,[]),
161 IdX1 = b(identifier('\\tmp1'),integer,[]),
162 IdX2 = b(identifier('\\tmp2'),integer,[]),
163 FullWidth = b(add(b(add(WidthA,WidthB),integer,[]),Int1),integer,[]),
164 TypeOfX1 = b(member(IdX1,b(interval(Int0,FullWidth),set(integer),[])),pred,[]),
165 TypeOfX2 = b(member(IdX2,b(interval(Int0,Int1),set(integer),[])),pred,[]),
166 ValOfX2 = b(if_then_else(b(less_equal(IdX1,WidthB),pred,[]),
167 b(function(BB,IdX1),integer,[]),
168 b(function(BA,b(minus(IdX1,WidthBP1),integer,[])),integer,[])),integer,[]),
169 conjunct_predicates([TypeOfX1,TypeOfX2,b(equal(IdX2,ValOfX2),pred,[])],Pred),
170 Out = b(comprehension_set([IdX1,IdX2],Pred),set(couple(integer,integer)),[]).
171 smt_term_to_prob_term(id_term(id(zero_extend(NewLength)),[A]),Env,Out) :- !,
172 smt_term_to_prob_term(A,Env,BA),
173 bvwidth(BA,WidthA),
174 WidthAP1 = b(add(WidthA,Int1),integer,[]),
175 Int0 = b(integer(0),integer,[]),
176 Int1 = b(integer(1),integer,[]),
177 IdX1 = b(identifier('\\tmp1'),integer,[]),
178 IdX2 = b(identifier('\\tmp2'),integer,[]),
179 FullWidth = b(add(WidthA,b(integer(NewLength),integer,[])),integer,[]),
180 TypeOfX1 = b(member(IdX1,b(interval(Int0,FullWidth),set(integer),[])),pred,[]),
181 TypeOfX2 = b(member(IdX2,b(interval(Int0,Int1),set(integer),[])),pred,[]),
182 ValOfX2 = b(if_then_else(b(less_equal(IdX1,WidthA),pred,[]),
183 b(integer(0),integer,[]),
184 b(function(BA,b(minus(IdX1,WidthAP1),integer,[])),integer,[])),integer,[]),
185 conjunct_predicates([TypeOfX1,TypeOfX2,b(equal(IdX2,ValOfX2),pred,[])],Pred),
186 Out = b(comprehension_set([IdX1,IdX2],Pred),set(couple(integer,integer)),[]).
187 smt_term_to_prob_term(id_term(id(sign_extend(NewLength)),[A]),Env,Out) :- !,
188 smt_term_to_prob_term(A,Env,BA),
189 bvwidth(BA,WidthA),
190 Int0 = b(integer(0),integer,[]),
191 Int1 = b(integer(1),integer,[]),
192 IdX1 = b(identifier('\\tmp1'),integer,[]),
193 IdX2 = b(identifier('\\tmp2'),integer,[]),
194 WidthAP1 = b(add(WidthA,Int1),integer,[]),
195 FullWidth = b(add(WidthA,b(integer(NewLength),integer,[])),integer,[]),
196 TypeOfX1 = b(member(IdX1,b(interval(Int0,FullWidth),set(integer),[])),pred,[]),
197 TypeOfX2 = b(member(IdX2,b(interval(Int0,Int1),set(integer),[])),pred,[]),
198 ValOfX2 = b(if_then_else(b(less_equal(IdX1,WidthA),pred,[]),
199 b(function(BA,IdX1),integer,[]),
200 b(function(BA,b(minus(IdX1,WidthAP1),integer,[])),integer,[])),integer,[]),
201 conjunct_predicates([TypeOfX1,TypeOfX2,b(equal(IdX2,ValOfX2),pred,[])],Pred),
202 Out = b(comprehension_set([IdX1,IdX2],Pred),set(couple(integer,integer)),[]).
203 smt_term_to_prob_term(id_term(id(extract(I,J)),[S]),Env,Out) :- !,
204 BI = b(integer(I),integer,[]),
205 BJ = b(integer(J),integer,[]),
206 smt_term_to_prob_term(S,Env,BS),
207 Int0 = b(integer(0),integer,[]),
208 Int1 = b(integer(1),integer,[]),
209 DomX1 = b(add(b(minus(BI,BJ),integer,[]),Int1),integer,[]),
210 IdX1 = b(identifier('\\tmp1'),integer,[]),
211 IdX2 = b(identifier('\\tmp2'),integer,[]),
212 TypeOfX1 = b(member(IdX1,b(interval(Int0,DomX1),set(integer),[])),pred,[]),
213 TypeOfX2 = b(member(IdX2,b(interval(Int0,Int1),set(integer),[])),pred,[]),
214 ValOfX2 = b(function(BS,IdX1),integer,[]),
215 conjunct_predicates([TypeOfX1,TypeOfX2,b(equal(IdX2,ValOfX2),pred,[])],Pred),
216 Out = b(comprehension_set([IdX1,IdX2],Pred),set(couple(integer,integer)),[]).
217 smt_term_to_prob_term(id_term(id('bvnot'),[A]),Env,Out) :- !,
218 smt_term_to_prob_term(A,Env,BA),
219 bvwidth(BA,Width),
220 Int0 = b(integer(0),integer,[]),
221 Int1 = b(integer(1),integer,[]),
222 IdX1 = b(identifier('\\tmp1'),integer,[]),
223 IdX2 = b(identifier('\\tmp2'),integer,[]),
224 TypeOfX1 = b(member(IdX1,b(interval(Int0,Width),set(integer),[])),pred,[]),
225 TypeOfX2 = b(member(IdX2,b(interval(Int0,Int1),set(integer),[])),pred,[]),
226 ValOfX2 = b(if_then_else(b(equal(b(function(BA,IdX1),integer,[]),Int0),pred,[]),Int1,Int0),integer,[]),
227 conjunct_predicates([TypeOfX1,TypeOfX2,b(equal(IdX2,ValOfX2),pred,[])],Pred),
228 Out = b(comprehension_set([IdX1,IdX2],Pred),set(couple(integer,integer)),[]).
229 smt_term_to_prob_term(id_term(id('bvand'),[A,B]),Env,Out) :- !,
230 smt_term_to_prob_term(A,Env,BA),
231 smt_term_to_prob_term(B,Env,BB),
232 bvwidth(BA,Width),
233 Int0 = b(integer(0),integer,[]),
234 Int1 = b(integer(1),integer,[]),
235 IdX1 = b(identifier('\\tmp1'),integer,[]),
236 IdX2 = b(identifier('\\tmp2'),integer,[]),
237 TypeOfX1 = b(member(IdX1,b(interval(Int0,Width),set(integer),[])),pred,[]),
238 TypeOfX2 = b(member(IdX2,b(interval(Int0,Int1),set(integer),[])),pred,[]),
239 ValOfX2 = b(if_then_else(b(equal(b(function(BA,IdX1),integer,[]),Int0),pred,[]),Int0,b(function(BB,IdX1),integer,[])),integer,[]),
240 conjunct_predicates([TypeOfX1,TypeOfX2,b(equal(IdX2,ValOfX2),pred,[])],Pred),
241 Out = b(comprehension_set([IdX1,IdX2],Pred),set(couple(integer,integer)),[]).
242 smt_term_to_prob_term(id_term(id('bvor'),[A,B]),Env,Out) :- !,
243 smt_term_to_prob_term(A,Env,BA),
244 smt_term_to_prob_term(B,Env,BB),
245 bvwidth(BA,Width),
246 Int0 = b(integer(0),integer,[]),
247 Int1 = b(integer(1),integer,[]),
248 IdX1 = b(identifier('\\tmp1'),integer,[]),
249 IdX2 = b(identifier('\\tmp2'),integer,[]),
250 TypeOfX1 = b(member(IdX1,b(interval(Int0,Width),set(integer),[])),pred,[]),
251 TypeOfX2 = b(member(IdX2,b(interval(Int0,Int1),set(integer),[])),pred,[]),
252 ValOfX2 = b(if_then_else(b(equal(b(function(BA,IdX1),integer,[]),Int1),pred,[]),Int1,b(function(BB,IdX1),integer,[])),integer,[]),
253 conjunct_predicates([TypeOfX1,TypeOfX2,b(equal(IdX2,ValOfX2),pred,[])],Pred),
254 Out = b(comprehension_set([IdX1,IdX2],Pred),set(couple(integer,integer)),[]).
255 smt_term_to_prob_term(id_term(id('bvxor'),[A,B]),Env,Out) :- !,
256 smt_term_to_prob_term(A,Env,BA),
257 smt_term_to_prob_term(B,Env,BB),
258 bvwidth(BA,Width),
259 Int0 = b(integer(0),integer,[]),
260 Int1 = b(integer(1),integer,[]),
261 IdX1 = b(identifier('\\tmp1'),integer,[]),
262 IdX2 = b(identifier('\\tmp2'),integer,[]),
263 TypeOfX1 = b(member(IdX1,b(interval(Int0,Width),set(integer),[])),pred,[]),
264 TypeOfX2 = b(member(IdX2,b(interval(Int0,Int1),set(integer),[])),pred,[]),
265 ValOfX2 = b(if_then_else(b(equal(b(function(BA,IdX1),integer,[]),b(function(BB,IdX1),integer,[])),pred,[]),Int0,Int1),integer,[]),
266 conjunct_predicates([TypeOfX1,TypeOfX2,b(equal(IdX2,ValOfX2),pred,[])],Pred),
267 Out = b(comprehension_set([IdX1,IdX2],Pred),set(couple(integer,integer)),[]).
268 smt_term_to_prob_term(id_term(id('bvult'),[A,B]),Env,Out) :- !,
269 bv_to_nat_and_compare(A,B,less,Env,Out).
270 smt_term_to_prob_term(id_term(id('bvule'),[A,B]),Env,Out) :- !,
271 bv_to_nat_and_compare(A,B,less_equal,Env,Out).
272 smt_term_to_prob_term(id_term(id('bvuge'),[A,B]),Env,Out) :- !,
273 bv_to_nat_and_compare(A,B,greater_equal,Env,Out).
274 smt_term_to_prob_term(id_term(id('bvugt'),[A,B]),Env,Out) :- !,
275 bv_to_nat_and_compare(A,B,greater,Env,Out).
276 smt_term_to_prob_term(id_term(id('bvslt'),[A,B]),Env,Out) :- !,
277 signed_bv_to_nat_and_compare(A,B,less,Env,Out).
278 smt_term_to_prob_term(id_term(id('bvsle'),[A,B]),Env,Out) :- !,
279 signed_bv_to_nat_and_compare(A,B,less_equal,Env,Out).
280 smt_term_to_prob_term(id_term(id('bvsge'),[A,B]),Env,Out) :- !,
281 signed_bv_to_nat_and_compare(A,B,greater_equal,Env,Out).
282 smt_term_to_prob_term(id_term(id('bvsgt'),[A,B]),Env,Out) :- !,
283 signed_bv_to_nat_and_compare(A,B,greater,Env,Out).
284 smt_term_to_prob_term(id_term(id('bvneg'),[A]),Env,Out) :- !,
285 smt_term_to_prob_term(A,Env,BA),
286 bvwidth(BA,Width),
287 WidthP1 = b(add(Width,b(integer(1),integer,[])),integer,[]),
288 bv2nat(BA,BANat),
289 Int2 = b(integer(2),integer,[]),
290 Pow = b(power_of(Int2,WidthP1),integer,[]),
291 Differenz = b(minus(Pow,BANat),integer,[]),
292 nat2bv(Differenz,Width,Out).
293 smt_term_to_prob_term(id_term(id('bvadd'),[A,B]),Env,Out) :- !,
294 smt_term_to_prob_term(A,Env,BA),
295 smt_term_to_prob_term(B,Env,BB),
296 bvwidth(BA,Width),
297 bv2nat(BA,BANat),
298 bv2nat(BB,BBNat),
299 Sum = b(add(BANat,BBNat),integer,[]),
300 nat2bv(Sum,Width,Out).
301 smt_term_to_prob_term(id_term(id('bvsub'),[A,B]),Env,Out) :- !,
302 smt_term_to_prob_term(A,Env,BA),
303 smt_term_to_prob_term(B,Env,BB),
304 bvwidth(BA,Width),
305 bv2nat(BA,BANat),
306 bv2nat(BB,BBNat),
307 Sum = b(minus(BANat,BBNat),integer,[]),
308 nat2bv(Sum,Width,Out).
309 smt_term_to_prob_term(id_term(id('bvmul'),[A,B]),Env,Out) :- !,
310 smt_term_to_prob_term(A,Env,BA),
311 smt_term_to_prob_term(B,Env,BB),
312 bvwidth(BA,Width),
313 bv2nat(BA,BANat),
314 bv2nat(BB,BBNat),
315 Prod = b(multiplication(BANat,BBNat),integer,[]),
316 nat2bv(Prod,Width,Out).
317 smt_term_to_prob_term(id_term(id('bvudiv'),[A,B]),Env,Out) :- !,
318 smt_term_to_prob_term(A,Env,BA),
319 smt_term_to_prob_term(B,Env,BB),
320 bvwidth(BA,Width),
321 bv2nat(BA,BANat),
322 bv2nat(BB,BBNat),
323 Div = b(div(BANat,BBNat),integer,[]),
324 nat2bv(Div,Width,Out).
325 smt_term_to_prob_term(id_term(id('bvurem'),[A,B]),Env,Out) :- !,
326 smt_term_to_prob_term(A,Env,BA),
327 smt_term_to_prob_term(B,Env,BB),
328 bvwidth(BA,Width),
329 bv2nat(BA,BANat),
330 bv2nat(BB,BBNat),
331 Rem = b(modulo(BANat,BBNat),integer,[]),
332 nat2bv(Rem,Width,Out).
333 smt_term_to_prob_term(id_term(id('bvshl'),[A,B]),Env,Out) :- !,
334 smt_term_to_prob_term(A,Env,BA),
335 smt_term_to_prob_term(B,Env,BB),
336 bvwidth(BA,Width),
337 bv2nat(BA,BANat),
338 bv2nat(BB,BBNat),
339 Int2 = b(integer(2),integer,[]),
340 Exp = b(power_of(Int2,BBNat),integer,[]),
341 Res = b(multiplication(BANat,Exp),integer,[]),
342 nat2bv(Res,Width,Out).
343 smt_term_to_prob_term(id_term(id('bvlshr'),[A,B]),Env,Out) :- !,
344 smt_term_to_prob_term(A,Env,BA),
345 smt_term_to_prob_term(B,Env,BB),
346 bvwidth(BA,Width),
347 bv2nat(BA,BANat),
348 bv2nat(BB,BBNat),
349 Int2 = b(integer(2),integer,[]),
350 Exp = b(power_of(Int2,BBNat),integer,[]),
351 Res = b(div(BANat,Exp),integer,[]),
352 nat2bv(Res,Width,Out).
353 % division is a special case, because it has a different
354 % semantic in B and SMT-LIB
355 smt_term_to_prob_term(id_term(id(div),[Dividend|Divisors]),Env,Out) :- !,
356 smt_term_to_prob_term(id_term(id('*'),Divisors),Env,BDivisor),
357 smt_term_to_prob_term(Dividend,Env,BDividend),
358 Zero = b(integer(0),integer,[]),
359 DividendLessZero = b(less(BDividend,Zero),pred,[]),
360 DivisorLessZero = b(less(BDivisor,Zero),pred,[]),
361 DivisorGreaterZero = b(greater(BDivisor,Zero),pred,[]),
362 DivisorMinusOne = b(minus(BDivisor,b(integer(1),integer,[])),integer,[]),
363 DivisorPlusOne = b(add(BDivisor,b(integer(1),integer,[])),integer,[]),
364 MinusDivisorPlusOne = b(unary_minus(DivisorPlusOne),integer,[]),
365
366 conjunct_predicates([DividendLessZero,DivisorGreaterZero],If1),
367 conjunct_predicates([DividendLessZero,DivisorLessZero],If2),
368
369 FixInner = b(if_then_else(If2,MinusDivisorPlusOne,Zero),integer,[]),
370 Fix = b(if_then_else(If1,DivisorMinusOne,FixInner),integer,[]),
371 NewBDividend = b(minus(BDividend,Fix),integer,[]),
372 Out = b(div(NewBDividend,BDivisor),integer,[]).
373 % general cases
374 smt_term_to_prob_term(id_term(id(Id),Args),Env,Out) :-
375 smt_id_to_prob_id_preds(Id,BId), !,
376 maplist(smt_term_to_prob_term_maplist(Env),Args,BArgs),
377 maplist(bool_to_pred,BArgs,PredBArgs),
378 interleave(BId,PredBArgs,Out).
379 smt_term_to_prob_term(id_term(id(Id),Args),Env,Out) :-
380 smt_id_to_prob_id(Id,BId,ConnectingPred), !,
381 maplist(smt_term_to_prob_term_maplist(Env),Args,BArgs),
382 call(ConnectingPred,BId,BArgs,Out).
383 smt_term_to_prob_term(id_term(id(Id),Args),Env,Out) :-
384 get_function(Id,Env,Params,_Results,Definition), !,
385 replace_identifiers(Params,Args,Definition,Out,Env).
386 smt_term_to_prob_term(id_term(id(Id),Args),Env,Out) :-
387 get_type(Id,Env,set(couple(_X,Y))), !,
388 smt_term_to_prob_term(id(Id),Env,BId),
389 maplist(smt_term_to_prob_term_maplist(Env),Args,BArgs),
390 create_couple(BArgs,BArg),
391 Out = b(function(BId,BArg),Y,[]).
392 smt_term_to_prob_term(id(true),_,b(boolean_true,boolean,[])) :- !.
393 smt_term_to_prob_term(id(false),_,b(boolean_false,boolean,[])) :- !.
394 smt_term_to_prob_term(id(Id),Env,OutId) :- !,
395 get_type(Id,Env,Type),
396 OutId = b(identifier(Id),Type,[]).%,
397 %(Type = boolean
398 % -> bool_to_pred(OutId,Out)
399 % ; Out = OutId).
400 smt_term_to_prob_term(id(Id,Sort),Env,OutId) :- !,
401 smt_type_to_prob_type(Sort,Env,Type),
402 OutId = b(identifier(Id),Type,[]).
403 smt_term_to_prob_term(svar(Id,Sort),Env,Out) :- !,
404 smt_type_to_prob_type(Sort,Env,Type),
405 Out = b(identifier(Id),Type,[]).
406 smt_term_to_prob_term(integer(I),_,b(integer(I),integer,[])) :- !.
407 smt_term_to_prob_term(let(Bindings,Term),Env,BTerm) :- !,
408 let_equalities_and_bids(Bindings,BIDs,Assignments,Env),
409 create_local_env(Env,BIDs,LocalEnv),
410 smt_term_to_prob_term(Term,LocalEnv,InnerBTerm),
411 get_texpr_type(InnerBTerm,InnerType),
412 (InnerType = pred
413 -> safe_create_texpr(let_predicate(BIDs,Assignments,InnerBTerm),pred,BTerm)
414 ; safe_create_texpr(let_expression(BIDs,Assignments,InnerBTerm),InnerType,BTerm)).
415 smt_term_to_prob_term(forall(IDs,Term),Env,Forall) :- !,
416 maplist(smt_term_to_prob_term_maplist(Env),IDs,Identifiers),
417 create_local_env(Env,Identifiers,LocalEnv),
418 smt_term_to_prob_term(Term,LocalEnv,InnerTerm),
419 convlist(typing_constraint,IDs,InnerConstraints),
420 bool_to_pred(InnerTerm,InnerTermAsPred), % necessary ??
421 conjunct_predicates(InnerConstraints,LHS),
422 create_implication(LHS,InnerTermAsPred,Body),
423 create_forall(Identifiers,Body,Forall).
424 smt_term_to_prob_term(exists(IDs,Term),Env,Forall) :- !,
425 maplist(smt_term_to_prob_term_maplist(Env),IDs,Identifiers),
426 create_local_env(Env,Identifiers,LocalEnv),
427 smt_term_to_prob_term(Term,LocalEnv,InnerTerm),
428 convlist(typing_constraint,IDs,InnerConstraints),
429 append(InnerConstraints,[InnerTerm],IList),
430 conjunct_predicates(IList,Inner),
431 bool_to_pred(Inner,InnerAsPred),
432 create_exists(Identifiers,InnerAsPred,Forall).
433 smt_term_to_prob_term(bitvector(Value,Length),_Env,Out) :- !,
434 integer_to_binary_couples(Value,Length,Couples),
435 Out = b(set_extension(Couples),set(couple(integer,integer)),[]).
436 smt_term_to_prob_term(bitvector(Bits),_Env,Out) :- !,
437 binary_to_binary_couples(Bits,Couples),
438 Out = b(set_extension(Couples),set(couple(integer,integer)),[]).
439 smt_term_to_prob_term(X,_,_) :-
440 add_error(smtlib2_translation,'Unsupported term in smt_term_to_prob_term:',X), fail.
441
442
443 bool_to_pred(Bool,Pred) :-
444 get_texpr_expr(Bool,convert_bool(Pred)), !.
445 bool_to_pred(Bool,Pred) :-
446 get_texpr_type(Bool,boolean), !,
447 safe_create_texpr(equal(Bool,b(boolean_true,boolean,[])),pred,Pred).
448 bool_to_pred(Bool,Bool) :-
449 get_texpr_type(Bool,pred), !.
450
451 to_bool_if_necessary(PossiblePred,Bool) :-
452 get_texpr_type(PossiblePred,pred), !,
453 safe_create_texpr(convert_bool(PossiblePred),boolean,Bool).
454 to_bool_if_necessary(NonPred,NonPred).
455
456 let_equalities_and_bids([bind(ID,Term)],[IDTerm],[AssOut],Env) :- !,
457 smt_term_to_prob_term(Term,Env,Ass),
458 get_texpr_type(Ass,IdentifierType),
459 (IdentifierType == pred
460 -> IDTerm = b(identifier(ID),boolean,[]),
461 safe_create_texpr(convert_bool(Ass),boolean,AssOut)
462 ; IDTerm = b(identifier(ID),IdentifierType,[]),
463 AssOut = Ass).
464 let_equalities_and_bids([bind(ID,Term)|Further],[IDTerm|FurtherIdentifiers],Assignments,Env) :-
465 let_equalities_and_bids([bind(ID,Term)],[IDTerm],FirstAssignment,Env),
466 let_equalities_and_bids(Further,FurtherIdentifiers,FurtherAssignments,Env),
467 append(FirstAssignment,FurtherAssignments,Assignments).
468
469 replace_identifiers([],[],D,D,_Env).
470 replace_identifiers([b(identifier(I),_,_)|T1],[Term|Terms],In,Out,Env) :-
471 smt_term_to_prob_term(Term,Env,BTerm),
472 replace_id_by_expr(In,I,BTerm,TOut),
473 replace_identifiers(T1,Terms,TOut,Out,Env).
474
475 % certain sorts enforce an inner constrait to strengthen their type
476 typing_constraint(svar(Name,sort('Array',[Index,Element])),Constraint) :-
477 smt_type_to_prob_type(Index,EIn,BIndex),
478 smt_type_to_prob_type(Element,EIn,BElement),
479 Identifier = b(identifier(Name),FullType,[]),
480 Constraint = b(member(Identifier,b(EXPR,set(FullType),[])),pred,[]),
481 type_to_expr(BIndex,From),
482 (BElement=boolean,get_preference(smtlib2b_arrays_as_sets,true) % we translate boolean Array as Set
483 -> EXPR = pow_subset(From),
484 FullType = set(BIndex)
485 ; type_to_expr(BElement,To),
486 EXPR=total_function(From,To),
487 FullType = set(couple(BIndex,BElement))
488 ).
489 typing_constraint(svar(Name,sort('BitVec',[Length])),Constraint) :-
490 Zero = b(integer(0),integer,[]),
491 One = b(integer(1),integer,[]),
492 L2 is Length - 1,
493 LengthMinusOne = b(integer(L2),integer,[]),
494 FullType = set(couple(integer,integer)),
495 Identifier = b(identifier(Name),FullType,[]),
496 From = b(interval(Zero,LengthMinusOne),set(integer),[]),
497 To = b(interval(Zero,One),set(integer),[]),
498 Constraint = b(member(Identifier,b(total_function(From,To),set(FullType),[])),pred,[]).
499
500 is_function_constraint(Id,FullType,Constraint) :-
501 FullType = set(couple(From,To)),
502 Identifier = b(identifier(Id),FullType,[]),
503 type_to_expr(From,FromExpr),
504 type_to_expr(To,ToExpr),
505 Constraint = b(member(Identifier,b(partial_function(FromExpr,ToExpr),set(FullType),[])),pred,[]).
506
507 integer_to_binary_couples(Value,Length,Couples) :-
508 PLength is Length - 1,
509 integer_to_binary_couples(Value,0,PLength,Couples).
510 integer_to_binary_couples(Value,Current,Current,[b(couple(A,B),couple(integer,integer),[])]) :- !,
511 A = b(integer(Current),integer,[]),
512 BVal is mod(Value,2),
513 B = b(integer(BVal),integer,[]).
514 integer_to_binary_couples(Value,Current,PLength,[b(couple(A,B),couple(integer,integer),[])|Cs]) :-
515 A = b(integer(Current),integer,[]),
516 BVal is mod(Value,2),
517 B = b(integer(BVal),integer,[]),
518 NValue is Value // 2,
519 NCurrent is Current + 1,
520 integer_to_binary_couples(NValue,NCurrent,PLength,Cs).
521
522 binary_to_binary_couples(Bits,Couples) :-
523 length(Bits,L), FirstL is L - 1,
524 binary_to_binary_couples(FirstL,Bits,Couples).
525 binary_to_binary_couples(-1,[],[]).
526 binary_to_binary_couples(L,[Bit|Bits],[Couple|Couples]) :-
527 A = b(integer(L),integer,[]),
528 B = b(integer(Bit),integer,[]),
529 Couple = b(couple(A,B),couple(integer,integer),[]),
530 L2 is L - 1,
531 binary_to_binary_couples(L2,Bits,Couples).
532
533 smt_id_to_prob_id('<=',less_equal,chain).
534 smt_id_to_prob_id('>=',greater_equal,chain).
535 smt_id_to_prob_id('<',less,chain).
536 smt_id_to_prob_id('>',greater,chain).
537 smt_id_to_prob_id('distinct',not_equal,chain).
538 smt_id_to_prob_id('*',multiplication,interleave).
539 smt_id_to_prob_id('+',add,interleave).
540 smt_id_to_prob_id('-',minus,interleave).
541
542 smt_id_to_prob_id_preds('or',disjunct).
543 smt_id_to_prob_id_preds('and',conjunct).
544 smt_id_to_prob_id_preds('=>',implication).
545
546 bvwidth(BV,Width) :-
547 Width = b(max(b(domain(BV),set(integer),[])),integer,[]).
548
549 bv2nat(BV,Nat) :-
550 IntOne = b(integer(1),integer,[]),
551 IntTwo = b(integer(2),integer,[]),
552 IdX1 = b(identifier('\\tmp1'),integer,[]),
553 IdX2 = b(identifier('\\tmp2'),integer,[]),
554 PowerOf = b(power_of(IntTwo,b(minus(IdX1,IntOne),integer,[])),integer,[]),
555 Nat = b(general_sum([IdX1,IdX2],b(member(b(couple(IdX1,IdX2),couple(integer,integer),[]),BV),pred,[]),b(multiplication(IdX2,PowerOf),integer,[])),integer,[]).
556 signed_bv2nat(BV,Nat) :-
557 IntOne = b(integer(1),integer,[]),
558 IntTwo = b(integer(2),integer,[]),
559 IntMinusOne = b(integer(-1),integer,[]),
560 % todo: make sure identifiers do not collide
561 IdX1 = b(identifier('\\tmp1'),integer,[]),
562 IdX2 = b(identifier('\\tmp2'),integer,[]),
563 NotZeroIndex = b(not_equal(IdX1,b(integer(0),integer,[])),pred,[]),
564 MemberConstraint = b(member(b(couple(IdX1,IdX2),couple(integer,integer),[]),BV),pred,[]),
565 conjunct_predicates([NotZeroIndex,MemberConstraint],Const),
566 PowerOf = b(power_of(IntTwo,b(minus(IdX1,IntOne),integer,[])),integer,[]),
567 Sum = b(general_sum([IdX1,IdX2],Const,b(multiplication(IdX2,PowerOf),integer,[])),integer,[]),
568 ZeroIndex = b(function(BV,b(integer(0),integer,[])),integer,[]),
569 Sign = b(power_of(IntMinusOne,ZeroIndex),integer,[]),
570 Nat = b(multiplication(Sign,Sum),integer,[]).
571
572 nat2bv(Nat,Width,BV) :-
573 IntOne = b(integer(1),integer,[]),
574 IntTwo = b(integer(2),integer,[]),
575 % todo: make sure identifiers do not collide
576 IdX1 = b(identifier('\\tmp1'),integer,[]),
577 IdX2 = b(identifier('\\tmp2'),integer,[]),
578 TypeId1 = b(member(IdX1,b(interval(b(integer(1),integer,[]),Width),set(integer),[])),pred,[]),
579 TypeId2 = b(member(IdX2,b(interval(b(integer(0),integer,[]),b(integer(1),integer,[])),set(integer),[])),pred,[]),
580 PowerOf = b(power_of(IntTwo,b(minus(IdX1,IntOne),integer,[])),integer,[]),
581 ValueOfId2 = b(equal(IdX2,b(modulo(b(div(Nat,PowerOf),integer,[]),IntTwo),integer,[])),pred,[]),
582 conjunct_predicates([TypeId1,TypeId2,ValueOfId2],InnerPred),
583 BV = b(comprehension_set([IdX1,IdX2],InnerPred),set(couple(integer,integer)),[]).
584
585 type_to_expr(set(A),Res) :- !, Res = b(pow_subset(AE),set(set(A)),[]),
586 type_to_expr(A,AE).
587 type_to_expr(couple(A,B),b(cartesian_product(AE,BE),set(couple(AET,BET)),[])) :- !,
588 type_to_expr(A,AE), type_to_expr(B,BE),
589 get_texpr_type(AE,AET), get_texpr_type(BE,BET).
590 type_to_expr(integer,b(integer_set('INTEGER'),set(integer),[])) :- !.
591 type_to_expr(boolean,b(bool_set,set(boolean),[])) :- !.
592 type_to_expr(global(E),b(identifier(E),set(global(E)),[])) :- !.
593 type_to_expr(T,_) :-
594 add_error(smtlib2_translation,'Unsupported type in type_to_expr:',T), fail.
595
596 signed_bv_to_nat_and_compare(A,B,Op,Env,Out) :-
597 smt_term_to_prob_term(A,Env,BA),
598 smt_term_to_prob_term(B,Env,BB),
599 signed_bv2nat(BA,BANat),
600 signed_bv2nat(BB,BBNat),
601 Operation =.. [Op,BANat,BBNat],
602 Out = b(Operation,pred,[]).
603
604 bv_to_nat_and_compare(A,B,Op,Env,Out) :-
605 smt_term_to_prob_term(A,Env,BA),
606 smt_term_to_prob_term(B,Env,BB),
607 bv2nat(BA,BANat),
608 bv2nat(BB,BBNat),
609 Operation =.. [Op,BANat,BBNat],
610 Out = b(Operation,pred,[]).