smt_term_to_prob_term(attributed_term(Term,_Attr),Env,Out) :- !,
smt_term_to_prob_term(Term,Env,Out).
smt_term_to_prob_term(id_term(id('not'),[Arg]),Env,Out) :- !,
smt_term_to_prob_term(Arg,Env,BArg),
get_texpr_type(BArg,Type),
(Type = pred
-> Out = b(negation(BArg),pred,[])
; Out = b(equal(BArg,b(boolean_false,boolean,[])),pred,[])).
smt_term_to_prob_term(id_term(id('-'),[SingleArg]),Env,Out) :- !,
% special case for unary minus: can not be interleaved
smt_term_to_prob_term(SingleArg,Env,BArg),
Out = b(unary_minus(BArg),integer,[]).
smt_term_to_prob_term(id_term(id('='),Args),Env,Out) :- !,
maplist(smt_term_to_prob_term_maplist(Env),Args,BArgs),
maplist(get_texpr_type,BArgs,Types),
(member(pred,Types)
-> maplist(bool_to_pred,BArgs,BArgsPreds),
chain(equivalence,BArgsPreds,Out)
; chain(equal,BArgs,Out)).
smt_term_to_prob_term(id_term(id('ite'),[Test,If,Then]),Env,Out) :- !,
smt_term_to_prob_term(Test,Env,BTestT),
smt_term_to_prob_term(If,Env,BIfT),
smt_term_to_prob_term(Then,Env,BThenT),
bool_to_pred(BTestT,BTest),
to_bool_if_necessary(BIfT,BIf),
to_bool_if_necessary(BThenT,BThen),
get_texpr_type(BIf,Type),
Out = b(if_then_else(BTest,BIf,BThen),Type,[]).
smt_term_to_prob_term(id_term(id(member),[Element,Set]),Env,Out) :- !,
smt_term_to_prob_term(Set,Env,BSet),
smt_term_to_prob_term(Element,Env,BElement),
Out = b(member(BElement,BSet),pred,[]).
smt_term_to_prob_term(id_term(id(card),[Set]),Env,Out) :- !,
smt_term_to_prob_term(Set,Env,BSet),
Out = b(card(BSet),integer,[]).
smt_term_to_prob_term(id_term(id(singleton),[Element]),Env,Out) :- !,
smt_term_to_prob_term(Element,Env,BElement),
get_texpr_type(BElement,ElementType),
Out = b(set_extension([BElement]),set(ElementType),[]).
smt_term_to_prob_term(id_term(id(union),[SetA,SetB]),Env,Out) :- !,
smt_term_to_prob_term(SetA,Env,BSetA),
smt_term_to_prob_term(SetB,Env,BSetB),
get_texpr_type(BSetB,Type),
Out = b(union(BSetA,BSetB),Type,[]).
smt_term_to_prob_term(id_term(id(intersection),[SetA,SetB]),Env,Out) :- !,
smt_term_to_prob_term(SetA,Env,BSetA),
smt_term_to_prob_term(SetB,Env,BSetB),
get_texpr_type(BSetB,Type),
Out = b(intersection(BSetA,BSetB),Type,[]).
smt_term_to_prob_term(id_term(id(subset),[SetA,SetB]),Env,Out) :- !,
smt_term_to_prob_term(SetA,Env,BSetA),
smt_term_to_prob_term(SetB,Env,BSetB),
Out = b(subset(BSetA,BSetB),pred,[]).
smt_term_to_prob_term(id_term(id('store'),[Array,Index,Element]),Env,Out) :- !,
smt_term_to_prob_term(Array,Env,BArray),
get_texpr_type(BArray,ArrayType),
ArrayType = set(CoupleType),
smt_term_to_prob_term(Index,Env,BIndex),
smt_term_to_prob_term(Element,Env,BElement),
% TO DO: generate union or set_difference depending on Element=true or false when smtlib2b_arrays_as_sets
% store(X,Index,El) = IF El=TRUE THEN X \/ {Index} ELSE X \ {Index} END
SetEx = b(set_extension([b(couple(BIndex,BElement),CoupleType,[])]),ArrayType,[]),
Out = b(overwrite(BArray,SetEx),ArrayType,[]).
smt_term_to_prob_term(id_term(id('select'),[Array,Index]),Env,Out) :- !,
smt_term_to_prob_term(Array,Env,BArray),
smt_term_to_prob_term(Index,Env,BIndex),
get_texpr_type(BArray,ArrayType),
%format('select of array ~w (type: ~w) at index ~w~n',[Array,ArrayType,Index]),
(ArrayType = set(couple(_From,To)) % Array was translated as total function From --> To
-> Out = b(function(BArray,BIndex),To,[])
; ArrayType = set(_From), % Array was translated as set (smtlib2b_arrays_as_sets=true)
MEM = b(member(BIndex,BArray),pred,[]),
Out = b(convert_bool(MEM),boolean,[])
).
smt_term_to_prob_term(id_term(id('concat'),[A,B]),Env,Out) :- !,
smt_term_to_prob_term(A,Env,BA),
smt_term_to_prob_term(B,Env,BB),
bvwidth(BA,WidthA),
bvwidth(BB,WidthB),
WidthBP1 = b(add(WidthB,Int1),integer,[]),
Int0 = b(integer(0),integer,[]),
Int1 = b(integer(1),integer,[]),
IdX1 = b(identifier('\\tmp1'),integer,[]),
IdX2 = b(identifier('\\tmp2'),integer,[]),
FullWidth = b(add(b(add(WidthA,WidthB),integer,[]),Int1),integer,[]),
TypeOfX1 = b(member(IdX1,b(interval(Int0,FullWidth),set(integer),[])),pred,[]),
TypeOfX2 = b(member(IdX2,b(interval(Int0,Int1),set(integer),[])),pred,[]),
ValOfX2 = b(if_then_else(b(less_equal(IdX1,WidthB),pred,[]),
b(function(BB,IdX1),integer,[]),
b(function(BA,b(minus(IdX1,WidthBP1),integer,[])),integer,[])),integer,[]),
conjunct_predicates([TypeOfX1,TypeOfX2,b(equal(IdX2,ValOfX2),pred,[])],Pred),
Out = b(comprehension_set([IdX1,IdX2],Pred),set(couple(integer,integer)),[]).
smt_term_to_prob_term(id_term(id(zero_extend(NewLength)),[A]),Env,Out) :- !,
smt_term_to_prob_term(A,Env,BA),
bvwidth(BA,WidthA),
WidthAP1 = b(add(WidthA,Int1),integer,[]),
Int0 = b(integer(0),integer,[]),
Int1 = b(integer(1),integer,[]),
IdX1 = b(identifier('\\tmp1'),integer,[]),
IdX2 = b(identifier('\\tmp2'),integer,[]),
FullWidth = b(add(WidthA,b(integer(NewLength),integer,[])),integer,[]),
TypeOfX1 = b(member(IdX1,b(interval(Int0,FullWidth),set(integer),[])),pred,[]),
TypeOfX2 = b(member(IdX2,b(interval(Int0,Int1),set(integer),[])),pred,[]),
ValOfX2 = b(if_then_else(b(less_equal(IdX1,WidthA),pred,[]),
b(integer(0),integer,[]),
b(function(BA,b(minus(IdX1,WidthAP1),integer,[])),integer,[])),integer,[]),
conjunct_predicates([TypeOfX1,TypeOfX2,b(equal(IdX2,ValOfX2),pred,[])],Pred),
Out = b(comprehension_set([IdX1,IdX2],Pred),set(couple(integer,integer)),[]).
smt_term_to_prob_term(id_term(id(sign_extend(NewLength)),[A]),Env,Out) :- !,
smt_term_to_prob_term(A,Env,BA),
bvwidth(BA,WidthA),
Int0 = b(integer(0),integer,[]),
Int1 = b(integer(1),integer,[]),
IdX1 = b(identifier('\\tmp1'),integer,[]),
IdX2 = b(identifier('\\tmp2'),integer,[]),
WidthAP1 = b(add(WidthA,Int1),integer,[]),
FullWidth = b(add(WidthA,b(integer(NewLength),integer,[])),integer,[]),
TypeOfX1 = b(member(IdX1,b(interval(Int0,FullWidth),set(integer),[])),pred,[]),
TypeOfX2 = b(member(IdX2,b(interval(Int0,Int1),set(integer),[])),pred,[]),
ValOfX2 = b(if_then_else(b(less_equal(IdX1,WidthA),pred,[]),
b(function(BA,IdX1),integer,[]),
b(function(BA,b(minus(IdX1,WidthAP1),integer,[])),integer,[])),integer,[]),
conjunct_predicates([TypeOfX1,TypeOfX2,b(equal(IdX2,ValOfX2),pred,[])],Pred),
Out = b(comprehension_set([IdX1,IdX2],Pred),set(couple(integer,integer)),[]).
smt_term_to_prob_term(id_term(id(extract(I,J)),[S]),Env,Out) :- !,
BI = b(integer(I),integer,[]),
BJ = b(integer(J),integer,[]),
smt_term_to_prob_term(S,Env,BS),
Int0 = b(integer(0),integer,[]),
Int1 = b(integer(1),integer,[]),
DomX1 = b(add(b(minus(BI,BJ),integer,[]),Int1),integer,[]),
IdX1 = b(identifier('\\tmp1'),integer,[]),
IdX2 = b(identifier('\\tmp2'),integer,[]),
TypeOfX1 = b(member(IdX1,b(interval(Int0,DomX1),set(integer),[])),pred,[]),
TypeOfX2 = b(member(IdX2,b(interval(Int0,Int1),set(integer),[])),pred,[]),
ValOfX2 = b(function(BS,IdX1),integer,[]),
conjunct_predicates([TypeOfX1,TypeOfX2,b(equal(IdX2,ValOfX2),pred,[])],Pred),
Out = b(comprehension_set([IdX1,IdX2],Pred),set(couple(integer,integer)),[]).
smt_term_to_prob_term(id_term(id('bvnot'),[A]),Env,Out) :- !,
smt_term_to_prob_term(A,Env,BA),
bvwidth(BA,Width),
Int0 = b(integer(0),integer,[]),
Int1 = b(integer(1),integer,[]),
IdX1 = b(identifier('\\tmp1'),integer,[]),
IdX2 = b(identifier('\\tmp2'),integer,[]),
TypeOfX1 = b(member(IdX1,b(interval(Int0,Width),set(integer),[])),pred,[]),
TypeOfX2 = b(member(IdX2,b(interval(Int0,Int1),set(integer),[])),pred,[]),
ValOfX2 = b(if_then_else(b(equal(b(function(BA,IdX1),integer,[]),Int0),pred,[]),Int1,Int0),integer,[]),
conjunct_predicates([TypeOfX1,TypeOfX2,b(equal(IdX2,ValOfX2),pred,[])],Pred),
Out = b(comprehension_set([IdX1,IdX2],Pred),set(couple(integer,integer)),[]).
smt_term_to_prob_term(id_term(id('bvand'),[A,B]),Env,Out) :- !,
smt_term_to_prob_term(A,Env,BA),
smt_term_to_prob_term(B,Env,BB),
bvwidth(BA,Width),
Int0 = b(integer(0),integer,[]),
Int1 = b(integer(1),integer,[]),
IdX1 = b(identifier('\\tmp1'),integer,[]),
IdX2 = b(identifier('\\tmp2'),integer,[]),
TypeOfX1 = b(member(IdX1,b(interval(Int0,Width),set(integer),[])),pred,[]),
TypeOfX2 = b(member(IdX2,b(interval(Int0,Int1),set(integer),[])),pred,[]),
ValOfX2 = b(if_then_else(b(equal(b(function(BA,IdX1),integer,[]),Int0),pred,[]),Int0,b(function(BB,IdX1),integer,[])),integer,[]),
conjunct_predicates([TypeOfX1,TypeOfX2,b(equal(IdX2,ValOfX2),pred,[])],Pred),
Out = b(comprehension_set([IdX1,IdX2],Pred),set(couple(integer,integer)),[]).
smt_term_to_prob_term(id_term(id('bvor'),[A,B]),Env,Out) :- !,
smt_term_to_prob_term(A,Env,BA),
smt_term_to_prob_term(B,Env,BB),
bvwidth(BA,Width),
Int0 = b(integer(0),integer,[]),
Int1 = b(integer(1),integer,[]),
IdX1 = b(identifier('\\tmp1'),integer,[]),
IdX2 = b(identifier('\\tmp2'),integer,[]),
TypeOfX1 = b(member(IdX1,b(interval(Int0,Width),set(integer),[])),pred,[]),
TypeOfX2 = b(member(IdX2,b(interval(Int0,Int1),set(integer),[])),pred,[]),
ValOfX2 = b(if_then_else(b(equal(b(function(BA,IdX1),integer,[]),Int1),pred,[]),Int1,b(function(BB,IdX1),integer,[])),integer,[]),
conjunct_predicates([TypeOfX1,TypeOfX2,b(equal(IdX2,ValOfX2),pred,[])],Pred),
Out = b(comprehension_set([IdX1,IdX2],Pred),set(couple(integer,integer)),[]).
smt_term_to_prob_term(id_term(id('bvxor'),[A,B]),Env,Out) :- !,
smt_term_to_prob_term(A,Env,BA),
smt_term_to_prob_term(B,Env,BB),
bvwidth(BA,Width),
Int0 = b(integer(0),integer,[]),
Int1 = b(integer(1),integer,[]),
IdX1 = b(identifier('\\tmp1'),integer,[]),
IdX2 = b(identifier('\\tmp2'),integer,[]),
TypeOfX1 = b(member(IdX1,b(interval(Int0,Width),set(integer),[])),pred,[]),
TypeOfX2 = b(member(IdX2,b(interval(Int0,Int1),set(integer),[])),pred,[]),
ValOfX2 = b(if_then_else(b(equal(b(function(BA,IdX1),integer,[]),b(function(BB,IdX1),integer,[])),pred,[]),Int0,Int1),integer,[]),
conjunct_predicates([TypeOfX1,TypeOfX2,b(equal(IdX2,ValOfX2),pred,[])],Pred),
Out = b(comprehension_set([IdX1,IdX2],Pred),set(couple(integer,integer)),[]).
smt_term_to_prob_term(id_term(id('bvult'),[A,B]),Env,Out) :- !,
bv_to_nat_and_compare(A,B,less,Env,Out).
smt_term_to_prob_term(id_term(id('bvule'),[A,B]),Env,Out) :- !,
bv_to_nat_and_compare(A,B,less_equal,Env,Out).
smt_term_to_prob_term(id_term(id('bvuge'),[A,B]),Env,Out) :- !,
bv_to_nat_and_compare(A,B,greater_equal,Env,Out).
smt_term_to_prob_term(id_term(id('bvugt'),[A,B]),Env,Out) :- !,
bv_to_nat_and_compare(A,B,greater,Env,Out).
smt_term_to_prob_term(id_term(id('bvslt'),[A,B]),Env,Out) :- !,
signed_bv_to_nat_and_compare(A,B,less,Env,Out).
smt_term_to_prob_term(id_term(id('bvsle'),[A,B]),Env,Out) :- !,
signed_bv_to_nat_and_compare(A,B,less_equal,Env,Out).
smt_term_to_prob_term(id_term(id('bvsge'),[A,B]),Env,Out) :- !,
signed_bv_to_nat_and_compare(A,B,greater_equal,Env,Out).
smt_term_to_prob_term(id_term(id('bvsgt'),[A,B]),Env,Out) :- !,
signed_bv_to_nat_and_compare(A,B,greater,Env,Out).
smt_term_to_prob_term(id_term(id('bvneg'),[A]),Env,Out) :- !,
smt_term_to_prob_term(A,Env,BA),
bvwidth(BA,Width),
WidthP1 = b(add(Width,b(integer(1),integer,[])),integer,[]),
bv2nat(BA,BANat),
Int2 = b(integer(2),integer,[]),
Pow = b(power_of(Int2,WidthP1),integer,[]),
Differenz = b(minus(Pow,BANat),integer,[]),
nat2bv(Differenz,Width,Out).
smt_term_to_prob_term(id_term(id('bvadd'),[A,B]),Env,Out) :- !,
smt_term_to_prob_term(A,Env,BA),
smt_term_to_prob_term(B,Env,BB),
bvwidth(BA,Width),
bv2nat(BA,BANat),
bv2nat(BB,BBNat),
Sum = b(add(BANat,BBNat),integer,[]),
nat2bv(Sum,Width,Out).
smt_term_to_prob_term(id_term(id('bvsub'),[A,B]),Env,Out) :- !,
smt_term_to_prob_term(A,Env,BA),
smt_term_to_prob_term(B,Env,BB),
bvwidth(BA,Width),
bv2nat(BA,BANat),
bv2nat(BB,BBNat),
Sum = b(minus(BANat,BBNat),integer,[]),
nat2bv(Sum,Width,Out).
smt_term_to_prob_term(id_term(id('bvmul'),[A,B]),Env,Out) :- !,
smt_term_to_prob_term(A,Env,BA),
smt_term_to_prob_term(B,Env,BB),
bvwidth(BA,Width),
bv2nat(BA,BANat),
bv2nat(BB,BBNat),
Prod = b(multiplication(BANat,BBNat),integer,[]),
nat2bv(Prod,Width,Out).
smt_term_to_prob_term(id_term(id('bvudiv'),[A,B]),Env,Out) :- !,
smt_term_to_prob_term(A,Env,BA),
smt_term_to_prob_term(B,Env,BB),
bvwidth(BA,Width),
bv2nat(BA,BANat),
bv2nat(BB,BBNat),
Div = b(div(BANat,BBNat),integer,[]),
nat2bv(Div,Width,Out).
smt_term_to_prob_term(id_term(id('bvurem'),[A,B]),Env,Out) :- !,
smt_term_to_prob_term(A,Env,BA),
smt_term_to_prob_term(B,Env,BB),
bvwidth(BA,Width),
bv2nat(BA,BANat),
bv2nat(BB,BBNat),
Rem = b(modulo(BANat,BBNat),integer,[]),
nat2bv(Rem,Width,Out).
smt_term_to_prob_term(id_term(id('bvshl'),[A,B]),Env,Out) :- !,
smt_term_to_prob_term(A,Env,BA),
smt_term_to_prob_term(B,Env,BB),
bvwidth(BA,Width),
bv2nat(BA,BANat),
bv2nat(BB,BBNat),
Int2 = b(integer(2),integer,[]),
Exp = b(power_of(Int2,BBNat),integer,[]),
Res = b(multiplication(BANat,Exp),integer,[]),
nat2bv(Res,Width,Out).
smt_term_to_prob_term(id_term(id('bvlshr'),[A,B]),Env,Out) :- !,
smt_term_to_prob_term(A,Env,BA),
smt_term_to_prob_term(B,Env,BB),
bvwidth(BA,Width),
bv2nat(BA,BANat),
bv2nat(BB,BBNat),
Int2 = b(integer(2),integer,[]),
Exp = b(power_of(Int2,BBNat),integer,[]),
Res = b(div(BANat,Exp),integer,[]),
nat2bv(Res,Width,Out).
smt_term_to_prob_term(id_term(id(div),[Dividend|Divisors]),Env,Out) :- !,
smt_term_to_prob_term(id_term(id('*'),Divisors),Env,BDivisor),
smt_term_to_prob_term(Dividend,Env,BDividend),
Zero = b(integer(0),integer,[]),
DividendLessZero = b(less(BDividend,Zero),pred,[]),
DivisorLessZero = b(less(BDivisor,Zero),pred,[]),
DivisorGreaterZero = b(greater(BDivisor,Zero),pred,[]),
DivisorMinusOne = b(minus(BDivisor,b(integer(1),integer,[])),integer,[]),
DivisorPlusOne = b(add(BDivisor,b(integer(1),integer,[])),integer,[]),
MinusDivisorPlusOne = b(unary_minus(DivisorPlusOne),integer,[]),
conjunct_predicates([DividendLessZero,DivisorGreaterZero],If1),
conjunct_predicates([DividendLessZero,DivisorLessZero],If2),
FixInner = b(if_then_else(If2,MinusDivisorPlusOne,Zero),integer,[]),
Fix = b(if_then_else(If1,DivisorMinusOne,FixInner),integer,[]),
NewBDividend = b(minus(BDividend,Fix),integer,[]),
Out = b(div(NewBDividend,BDivisor),integer,[]).
smt_term_to_prob_term(id_term(id(Id),Args),Env,Out) :-
smt_id_to_prob_id_preds(Id,BId), !,
maplist(smt_term_to_prob_term_maplist(Env),Args,BArgs),
maplist(bool_to_pred,BArgs,PredBArgs),
interleave(BId,PredBArgs,Out).
smt_term_to_prob_term(id_term(id(Id),Args),Env,Out) :-
smt_id_to_prob_id(Id,BId,ConnectingPred), !,
maplist(smt_term_to_prob_term_maplist(Env),Args,BArgs),
call(ConnectingPred,BId,BArgs,Out).
smt_term_to_prob_term(id_term(id(Id),Args),Env,Out) :-
get_function(Id,Env,Params,_Results,Definition), !,
replace_identifiers(Params,Args,Definition,Out,Env).
smt_term_to_prob_term(id_term(id(Id),Args),Env,Out) :-
get_type(Id,Env,set(couple(_X,Y))), !,
smt_term_to_prob_term(id(Id),Env,BId),
maplist(smt_term_to_prob_term_maplist(Env),Args,BArgs),
create_couple(BArgs,BArg),
Out = b(function(BId,BArg),Y,[]).
smt_term_to_prob_term(id(true),_,b(boolean_true,boolean,[])) :- !.
smt_term_to_prob_term(id(false),_,b(boolean_false,boolean,[])) :- !.
smt_term_to_prob_term(id(Id),Env,OutId) :- !,
get_type(Id,Env,Type),
OutId = b(identifier(Id),Type,[]).%,
smt_term_to_prob_term(id(Id,Sort),Env,OutId) :- !,
smt_type_to_prob_type(Sort,Env,Type),
OutId = b(identifier(Id),Type,[]).
smt_term_to_prob_term(svar(Id,Sort),Env,Out) :- !,
smt_type_to_prob_type(Sort,Env,Type),
Out = b(identifier(Id),Type,[]).
smt_term_to_prob_term(integer(I),_,b(integer(I),integer,[])) :- !.
smt_term_to_prob_term(let(Bindings,Term),Env,BTerm) :- !,
let_equalities_and_bids(Bindings,BIDs,Assignments,Env),
create_local_env(Env,BIDs,LocalEnv),
smt_term_to_prob_term(Term,LocalEnv,InnerBTerm),
get_texpr_type(InnerBTerm,InnerType),
(InnerType = pred
-> safe_create_texpr(let_predicate(BIDs,Assignments,InnerBTerm),pred,BTerm)
; safe_create_texpr(let_expression(BIDs,Assignments,InnerBTerm),InnerType,BTerm)).
smt_term_to_prob_term(forall(IDs,Term),Env,Forall) :- !,
maplist(smt_term_to_prob_term_maplist(Env),IDs,Identifiers),
create_local_env(Env,Identifiers,LocalEnv),
smt_term_to_prob_term(Term,LocalEnv,InnerTerm),
convlist(typing_constraint,IDs,InnerConstraints),
bool_to_pred(InnerTerm,InnerTermAsPred), % necessary ??
conjunct_predicates(InnerConstraints,LHS),
create_implication(LHS,InnerTermAsPred,Body),
create_forall(Identifiers,Body,Forall).
smt_term_to_prob_term(exists(IDs,Term),Env,Forall) :- !,
maplist(smt_term_to_prob_term_maplist(Env),IDs,Identifiers),
create_local_env(Env,Identifiers,LocalEnv),
smt_term_to_prob_term(Term,LocalEnv,InnerTerm),
convlist(typing_constraint,IDs,InnerConstraints),
append(InnerConstraints,[InnerTerm],IList),
conjunct_predicates(IList,Inner),
bool_to_pred(Inner,InnerAsPred),
create_exists(Identifiers,InnerAsPred,Forall).
smt_term_to_prob_term(bitvector(Value,Length),_Env,Out) :- !,
integer_to_binary_couples(Value,Length,Couples),
Out = b(set_extension(Couples),set(couple(integer,integer)),[]).
smt_term_to_prob_term(bitvector(Bits),_Env,Out) :- !,
binary_to_binary_couples(Bits,Couples),
Out = b(set_extension(Couples),set(couple(integer,integer)),[]).
smt_term_to_prob_term(X,_,_) :-
add_error(smtlib2_translation,'Unsupported term in smt_term_to_prob_term:',X), fail.