b2p(BOP,Env,SetLogConstr) :-
bin_pred(BOP,A,B,SetLogOperator),!,
bexpr2setlog(A,Env,CA,RA),
bexpr2setlog(B,Env,CB,RB),
SLOG =.. [SetLogOperator,RA,RB],
sconj([CA,CB,SLOG],SetLogConstr).
b2p(truth,_,true).
b2p(falsity,_,false). % TODO: check this
b2p(not_subset_strict(A,B),Env,Constr) :-
bexpr2setlog(A,Env,CA,RA),
bexpr2setlog(B,Env,CB,RB),
create_not_subset(RA,B,Env,NotSubsetConstr),
sdisjoin('='(RA,RB),NotSubsetConstr,Disj),
sconj([CA,CB,Disj],Constr).
b2p(subset(A,B),Env,Constr) :-
bexpr2setlog(A,Env,CA,RA),
create_subset(RA,B,Env,SubsetConstr),
sconj([CA,SubsetConstr],Constr).
b2p(not_subset(A,B),Env,Constr) :-
bexpr2setlog(A,Env,CA,RA),
create_not_subset(RA,B,Env,NotSubsetConstr),
sconj([CA,NotSubsetConstr],Constr).
b2p(member(A,B),Env,Constr) :-
bexpr2setlog(A,Env,CA,RA),
bmember2setlog(B,RA,Env,CB), sconjoin(CA,CB,Constr).
b2p(not_member(A,B),Env,Constr) :-
bexpr2setlog(A,Env,CA,RA),
bnotmember2setlog(B,RA,Env,CB), sconjoin(CA,CB,Constr).
b2p(equal(A,B),Env,Constr) :-
bexpr2setlog(A,Env,CA,RA),
bexpr2setlog(B,Env,CB,RB),
(can_be_unified_in_translation(RA,A,RB,B)
-> RA=RB, sconjoin(CA,CB,Constr) % perform unification here to avoid creating internal fresh Prolog vars
; sconj([CA,CB,'='(RA,RB)],Constr)).
b2p(not_equal(A,B),Env,Constr) :-
bexpr2setlog(A,Env,CA,RA),
bexpr2setlog(B,Env,CB,RB),
(can_be_unified_in_translation(RA,A,RB,B),
can_be_negated(CA,NCA)
-> RA=RB, sconjoin(CB,NCA,Constr) % perform unification here to avoid creating internal fresh Prolog vars
; can_be_unified_in_translation(RA,A,RB,B),
can_be_negated(CB,NCB)
-> RA=RB, sconjoin(CA,NCB,Constr)
; sconj([CA,CB,'neq'(RA,RB)],Constr)).
b2p(negation(A),Env,CA) :- bnegpred2setlog(A,Env,CA).
b2p(conjunct(A,B),Env,Constr) :- bpred2setlog(A,Env,CA), bpred2setlog(B,Env,CB), sconjoin(CA,CB,Constr).
b2p(disjunct(A,B),Env,or(CA,CB)) :- bpred2setlog(A,Env,CA), bpred2setlog(B,Env,CB).
b2p(implication(A,B),Env,implies(CA,CB)) :- bpred2setlog(A,Env,CA), bpred2setlog(B,Env,CB).
b2p(equivalence(A,B),Env,Constr) :-
bpred2setlog(A,Env,CA), bpred2setlog(B,Env,CB),
sconjoin(implies(CA,CB),implies(CB,CA),Constr).
b2p(exists(TypedIds,Body),Env,Constr) :-
exclude(can_translate_typing_to_setlog,TypedIds,Rest),
Rest=[],!, % TODO: extract typing from Body
Constr = exists(Typing,CB),
generate_typing_predicates(TypedIds,TypingPreds),
conjunct_predicates(TypingPreds,TPS),
bpred2setlog(TPS,Env,Typing), bpred2setlog(Body,Env,CB).
b2p(forall(TypedIds,LHS,RHS),Env,Constr) :-
include(can_translate_typing_to_setlog,TypedIds,Translatable),
generate_typing_predicates(Translatable,TypingPreds),
conjunct_predicates(TypingPreds,TPS),
bpred2setlog(TPS,Env,Typing),
bpred2setlog(LHS,Env,CLHS), % TODO: filter LHS into setlog typing and rest and provide warnings
sconjoin(Typing,CLHS,SetLogLHS),
Constr = foreach(SetLogLHS,SetLogRHS),
bpred2setlog(RHS,Env,SetLogRHS).