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