diff --git a/Src/COLIBRI/check_lin_expr.pl b/Src/COLIBRI/check_lin_expr.pl index b51c5c62ccb66a97e2833f53b82df2e6f4cea308..6197d3892fa71e6b8ca3fab7eeb9c51a6901250e 100755 --- a/Src/COLIBRI/check_lin_expr.pl +++ b/Src/COLIBRI/check_lin_expr.pl @@ -71,7 +71,6 @@ try_check_exists_lin_expr_giving_diff_args(Type,A,B,Stop) :- init_vardef, - %((var(A),var(B)) -> call(spy_here)@eclipse ; true), setval(get_args_from_other,0), ((number(A), @@ -117,21 +116,30 @@ try_check_exists_lin_expr_giving_diff_args(Type,A,B,Stop) :- % qui peuvent etre utilises pour reduire A et B (reduce_var_from_rat_interval(Type,A,R1) -> true;call(spy_here)@eclipse), (reduce_var_from_rat_interval(Type,B,R2) -> true;call(spy_here)@eclipse), - ((number(A),Val = A,Other = B; - number(B),Val = B,Other = A) + ((is_real_box_rat(A,RA), + is_real_box_rat(B,RB)) -> - (Type == int -> - mfd:dvar_remove_element(Other,Val), - Stop = 1 - ; % real - ((not_inf_bounds(Other), % prudence pour p(Inf) ou s(-Inf) - is_float_number(Other), - not is_real_box(Other)) - -> - mreal:dvar_remove_element(Other,Val), + RA \== RB, + Stop = 1 + ; ((number(A), + Val = A, + Other = B; + number(B), + Val = B, + Other = A) + -> + (Type == int -> + mfd:dvar_remove_element(Other,Val), Stop = 1 - ; true)) - ; true). + ; % real + ((not_inf_bounds(Other), % prudence pour p(Inf) ou s(-Inf) + is_float_number(Other), + not is_real_box(Other)) + -> + mreal:dvar_remove_element(Other,Val), + Stop = 1 + ; true)) + ; true)). %% Repérer (x+y)^2 et (x-y)^2 exhiber des carrés forcant le signe protected_find_square_ids(L,R) :- diff --git a/Src/COLIBRI/col_solve.pl b/Src/COLIBRI/col_solve.pl index 2cf9d66f177eeb115c28d4ef23e34ab6018cc96e..f9f6e9fd365e2b7f869a30c8a25395cb50ba2dbe 100644 --- a/Src/COLIBRI/col_solve.pl +++ b/Src/COLIBRI/col_solve.pl @@ -613,10 +613,11 @@ smt_solve_bis0(Test,FILE,Code) :- ; true), Code = 3, setval(diag_code,(timeout,3)) - ; (Tag == syntax -> + ; (TagRead == syntax -> concat_string(["(error \"",FILE,":",TagRead,"\")"],Mess), writeln(output,Mess), - Code = 2 + Code = 2, + setval(diag_code,(unknown,2)) ; % debug (Test == 1 -> halt;true), writeln(output,unknown), @@ -754,7 +755,10 @@ clean_and_save_goal_before_check_sat(Goal,NewGoal) :- conj_to_list(Goal,LGoal), goals_before_check_sat(LGoal,NLGoal0,LEndNewGoal), get_type_decl_list(NLGoal0,LDecl,NLGoal1), - remove_unused_decl_goal(LDecl,NLDecl,NLGoal1,CleanLGoal), + (occurs(get_model,LEndNewGoal) -> + NLDecl = LDecl, + CleanLGoal = NLGoal1 + ; remove_unused_decl_goal(LDecl,NLDecl,NLGoal1,LEndNewGoal,CleanLGoal)), keep_ground_goals(CleanLGoal,NLGoal2,_GCG,_EGCG), % BUG copy_term trop gros @@ -799,10 +803,11 @@ list_to_conj([A,B|L],(A,CBL)) :- !, list_to_conj([A],A) :- !. list_to_conj([],true). -remove_unused_decl_goal([],[],LG,LG). -remove_unused_decl_goal([D|LD],NLD,LG,NLG) ?- !, +remove_unused_decl_goal([],[],LG,_,LG). +remove_unused_decl_goal([D|LD],NLD,LG,LEndNewGoal,NLG) ?- !, ((is_decl(D), term_variables(D,[V]), + not occurs(V,LEndNewGoal), member_begin_end(G,LG,NewLG,ELG,ELG), once member(G,[A $= B, A #= B, @@ -816,9 +821,9 @@ remove_unused_decl_goal([D|LD],NLD,LG,NLG) ?- !, -> % D inutile % call(spy_here)@eclipse, - remove_unused_decl_goal(LD,NLD,NewLG,NLG) + remove_unused_decl_goal(LD,NLD,NewLG,LEndNewGoal,NLG) ; NLD = [D|ENLD], - remove_unused_decl_goal(LD,ENLD,LG,NLG)). + remove_unused_decl_goal(LD,ENLD,LG,LEndNewGoal,NLG)). :- export my_term_variables/2. my_term_variables(Term,Vars) :- @@ -1944,6 +1949,7 @@ check_unit_tests(SatUnsat,TO,Mod) :- check_unit_tests(SatUnsat,TO) :- Sat = [ + "./UnitTests/sat/BV/", "./UnitTests/sat/FP/", "./UnitTests/sat/BVFP/", "./UnitTests/sat/FPLRA/", @@ -1979,6 +1985,7 @@ check_unit_tests(SatUnsat,TO) :- Unsat = [ "./UnitTests/unsat/FP/", + "./UnitTests/unsat/BV/", "./UnitTests/unsat/BVFPLRA/", "./UnitTests/unsat/ALL/", "./UnitTests/unsat/FP/", diff --git a/Src/COLIBRI/lp_arith.pl b/Src/COLIBRI/lp_arith.pl index 293df43b3e4aea2d153437da21b98a1bfcf6a21a..b16ee55b1baeb014c945bf6b9956c3bd324229e9 100755 --- a/Src/COLIBRI/lp_arith.pl +++ b/Src/COLIBRI/lp_arith.pl @@ -1856,6 +1856,23 @@ insert_lin_cstr(square_int(X,XX)) ?- !, make_poly([(LXpHX,X),(-1,XX),(OpHX,LX)],P3,Int3), assert_poly_geq_val(P3,Int3). +/* +si A non signe les propagateurs garantissent: +MaxB = min(op(MinA0),MaxA0) +MinB = 0 +MinA = max(op(MaxB0),MinA0) +MaxA = min(MaxB0,MaxA) + (Ap >= 0), + (An >= 0), + (Ap =< MaxB), + (An =< MaxB), + (Ap - An =:= A) + (Ap + An =:= B) + (Ap =< MaxB * Bool), + (NegBool + Bool = 1), + (An =< MaxB * NegBool) + NegBool * Bool = 0 +*/ insert_lin_cstr(abs_int(A,B)) ?- !, mfd:dvar_range(A,MinA,MaxA), (MaxA =< 0 -> diff --git a/Src/COLIBRI/ndelta.pl b/Src/COLIBRI/ndelta.pl index 61e6c1cf6432dec73fa86a3963b16338cc5d6743..a49fe0db683d29e3fc1a29a74e3dc167b68d443a 100755 --- a/Src/COLIBRI/ndelta.pl +++ b/Src/COLIBRI/ndelta.pl @@ -1444,11 +1444,13 @@ deltas_inter_diff(OMin..OMax,=,C,=,C,1) :- !, C \== 0. deltas_inter_diff(OMin..OMax,_PlusDiff,Min..Max,NS,NC,Check) :- NMin0 is protected_rat_max(OMin,Min), - (NMin0 =:= 0 -> + (fail,NMin0 =:= 0 -> + % seulement pour int et real_int NMin = 1 ; NMin = NMin0), NMax0 is protected_rat_min(OMax,Max), - (NMax0 =:= 0 -> + (fail,NMax0 =:= 0 -> + % seulement pour int et real_int NMax = -1 ; NMax = NMax0), % On peut echouer ici @@ -1463,7 +1465,7 @@ deltas_inter_diff(OMin..OMax,_PlusDiff,Min..Max,NS,NC,Check) :- NS = '=', NC = NMin ; NC = NMin..NMax, - ((NMin > 0; + ((NMin > 0; NMax < 0) -> NS = '+' diff --git a/Src/COLIBRI/realarith.pl b/Src/COLIBRI/realarith.pl index 3dae31c41abe98e0933c23863ee25fde19574a38..55c97e8ab8b50438667d9f93d81cd12c76c8d708 100644 --- a/Src/COLIBRI/realarith.pl +++ b/Src/COLIBRI/realarith.pl @@ -761,7 +761,7 @@ min_inv_round_rna_val(Type,B,A) :- (B == -0.0 -> get_next_float(Type,-0.5,A) ; A = 0.0) - ; safe_minus_rat(B,0.5,A0), + ; check_minus_rat(B,0.5,A0), (A0 == 0.0 -> (get_sign(B,neg) -> A = -0.0 @@ -1227,19 +1227,23 @@ ceiling_bis(Type,A,B) :- true ; (nonvar(A) -> get_next_float_int(Type,A,B) - ; (nonvar(B) -> - (abs(B) =:= 1.0Inf -> - % real impossible - Type \== real, - protected_unify(A,B) - ; get_previous_float_int(Type,B,LA0), - (Type == real -> - mreal:set_typed_intervals(A,Type,[LA0..B]), - Continue = 1 - % A peut devenir un float_int - ; get_next_float(Type,LA0,LA), - mreal:set_typed_intervals(A,Type,[LA..B]))) - ; Continue = 1)))), + ; (is_real_box_rat(A,RA) -> + ceiling(RA,CRA), + numerator(CRA,IC), + cast_int_real(Type,IC,B) + ; (nonvar(B) -> + (abs(B) =:= 1.0Inf -> + % real impossible + Type \== real, + protected_unify(A,B) + ; get_previous_float_int(Type,B,LA0), + (Type == real -> + mreal:set_typed_intervals(A,Type,[LA0..B]), + Continue = 1 + % A peut devenir un float_int + ; get_next_float(Type,LA0,LA), + mreal:set_typed_intervals(A,Type,[LA..B]))) + ; Continue = 1))))), (var(Continue) -> true ; save_cstr_suspensions([A]), @@ -3264,8 +3268,8 @@ add_real1(Type,A,B,C) :- set_priority(Prio), wake_if_other_scheduled(Prio). -check_real_add_opp(_,A,B,C,1) :- !. -check_real_add_opp(real,A,B,C,Continue) :- +%check_real_add_opp(_,A,B,C,1) :- !. +check_real_add_opp(real,A,B,C,Continue) ?- nonvar(C), C \== 0.0, var(A), @@ -3275,8 +3279,8 @@ check_real_add_opp(real,A,B,C,Continue) :- get_saved_cstr_suspensions(LS), ((member((_,op_real1(real,X,OpX)),LS), (X == A -> - % -X + B = C -> X - C = B - Goal = minus_real_bis(real,OpX,C,B) + % -X + B = C -> C + X = B + Goal = add_real_bis(real,OpX,C,B) ; (X == B -> % A + -X = C -> X + C = A Goal = add_real_bis(real,OpX,C,A) @@ -3287,9 +3291,9 @@ check_real_add_opp(real,A,B,C,Continue) :- % A + OpX = C -> A = X + C Goal = add_real_bis(real,X,C,A))))) -> - %call(spy_here)@eclipse, - call_priority(Goal,2), - Continue = 1 + call(spy_here)@eclipse, + call_priority(Goal,2) + %Continue = 1 ; Continue = 1). check_real_add_opp(_,A,B,C,1). @@ -4636,12 +4640,16 @@ is_fzero_interval([I]) ?- get_rel_between_real_args(A,A,RelAB) ?- !, RelAB = '='. get_rel_between_real_args(A,B,RelAB) :- - ((is_fzero(A),ZA = 1; - is_fzero(B)) + (((is_fzero(A), + ZA = 1, + get_type(B,Type); + is_fzero(B), + get_type(A,Type)), + Type \== real) -> (nonvar(ZA) -> (is_fzero(B) -> - % on ne peut pas dire = ici + % on ne peut pas dire = ici RelAB = ? ; mreal:dvar_range(B,MinB,MaxB), (MinB >= 0.0 -> @@ -7085,18 +7093,10 @@ cast_int_real(Rnd,Type,A,B) :- % initialisation de A si necessaire/possible (get_type(A,_) -> dvar_range(int,A,LA,HA), - ((LRnd == rtn, - LA == 0) - -> - LB = -0.0 - ; make_OCamlRat(LA,LRA), - float_of_OCamlRat(Type,LRnd,LRA,LB)), - ((LRnd == rtn, - HA == 0) - -> - HB = -0.0 - ; make_OCamlRat(HA,HRA), - float_of_OCamlRat(Type,HRnd,HRA,HB)), + make_OCamlRat(LA,LRA), + float_of_OCamlRat(Type,LRnd,LRA,LB), + make_OCamlRat(HA,HRA), + float_of_OCamlRat(Type,HRnd,HRA,HB), set_typed_intervals(B,Type,[LB..HB]) ; true), % pas de projection inverse @@ -7469,32 +7469,34 @@ cast_int_real_intervals(Type,[I|L],[CI|CL]) :- %% Pour simplif_node int_to_real_interval(I,CI) :- - getval(float_eval,Type)@eclipse, - int_to_real_interval(Type,I,CI). + getval(float_eval,Type)@eclipse, + int_to_real_interval(Type,I,CI). int_to_real_interval(real,I,CI) :- !, - int_to_real_interval0(I,CI). + int_to_real_interval0(I,CI). int_to_real_interval(Type,I,CI) :- - int_to_float_interval(Type,I,CI). + int_to_float_interval(Type,I,CI). int_to_real_interval0(Min..Max,CI) ?- !, - int_to_float_min(real,Min,CMin), - int_to_float_max(real,Max,CMax), - interval_from_bounds(CMin,CMax,CI). + int_to_float_min(real,Min,CMin), + int_to_float_max(real,Max,CMax), + interval_from_bounds(CMin,CMax,CI). int_to_real_interval0(I,CI) :- - int_to_float_min_max(real,I,CMin,CMax), - interval_from_bounds(CMin,CMax,CI). + int_to_float_min_max(real,I,CMin,CMax), + interval_from_bounds(CMin,CMax,CI). int_to_float_interval(Type,Min..Max,CI) ?- !, - int_to_float(Type,Min,CMin), - int_to_float(Type,Max,CMax), - interval_from_bounds(CMin,CMax,CI). + int_to_float(Type,Min,CMin), + int_to_float(Type,Max,CMax), + interval_from_bounds(CMin,CMax,CI). int_to_float_interval(Type,I,F) :- - int_to_float(Type,I,F). + int_to_float(Type,I,F). +inv_cast_int_real_interval(Type,1.0Inf,A) ?- !. +inv_cast_int_real_interval(Type,-1.0Inf,A) ?- !. inv_cast_int_real_interval(Type,B,A) :- - mfd:dvar_range(A,MinA,MaxA), + mfd:dvar_range(A,MinA,MaxA), mreal:dvar_range(B,MinB,MaxB), (MinB == -1.0Inf -> Stop = 1, @@ -8398,7 +8400,7 @@ check_op_mult_div_real(real,A,OpA) ?- !, % -(X op Y) = OpA % ou -round/truncate(X) = OpA % on essaye de saturer - call(spy_here)@eclipse, + %call(spy_here)@eclipse, (foreach(NGs,LNGs) do call_priority(NGs,2)) ; true). @@ -13601,37 +13603,36 @@ idiv_mod_real(A,B,Q,R) :- !, % pour la simulation des entiers non bornes par des reels get_priority(P), set_priority(1), - set_lazy_domain(real,A), - set_lazy_domain(real,B), - set_lazy_domain(real,Q), - set_lazy_domain(real,BQ), - set_lazy_domain(real,R), - launch_float_int_number(A), - launch_float_int_number(B), - launch_float_int_number(Q), - launch_float_int_number(BQ), - launch_float_int_number(R), - ensure_not_NaN([A,B,Q,BQ,R]), - % 0.0 <= R <= abs(B)-1.0 - launch_geq_real(real,R,0.0), - abs_val_real(real,B,AbsB), - launch_gt_real(real,AbsB,R), - % A = BQ + R - mult_real(real,B,Q,BQ), - add_real(real,BQ,R,A), - % cas à gérer explicitement pour forcer - % les signes de A et B - chk_nan(as(A,real) $= as(0.0,real), - (as(Q,real) $= as(0.0,real)) and - (as(R,real) $= as(0.0,real)), - chk_nan(as(A,real) $> as(0.0,real), - chk_nan(as(B,real) $> as(0.0,real), - as(Q,real) $>= as(0.0,real), - as(Q,real) $=< as(0.0,real)), - chk_nan(as(B,real) $> as(0.0,real), - as(Q,real) $=< as(0.0,real), - as(Q,real) $>= as(0.0,real)))), - check_idiv_mod_real(A,B,Q,BQ,R), + save_cstr_suspensions((A,B)), + get_saved_cstr_suspensions(LS), + ((member((_,check_idiv_mod_real(AA,BB,QQ,BQ,RR)),LS), + A == AA,B == BB) + -> + protected_unify(Q,QQ), + protected_unify(R,RR) + ; set_lazy_domain(real,BQ), + launch_float_int_number(BQ), + ensure_not_NaN([A,B,Q,BQ,R]), + % 0.0 <= R <= abs(B)-1.0 + launch_geq_real(real,R,0.0), + abs_val_real(real,B,AbsB), + launch_gt_real(real,AbsB,R), + % A = BQ + R + mult_real(real,B,Q,BQ), + add_real(real,BQ,R,A), + % cas à gérer explicitement pour forcer + % les signes de A et B + chk_nan(as(A,real) $= as(0.0,real), + (as(Q,real) $= as(0.0,real)) and + (as(R,real) $= as(0.0,real)), + chk_nan(as(A,real) $> as(0.0,real), + chk_nan(as(B,real) $> as(0.0,real), + as(Q,real) $>= as(0.0,real), + as(Q,real) $=< as(0.0,real)), + chk_nan(as(B,real) $> as(0.0,real), + as(Q,real) $=< as(0.0,real), + as(Q,real) $>= as(0.0,real)))), + check_idiv_mod_real(A,B,Q,BQ,R)), set_priority(P), wake_if_other_scheduled(P). @@ -13696,6 +13697,30 @@ check_idiv_mod_real(X,Y,Q,YQ,R) :- protected_unify(R,RR) ; call_priority(Goal,2)) ; true), + % issue 63, A ETOFFER ? + % X > 0, X = -OpX, Q = -OpQ ,R = -OpR + % => idiv_mod_real(OpX,Y,OpQ,OpR) + % saturation: OpX = Y*OpQ + OpR + ((member_begin_end((_,op_real1(real,A,B)),LSusp,BLS,ELS,ELS), + (A == X -> + OpX = B + ; B == X, + OpX = A), + member_begin_end((_,op_real1(real,C,D)),BLS,BLS1,ELS1,ELS1), + (C == Q -> + OpQ = D + ; D == Q, + OpQ = C), + member_begin_end((_,op_real1(real,E,F)),BLS1,BLS2,ELS2,ELS2), + (E == R -> + OpR = F + ; F == R, + OpR = E)) + -> + Goal = (mult_real(real,Y,OpQ,YOpQ), + add_real(real,YOpQ,OpR,OpX)), + call_priority(Goal,2) + ; true), % X et/ou Y variable ((var(Stop), divides_real_vars(Y,X,[])) @@ -13728,11 +13753,8 @@ check_idiv_mod_real(X,Y,Q,YQ,R) :- -> launch_diff_real(real,D1,D2) ; true)), - - (var(Stop) -> - my_suspend(check_idiv_mod_real(X,Y,Q,YQ,R),4,(X,Y,Q,YQ,R)-> - suspend:constrained) - ; true) + my_suspend(check_idiv_mod_real(X,Y,Q,YQ,R),4, + (X,Y,Q,YQ,R)->suspend:constrained) ; true), set_priority(P), wake_if_other_scheduled(P). @@ -19734,27 +19756,30 @@ diff_real_ineq(_,_,_). is_removable_real_value_in_var(Type,DiffGt,A,B,PA,NA) ?- !, number(A), - (is_float_number(B) -> - get_previous_float(Type,A,PA0), - get_next_float(Type,A,NA0), - ((DiffGt == diff, - Type \== real, - abs(A) =:= 0.0) - -> - (A == 0.0 -> - PA = -0.0, - NA = NA0 - ; % A = -0 - PA = PA0, - NA = 0.0) - ; PA = PA0, - NA = NA0) - ; Type = real, - is_float_int_number(B), - get_previous_float_int(real,A,PA), - is_inside_mantissa(real,PA), - get_next_float_int(real,A,NA), - is_inside_mantissa(real,NA)). + (is_float_int_number(B) -> + get_previous_float_int(Type,A,PA), + get_next_float_int(Type,A,NA) + ; (is_float_number(B) -> + get_previous_float(Type,A,PA0), + get_next_float(Type,A,NA0), + ((DiffGt == diff, + Type \== real, + abs(A) =:= 0.0) + -> + (A == 0.0 -> + PA = -0.0, + NA = NA0 + ; % A = -0 + PA = PA0, + NA = 0.0) + ; PA = PA0, + NA = NA0) + ; Type = real, + is_float_int_number(B), + get_previous_float_int(real,A,PA), + is_inside_mantissa(real,PA), + get_next_float_int(real,A,NA), + is_inside_mantissa(real,NA))). diff_real_number_box(_,A,B,1,Continue) ?- !. diff_real_number_box(Type,A,B,_,Continue) :- @@ -20127,7 +20152,11 @@ check_geq_real(Type,A,B,_,Suspend) :- ; geq_real_number_box(Type,A,B,Continue), (var(Continue) -> true - ; Suspend = 1))). + ; mreal:mindomain(A,NMinA), + mreal:maxdomain(B,NMaxB), + (NMinA >= NMaxB -> + true + ; Suspend = 1)))). geq_real_number_box(real,A,B,Continue) ?- !, (is_real_box_rat(A,RA) -> @@ -20163,7 +20192,9 @@ geq_real_number_box(real,A,B,Continue) ?- !, -> true ; % on a pu creer une boite - (get_next_float(real,-1.0Inf) =:= MaxB -> + ((var(B), + get_next_float(real,-1.0Inf) =:= MaxB) + -> launch_box(B), geq_real_number_box(real,A,B,Continue) ; Continue = 1)))))) @@ -20205,7 +20236,9 @@ geq_real_number_box(real,A,B,Continue) ?- !, ; mreal:maxdomain(B,MaxB), (MinA >= MaxB -> true - ; (MaxB =:= get_next_float(real,-1.0Inf) -> + ; ((var(B), + MaxB =:= get_next_float(real,-1.0Inf)) + -> launch_box(B), geq_real_number_box(real,A,B,Continue) ; Continue = 1))))) @@ -20225,7 +20258,9 @@ geq_real_number_box(real,A,B,Continue) ?- !, ; % peut echouer mreal:maxdomain(A) >= MinB, % on peut avoir une boite pour A maintenant - (MinA =:= get_previous_float(real,1.0Inf) -> + ((var(A), + MinA =:= get_previous_float(real,1.0Inf)) + -> % nouvelle boite, on recommence launch_box(A), geq_real_number_box(real,A,B,Continue) @@ -20236,11 +20271,15 @@ geq_real_number_box(real,A,B,Continue) ?- !, mreal:dvar_remove_greater(B,MaxA), mreal:mindomain(B,MinB), mreal:dvar_remove_smaller(A,MinB), - (mreal:maxdomain(B) =:= get_next_float(real,-1.0Inf) -> + ((var(B), + mreal:maxdomain(B) =:= get_next_float(real,-1.0Inf)) + -> launch_box(B), Iter = 1 ; true), - (mreal:mindomain(A) =:= get_previous_float(real,1.0Inf) -> + ((var(A), + mreal:mindomain(A) =:= get_previous_float(real,1.0Inf)) + -> launch_box(A), Iter = 1 ; true), diff --git a/Src/COLIBRI/smt_import.pl b/Src/COLIBRI/smt_import.pl index 51496686c66e1dd460c1d86e610dac4981a715e4..cc621e38c28b185c1b9a4d9f2e66995bc93a5dfd 100644 --- a/Src/COLIBRI/smt_import.pl +++ b/Src/COLIBRI/smt_import.pl @@ -23,7 +23,7 @@ quant_abs(Expr) :- (occurs(Expr,(0,1)) -> Var = Expr ; exit_block(syntax)) - ; Var = 1, + ; %Var = 1, call(as(Var,bool) #= as(Expr,bool)))), getval(quant_abs,TL), (TL == 0 -> @@ -91,7 +91,8 @@ parse_smtlib_file(File,Res) :- wait(ComPid,Status), Status == 0 ; FilteredFile = File), - block((p_simplex_ocaml_create_parser(FilteredFile,PEnv), + ignore_logic(FilteredFile,NFilteredFile), + block((p_simplex_ocaml_create_parser(NFilteredFile,PEnv), read_dolmen_terms(PEnv,Res)), Tag, (getval(scrambler,1)@eclipse -> @@ -99,6 +100,45 @@ parse_smtlib_file(File,Res) :- exit(4) ; exit_block(Tag))). +ignore_logic(File,NFile) :- + open(File,update,Stream), + find_logic(Stream,Logic,NewFstr), + close(Stream), + setval(logic,Logic)@eclipse, + (var(NewFstr) -> + NFile = File + ; NFile = "/tmp/col_temp.smt2", + open(NFile,write,S), + write(S,NewFstr), + close(S)). +find_logic(Stream,Logic,NewFStr) :- + (at_eof(Stream) -> + Logic = ALL + ; at(Stream,Pos), + read_string(Stream, end_of_line, Length, String), + ((substring(String,Before,After,"(set-logic "), + PBefore is Before-1, + not substring(String,1,PBefore,";")) + -> + (String == "(set-logic ALL)" -> + Logic = "ALL" + ; Start is Before+11, + End is Length-Start, + substring(String,Start,End,EStr), + split_string(EStr,")","",LEstr), + (LEstr = [Logic] -> + true + ; LEstr = [_,Logic|_]), + at(Stream,PosE), + read_string(Stream,end_of_file,_,EFStr), + % on remplace pas un commentaire + concat_string(["(set-logic ALL)\n;",String,"\n",EFStr],EndStr), + seek(Stream,0), + read_string(Stream,end_of_file,_,FStr), + substring(FStr,1,Pos,BFStr), + concat_string([BFStr,EndStr],NewFStr)) + ; find_logic(Stream,Logic,NewFStr))). + read_dolmen_terms(PEnv,Terms) :- p_simplex_ocaml_parser_next(PEnv,DTerm), (DTerm == end -> @@ -625,10 +665,16 @@ check_sat :- writeln(output,unknown), setval(unknown_quantifier_abstraction,1)@eclipse ; setval(unknown_quantifier_abstraction,0)@eclipse, - check_sat_vars, - setval(diag_code,(sat,1))@eclipse, - writeln(output,sat))). - + %setval(check_sat_vars,1)@eclipse, + check_sat0)). +/* (check_sat_vars -> + setval(check_sat_vars,0)@eclipse, + setval(diag_code,(sat,1))@eclipse, + writeln(output,sat) + ; setval(diag_code,(unknown,2))@eclipse, + writeln(output,unknown), + setval(check_sat_vars,0)@eclipse))). +*/ check_sat0 :- % pour les unknowm lies aux % contraintes residuelles en Real @@ -1833,7 +1879,14 @@ add_binding(Var,Type,Val) :- get_binding(Var,Type,Val) :- getval(binding,HBinding), hash_contains(HBinding,Var), - hash_get(HBinding,Var,(Type,Val)). + hash_get(HBinding,Var,(Type0,Val)), + (var(Type) -> + Type = Type0 + ; (real_type(Type0,T) -> + (var(Type) -> + Type = T + ; real_type(Type,T)) + ; Type0 = Type)). add_label(Label,Type,Val) :- getval(binding,HBinding), @@ -1871,7 +1924,13 @@ remove_let_var(Var) :- get_let_var_type(Var,NVar,Type) :- atomic(Var), getval(let_vars,HLV), - hash_get(HLV,Var,(Type,NVar)). + hash_get(HLV,Var,(Type0,NVar)), + (var(Type) -> + Type = Type0 + ; (Type == Type0 -> + true + ; real_type(Type,T), + real_type(Type,T))). unsupported_error(Com) :- concat_string(["(error \"Unsupported:",Com,"\")"],Err), @@ -1964,8 +2023,9 @@ smt_interp(Expr,IExpr,Type) :- :- setval(in_assert,0). % INTERPRETATION smt_interp0(exit,true,bool) :- !. -smt_interp0('set-logic'(SLogic),true,bool) :- !, - setval(logic,SLogic)@eclipse. +smt_interp0('set-logic'(SLogic),true,bool) :- !. + % deja fait dans ignore_logic + % setval(logic,SLogic)@eclipse. smt_interp0('get-info'(Key),true,bool) :- call(spy_here)@eclipse, @@ -2042,7 +2102,8 @@ smt_interp0(assert(A0),NewDecl,bool) :- !, ; IA = IA0)) ; IA = IA0), getval(decl,Decl-NEnd), - ((var(IA),VIA = IA; + ((var(IA), + VIA = IA; remove_upper_as(IA,VIA,_), var(VIA)) -> @@ -2053,17 +2114,7 @@ smt_interp0(assert(A0),NewDecl,bool) :- !, ; NEnd = IA), (integer(Decl) -> NDecl = as(Decl,bool) - ; ((Decl =.. [FD,X,Y], - occurs(FD,('#=','$=')), - remove_upper_as(X,X1,_), - remove_upper_as(Y,Y1,_), - (var(X1);atomic(X1)), - (var(Y1);atomic(Y1))) - -> - (protected_unify(X1,Y1) -> - NDecl = as(1,bool) - ; NDecl = as(0,bool)) - ; NDecl = Decl))), + ; NDecl = Decl)), reset_let_vars, remove_true_decl(NDecl,NewDecl), setval(decl,OD), @@ -2375,9 +2426,7 @@ smt_interp0(not(A),NegIA,bool) :- !, ((nonvar(A), remove_upper_as(A,AA,_), (AA = let(Pairs,Expr), - NA = let(Pairs,not(Expr)); - AA = forall(Pairs,Expr), - NA = exists(Pairs,not(Expr)))) + NA = let(Pairs,not(Expr)))) -> smt_interp(NA,NegIA,bool) ; ((nonvar(A), @@ -2405,8 +2454,14 @@ smt_interp0(A => B,IA => IB,bool) :- !, smt_interp(B,IB,bool). % comparaisons smt_interp0(A < B,Comp,bool) :- !, - smt_interp(A,IA0,Type), - smt_interp(B,IB,Type), + smt_interp(A,IA0,Type0), + smt_interp(B,IB,Type1), + ((real_type(Type0,Type), + real_type(Type1,Type)) + -> + true + ; Type0 == Type1, + Type = Type0), get_real_int_type_from_logic(Type), add_as(Type,IA0,IA), functor(Type,FType,_), @@ -2414,8 +2469,14 @@ smt_interp0(A < B,Comp,bool) :- !, Comp = (as(IA,FType) #< IB) ; Comp = (IA $< IB)). smt_interp0(A <= B,Comp,bool) :- !, - smt_interp(A,IA0,Type), - smt_interp(B,IB,Type), + smt_interp(A,IA0,Type0), + smt_interp(B,IB,Type1), + ((real_type(Type0,Type), + real_type(Type1,Type)) + -> + true + ; Type0 == Type1, + Type = Type0), get_real_int_type_from_logic(Type), add_as(Type,IA0,IA), functor(Type,FType,_), @@ -3472,13 +3533,23 @@ get_type_from_sort('Bool',bool,bool) :- !. get_type_from_sort('Int',IType,Type) :- setval(int_used,1)@eclipse, (getval(real_for_int,1)@eclipse -> -% IType = real, - IType = real_int, - Type = real_int + (var(IType) -> + IType = real_int, + Type = real_int + ; Type = real) ; Type = IType, IType = int), !. -get_type_from_sort('Real',real,real) :- !. +get_type_from_sort('Real',IType,Type) ?- !, + (var(IType) -> + (var(Type) -> + IType = real, + Type = IType + ; Type = IType) + ; (var(Type) -> + Type = IType + ; occurs(IType,(real,real_int)), + occurs(Type,(real,real_int)))). get_type_from_sort('RoundingMode',rnd,rnd) :- !. get_type_from_sort('_'('BitVec',N),uint(N),uint(N)) :- !. get_type_from_sort('Float32',float_simple,float) :- !. diff --git a/Src/COLIBRI/solve.pl b/Src/COLIBRI/solve.pl index 759b7a66a6ce6f39ee6855a8aa6a5a232818da61..6236381094f3bc587d489fb57e9f70b9e8fd363b 100644 --- a/Src/COLIBRI/solve.pl +++ b/Src/COLIBRI/solve.pl @@ -2488,7 +2488,7 @@ unfold_int_expr(EA $= EB,D,Cstr,Type0,R) ?- insert_dep_inst(dep(A,D,[R])), insert_dep_inst(dep(B,D,[R])), make_conj(CA,CB,CAB), - (((Type \== real; + ((fail,(Type \== real; fail,is_float_int_number(B)), (number(A), C = A; @@ -2497,7 +2497,7 @@ unfold_int_expr(EA $= EB,D,Cstr,Type0,R) ?- var(B)) -> Goal = in_intervals_reif(Type,B,[C],R) - ; (((Type \== real; + ; ((fail,(Type \== real; fail,is_float_int_number(A)), (number(B), C = B; @@ -2574,7 +2574,7 @@ unfold_int_expr(EA $\= EB,D,Cstr,Type0,R) ?- !, insert_dep_inst(dep(A,D,[R])), insert_dep_inst(dep(B,D,[R])), make_conj(CA,CB,CAB), - ((Type \== real, + (fail,(Type \== real, (number(A),C = A; number(EA),to_real(Type,EA,C)), var(B)) @@ -2588,7 +2588,7 @@ unfold_int_expr(EA $\= EB,D,Cstr,Type0,R) ?- !, Inter = [NA..1.0Inf] ; Inter = [-1.0Inf..PA,NA..1.0Inf])), Goal = in_intervals_reif(Type,B,Inter,R) - ; (((Type \== real; + ; ((fail,(Type \== real; fail,is_float_int_number(A)), (number(B), C = B; @@ -2642,7 +2642,7 @@ unfold_int_expr(EA $< EB,D,Cstr,Type0,R) ?- insert_dep_inst(dep(A,D,[R])), insert_dep_inst(dep(B,D,[R])), min_max_lazy(Type,Min,Max,_), - (((Type \== real; + ((fail,(Type \== real; fail,is_float_int_number(B), FI = 1), (number(A),C = A; @@ -2655,7 +2655,7 @@ unfold_int_expr(EA $< EB,D,Cstr,Type0,R) ?- ; NA = C), Inter = [NA..Max], Goal = in_intervals_reif(Type,B,Inter,R) - ; (((Type \== real; + ; ((fail,(Type \== real; fail,is_float_int_number(A), FI = 1), (number(B),C = B; @@ -2745,7 +2745,7 @@ unfold_int_expr(EA $=< EB,D,Cstr,Type0,R) ?- insert_dep_inst(dep(A,D,[R])), insert_dep_inst(dep(B,D,[R])), min_max_lazy(Type,Min,Max,_), - (((Type \== real; + ((fail,(Type \== real; fail,is_float_int_number(B)), (number(A),C = A; number(EA),to_real(Type,EA,C)), @@ -2759,7 +2759,7 @@ unfold_int_expr(EA $=< EB,D,Cstr,Type0,R) ?- ; NC = C), Inter = [NC..Max], Goal = in_intervals_reif(Type,B,Inter,R) - ; (((Type \== real; + ; ((fail,(Type \== real; fail,is_float_int_number(A)), (number(B),C = B; number(EB),to_real(Type,EB,C)), @@ -5818,7 +5818,10 @@ isNaN(F,R) :- protected_unify(R,RR), (R == 0 -> ensure_not_NaN(F) - ; true) + ; (R == 1 -> + protected_unify(F,nan) + ; % on laisse l'autre travailler + true)) ; my_suspend(isNaN(F,R),0,[trigger(isNaN),(F,R)->suspend:constrained])))), set_priority(Prio), wake_if_other_scheduled(Prio). @@ -6292,7 +6295,8 @@ to_real(Type,X,FX) :- to_real1(real,X,FX) ?- !, (getval(check_sat_vars,1)@eclipse -> FX = X - ; term_string(X,SX), + ; rational(X,RX), + term_string(RX,SX), unfold_real_expr(realString(SX),0,_,real,FX)). %norm_zero(real,X,FX). to_real1(_Type,nan,FX) ?- !, @@ -6596,6 +6600,11 @@ unfold_real_expr(float_from_raw_uintN(EA),D,Cstr,Type,R) :- ; Size == 64, Type = float_double), !, + unfold_int_expr(isNaN(as(R,Type)),D,CN,bool,Bool), + insert_dep_inst(dep(R,D,[A,Bool])), + make_conj(CA,CN,CAN), + make_conj(CAN,float_from_raw_uintN(Type,A,R),Cstr). +/* ((number(A); number(R)) -> @@ -6603,6 +6612,7 @@ unfold_real_expr(float_from_raw_uintN(EA),D,Cstr,Type,R) :- blocked_call(float_from_raw_uintN(Type,A,R)) ; insert_dep_inst(dep(R,D,[A])), make_conj(CA,float_from_raw_uintN(Type,A,R),Cstr)). +*/ unfold_real_expr(float_from_int(EA),D,Cstr,float_simple,R) :- !, unfold_real_expr(float_from_int(rne,EA),D,Cstr,float_simple,R). unfold_real_expr(float_from_int(Rnd0,EA),D,Cstr,float_simple,R) :- @@ -10135,27 +10145,35 @@ check_exists_fp_geq_reif(Cond,Type,A,B,Bool,Continue) :- ; Continue = 1). +gt_real_reif(Type,A,A,Bool) ?- + check_not_NaN(A), + !, + protected_unify(Bool,0). +gt_real_reif(Type,A,B,Bool) ?- + Type \== real, + is_fzero(A), + is_fzero(B), + !, + protected_unify(Bool,0). gt_real_reif(Type,A,B,Bool) :- - (A == B -> - protected_unify(Bool,0) - ; (nonvar(Bool) -> - (Bool == 1 -> - launch_gt_real(Type,A,B) - ; % Bool = 0 - launch_geq_real(Type,B,A)) - ; ((getval(check_sat_vars,1)@eclipse, - Type == real, - once (number(A), - rational(A,RA); - is_real_box_rat(A,RA)), - once (number(B), - rational(B,RB); - is_real_box_rat(B,RB))) - -> - (RA > RB -> - protected_unify(Bool,1) - ; protected_unify(Bool,0)) - ; gt_real_reif_bis(Type,A,B,Bool)))). + (nonvar(Bool) -> + (Bool == 1 -> + launch_gt_real(Type,A,B) + ; % Bool = 0 + launch_geq_real(Type,B,A)) + ; ((getval(check_sat_vars,1)@eclipse, + Type == real, + once (number(A), + rational(A,RA); + is_real_box_rat(A,RA)), + once (number(B), + rational(B,RB); + is_real_box_rat(B,RB))) + -> + (RA > RB -> + protected_unify(Bool,1) + ; protected_unify(Bool,0)) + ; gt_real_reif_bis(Type,A,B,Bool))). gt_real_reif_bis(Type,A,B,Bool) :- get_priority(Prio), @@ -10204,9 +10222,32 @@ check_exists_gt_real_reif(Type,A,B,Bool,Continue) :- ; Continue = 1). +geq_real_reif(Type,A,A,Bool) ?- + check_not_NaN(A), + !, + protected_unify(Bool,1). +geq_real_reif(Type,A,B,Bool) ?- + Type \== real, + is_fzero(A), + is_fzero(B), + !, + protected_unify(Bool,1). geq_real_reif(Type,A,B,Bool) :- + get_priority(Prio), + set_priority(1), not_int(Bool,NotBool), - gt_real_reif(Type,B,A,NotBool). + gt_real_reif(Type,B,A,NotBool), + (nonvar(Bool) -> + (Bool == 1 -> + protected_unify(NotBool,0) + ; protected_unify(NotBool,1)) + ; (nonvar(NotBool) -> + (NotBool == 1 -> + protected_unify(Bool,0) + ; protected_unify(Bool,1)) + ; true)), + set_priority(Prio), + wake_if_other_scheduled(Prio). /* geq_real_reif(Type,A,B,Bool) :- gt_real_reif(Type,B,A,NotBool), @@ -10253,11 +10294,9 @@ float_from_raw_uintN(Type,Size,Int,Res) :- Res == R, check_not_NaN(Res))) -> - kill_suspension(S), protected_unify(Int,IInt), protected_unify(R,Res) - ; true), - check_before_susp_float_from_raw_uintN(Type,Size,Int,Res)), + ; check_before_susp_float_from_raw_uintN(Type,Size,Int,Res))), set_priority(Prio), wake_if_other_scheduled(Prio). @@ -10265,10 +10304,10 @@ check_before_susp_float_from_raw_uintN(Type,Size,Int,Res) :- float_from_raw_uintN_inst(Type,Size,Int,Res,Continue), (var(Continue) -> true - ; (check_not_NaN(Res) -> + ; ((true;check_not_NaN(Res)) -> my_suspend(float_from_raw_uintN(Type,Size,Int,Res), 0,(Int,Res)->suspend:constrained), - (get_sign(Res,_) -> + ((true;get_sign(Res,_)) -> true ; % A VERIFIER SUR UnitTest QF_*BVFP* !!! chk_nan(not(isZero((as(Res,Type)))), @@ -10276,10 +10315,14 @@ check_before_susp_float_from_raw_uintN(Type,Size,Int,Res) :- as(0.0,Type) $>= as(Res,Type), as(Res,Type) $>= as(0.0,Type)), as(1,bool))) - ; int_vars(bool,Bool), - my_suspend(float_from_raw_uintN(Type,Size,Int,Res), - 0,Bool->suspend:inst), - isNaN(Res,Bool))). + ; get_saved_cstr_suspensions(LS), + ((member((_,isNaN(R,B)),LS), + R == Res) + -> + protected_unify(B,Bool) + ; int_vars(bool,Bool), + isNaN(Res,Bool)), + my_suspend(float_from_raw_uintN(Type,Size,Int,Res),0,Bool->suspend:inst))). float_from_raw_uintN_inst(Type,Size,Int,Res,Continue) :- (integer(Int) -> @@ -11112,6 +11155,7 @@ cdiv_crem(A,B,Q,R) :- mult_real(real,B,Q,BQ), % A = BQ + R add_real(real,BQ,R,A), +/* % cas à gérer explicitement pour forcer % les signes de A et B chk_nan(as(A,real) $= as(0.0,real), @@ -11124,6 +11168,7 @@ cdiv_crem(A,B,Q,R) :- chk_nan(as(B,real) $> as(0.0,real), as(Q,real) $=< as(0.0,real), as(Q,real) $>= as(0.0,real)))), +*/ check_cdiv_crem(A,B,Q,BQ,R), set_priority(P), wake_if_other_scheduled(P). @@ -11132,22 +11177,53 @@ cdiv_crem(A,B,Q,R) :- check_cdiv_crem(A,B,Q,BQ,R) :- get_priority(P), set_priority(1), - check_cdiv_crem1(A,B,Q,BQ,R), + check_cdiv_crem_inst_free(A,B,Q,BQ,R,Continue), + (nonvar(Continue) -> + check_cdiv_crem1(A,B,Q,BQ,R) + ; true), set_priority(P), wake_if_other_scheduled(P). -check_cdiv_crem1(A,B,Q,BQ,A) ?- !, - protected_unify(BQ,0.0), - protected_unify(Q,0.0). -check_cdiv_crem1(A,B,Q,BQ,R) :- - nonvar(A), - nonvar(B), - !, - div_real(real,A,B,RQ), - truncate(real,RQ,Q), - mult_real(real,B,Q,BQ), - add_real(real,BQ,R,A). +check_cdiv_crem_inst_free(A,B,Q,BQ,R,Continue) ?- !, + (A == 0.0 -> + protected_unify(Q,0.0), + protected_unify(R,0.0); + (B == 1 -> + protected_unify(Q,A), + protected_unify(R,0.0); + (B == -1 -> + protected_unify(R,0.0), + op_real(real,A,Q); + (R == 0 -> + mult_real(real,B,Q,A); + (A == B -> + protected_unify(Q,1.0), + protected_unify(R,0.0); + (A == R -> + protected_unify(BQ,0.0), + protected_unify(Q,0.0); + ((Q == 0.0; + BQ == 0.0) + -> + protected_unify(Q,0.0), + protected_unify(BQ,0.0), + protected_unify(A,R); + ((is_inst_box(B), + once (is_inst_box(A); + is_inst_box(Q))) + -> + div_real(real,A,B,RQ), + truncate(real,RQ,Q), + mult_real(real,B,Q,BQ), + add_real(real,BQ,R,A); + Continue = 1)))))))). + +is_inst_box(A) :- + once (nonvar(A); + is_real_box_rat(A,_)). + check_cdiv_crem1(A,B,Q,BQ,R) :- +/* ((not not_zero(A), not not_zero(Q), (nonvar(A); @@ -11156,18 +11232,21 @@ check_cdiv_crem1(A,B,Q,BQ,R) :- is_real_box_rat(B,_))) -> true - ; % A FAIRE: anti_congr,gestion des opposés ... - save_cstr_suspensions((A,B,Q,BQ,R)), - get_saved_cstr_suspensions(LS1), - attached_suspensions(cdcr,LST), - (foreach(S,LST), - fromto(LS1,ILS,OLS,LS) do - (get_suspension_data(S,goal,GS) -> - OLS = [(S,GS)|ILS] - ; OLS = ILS)), + ; +*/ + % A FAIRE: anti_congr,gestion des opposés ... + save_cstr_suspensions((A,B,Q,BQ,R)), + get_saved_cstr_suspensions(LS1), + attached_suspensions(cdcr,LST), + (foreach(S,LST), + fromto(LS1,ILS,OLS,LS) do + (get_suspension_data(S,goal,GS) -> + OLS = [(S,GS)|ILS] + ; OLS = ILS)), + (member((_,check_cdiv_crem(_,_,_,_,_)),LS) -> (foreach((S,G),LS), foreach(Unif,LUnif), - param(A,B,Q,BQ,R) do + param(A,B,Q,BQ,R,Stop) do (G = check_cdiv_crem(AA,BB,QQ,BBQQ,RR) -> (AA == A -> (BB == B -> @@ -11179,7 +11258,9 @@ check_cdiv_crem1(A,B,Q,BQ,R) :- ; (RR == R -> % R = A - BBQQ et R = A - BQ % donc BBQQ = BQ - (QQ == Q -> + ((QQ == Q, + not_zero(Q)) + -> % R = A - BBQ et R = A - BQ % donc BB == B Stop = 1, @@ -11209,9 +11290,7 @@ check_cdiv_crem1(A,B,Q,BQ,R) :- % donc RR = OpA + BQ % donc RR = -R Stop = 1, - Unif = (set_lazy_domain(real,Q,QQ), - op_real_bis(real,Q,QQ), - set_lazy_domain(real,RR), + Unif = (op_real_bis(real,Q,QQ), op_real_bis(real,R,RR)) ; ((is_op_real(real,B,OpB), BB == OpB) @@ -11223,19 +11302,18 @@ check_cdiv_crem1(A,B,Q,BQ,R) :- % donc RR = -R Stop = 1, Unif = (protected_unify(Q,QQ), - set_lazy_domain(real,BBQQ), op_real_bis(real,BQ,BBQQ), - set_lazy_domain(real,RR), op_real_bis(real,R,RR)) ; Unif = true)) ; Unif = true)) ; Unif = true)), (foreach(U,LUnif) do - call_priority(U,2)), - (var(Stop) -> - my_suspend(check_cdiv_crem(A,B,Q,BQ,R),0, - [trigger(cdcr),(A,B,Q,BQ,R)->suspend:constrained]) - ; true)). + call_priority(U,2)) + ; true), + (nonvar(Stop) -> + true + ; my_suspend(check_cdiv_crem(A,B,Q,BQ,R),0, + [trigger(cdcr),(A,B,Q,BQ,R)->suspend:constrained])). same_abs(Type,A,X,LSusp,Rel,NLSusp) :- (Type = real -> @@ -12771,6 +12849,7 @@ dvar_size_check_real(real,V,Size) ?- !, real_int_size(V,Size) ; dvar_size(float_double,V,Size)) ; Size = 1.0Inf). + dvar_size_check_real(Type,V,Size) :- dvar_size(Type,V,Size).