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