diff --git a/Src/COLIBRI/QF_LRA b/Src/COLIBRI/QF_LRA new file mode 120000 index 0000000000000000000000000000000000000000..fc098200d87d9d6a8ec14daa19572a3e3275ad3d --- /dev/null +++ b/Src/COLIBRI/QF_LRA @@ -0,0 +1 @@ +../../../svn_gatel/trunk/Src/COLIBRI/QF_LRA \ No newline at end of file diff --git a/Src/COLIBRI/arith.pl b/Src/COLIBRI/arith.pl index c9d7be0cbb79736557d8d1ced3f965d8d7c5d3d4..539305cdf03643ed9d914d9443b00a74e63d8059 100755 --- a/Src/COLIBRI/arith.pl +++ b/Src/COLIBRI/arith.pl @@ -40,12 +40,12 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% :- export add/3. add(A,B,C) :- - set_lazy_domain(int,A), - set_lazy_domain(int,B), + set_lazy_domain(int,A), + set_lazy_domain(int,B), % un minus cache ?? (get_type(C,int) -> true - ; mfd:dvar_range(A,MinA,MaxA), + ; mfd:dvar_range(A,MinA,MaxA), mfd:dvar_range(B,MinB,MaxB), MinC is MinA+MinB, MaxC is MaxA+MaxB, @@ -81,7 +81,7 @@ add_int(A,TA,B,TB,C,TC) :- wake_if_other_scheduled(Prio). % on cherche A + (-X) = C --> X + C = A -%check_add_opp(A,B,C,1) :- !. +check_add_opp(A,B,C,1) :- !. check_add_opp(A,B,C,Continue) :- save_cstr_suspensions((A,B)), get_saved_cstr_suspensions(LS), @@ -1347,7 +1347,10 @@ minus(A,B,C) :- MinC is MinA-MaxB, MaxC is MaxA-MinB, mfd:(C::MinC..MaxC)), - add(B,C,A). +% add(B,C,A). + % ennoncé permettant de garder C en résultat + op(B,OpB), + add(A,OpB,C). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% C = A * B @@ -1385,7 +1388,7 @@ no_lin_mult(A,B,C) :- mult_int(A,_,A,_,C,_) ?- !, - power(A,2,C). + square(A,C). mult_int(A,TA,B,TB,C,TC) :- get_priority(Prio), set_priority(1), @@ -1411,6 +1414,7 @@ mult_bis(A,TA,B,TB,C,TC) :- mfd:get_intervals(B,IB), mfd:get_intervals(C,IC), save_cstr_suspensions((A,B,C)), + get_saved_cstr_suspensions(LSusp), % Point fixe sur les projections de congruence % on peut aller jusqu'a instancier A,B ou C fp_congr_mult(int,A,B,C), @@ -1423,30 +1427,47 @@ mult_bis(A,TA,B,TB,C,TC) :- true ; % Factorisation avec un mult_int clear_Goal(mult_int,A,B,C), - % On regarde si on a un div_mod_int(C,A,...) - % ou div_mod_int(C,B,...) - check_fusion_div_mod_int(mult_int,A,B,C), - check_zero_mult_int(A,B,C), - check_assoc_dist(mult_int,A,B,C), - % On a peut etre reduit A,B,C avant - mfd:get_intervals(A,NIA), - mfd:get_intervals(B,NIB), - mfd:get_intervals(C,NIC), - check_reduced(IA,NIA,TA), - check_reduced(IB,NIB,TB), - check_reduced(IC,NIC,TC), - ((true;var(TA),var(TB),var(TC)) -> - % Probleme avec arith_sched sans doute - TA = 1, - TB = 1, - TC = 1 - ; true), - % Calcul des projections - mult_free_proj(A,TA,B,TB,C,TC), - int_check_notify_constrained(A,IA), - int_check_notify_constrained(B,IB), - int_check_notify_constrained(C,IC), - check_before_susp_mult(A,B,C))). + ((member((Susp,mult_int(AA,_,BB,_,CC,_)),LSusp), + CC == C, + (A == BB -> + exists_diff_Rel(B,AA), + Z = A + ; (A == AA -> + exists_diff_Rel(B,BB), + Z = A + ; B == BB, + exists_diff_Rel(A,AA), + Z = B))) + -> + % cas manquant + call(spy_here)@eclipse, + kill_suspension(Susp), + protected_unify(C,0), + protected_unify(Z,0) + ; % On regarde si on a un div_mod_int(C,A,...) + % ou div_mod_int(C,B,...) + check_fusion_div_mod_int(mult_int,A,B,C), + check_zero_mult_int(A,B,C), + check_assoc_dist(mult_int,A,B,C), + % On a peut etre reduit A,B,C avant + mfd:get_intervals(A,NIA), + mfd:get_intervals(B,NIB), + mfd:get_intervals(C,NIC), + check_reduced(IA,NIA,TA), + check_reduced(IB,NIB,TB), + check_reduced(IC,NIC,TC), + ((true;var(TA),var(TB),var(TC)) -> + % Probleme avec arith_sched sans doute + TA = 1, + TB = 1, + TC = 1 + ; true), + % Calcul des projections + mult_free_proj(A,TA,B,TB,C,TC), + int_check_notify_constrained(A,IA), + int_check_notify_constrained(B,IB), + int_check_notify_constrained(C,IC), + check_before_susp_mult(A,B,C)))). check_exists_power_int_with_mult_args(X,Y,Z,1,Continue) ?- !, @@ -4603,30 +4624,64 @@ check_zero_and_div_interval(Val1,Val2,Val) :- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% B = A^2 +%% B = A^2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% square(A,B) :- - power(A,2,B). + power(A,2,B). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% B = A^N avec N entier >= 0 +%% B = A^N avec N entier >= 0 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% power(A,N,B) :- - set_lazy_domain(int,A), - integer(N), - (N == 0 -> - protected_unify(B = 1) - ; (N == 1 -> - protected_unify(B = A) - ; N > 1, - (get_type(B,int) -> - true - ; mfd:dvar_range(A,MinA,MaxA), - Mod2 is N mod 2, - power_interval_list([MinA..MaxA],N,Mod2,IB), - mfd:(B::IB)), - power_int(A,1,N,B,1))). + get_priority(P), + set_priority(1), + set_lazy_domain(int,A), + set_lazy_domain(int,B), + integer(N), + (N \== 2 -> + (N == 0 -> + protected_unify(B = 1) + ; (N == 1 -> + protected_unify(B = A) + ; N > 1, + (get_type(B,int) -> + true + ; mfd:dvar_range(A,MinA,MaxA), + Mod2 is N mod 2, + power_interval_list([MinA..MaxA],N,Mod2,IB), + mfd:(B::IB)), + power_int(A,1,N,B,1))) + ; get_cstr_suspensions(A,LS), + ((Goal = add_int(X,_,Y,_,AA,_), + member(Susp,LS), + get_suspension_data(Susp,goal,Goal), + A == AA) + -> + % Identités remarquables: + % (X+Y)^2 ou (X-Y)^2 + % SATURATION DU STORE + ((delayed_goals(Y,DGY), + member(op_int(Z,YY),DGY), + Y == YY) + -> + % c'est un minus: (X-Z)^2 + power(X,2,X2), + power(Z,2,Z2), + add(X2,Z2,X2pZ2), + mult(X,Z,XZ), + mult(-2,XZ,MDXZ), + add(X2pZ2,MDXZ,B) + ; power(X,2,X2), + power(Y,2,Y2), + add(X2,Y2,X2pY2), + mult(X,Y,XY), + mult(2,XY,DXY), + add(X2pY2,DXY,B)) + ; power_int(A,1,2,B,1), + lin_mult_int(A,A,B))), + set_priority(P), + wake_if_other_scheduled(P). power_int(A,TA,N,B,TB) :- diff --git a/Src/COLIBRI/arith_sched.pl b/Src/COLIBRI/arith_sched.pl index 5f79db330e9c86f5c4b1467080cf9e5e287c1809..dc9b35cd11a0beeb9bb5dc5ce43422168717637b 100755 --- a/Src/COLIBRI/arith_sched.pl +++ b/Src/COLIBRI/arith_sched.pl @@ -81,6 +81,22 @@ set_touched_arg_from_goal(mult_real1(_,A,B,C),_Var,S) :- !, NInst = NInst0), change_prio_if_inst_arg(NInst,2,S,LP,4). +set_touched_arg_from_goal(square_real1(_,A,B),_Var,S) :- !, + ((nonvar(A); + nonvar(B); + A == B) + -> + change_prio_if_not_RC(S,2) + ; true). + +set_touched_arg_from_goal(sqrt_real1(_,A,B),_Var,S) :- !, + ((nonvar(A); + nonvar(B); + A == B) + -> + change_prio_if_not_RC(S,2) + ; true). + set_touched_arg_from_goal(div_mod_int(A,B,C,_BC,R),_Var,S) :- !, term_variables((A,B,C,R),L), NInst0 is 4 - length(L), @@ -127,10 +143,14 @@ set_touched_arg_from_goal(op_int(A,B),_Var,S) :- !, -> change_prio_if_not_RC(S,2) ; true)). -set_touched_arg_from_goal(op_real1(_,A,B),_Var,S) :- !, +set_touched_arg_from_goal(op_real1(Type,A,B),_Var,S) :- !, (nonvar(A) -> (nonvar(B) -> - B is -A + ((Type == real, + B == 0.0) + -> + B == A + ; B is -A) ; change_prio_if_not_RC(S,2)) ; ((nonvar(B); A == B) diff --git a/Src/COLIBRI/check_lin_expr.pl b/Src/COLIBRI/check_lin_expr.pl index a1cbfe23481b434ab55b60b8e755e2f5e046f6aa..b51c5c62ccb66a97e2833f53b82df2e6f4cea308 100755 --- a/Src/COLIBRI/check_lin_expr.pl +++ b/Src/COLIBRI/check_lin_expr.pl @@ -26,8 +26,8 @@ check_exists_lin_expr_giving_diff_args(Type,A,B,Stop) :- -> true ; getval(gdbg,1)@eclipse, - call(spy_here)@eclipse, - try_check_exists_lin_expr_giving_diff_args(Type,A,B,Stop), + %call(spy_here)@eclipse, + %try_check_exists_lin_expr_giving_diff_args(Type,A,B,Stop), writeln(output,fail_lin_expr_giving_diff_args), fail). check_exists_lin_expr_giving_diff_args(_,_,_,_). @@ -100,6 +100,7 @@ try_check_exists_lin_expr_giving_diff_args(Type,A,B,Stop) :- launch_congr(B,Rest2,Mod2) ; true)) ; true), + check_same_lin_sum(Res1,Res2), protected_find_square_ids(Res1,NRes1), protected_find_square_ids(Res2,NRes2), %remove_common_vars(L1,L2,NL1,NL2,Work), @@ -211,20 +212,21 @@ get_single_var_square_ids(LS,NL,EndNL,Cst0,NCst,Work) :- % X^2 + X + 1_4 -> 1_4*(4*X2 +2*(4/2)*X +1) % 1_4*((2*X + 1)^2 + (4-4)X^2) % 1_4*(2*X + 1)^2 - Factor = Cst1, CX2 is safe_div_rat(CX21,Cst1), CX is safe_div_rat(CX1,Cst1), NCX2 is safe_div_rat(CX,2_1), RemCX20 is safe_minus_rat(CX2,safe_mult_rat(NCX2,NCX2)), - RemCX20 >= 0, - RemCX2 is (Factor*Sign)*RemCX20, - RemCst is Factor*Sign) + RemCX20 >= 0) -> Work = 1, + Factor = Cst1, + RemCX2 is (Factor*Sign)*RemCX20, NX = NCX2*X, Sum = NX + 1, SId = sqr(Sum), CSum is Factor*Sign, + % On a consommé CSum de Cst0 + RemCst is Cst0 - CSum, ((member_begin_end(CS*Sqr1,NEndNL,NNEndNL,ES,ES), nonvar(Sqr1), Sqr1 = sqr(SSum), @@ -854,173 +856,173 @@ get_args_from_other_add_op_mult(Type,LC,V,LArgs) :- remove_common_vars([],L2,[],NL2,_) :- !, - remove_null_fact(L2,NL2). + remove_null_fact(L2,NL2). remove_common_vars(L1,[],NL1,[],_) :- !, - remove_null_fact(L1,NL1). + remove_null_fact(L1,NL1). remove_common_vars([N1*X|L1],L2,NewL1,NewL2,Work) :- - ((occurs(X,L2), - member_begin_end(N2*XX,L2,NL2,End,End), - X == XX) - -> - Work = 1, - (N1 > N2 -> - Diff is N1 - N2, - NewL1 = [Diff*X|EndNewL1], - remove_common_vars(L1,NL2,EndNewL1,NewL2,_) - ; (N1 == N2 -> - remove_common_vars(L1,NL2,NewL1,NewL2,_) - ; %% N1 < N2 - Diff is N2 - N1, - NewL2 = [Diff*X|EndNewL2], - remove_common_vars(L1,NL2,NewL1,EndNewL2,_))) - ; (N1 == 0 -> - remove_common_vars(L1,L2,NewL1,NewL2,Work) - ; NewL1 = [N1*X|EndNewL1], - remove_common_vars(L1,L2,EndNewL1,NewL2,Work))). + ((occurs(X,L2), + member_begin_end(N2*XX,L2,NL2,End,End), + X == XX) + -> + Work = 1, + (N1 > N2 -> + Diff is N1 - N2, + NewL1 = [Diff*X|EndNewL1], + remove_common_vars(L1,NL2,EndNewL1,NewL2,_) + ; (N1 == N2 -> + remove_common_vars(L1,NL2,NewL1,NewL2,_) + ; % N1 < N2 + Diff is N2 - N1, + NewL2 = [Diff*X|EndNewL2], + remove_common_vars(L1,NL2,NewL1,EndNewL2,_))) + ; (N1 == 0 -> + remove_common_vars(L1,L2,NewL1,NewL2,Work) + ; NewL1 = [N1*X|EndNewL1], + remove_common_vars(L1,L2,EndNewL1,NewL2,Work))). remove_null_fact([],[]). remove_null_fact([N*X|L],NL) :- - (N =:= 0 -> - remove_null_fact(L,NL) - ; NL = [N*X|EndL], - remove_null_fact(L,EndL)). + (N =:= 0 -> + remove_null_fact(L,NL) + ; NL = [N*X|EndL], + remove_null_fact(L,EndL)). %% Coeff1*V1 + C1 = Coeff2*V2 + C2 %% On regarde si on peut definir V1 (ou V2) en fonction %% de V2 (ou V1) par Vi = K*Vj + Cste get_affine_def_from_lin_expr([Coeff1*V1],[Coeff2*V2],C1,C2,FromGoal,Goal) :- - GCD is gcd(Coeff1,Coeff2), - (GCD == Coeff1 -> - Cste0 is C2-C1, - 0 is Cste0 mod GCD, - X = V1, - Y = V2, - K is Coeff2 div GCD - ; GCD == Coeff2, - Cste0 is C1-C2, - 0 is Cste0 mod GCD, - X = V2, - Y = V1, - K is Coeff1 div GCD), - Cste is Cste0 div GCD, - (K == 1 -> - (Cste == 0 -> - Goal = [X=Y] - ; (FromGoal = add(B,C,A) -> - %% pour ne pas boucler - (Y,Cste) \== (B,C), - (Y,Cste) \== (C,B) - ; true), - Goal = [no_lin_add(Y,Cste,X)]) - ; (FromGoal = mult(B,C,A) -> - %% pour ne pas boucler - (K,Y) \== (B,C), - (Y,K) \== (B,C) - ; true), - (Cste == 0 -> - Goal = [no_lin_mult(K,Y,X)] - ; (FromGoal == add(B,C,A) -> - %% pour ne pas boucler - (Cste,X) \== (B,A), - (Cste,X) \== (C,A) - ; true), - Goal = [no_lin_mult(K,Y,P),no_lin_add(P,Cste,X)])), - !. + GCD is gcd(Coeff1,Coeff2), + (GCD == Coeff1 -> + Cste0 is C2-C1, + 0 is Cste0 mod GCD, + X = V1, + Y = V2, + K is Coeff2 div GCD + ; GCD == Coeff2, + Cste0 is C1-C2, + 0 is Cste0 mod GCD, + X = V2, + Y = V1, + K is Coeff1 div GCD), + Cste is Cste0 div GCD, + (K == 1 -> + (Cste == 0 -> + Goal = [X=Y] + ; (FromGoal = add(B,C,A) -> + % pour ne pas boucler + (Y,Cste) \== (B,C), + (Y,Cste) \== (C,B) + ; true), + Goal = [no_lin_add(Y,Cste,X)]) + ; (FromGoal = mult(B,C,A) -> + % pour ne pas boucler + (K,Y) \== (B,C), + (Y,K) \== (B,C) + ; true), + (Cste == 0 -> + Goal = [no_lin_mult(K,Y,X)] + ; (FromGoal == add(B,C,A) -> + % pour ne pas boucler + (Cste,X) \== (B,A), + (Cste,X) \== (C,A) + ; true), + Goal = [no_lin_mult(K,Y,P),no_lin_add(P,Cste,X)])), + !. get_affine_def_from_lin_expr(_,_,_,_,_,[]). %%check_and_call_goals(_) :- !. check_and_call_goals([]) :- !. check_and_call_goals(Goals) :- - call_priority(check_and_call_goals0(Goals),2). + call_priority(check_and_call_goals0(Goals),2). check_and_call_goals0([]). check_and_call_goals0([Goal|Goals]) :- - check_and_call(Goal), - check_and_call_goals0(Goals). + check_and_call(Goal), + check_and_call_goals0(Goals). check_and_call(X=Y) :- !, - protected_unify(X = Y). + protected_unify(X = Y). check_and_call(protected_unify(X=Y)) :- !, - protected_unify(X = Y). + protected_unify(X = Y). check_and_call(insert_dep_inst(A)) :- !, insert_dep_inst(A). check_and_call(add(A,B,C)) :- !, - ((once (var(A), - suspensions(A,LSusp); - var(B), - suspensions(B,LSusp)), - member(Susp,LSusp), - get_suspension_data(Susp,goal,add_int(X,_,Y,_,Z,_)), - (match_bin_op(all,A,B,C,X,Y,Z,U1,U2); - match_add_with_op_number(add_int,A,B,C,X,Y,Z,U1,U2); - %% On essaye le match de minus(A,B,C) - match_minus(add_int,A,B,C,X,Y,Z,U1,U2))) - -> - protected_unify(U1 = U2) - ; add(A,B,C)). + ((once (var(A), + suspensions(A,LSusp); + var(B), + suspensions(B,LSusp)), + member(Susp,LSusp), + get_suspension_data(Susp,goal,add_int(X,_,Y,_,Z,_)), + (match_bin_op(all,A,B,C,X,Y,Z,U1,U2); + match_add_with_op_number(add_int,A,B,C,X,Y,Z,U1,U2); + % On essaye le match de minus(A,B,C) + match_minus(add_int,A,B,C,X,Y,Z,U1,U2))) + -> + protected_unify(U1 = U2) + ; add(A,B,C)). check_and_call(no_lin_add(A,B,C)) :- !, - ((once (var(A), - suspensions(A,LSusp); - var(B), - suspensions(B,LSusp)), - member(Susp,LSusp), - get_suspension_data(Susp,goal,add_int(X,_,Y,_,Z,_)), - (match_bin_op(all,A,B,C,X,Y,Z,U1,U2); - match_add_with_op_number(add_int,A,B,C,X,Y,Z,U1,U2); - %% On essaye le match de minus(A,B,C) - match_minus(add_int,A,B,C,X,Y,Z,U1,U2))) - -> - protected_unify(U1 = U2) - ; no_lin_add(A,B,C)). + ((once (var(A), + suspensions(A,LSusp); + var(B), + suspensions(B,LSusp)), + member(Susp,LSusp), + get_suspension_data(Susp,goal,add_int(X,_,Y,_,Z,_)), + (match_bin_op(all,A,B,C,X,Y,Z,U1,U2); + match_add_with_op_number(add_int,A,B,C,X,Y,Z,U1,U2); + % On essaye le match de minus(A,B,C) + match_minus(add_int,A,B,C,X,Y,Z,U1,U2))) + -> + protected_unify(U1 = U2) + ; no_lin_add(A,B,C)). check_and_call(mult(A,B,C)) :- !, - ((once (var(A), - suspensions(A,LSusp); - var(B), - suspensions(B,LSusp)), - member(Susp,LSusp), - get_suspension_data(Susp,goal,mult_int(X,_,Y,_,Z,_)), - (X == A -> - Y == B - ; X == B, - Y == A)) - -> - protected_unify(C = Z) - ; mult(A,B,C)). + ((once (var(A), + suspensions(A,LSusp); + var(B), + suspensions(B,LSusp)), + member(Susp,LSusp), + get_suspension_data(Susp,goal,mult_int(X,_,Y,_,Z,_)), + (X == A -> + Y == B + ; X == B, + Y == A)) + -> + protected_unify(C = Z) + ; mult(A,B,C)). check_and_call(no_lin_mult(A,B,C)) :- !, - ((once (var(A), - suspensions(A,LSusp); - var(B), - suspensions(B,LSusp)), - member(Susp,LSusp), - get_suspension_data(Susp,goal,mult_int(X,_,Y,_,Z,_)), - (X == A -> - Y == B - ; X == B, - Y == A)) - -> - protected_unify(C = Z) - ; no_lin_mult(A,B,C)). + ((once (var(A), + suspensions(A,LSusp); + var(B), + suspensions(B,LSusp)), + member(Susp,LSusp), + get_suspension_data(Susp,goal,mult_int(X,_,Y,_,Z,_)), + (X == A -> + Y == B + ; X == B, + Y == A)) + -> + protected_unify(C = Z) + ; no_lin_mult(A,B,C)). check_and_call(launch_diff_int(A,B)) :- !, - ((once (var(A), - suspensions(A,LSusp); - var(B), - suspensions(B,LSusp)), - member(Susp,LSusp), - get_suspension_data(Susp,goal,Goal), - (Goal = diff_int(X,Y);Goal = gt(X,Y)), - (X == A -> - Y == B - ; X == B, - Y == A)) - -> - true - ; launch_diff_int(A,B)). + ((once (var(A), + suspensions(A,LSusp); + var(B), + suspensions(B,LSusp)), + member(Susp,LSusp), + get_suspension_data(Susp,goal,Goal), + (Goal = diff_int(X,Y);Goal = gt(X,Y)), + (X == A -> + Y == B + ; X == B, + Y == A)) + -> + true + ; launch_diff_int(A,B)). check_and_call(Goal) :- (getval(gdbg,1)@eclipse -> diff --git a/Src/COLIBRI/col_solve.pl b/Src/COLIBRI/col_solve.pl index 34253eaa2af94c04b36611b31582da958ad6beee..2cf9d66f177eeb115c28d4ef23e34ab6018cc96e 100644 --- a/Src/COLIBRI/col_solve.pl +++ b/Src/COLIBRI/col_solve.pl @@ -63,10 +63,6 @@ :- no_3B. :- setval(solve,1). :- setval(time_limit,0). -:- setval(exit_at_end,1). - -col_exit(Code) :- - (getval(exit_at_end, 1) -> exit(Code) ; true). no_solve :- setval(solve,0). @@ -106,7 +102,7 @@ interactive_solve :- write(output,[colibri]:""), block(read(input,Goal), Tag, - (writeln(error,col_exit(Tag)), + (writeln(error,exit(Tag)), fail)), ((Goal == halt; Goal == end_of_file) @@ -175,7 +171,7 @@ interactive_solve :- ; nl(output), writeln(output,'UNSAT')), Tag, - writeln(error,col_exit(Tag))), + writeln(error,exit(Tag))), fail). get_goals([],_,[]). @@ -252,7 +248,7 @@ trivial_goal_elim([Goal|Goals],NewGoals) :- solve(FILE) :- solve(_,FILE,0,Code), - col_exit(Code). + exit(Code). solve(Test,FILE,TO,Code) :- setval(solve,1), @@ -478,7 +474,7 @@ smt_solve_count_steps(FILE,TO) :- setval(use_simplex,US)@eclipse, fail), Tag, - (writeln(output,col_exit(Tag)), + (writeln(output,exit(Tag)), setval(use_delta,UD)@eclipse, setval(use_simplex,US)@eclipse, exit_block(Tag))), @@ -502,7 +498,7 @@ smt_comp_solve(FILE) :- % on desactive les warning de dolmen setval(no_dolmen_warning,1)@eclipse, smt_solve(_,FILE,0,Code), - col_exit(Code). + exit(Code). simplex_alway :- setval(simplex_delay_deactivation,0)@eclipse. @@ -527,7 +523,7 @@ smt_solve(FILE) :- Test = 1 ; true), smt_solve(Test,FILE,0,Code), - col_exit(Code). + exit(Code). smt_solve_get_stat(FILE) :- seed(0), @@ -545,7 +541,7 @@ smt_solve_get_stat(FILE) :- smt_solve(Test,FILE,0,Code), getval(nb_steps,Steps)@eclipse, writeln(output,"Steps":Steps), - col_exit(Code). + exit(Code). smt_solve(Test,FILE,TO,Code) :- no_3B, @@ -578,6 +574,8 @@ smt_solve_bis0(Test,FILE,Code) :- min_max_lazy(int,MinInt,MaxInt,_), setval(refutation_chk,0)@eclipse, setval(logic,"ALL")@eclipse, + % par default on n'éssaye pas de réduire les sous intervalles + no_reduce_sub_intervals, % les deltas sont utiles pour les tableaux % positionné par smt_interp0, lu dans solve.pl setval(keep_deltas_if_arrays_or_reals,0)@eclipse, @@ -633,16 +631,19 @@ smt_solve_bis0(Test,FILE,Code) :- -> getval(diag_code,(Diag,Code)) ; % echec a la propagation - getval(smt_status,Status)@eclipse, - (Status == sat -> - Code = 2, - Diag = unknown, + (getval(unknown_if_unsat,1)@eclipse -> writeln(output,unknown), - writeln(error,"wrong unsat") - ; Code = 0, - Diag = unsat, - writeln(output,unsat)), - setval(diag_code,(Diag,Code))), + setval(diag_code,(unknown,2)) + ; getval(smt_status,Status)@eclipse, + (Status == sat -> + Code = 2, + Diag = unknown, + writeln(output,unknown), + writeln(error,"wrong unsat") + ; Code = 0, + Diag = unsat, + writeln(output,unsat)), + setval(diag_code,(Diag,Code)))), Tag, (update_min_max_lazy_int(MinInt,MaxInt), (Tag == timeout_col -> @@ -698,8 +699,21 @@ get_type_decl_list(Goals,Decl,EndGoals) :- -> Decl = [D|EDecl], get_type_decl_list(NGoals,EDecl,EndGoals) - ; Decl = [], - EndGoals = Goals). + ; findall(Path,cgiveInstancePath(new_quantified_var(_,_),Goals, + Path),Paths), + EndGoals = Goals, + (Paths == [] -> + Decl = [] + ; (foreach(P,Paths), + foreach(D,Decl), + param(Goals) do + subscript(Goals,P,NQV), + NQV = new_quantified_var(V,T), + % call(spy_here)@eclipse, + protected_set_var_name(V,"ColQuantV"), + (real_type(T,_) -> + D = real_vars(T,V) + ; D = int_vars(T,V))))). is_decl(int_vars(_,_)) ?- !. is_decl(bool_vars(_,_)) ?- !. @@ -762,7 +776,10 @@ clean_and_save_goal_before_check_sat(Goal,NewGoal) :- (NLGoal0 == LEndNewGoal -> % pas de check_sat ???? append(NLDecl,[check_sat|CleanLGoal],NewGoals) - ; append(CleanLGoal,[check_sat|LEndNewGoal],ENewGoals), + ; list_to_conj(CleanLGoal,CleanGoal), + CNewGoal =.. [call_priority,CleanGoal,2], + % CNewGoal =.. [call_priority,CleanGoal,12], + append([CNewGoal],[check_sat|LEndNewGoal],ENewGoals), append(NLDecl,ENewGoals,NewGoals) ), list_to_conj(NewGoals,NewGoal). @@ -787,8 +804,10 @@ remove_unused_decl_goal([D|LD],NLD,LG,NLG) ?- !, ((is_decl(D), term_variables(D,[V]), member_begin_end(G,LG,NewLG,ELG,ELG), - G =.. [FG,A,B], - occurs(FG,($=,#=)), + once member(G,[A $= B, + A #= B, + array_def(A,_), + array_elt_def(_,A,B)]), remove_all_as(A,NA), once (NA == V; remove_all_as(B,NB), @@ -796,7 +815,7 @@ remove_unused_decl_goal([D|LD],NLD,LG,NLG) ?- !, not occurs(V,NewLG)) -> % D inutile - call(spy_here)@eclipse, + % call(spy_here)@eclipse, remove_unused_decl_goal(LD,NLD,NewLG,NLG) ; NLD = [D|ENLD], remove_unused_decl_goal(LD,ENLD,LG,NLG)). @@ -855,7 +874,7 @@ incNbCode(6) :- smt_solve_test(FILE,TO) :- seed(0), smt_solve_test_bis(FILE,TO,Code), - col_exit(Code). + exit(Code). smt_solve_test_bis(FILE,TO,Code) :- %set_threshold(1e-3), @@ -900,7 +919,7 @@ smt_test(TO,Size,CI) :- %StrDir = "./colibri_tests/colibri/tests/", %StrDir = "./colibri_tests/colibri/tests/sat/", % 0 en 20s (sans real/float->int!) - StrDir = "./colibri_tests/colibri/tests/unsat/", %0 + %StrDir = "./colibri_tests/colibri/tests/unsat/", %0 %StrDir = "./colibri_tests/colibri/tests/unknown/", %StrDir = "./colibri_tests/colibri/tests/timeout/", @@ -979,7 +998,7 @@ smt_test(TO,Size,CI) :- %StrDir = "./smtlib_schanda-master/random/fp.leq/", %StrDir = "./smtlib_schanda-master/random/fp.lt/", %StrDir = "./smtlib_schanda-master/random/fp.from.ubv/", - %StrDir = "./smtlib_schanda-master/random/fp.from.sbv/", + %StrDir = "./smtlib_schanda-master/randorm/fp.from.sbv/", % declare-datatypes ???? %StrDir = "./smtlib_schanda-master/spark_2014/", %StrDir = "./smtlib_schanda-master/wintersteiger/", @@ -1072,9 +1091,9 @@ smt_test(TO,Size,CI) :- %---------------------------------------------------------------- %StrDir = "./QF_FP/20170501-Heizmann-UltimateAutomizer/", % 0/2 %StrDir = "./QF_FP/20190429-UltimateAutomizerSvcomp2019/",% 0/24 (bitwuzla 0) - %StrDir = "./QF_FP/griggio/fmcad12/", % 50/214 (min_solve, sans lin_solve ni ls_reduce..)(39) + %StrDir = "./QF_FP/griggio/fmcad12/", % 46/214 (min_solve, sans lin_solve ni ls_reduce..)(39) %(cvc4/5 89/88)(bitwuzla 74) LES DD DEMARRENT TROP VITE ? - %StrDir = "./QF_FP/schanda/spark/", % 6! (min_solve avec X =< (X+Y)/2 =< Y) (cvc5 6)(bitwuzla 3) + %StrDir = "./QF_FP/schanda/spark/", % 5! (min_solve avec X =< (X+Y)/2 =< Y) (cvc5 6)(bitwuzla 3) %StrDir = "./QF_FP/wintersteiger/", % tout OK %----------------------------------------------------------------------- %StrDir = "./QF_UFFP/schanda/",% 0 @@ -1158,6 +1177,43 @@ smt_test(TO,Size,CI) :- %StrDir = "QF_ANIA/",% 0/1 (7 I) %StrDir = "QF_ABV/bmc-arrays/", % 11/20 (19 I) + + StrDir = "./FP/", % 1864 benchs + % cvc5 499 TO, bitwuzla 404 TO, colibri 227 TO + %StrDir = "./FP/20170501-Heizmann-UltimateAutomizer/", % 1 bench + % cvc5 1 TO, bitwuzla 0 TO, colibri 0 TO + %StrDir = "./FP/20190429-UltimateAutomizerSvcomp2019/", + % cvc5 0 TO, bitwuzla 0 TO, colibri 0 TO + %StrDir = "./FP/2019-Preiner/", % 1610 benchs + % cvc5 441 TO,bitwuzla 318 TO, colibri 157 TO !!! + %StrDir = "./FP/20200911-Pine/", % 245 benchs + % cvc5 232 TO,bitwuzla 232 TO, colibri 76 TO !!! + + %StrDir = "./BVFP/", % 208 benchs; 24s + % cvc5 34+? TO + 12 U, bitwuzla 18 TO, colibri 32 TO + %StrDir = "./BVFP/20190429-UltimateAutomizerSvcomp2019/", % 200 benchs, + % cvc5 26 TO + 12 U, bitwuzla 17 TO, colibri 32 TO + %StrDir = "./BVFP/20230321-UltimateAutomizerSvcomp2023/", % 3 benchs, + % cvc5 3 TO, bitwuzla 1 TO, colibri 0 TO !!! + %StrDir = "./BVFP/20210301-Alive2/", % 5 benchs, + % cvc5 5 TO, bitwuzla 5 TO, colibri 3 TO !!!(satus unknown ?) + + %StrDir = "./FPLRA/", % 41 benchs, 24 s + % cvc5 18 TO, bitwuzla 4 TO, colibri 0 TO + %StrDir = "./FPLRA/20170501-Heizmann-UltimateAutomizer/", % 14 benchs + % cvc5 7 TO, bitwuzla 4 TO, colibri 0 TO + %StrDir = "./FPLRA/20190429-UltimateAutomizerSvcomp2019/", % 27 benchs + % cvc5 11 TO + 1 U, bitwuzla 0 TO, colibri 0 TO + + %StrDir = "./BVFPLRA/", % 266 benchs, 24s + % cvc5 99 TO, bitwuzla 8 TO, colibri 8 TO + %StrDir = "./BVFPLRA/20170501-Heizmann-UltimateAutomizer/", % 70 benchs + % cvc5 35 TO, bitwuzla 0 TO, colibri 0 TO + %StrDir = "./BVFPLRA/20230321-UltimateAutomizerSvcomp2023/", % 11 benchs + % cvc5 11 TO, bitwuzla 0 TO, colibri 0 TO + %StrDir = "./BVFPLRA/20190429-UltimateAutomizerSvcomp2019/", % 185 benchs + % cvc5 55 TO, bitwuzla 10 TO, colibri 8 TO + smt_test0(TO,Size,StrDir,CI). :- lib(timeout). @@ -1249,12 +1305,11 @@ smt_test0(TO,Size,StrDir0,CI) :- concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s ",ECLIPSE," -b ",COL," -g ",SizeM," -e \"seed(0),use_delta,use_simplex,setval(def_real_for_int,1)@colibri,setval(step_limit,0),setval(no_dolmen_warning,1)@eclipse,setval(show_steps,1),",UDS,USS,"smt_solve_get_stat(\'",F,"\')\""],Com) ; concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s ",ECLIPSE," -b ",COL," -g ",SizeM," -e \"seed(0),use_delta,use_simplex,setval(def_real_for_int,1)@colibri,setval(step_limit,0),setval(no_dolmen_warning,1)@eclipse,setval(show_steps,1),",UDS,USS,"setval(scrambler,1)@eclipse,smt_solve_get_stat(\'",F,"\')\""],Com))), */ - ; concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s ",ECLIPSE," -b ",COL," -g ",SizeM," -e \"seed(0),smt_comp_solve(\'",F,"\')\""],Com)), - -%; concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s cvc5 ",F],Com)), -%; concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s ncvc4 --fp-exp ",F],Com)), -%; concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s z3 ",F],Com)), -%; concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s bitwuzla ",F],Com)), +%; concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s ",ECLIPSE," -b ",COL," -g ",SizeM," -e \"seed(0),smt_comp_solve(\'",F,"\')\""],Com)), +% 9 !! +; concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s z3 ",F],Com)), % trop long +%; concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s cvc5 ",F],Com)), % 53 +%; concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s bitwuzla ",F],Com)),% 84 exec(Com,[],Pid), wait(Pid,CodeExt), writeln(code:CodeExt), @@ -1397,18 +1452,65 @@ smt_unit_test_CI(TO) :- smt_unit_test(TO,1). smt_unit_test(TO,CI) :- + %StrDir = "UnitTests/sat/FP/", + %StrDir = "UnitTests/unsat/FP/", + %StrDir = "./FP/", % 1864 benchs, 24s + % cvc5 499 TO, bitwuzla 404 TO, colibri 227 TO + %StrDir = "./FP/20170501-Heizmann-UltimateAutomizer/", % 1 bench + % cvc5 1 TO, bitwuzla 0 TO, colibri 0 TO + %StrDir = "./FP/20190429-UltimateAutomizerSvcomp2019/", + % cvc5 0 TO, bitwuzla 0 TO, colibri 0 TO + %StrDir = "./FP/2019-Preiner/", % 1610 benchs + % cvc5 441 TO,bitwuzla 318 TO, colibri 157 TO !!! + %StrDir = "./FP/20200911-Pine/", % 245 benchs + % cvc5 232 TO,bitwuzla 232 TO, colibri 76 TO !!! + + %StrDir = "./BVFP/", % 208 benchs; 24s + % cvc5 34+? TO + 12 U, bitwuzla 18 TO, colibri 32 TO + %StrDir = "./BVFP/20190429-UltimateAutomizerSvcomp2019/", % 200 benchs, + % cvc5 26 TO + 12 U, bitwuzla 17 TO, colibri 32 TO + %StrDir = "./BVFP/20230321-UltimateAutomizerSvcomp2023/", % 3 benchs, + % cvc5 3 TO, bitwuzla 1 TO, colibri 0 TO !!! + %StrDir = "./BVFP/20210301-Alive2/", % 5 benchs, + % cvc5 5 TO, bitwuzla 5 TO, colibri 3 TO !!!(satus unknown ?) + + %StrDir = "./FPLRA/", % 41 benchs, 24 s + % cvc5 18 TO, bitwuzla 4 TO, colibri 0 TO + %StrDir = "./FPLRA/20170501-Heizmann-UltimateAutomizer/", % 14 benchs + % cvc5 7 TO, bitwuzla 4 TO, colibri 0 TO + %StrDir = "./FPLRA/20190429-UltimateAutomizerSvcomp2019/", % 27 benchs + % cvc5 11 TO + 1 U, bitwuzla 0 TO, colibri 0 TO + + %StrDir = "./BVFPLRA/", % 266 benchs, 24s + % cvc5 99 TO, bitwuzla 8 TO, colibri 8 TO + %StrDir = "./BVFPLRA/20170501-Heizmann-UltimateAutomizer/", % 70 benchs + % cvc5 35 TO, bitwuzla 0 TO, colibri 0 TO + %StrDir = "./BVFPLRA/20230321-UltimateAutomizerSvcomp2023/", % 11 benchs + % cvc5 11 TO, bitwuzla 0 TO, colibri 0 TO + %StrDir = "./BVFPLRA/20190429-UltimateAutomizerSvcomp2019/", % 185 benchs + % cvc5 55 TO, bitwuzla 10 TO, colibri 8 TO + %StrDir = "./UnitTests/sat/", %StrDir = "./UnitTests/unsat/", + + %StrDir = "./FP/20170501-Heizmann-UltimateAutomizer/", + %StrDir = "./FP/20190429-UltimateAutomizerSvcomp2019/", + %StrDir = "./FP/2019-Preiner/", + %StrDir = "./FP/20200911-Pine/", + %StrDir = "./UnitTests/unsat/QF_ABV/", %StrDir = "./UnitTests/sat/QF_ABV/", %StrDir = "./UnitTests/sat/QF_ABV/", %StrDir = "./UnitTests/sat/QF_BV/", %StrDir = "./UnitTests/sat/QF_NIA/", + %StrDir = "./UnitTests/sat/QF_FP/", + %StrDir = "./UnitTests/sat/QF_NIA/", + %StrDir = "./UnitTests/unsat/QF_FP/", %StrDir = "./colibri_tests/colibri/tests/sat/", % 0 (en 15s, 1 en % 2s newton) - StrDir = "./colibri_tests/colibri/tests/unsat/", % 0 + %StrDir = "./colibri_tests/colibri/tests/unsat/", % 0 %StrDir = "./smtlib_schanda-master/random/", % tout OK ou unsupported @@ -1420,19 +1522,19 @@ smt_unit_test(TO,CI) :- %StrDir = "./smtlib_schanda-master/spark_2014/", %----------------------------------------------------------------------- - %StrDir = "./QF_AUFBVFP/20210301-Alive2/",% 1/1 + StrDir = "./QF_AUFBVFP/20210301-Alive2/",% 1/1 %------------------------------------------------------------------------ - %StrDir = "./QF_ABVFPLRA/", % 1/74 - %StrDir = "./QF_ABVFPLRA/20190429-UltimateAutomizerSvcomp2019/",% 0/41 - %StrDir = "./QF_ABVFPLRA/20170501-Heizmann-UltimateAutomizer/",% 1/33 + %StrDir = "./QF_ABVFPLRA/", % 1/74 (4 en 5s) + %StrDir = "./QF_ABVFPLRA/20190429-UltimateAutomizerSvcomp2019/",% 1/41 + %StrDir = "./QF_ABVFPLRA/20170501-Heizmann-UltimateAutomizer/",% 0/33 %------------------------------------------------------------------------ %StrDir = "./QF_ABVFP/", - %StrDir = "./QF_ABVFP/20170428-Liew-KLEE/", % 113/18033 TO (1 I, - % 177 u) (69 sans simplex) (cvc4 76) - %StrDir = "./QF_ABVFP/20170501-Heizmann-UltimateAutomizer/", % 1/96 TO + %StrDir = "./QF_ABVFP/20170428-Liew-KLEE/", % 106 !! 113/18033 TO (1 I, + % 177 u) (167 en 5s) (69 sans simplex) (cvc4 76) + %StrDir = "./QF_ABVFP/20170501-Heizmann-UltimateAutomizer/", % 0/96 TO %------------------------------------------------------------------------ %StrDir = "./QF_BVFP/", - %StrDir = "./QF_BVFP/20170428-Liew-KLEE/", % 46/17156 (89 u) + %StrDir = "./QF_BVFP/20170428-Liew-KLEE/", % 0/17156 (89 u)(124 en 5s) %StrDir = "./QF_BVFP/20170501-Heizmann-UltimateAutomizer/", % 0/4 TO %StrDir = "./QF_BVFP/ramalho/", % 0/32 TO %StrDir = "./QF_BVFP/schanda/spark/", % 1/8 TO @@ -1443,11 +1545,11 @@ smt_unit_test(TO,CI) :- %StrDir = "./QF_FPLRA/20170501-Heizmann-UltimateAutomizer/",% 0/4 TO %StrDir = "./QF_FPLRA/20190429-UltimateAutomizerSvcomp2019/",% 0/38 TO %StrDir = "./QF_FPLRA/schanda/spark/",% 0/2 TO - %StrDir = "./QF_FPLRA/2019-Gudemann/",% 2/13 (3/13 en 2s) + %StrDir = "./QF_FPLRA/2019-Gudemann/",% 1/13 (3/13 en 2s) %------------------------------------------------------------------------ %StrDir = "./QF_BVFPLRA/", %StrDir = "./QF_BVFPLRA/20170501-Heizmann-UltimateAutomizer/",% 0/15 TO - %StrDir = "./QF_BVFPLRA/20190429-UltimateAutomizerSvcomp2019/",% 10(9)/152 (11 u) (12/152 en 2s) + %StrDir = "./QF_BVFPLRA/20190429-UltimateAutomizerSvcomp2019/",% 0/152 (11 u) (12/152 en 2s) %StrDir = "./QF_BVFPLRA/2019-Gudemann/",% 0/1 TO %------------------------------------------------------------------------ %StrDir = "./QF_FP/20170501-Heizmann-UltimateAutomizer/", % 0/2 TO @@ -1455,7 +1557,7 @@ smt_unit_test(TO,CI) :- %StrDir = "./QF_FP/20230321-UltimateAutomizerSvcomp2023/", % 0/1 %StrDir = "./QF_FP/20210211-Vector/", % 0/91 %StrDir = "./QF_FP/ramalho/",% 0/38 T0 (5/38 en 2s) - %StrDir = "./QF_FP/griggio/fmcad12/", % 45/214 TO en 24s (cvc4 90 en 60s) (65/214 en 2s) + %StrDir = "./QF_FP/griggio/fmcad12/", % 46! 45/214 TO en 24s (cvc4 90 en 60s) (65/214 en 2s) %StrDir = "./QF_FP/schanda/spark/",% 5/46 TO (7 en 2s) %StrDir = "./QF_FP/wintersteiger/", % 0/39994 %----------------------------------------------------------------------- @@ -1730,10 +1832,10 @@ smt_unit_test(StrDir0,TO,CI) :- -> % on est en mode check avec scrambler writeln(output,bug:F), - col_exit(4) + exit(4) ; true), getval(bug,Bugs), - (Status == unknown -> + (fail,Status == unknown -> setval(bug,[smt_unknown:F|Bugs]) ; setval(bug,[F|Bugs])) ; pathname(F,PF,NF), @@ -1771,7 +1873,7 @@ smt_unit_test(StrDir0,TO,CI) :- garbage_collect, fail ; true), - call(spy_here)@eclipse, + % call(spy_here)@eclipse, (getval(make_UT,1)@eclipse -> Slog = output ; % on est en check @@ -1842,20 +1944,25 @@ check_unit_tests(SatUnsat,TO,Mod) :- check_unit_tests(SatUnsat,TO) :- Sat = [ - "./UnitTests/sat/ALL/", + "./UnitTests/sat/FP/", + "./UnitTests/sat/BVFP/", + "./UnitTests/sat/FPLRA/", + "./UnitTests/sat/BVFPLRA/", + "./UnitTests/sat/ALL/", "./UnitTests/sat/QF_ABVFPLRA/", "./UnitTests/sat/QF_AX/", "./UnitTests/sat/QF_BVFPLRA/", - "./UnitTests/sat/QF_LIA/" + "./UnitTests/sat/QF_LIA/", "./UnitTests/sat/QF_UF/", "./UnitTests/sat/QF_UFLRA/", "./UnitTests/sat/QF_ABV/", - "./UnitTests/sat/QF_ALIA/", +% "./UnitTests/sat/QF_ALIA/", VIDE (trop gros) "./UnitTests/sat/QF_BV/", + % TO sur square_neg_id_fp_sat.smt2 "./UnitTests/sat/QF_FP/", "./UnitTests/sat/QF_LRA/", "./UnitTests/sat/QF_UFIDL/", @@ -1864,27 +1971,26 @@ check_unit_tests(SatUnsat,TO) :- "./UnitTests/sat/QF_BVFP/", "./UnitTests/sat/QF_FPLRA/", - "./UnitTests/sat/QF_NIA/", + "./UnitTests/sat/QF_NIA/", "./UnitTests/sat/QF_UFLIA/" ], Unsat = [ + "./UnitTests/unsat/FP/", + "./UnitTests/unsat/BVFPLRA/", "./UnitTests/unsat/ALL/", - + "./UnitTests/unsat/FP/", "./UnitTests/unsat/QF_ABV/", - "./UnitTests/unsat/QF_ABVFP/", "./UnitTests/unsat/QF_ABVFPLRA/", - "./UnitTests/unsat/QF_ALIA/", + "./UnitTests/unsat/QF_ALIA/", "./UnitTests/unsat/QF_AUFBV/", "./UnitTests/unsat/AUFBVFPDTNIRA/", "./UnitTests/unsat/QF_AX/", "./UnitTests/unsat/QF_BV/", - "./UnitTests/unsat/QF_BVFP/", - "./UnitTests/unsat/QF_BVFPLRA/", "./UnitTests/unsat/QF_FP/", "./UnitTests/unsat/QF_FPLRA/", @@ -1911,8 +2017,21 @@ check_unit_tests(SatUnsat,TO) :- COL = "col_solve.pl"), %Scr = 1, Scr = 0, + % Menage des trop gros + MaxSize = 10000, (foreach(Dir,Dirs), - param(TO,ECLIPSE,COL,Scr) do + param(MaxSize,TO,ECLIPSE,COL,Scr) do + read_directory(Dir, "*.smt2", _, SmtList), + (foreach(F,SmtList), + param(Dir,MaxSize) do + concat_string([Dir,"/",F],PF), + os_file_name(PF,OS_PF), + get_file_info(OS_PF,size,FSize), + (FSize > MaxSize -> + % Trop gros on le supprime + concat_string(["rm ",OS_PF],RmCom), + system(RmCom) + ; true)), concat_string([ECLIPSE, " -b ",COL," -g 5000M -e \"setval(make_UT,0)@eclipse,smt_unit_test('", Dir, @@ -1925,9 +2044,12 @@ check_unit_tests(SatUnsat,TO) :- % writeln(Com), exec(Com,[],Pid), wait(Pid,CodeExt), - (CodeExt =:= 4*256 -> + (fail,CodeExt =:= 4*256 -> halt - ; true)). + ; true), + getenv('PWD',Cwd), + concat_string(["cd ",Dir,"; git add *.smt2; cd ",Cwd],NCom), + system(NCom)). show_stats :- diff --git a/Src/COLIBRI/lp_arith.pl b/Src/COLIBRI/lp_arith.pl index be8499ebd5dbd188a0220d6085add8f1cf1c5170..293df43b3e4aea2d153437da21b98a1bfcf6a21a 100755 --- a/Src/COLIBRI/lp_arith.pl +++ b/Src/COLIBRI/lp_arith.pl @@ -2548,7 +2548,10 @@ ocaml_sqrt_simple(Rnd,F,SqrtF) :- % round to nearest even integer (pour fp_rem) -round_rat_integer(Rat,IRat) :- +round_rat_integer(Rat0,IRat) :- + (number(Rat0) -> + make_OCamlRat(Rat0,Rat) + ; Rat = Rat0), protect_interrupts_and_gc(p_simplex_ocaml_rat_round_integer_RNE(Rat,IRat)). get_OCamlRat_strings_from_cst(Int,SNum,SDen) :- @@ -2627,7 +2630,10 @@ ocaml_round(rtn,dn) :- !. ocaml_round(rtp,up) :- !. ocaml_round(Rnd,Rnd). -float_of_OCamlRat(Type,Rnd,Rat,Float) :- +float_of_OCamlRat(Type,Rnd,Rat0,Float) :- + (number(Rat0) -> + make_OCamlRat(Rat0,Rat) + ; Rat = Rat0), ocaml_round(Rnd,NRnd), float_of_OCamlRat0(Type,NRnd,Rat,Float0), protected_unify(Float0,Float). diff --git a/Src/COLIBRI/mbv_propa.pl b/Src/COLIBRI/mbv_propa.pl index 20025a966404de2509b474276541cfb89960f6e2..715e47611bb04b6fbb543d885b065bf4eb69b3ec 100644 --- a/Src/COLIBRI/mbv_propa.pl +++ b/Src/COLIBRI/mbv_propa.pl @@ -60,11 +60,12 @@ update_congr_interval_eq(X,Y):- fill_bvbounds(Y,DY). % EN TEST: ca marche !!! - +% FAUX +/* launch_bveq(Sx,X,Sy,Y) :- !, protected_unify(X,Y). - +*/ launch_bveq(S,X,S,Y) ?- !, protected_unify(X,Y). @@ -152,12 +153,27 @@ bvand_bis(M,X,0,Z) ?- !, protected_unify(Z,0). bvand_bis(M,X,X,Z) ?- !, protected_unify(Z,X). +% TEST +/* +bvand_bis(M,X,Y,Z) :- + (var(X); + var(Y)), + !, + my_suspend(bvand_bis(M,X,Y,Z),0,(X,Y)->suspend:inst). +*/ bvand_bis(M,X,Y,Z) :- integer(Z), Z is \(-1 << M), !, % Z tout a 1 protected_unify(X,Z), protected_unify(Y,Z). +bvand_bis(M,X,Y,Z) :- + is_ones_for_other(M,X,Y), !, + protected_unify(Z,Y). +bvand_bis(M,X,Y,Z) :- + is_ones_for_other(M,Y,X), !, + protected_unify(Z,X). + /* bvand_bis(M,X,Y,Z) :- % Should I add that test on the use_simplification? @@ -179,12 +195,6 @@ quand on a A & B = 0 ou A | B = Mask, chercher l'autre, s'il existe, alors les enlever tous les deux et mettre A = ¬ B */ -bvand_bis(M,X,Y,Z) :- - is_ones_for_other(M,X,Y), !, - protected_unify(Z,Y). -bvand_bis(M,X,Y,Z) :- - is_ones_for_other(M,Y,X), !, - protected_unify(Z,X). bvand_bis(M,X,Y,Z) :- get_priority(Prio), set_priority(1), @@ -213,7 +223,49 @@ bvand_bis(M,X,Y,Z) :- fill_bvbounds(Z,NDZ), bvand_inst_free(M,X,Y,Z,Continue1), (nonvar(Continue1) -> - my_suspend(bvand_bis(M,X,Y,Z), 0, (X,Y,Z) -> suspend:constrained) + (fail,((X == Z, + A = Y, + B = X); + (Y == Z, + A = X, + B = Y)) + -> + % bvand(M,A,B,B) + call(spy_here)@eclipse, + Ones is 2^(M-1), + (not_unify(A,Ones) -> + my_suspend(bvand_bis(M,A,B,B), 0, + (A,B) -> suspend:constrained) +/* + (not_unify(A,B) -> + my_suspend(bvand_bis(M,A,B,B), 0, + (A,B) -> suspend:constrained) + ; % on essaye de forcer A = B + int_vars(bool,Bool), + (as(A,uint(M)) #\= as(B,uint(M))) + #= as(Bool,bool), + (Bool == 0 -> + true + ; my_suspend(bvand_bis(M,A,B,B), 0, + (A,B,Bool) -> suspend:constrained))) +*/ + ; % on essaye de forcer A = Ones + get_cstr_suspensions(A,LSA), + ((member(SA,LSA), + get_suspension_data(SA,goal, + eq_int_reif_bis(_,Ones,AA,NotBool)), + A == AA) + -> + Test = (NotBool == 1) + ; int_vars(bool,Bool), + diff_int_reif(Ones,A,Bool), + Test = (Bool == 0)), + (call(Test) -> + true + ; my_suspend(bvand_bis(M,A,B,B), 0, + (A,B,Bool) -> suspend:constrained))) + ; my_suspend(bvand_bis(M,X,Y,Z), 0, + (X,Y,Z) -> suspend:constrained)) ; true))), set_priority(Prio), wake_if_other_scheduled(Prio). @@ -387,8 +439,19 @@ bvor_bis(M,X,0,Z) ?- !, bvor_bis(M,X,Y,0) ?- !, protected_unify(X,0), protected_unify(Y,0). +bvor_bis(M,X,Y,Z) :- + nonvar(X), + nonvar(Y),!, + bvor_inst_free(M,X,Y,Z,_). - +% TEST +/* +bvor_bis(M,X,Y,Z) :- + (var(X); + var(Y)), + !, + my_suspend(bvor_bis(M,X,Y,Z),0,(X,Y)->suspend:inst). +*/ /* LABEL1 @@ -405,10 +468,6 @@ que c'est exactement l'inverse du OR, ça boucle. voir LABEL2 */ -bvor_bis(M,X,Y,Z) :- - nonvar(X), - nonvar(Y),!, - bvor_inst_free(M,X,Y,Z,_). /* bvor_bis(M,X,Y,Z) :- % Should I add that test on the use_simplification? @@ -458,7 +517,6 @@ bvor_bis(M,X,Y,Z) :- set_priority(1), save_cstr_suspensions((X,Y)), % union des congr si elles existent - get_congr(X,CX,MX), get_congr(Y,CY,MY), union_congr(CX,CY,MX,MY,CZ,MZ,_), @@ -487,7 +545,41 @@ bvor_bis(M,X,Y,Z) :- fill_bvbounds(Z,NDZ), bvor_inst_free(M,X,Y,Z,Continue1), (nonvar(Continue1) -> - my_suspend(bvor_bis(M,X,Y,Z), 0, (X,Y,Z) -> suspend:constrained) + (fail,((X == Z, + A = Y, + B = X); + (Y == Z, + A = X, + B = Y)) + -> + % bvor(M,A,B,B) + call(spy_here)@eclipse, + (not_unify(A,0) -> + my_suspend(bvor_bis(M,A,B,B), 0, + (A,B) -> suspend:constrained) +/* + (not_unify(A,B) -> + my_suspend(bvor_bis(M,A,B,B), 0, + (A,B) -> suspend:constrained) + ; % on essaye de forcer A = B + int_vars(bool,Bool), + (as(A,uint(M)) #\= as(B,uint(M))) + #= as(Bool,bool), + (Bool == 0 -> + true + ; my_suspend(bvor_bis(M,A,B,B), 0, + (A,B,Bool) -> suspend:constrained))) +*/ + ; % on essaye de forcer A = 0 + int_vars(bool,Bool), + (as(A,uint(M)) #\= as(0,uint(M))) + #= as(Bool,bool), + (Bool == 0 -> + true + ; my_suspend(bvor_bis(M,A,B,B), 0, + (A,B,Bool) -> suspend:constrained))) + ; my_suspend(bvor_bis(M,X,Y,Z), 0, + (X,Y,Z) -> suspend:constrained)) ; true))), set_priority(Prio), wake_if_other_scheduled(Prio). @@ -1011,7 +1103,8 @@ bvsr_bis(M,0,Y,Z) ?- !, protected_unify(Z,0). bvsr_bis(M,X,Y,Z) :- mfd:dvar_range(X,_, Max), - Max < 2^ Y,!, % A simple bang point turns UNSAT to SAT!! + Max < 2^ Y, + !, % A simple bang point turns UNSAT to SAT!! protected_unify(Z,0). bvsr_bis(M,X,Y,Z) :- get_bvbounds(X, bvbounds(X1, X0)), @@ -1027,7 +1120,7 @@ bvsr_bis(M,X,Y,Z) :- get_saved_cstr_suspensions(LSusp), filter_bvsr_susps(M,X,Y,Z,LSusp), (exists_congr(X,_,_) -> - call(spy_here)@eclipse, + %call(spy_here)@eclipse, DpY is 2^Y, congr_div_directe(int,X,DpY,Z) ; true), @@ -1145,9 +1238,10 @@ bvlsr(M, X, Y, Z) :- % =========== arithmetic right shift=========== :- export bvasr/4. - +% INUTILE traité dans solve.pl bvasr(M,X,Y,Z) :- - var(Y), !, + var(Y), + !, my_suspend(bvasr(M,X,Y,Z), 0, [Y] -> suspend:inst). bvasr(M,X,0,Z) ?- !, @@ -1161,25 +1255,14 @@ bvasr(M, X, Y, Z):- bvasr_bis(M, X, Y, Z). :- export bvasr_bis/4. + %% Version correcte a optimiser -/* -bvasr_bis(M, X, Y, Z) :- - mfd:dvar_range(X,_,HX), - Mm1 is M - 1, - (HX < 2^Mm1 -> - % msb(X) = 0 - bvsr(M, X, Y, Z) - ; bvextract(M, Mm1, Y, X, XX), - MXX is M - Y, - sign_extend(MXX, Y, XX, Z)). -*/ -bvasr_bis(M, X, Y, Z) :- - Mm1 is M - 1, - bvextract(M, Mm1, Y, X, XX), - insert_dep_inst(dep(XX,0,[Y,X])), - insert_dep_inst(dep(Z,0,[Y,XX])), - MXX is M - Y, - sign_extend(MXX, Y, XX, Z). +bvasr_bis(Size, X, Shift, R) :- !, + Sm1 is Size - 1, + ite(extract(Size,Sm1,Sm1,X) #= as(0,uint(1)), + bvlshr(Size,X,Shift), + bvnot(Size,bvlshr(Size,bvnot(Size,X),Shift))) + #= R. % ================= Extract ================== :- export bvextract/5. @@ -1188,15 +1271,7 @@ bvextract(SX,I,J,0,Y) ?- protected_unify(Y, 0). bvextract(SX,I,0,X,Y) ?- - integer(Y), - !, - Power is 2 ^ (I+1), - gardefou(Y < Power), - set_lazy_domain(bv,SX,X), - launch_congr(X, Y, Power). - -bvextract(SX,I,0,X,Y) ?- - SX is I + 1, + SX is I - 1, !, set_lazy_domain(bv,SX,X), protected_unify(X,Y). @@ -1310,18 +1385,25 @@ bvconcat(SX,X,SY,Y,Z) :- %bvconcat_v1(SX,X,SY,Y,Z). bvconcat_v2(SX,X,SY,Y,Z). */ + % plus efficace !!! +bvconcat(SX,0,SY,Y,Z) ?- !, + SZ is SX + SY, + launch_bveq(SY,Y,SZ,Z). bvconcat(SX,X,SY,Y,Z) :- SizeXY is SX + SY, set_lazy_domain(bv,SX,X), set_lazy_domain(bv,SY,Y), set_lazy_domain(bv,SizeXY,Z), N is 2^SY, + div_mod(Z,N,X,Y). +/* insert_dep_inst(dep(NX,0,[X])), insert_dep_inst(dep(Z,0,[NX,Y])), mult(N,X,NX), add(NX,Y,Z). - +*/ +% FAUX bvconcat_v1(0, _, SY, Y, Z) ?- !, protected_unify(Z, Y). bvconcat_v1( SY, Y,0, _, Z) ?- @@ -1832,27 +1914,45 @@ zero_extend(Sx,Extend,X,Y) :- % pour obtenir Y sign_extend(Sx, I, X, Y) :- var(I), !, - my_suspend(sign_extend(Sx, I, X, Y),0,[I] -> inst). -sign_extend(_, 0, X, Y) ?- - !, protected_unify(X,Y). -sign_extend(Sx, I, 0, Y) ?- - !, protected_unify(Y, 0). -sign_extend(Sx, I, X, 0) ?- - !, protected_unify(X, 0). + my_suspend(sign_extend(Sx, I, X, Y),0,I->suspend:inst). + +sign_extend(_, 0, X, Y) ?- !, + protected_unify(X,Y). +sign_extend(Sx, I, X, 0) ?- !, + protected_unify(X, 0). +sign_extend(Sx, I, 0, Y) ?- !, + protected_unify(Y, 0). sign_extend(Sx, I, X, Y) :- integer(X), !, - (X < (2 ^ (Sx - 1)) -> + PF is Sx - 1, + bvextract(Sx,PF,PF,X,PFX), + (PFX == 0 -> % poid fort à 0 protected_unify(X,Y) ; % poid fort à 1 - YY is X \/ (( \ (- 1 << I)) << Sx), - protected_unify(YY,Y)). + BegY is 2^I - 1, + bvconcat(I,BegY,Sx,X,Y)). sign_extend(Sx, I, X, Y) :- - integer(Y), !, - XX is Y /\ ( \ (- 1 << Sx)), - protected_unify(XX,X). + integer(Y), + !, + SxM1 is Sx-1, + Sy is Sx+I, + bvextract(Sy,SxM1,0,Y,X), + % Necessaire pour pouvoir échouer ! + sign_extend(Sx,I,X,Y). + +sign_extend(Sx, I, X, Y) :- !, + PF is Sx - 1, + bvextract(Sx,PF,PF,X,PFX), + Sy is Sx + I, + MaxBegY is 2^I -1, + chk_nan(as(PFX,uint(1)) #= 1, + concat(I,as(MaxBegY,uint(I)),Sx,as(X,uint(Sx))), + zero_extend(Sx,I,as(X,uint(Sx)))) + #= as(Y,uint(Sy)). +% A supprimer !! sign_extend(SX, I, X, Y) :- SX == 1, !, @@ -1865,61 +1965,83 @@ sign_extend(SX, I, X, Y) :- bvextract(SY, 2, 2, Y, X). % TODO : faster with 2, 2 instead of I, I? meh sign_extend(Sx, I, X, Y) :- + get_priority(P), + set_priority(1), + save_cstr_suspensions((X,Y)), Sx > 1, Sy is Sx + I, set_lazy_domain(bv, Sx, X), set_lazy_domain(bv, Sy, Y), - mfd:get_intervals(X,InterX), - (not (member(Vx,InterX), - Vx = _.._) - -> - % only_values_in_intervals(InterX) - (foreach(Vx,InterX), - foreach(Vy,InterY), - param(Sx,I) do - sign_extend(Sx,I,Vx,Vy)), - mfd:set_intervals(Y,InterY) - ; true), - mfd:get_intervals(Y,NInterY), - (not (member(Vy,NInterY), - Vy = _.._) - -> - % only_values_in_intervals(NInterY) - (foreach(Vy,NInterY), - foreach(Vx,NInterX), - param(Sx,I) do - sign_extend(Sx,I,Vx,Vy)), - mfd:set_intervals(X,NInterX), - mfd:get_intervals(X,NNInterX), - (InterX \== NNInterX -> - % only_values_in_intervals(NNInterX) - (foreach(Vx,NNInterX), - foreach(Vy,NInterY), + get_saved_cstr_suspensions(LSusp), + (foreach((Susp,G),LSusp), + param(Fact) do + ((G = sign_extend(Sx, II, XX, YY), + II == I, + (XX == X; + YY == Y)) + -> + Fact = 1, + protected_unify(X,XX), + protected_unify(Y,YY) + ; true)), + (var(Fact) -> + my_suspend(sign_extend(Sx, I, X, Y),0,(X,Y)->suspend:inst) +/* + mfd:get_intervals(X,InterX), + (not (member(Vx,InterX), + Vx = _.._) + -> + % only_values_in_intervals(InterX) + (foreach(Vx,InterX), + foreach(Vy,InterY), param(Sx,I) do sign_extend(Sx,I,Vx,Vy)), - mfd:set_intervals(Y,NInterY) - ; true) + mfd:set_intervals(Y,InterY) + ; true), + mfd:get_intervals(Y,NInterY), + (not (member(Vy,NInterY), + Vy = _.._) + -> + % only_values_in_intervals(NInterY) + (foreach(Vy,NInterY), + foreach(Vx,NInterX), + param(Sx,I) do + sign_extend(Sx,I,Vx,Vy)), + mfd:set_intervals(X,NInterX), + mfd:get_intervals(X,NNInterX), + (InterX \== NNInterX -> + % only_values_in_intervals(NNInterX) + (foreach(Vx,NNInterX), + foreach(Vy,NInterY), + param(Sx,I) do + sign_extend(Sx,I,Vx,Vy)), + mfd:set_intervals(Y,NInterY) + ; true) + ; true), + Sxm1 is Sx - 1, + Sym1 is Sy - 1, + mfd:dvar_range(X,LX,HX), + DpSxm1 is 2^Sxm1, + mfd:dvar_range(Y,LY,HY), + DpSym1 is 2^Sym1, + % signe à 0 ? + ((HX < DpSxm1; + HY < DpSym1) + -> + launch_bveq(Sx,X,Sy,Y) + ; % Mask contient I bits a 1 + % Mask vaut donc 2^(I+1) - 1 + Mask is \ (-1 << I), + mfd:set_intervals(Ext, [0,Mask]), + % X et Y de meme signe + insert_dep_inst(dep(Sign,0,[X,Y])), + bvextract(Sx, Sxm1, Sxm1, X, Sign), + bvextract(Sy, Sym1, Sym1, Y, Sign), + bvconcat(I, Ext, Sx, X, Y)) +*/ ; true), - Sxm1 is Sx - 1, - Sym1 is Sy - 1, - mfd:dvar_range(X,LX,HX), - DpSxm1 is 2^Sxm1, - mfd:dvar_range(Y,LY,HY), - DpSym1 is 2^Sym1, - % signe à 0 ? - ((HX < DpSxm1; - HY < DpSym1) - -> - launch_bveq(Sx,X,Sy,Y) - ; % Mask contient I bits a 1 - % Mask vaut donc 2^(I+1) - 1 - Mask is \ (-1 << I), - mfd:set_intervals(Ext, [0,Mask]), - % X et Y de meme signe - insert_dep_inst(dep(Sign,0,[X,Y])), - bvextract(Sx, Sxm1, Sxm1, X, Sign), - bvextract(Sy, Sym1, Sym1, Y, Sign), - bvconcat(I, Ext, Sx, X, Y)). + set_priority(P), + wake_if_other_scheduled(P). % =================== Add ====================248474 :- export bvadd/4. diff --git a/Src/COLIBRI/mreal.pl b/Src/COLIBRI/mreal.pl index b88a9085acdafc9b05450eea0d82ef611b30f2cb..089133cd001d8d751ebaed4c6551de22be15f562 100755 --- a/Src/COLIBRI/mreal.pl +++ b/Src/COLIBRI/mreal.pl @@ -448,20 +448,27 @@ one_is_contained(_Type,LI1,S1,LI1,S2,LI,S) ?- !, S1 = S2, S = S1. one_is_contained(Type,LI1,S1,[Min2..Max2],_,LI1,S1) :- - interval_range(LI1,Min1,Max1), + LI1 = [Min1..Max1], compare(O1,Min1,Min2), occurs(O1,(>,=)), + % Min1 >= Min2 compare(O2,Max1,Max2), - occurs(O2,(<,=)),!, + occurs(O2,(<,=)), + !, + % Max1 =< Max2 + % LI1 est dans Min2..Max2!, (var(S1) -> real_interval_size(Type,LI1,0,S1) ; true). one_is_contained(Type,[Min1..Max1],_,LI2,S2,LI2,S2) :- - interval_range(LI2,Min2,Max2), + LI2 = [Min2..Max2], compare(O1,Min2,Min1), occurs(O1,(>,=)), + % Min2 >= Min1 compare(O2,Max2,Max1), occurs(O2,(<,=)), + !, + % Max2 =< Max1 (var(S2) -> real_interval_size(Type,LI2,0,S2) ; true). diff --git a/Src/COLIBRI/ndelta.pl b/Src/COLIBRI/ndelta.pl index 9cb008b4a0d1820557053b61525eee4dac3935ec..61e6c1cf6432dec73fa86a3963b16338cc5d6743 100755 --- a/Src/COLIBRI/ndelta.pl +++ b/Src/COLIBRI/ndelta.pl @@ -425,12 +425,13 @@ pre_unify_delta0(T1,T2) :- float(T1),abs(T1) =:= 1.0Inf,T=T1; float(T2),abs(T2) =:= 1.0Inf,T=T2) -> - (call(getval(gdbg,1))@eclipse -> - writeln(output,nan_inf(T)) - ; true), - call(spy_nan_inf)@eclipse, - not getval(no_float_error,1)@eclipse - ; true))). + (getval(no_float_error,1)@eclipse -> + call(spy_nan_inf)@eclipse, + call(getval(gdbg,1))@eclipse, + writeln(output,nan_inf(T)), + fail + ; true) + ; true))). pre_unify_delta_var(V1,T2) :- (not not_unify(V1,T2)), diff --git a/Src/COLIBRI/rbox.pl b/Src/COLIBRI/rbox.pl index d9fd661713d2c816f667e9eb58ad317f3a255164..75d6413bb7c7334d767e9b84237571487d859192 100755 --- a/Src/COLIBRI/rbox.pl +++ b/Src/COLIBRI/rbox.pl @@ -54,6 +54,13 @@ protected_denominator/2 from colibri. +:- export notify_replace_attribute/4. +notify_replace_attribute(Var,OA,NA,Mod) :- + replace_attribute(Var,NA,Mod), + (OA \== NA -> + my_notify_constrained(Var), + wake + ; true). %---------------------------------------------------------------- % attribute declaration %---------------------------------------------------------------- @@ -134,16 +141,20 @@ unify_rbox_rbox(Y, rf(InfosX,NaNX), rf(InfosY,NaNY)) ?- -> InfosX = InfosY ; ((InfosX == InfosY; + Diff = 1, InfosX = BoxX-RatX, InfosY = BoxY-RatY) -> RatX = RatY, (BoxY == rbox -> - replace_attribute(Y,rf(BoxX-RatX,NaNX),rbox) + notify_replace_attribute(Y,rf(InfosY,NaNY),rf(BoxX-RatX,NaNX),rbox) ; (BoxY == float_int -> BoxX \== not_float_int ; % not_float_int - BoxX \== float_int)) + BoxX \== float_int), + (nonvar(Diff) -> + my_notify_constrained(Y) + ; true)) ; (InfosX == float -> atomic(InfosY), occurs(InfosY,(float_int,not_float_int)) @@ -329,7 +340,7 @@ launch_box_prio(Var{rbox:rf(RF,NaN)},Rat) ?- !, Den \== 1 ; NBox = rbox)), (var(Var) -> - replace_attribute(Var,rf(NBox-Rat,0),rbox), + notify_replace_attribute(Var,rf(RF,NaN),rf(NBox-Rat,0),rbox), (get_real_cst(Rat,NVar) -> protected_unify(Var,NVar) ; add_real_cst(Rat,Var)) @@ -354,7 +365,7 @@ launch_box_prio(Var{rbox:rf(RF,NaN)},Rat) ?- !, ; (RF == not_float_int -> Box = nibox ; Box = rbox)), - replace_attribute(Var,rf(Box-_,0),rbox))). + notify_replace_attribute(Var,rf(RF,NaN),rf(Box-_,0),rbox))). %% Pas d'attribut launch_box_prio(Var,Rat) :- (nonvar(Rat) -> @@ -440,7 +451,7 @@ launch_float_int_prio(Var{rbox:rf(RF,NaN)}) ?- !, -> NRF = float_int ; NRF = ibox-Rat), - replace_attribute(Var,rf(NRF,NaN),rbox), + notify_replace_attribute(Var,rf(RF,NaN),rf(NRF,NaN),rbox), (mreal:dvar_domain(Var,Dom) -> mreal:dom_type(Dom,Type), mreal:dom_interval(Dom,Inter), @@ -505,7 +516,7 @@ launch_not_float_int_prio(Var{rbox:rf(RF,NaN)}) ?- !, -> NRF = nibox-Rat ; NRF = not_float_int), - replace_attribute(Var,rf(NRF,NaN),rbox), + notify_replace_attribute(Var,rf(RF,NaN),rf(NRF,NaN),rbox), (get_type(Var,Type) -> set_not_integral_dom(Type,Var), (RF == not_float_int -> diff --git a/Src/COLIBRI/real_util.pl b/Src/COLIBRI/real_util.pl index a2b99e3e631a2091a709dd5e99f9001c3ee6690e..8be633d65d901a3f655e0770511a7bdac17ba535 100755 --- a/Src/COLIBRI/real_util.pl +++ b/Src/COLIBRI/real_util.pl @@ -520,255 +520,255 @@ get_number_of_simple_floats_between(Inf,Sup,Nb) :- %PMO a verif get_nth_float_from(float_simple,F,N,NF) ?- !, - get_nth_simple_float_from(F,N,NF). + get_nth_simple_float_from(F,N,NF). get_nth_float_from(_,F,N,NF) :- - get_nth_double_float_from(F,N,NF). + get_nth_double_float_from(F,N,NF). get_nth_float_from(F,N,NF):- - (getval(float_eval,float_simple)@eclipse-> - get_nth_simple_float_from(F,N,NF) - ; get_nth_double_float_from(F,N,NF)). + (getval(float_eval,float_simple)@eclipse-> + get_nth_simple_float_from(F,N,NF) + ; get_nth_double_float_from(F,N,NF)). get_nth_simple_float_from(F,0,F) :- !. get_nth_simple_float_from(F,1,NF) :- !, - get_next_simple_float(F,NF). + get_next_simple_float(F,NF). get_nth_simple_float_from(F,-1,NF) :- !, - get_previous_simple_float(F,NF). + get_previous_simple_float(F,NF). get_nth_simple_float_from(F,N,NF) :- - (N > 0 -> - DInf is get_number_of_simple_floats_between(F,1.0Inf), - (DInf =< N + 1 -> - NF = 1.0Inf - ; get_nth_simple_from1(F,N,NF)) - ; %% N < 0, on reculle - OpF is norm_zero_op(real,F), - OpN is -N, - DInf is get_number_of_simple_floats_between(OpF,1.0Inf), - (DInf =< OpN + 1 -> - NF = -1.0Inf - ; get_nth_simple_from1(OpF,OpN,OpNF), - NF is norm_zero_op(real,OpNF))). + (N > 0 -> + DInf is get_number_of_simple_floats_between(F,1.0Inf), + (DInf =< N + 1 -> + NF = 1.0Inf + ; get_nth_simple_from1(F,N,NF)) + ; % N < 0, on reculle + OpF is norm_zero_op(real,F), + OpN is -N, + DInf is get_number_of_simple_floats_between(OpF,1.0Inf), + (DInf =< OpN + 1 -> + NF = -1.0Inf + ; get_nth_simple_from1(OpF,OpN,OpNF), + NF is norm_zero_op(real,OpNF))). %% PMO a verif %% Entre chaque puissance de 2 "normalisee" %% on a 2^23 flottants? get_nth_simple_from1(F,N,NF) :- - (F =:= -1.0Inf -> - get_next_simple_float(F,SF), - NN is N - 1, - get_nth_simple_from2(SF,NN,NF0) - ; get_nth_simple_from2(F,N,NF0)), + (F =:= -1.0Inf -> + get_next_simple_float(F,SF), + NN is N - 1, + get_nth_simple_from2(SF,NN,NF0) + ; get_nth_simple_from2(F,N,NF0)), (NF0 == 0.0 -> NF = -0.0 ; NF = NF0). get_nth_simple_from2(F,N,NF) :- - %% N > 0 - % Representant double du plus petit normalise 1.17549351e-38 - MinNorm = 1.1754943508222875e-38,%% 2^(-126) - OpMinNorm = -1.1754943508222875e-38, - DeuxP23 = 8388608, - (F =< OpMinNorm -> - DOpMinNorm is get_number_of_simple_floats_between(F,OpMinNorm) - 1, - (N < DOpMinNorm -> - %% On avance dans les normalises negatifs - NbUlp is N div DeuxP23, - (NbUlp > 0 -> - F1 is F*2.0^(-NbUlp), - N1 is N mod DeuxP23 - ; % moins de 1 ulp - F1 = F, - N1 = N), - %% On a moins de 1 ulp a partir de F1 - %% On avance jusqu'a la prochaine puissance de 2 - AF is abs(F1), - FL2AF is floor_log2(AF), - F02 is - (2^FL2AF), - norm_zero(real,F02,F2), - D12 is get_number_of_simple_floats_between(F1,F2)-1, - (N1 =< D12 -> - %% on s'arrete avant F2 - Step is 2.0^(FL2AF-23), - NF is F1 + N1*Step - ; %% on franchit une puisance de 2 (F2) en allant vers 0 donc - %% on divise par 2 l'ulp (on passe à 2^(FL2AF-24) pour ulp) - N2 is N1 - D12, - Step is 2.0^(FL2AF-24), - NF is F2 + N2*Step), - Stop = 1 - ; %% N >= DOpMinNorm, on passe par les denormalises - D0 is get_number_of_simple_floats_between(F,MinNorm)-1, - (N < D0 -> - %% On reste dans les denormalises - F1 = OpMinNorm, - N1 is N - DOpMinNorm, - NF is F1 + N1* get_simple_float_epsilon, - Stop = 1 - ; %% On avance en MinNorm - F0 = MinNorm, - N0 is N - D0)) - ; F0 = F, - N0 = N), - (nonvar(Stop) -> - true - ; (F0 < MinNorm -> - %% On passe par les denormalises - DMinNorm is get_number_of_simple_floats_between(F0,MinNorm)-1, - (N0 > DMinNorm -> - %% On avance en MinNorm - F01 = MinNorm, - N01 is N - DMinNorm - ; %% On reste dans les denormalises - NF is F0 + N0*get_simple_float_epsilon, - %% On a fini - Stop = 1) - ; F01 = F0, - N01 = N0), - (nonvar(Stop) -> - true - ; %% On est dans les normalises positifs - NbUlp is N01 div DeuxP23, - (NbUlp > 0 -> - F1 is F01*2.0^NbUlp, - N1 is N01 mod DeuxP23 - ; F1 = F01, - N1 = N01), - %% On a moins d'une ulp mais on peut en franchir une - %% On recule jusqu'a La precedente puissance de 2 - L2F1 is floor_log2(F1), - F2 is 2.0^(L2F1+1), - D12 is get_number_of_simple_floats_between(F1,F2)-1, - (N1 =< D12 -> - %% on s'arrete avant F2 - Step is 2.0^(L2F1-23), - NF is F1 + N1*Step - ; %% On avance en F2 et on consomme le reste de N - Step is 2.0^(L2F1-22), - N2 is N1 - D12, - NF is F2 + N2*Step))). + % N > 0 + % Representant double du plus petit normalise 1.17549351e-38 + MinNorm = 1.1754943508222875e-38,%% 2^(-126) + OpMinNorm = -1.1754943508222875e-38, + DeuxP23 = 8388608, + (F =< OpMinNorm -> + DOpMinNorm is get_number_of_simple_floats_between(F,OpMinNorm) - 1, + (N < DOpMinNorm -> + % On avance dans les normalises negatifs + NbUlp is N div DeuxP23, + (NbUlp > 0 -> + F1 is F*2.0^(-NbUlp), + N1 is N mod DeuxP23 + ; % moins de 1 ulp + F1 = F, + N1 = N), + % On a moins de 1 ulp a partir de F1 + % On avance jusqu'a la prochaine puissance de 2 + AF is abs(F1), + FL2AF is floor_log2(AF), + F02 is - (2^FL2AF), + norm_zero(real,F02,F2), + D12 is get_number_of_simple_floats_between(F1,F2)-1, + (N1 =< D12 -> + % on s'arrete avant F2 + Step is 2.0^(FL2AF-23), + NF is F1 + N1*Step + ; % on franchit une puisance de 2 (F2) en allant vers 0 donc + % on divise par 2 l'ulp (on passe à 2^(FL2AF-24) pour ulp) + N2 is N1 - D12, + Step is 2.0^(FL2AF-24), + NF is F2 + N2*Step), + Stop = 1 + ; % N >= DOpMinNorm, on passe par les denormalises + D0 is get_number_of_simple_floats_between(F,MinNorm)-1, + (N < D0 -> + % On reste dans les denormalises + F1 = OpMinNorm, + N1 is N - DOpMinNorm, + NF is F1 + N1* get_simple_float_epsilon, + Stop = 1 + ; % On avance en MinNorm + F0 = MinNorm, + N0 is N - D0)) + ; F0 = F, + N0 = N), + (nonvar(Stop) -> + true + ; (F0 < MinNorm -> + % On passe par les denormalises + DMinNorm is get_number_of_simple_floats_between(F0,MinNorm)-1, + (N0 > DMinNorm -> + % On avance en MinNorm + F01 = MinNorm, + N01 is N - DMinNorm + ; % On reste dans les denormalises + NF is F0 + N0*get_simple_float_epsilon, + % On a fini + Stop = 1) + ; F01 = F0, + N01 = N0), + (nonvar(Stop) -> + true + ; % On est dans les normalises positifs + NbUlp is N01 div DeuxP23, + (NbUlp > 0 -> + F1 is F01*2.0^NbUlp, + N1 is N01 mod DeuxP23 + ; F1 = F01, + N1 = N01), + % On a moins d'une ulp mais on peut en franchir une + % On recule jusqu'a La precedente puissance de 2 + L2F1 is floor_log2(F1), + F2 is 2.0^(L2F1+1), + D12 is get_number_of_simple_floats_between(F1,F2)-1, + (N1 =< D12 -> + % on s'arrete avant F2 + Step is 2.0^(L2F1-23), + NF is F1 + N1*Step + ; % On avance en F2 et on consomme le reste de N + Step is 2.0^(L2F1-22), + N2 is N1 - D12, + NF is F2 + N2*Step))). get_nth_double_float_from(F,0,F) :- !. get_nth_double_float_from(F,1,NF) :- !, - get_next_double_float(F,NF). + get_next_double_float(F,NF). get_nth_double_float_from(F,-1,NF) :- !, - get_previous_double_float(F,NF). + get_previous_double_float(F,NF). get_nth_double_float_from(F,N,NF) :- - (N > 0 -> - DInf is get_number_of_double_floats_between(F,1.0Inf), - (DInf =< N + 1 -> - NF = 1.0Inf - ; get_nth_double_from1(F,N,NF)) - ; %% N < 0, on reculle - OpF is norm_zero_op(real,F), - OpN is -N, - DInf is get_number_of_double_floats_between(OpF,1.0Inf), - (DInf =< OpN + 1 -> - NF = -1.0Inf - ; get_nth_double_from1(OpF,OpN,OpNF), - NF is norm_zero_op(real,OpNF))). + (N > 0 -> + DInf is get_number_of_double_floats_between(F,1.0Inf), + (DInf =< N + 1 -> + NF = 1.0Inf + ; get_nth_double_from1(F,N,NF)) + ; % N < 0, on reculle + OpF is norm_zero_op(real,F), + OpN is -N, + DInf is get_number_of_double_floats_between(OpF,1.0Inf), + (DInf =< OpN + 1 -> + NF = -1.0Inf + ; get_nth_double_from1(OpF,OpN,OpNF), + NF is norm_zero_op(real,OpNF))). %% Entre chaque puissance de 2 "normalisee" %% on a 2^52 flottants get_nth_double_from1(F,N,NF) :- - (F =:= -1.0Inf -> - get_next_double_float(F,SF), - NN is N - 1, - get_nth_double_from2(SF,NN,NF0) - ; get_nth_double_from2(F,N,NF0)), + (F =:= -1.0Inf -> + get_next_double_float(F,SF), + NN is N - 1, + get_nth_double_from2(SF,NN,NF0) + ; get_nth_double_from2(F,N,NF0)), (NF0 == 0.0 -> NF = -0.0 ; NF = NF0). get_nth_double_from2(F,N,NF) :- - %% N > 0 - MinNorm = 4.4501477170144028e-308, % 2^-1021 - OpMinNorm = -4.4501477170144028e-308, - DeuxP52 = 4503599627370496, - (F =< OpMinNorm -> - DOpMinNorm is get_number_of_double_floats_between(F,OpMinNorm) - 1, - (N < DOpMinNorm -> - %% On avance dans les normalises negatifs - NbUlp is N div DeuxP52, - (NbUlp > 0 -> - F1 is F*2.0^(-NbUlp), - N1 is N mod DeuxP52 - ; F1 = F, - N1 = N), - %% On a moins d'une ulp mais on peut en franchir une - %% On avance jusqu'a la prochaine puissance de 2 - AF is abs(F1), - FL2AF is floor_log2(AF), - F02 is - (2^FL2AF), - norm_zero(real,F02,F2), - D12 is get_number_of_double_floats_between(F1,F2)-1, - (N1 =< D12 -> - %% on s'arrete avant F2 - Step is 2.0^(FL2AF-52), - NF is F1 + N1*Step - ; %% on franchit une puisance de 2 (F2) en allant vers 0 donc - %% on divise par 2 l'ulp (on passe à 2^(FL2AF-53) pour ulp) - N2 is N1 - D12, - Step is 2.0^(FL2AF-53), - NF is F2 + N2*Step), - Stop = 1 - ; %% N >= DOpMinNorm, on passe par les denormalises - D0 is get_number_of_double_floats_between(F,MinNorm)-1, - (N < D0 -> - %% On reste dans les denormalises - F1 = OpMinNorm, - N1 is N - DOpMinNorm, - NF is F1 + N1* get_double_float_epsilon, - Stop = 1 - ; %% On avance en MinNorm - F0 = MinNorm, - N0 is N - D0)) - ; F0 = F, - N0 = N), - (nonvar(Stop) -> - true - ; (F0 < MinNorm -> - %% On passe par les denormalises - DMinNorm is get_number_of_double_floats_between(F0,MinNorm)-1, - (N0 > DMinNorm -> - %% On avance en MinNorm - F01 = MinNorm, - N01 is N - DMinNorm - ; %% On reste dans les denormalises - NF is F0 + N0*get_double_float_epsilon, - %% On a fini - Stop = 1) - ; F01 = F0, - N01 = N0), - (nonvar(Stop) -> - true - ; %% On est dans les normalises positifs - NbUlp is N01 div DeuxP52, - (NbUlp > 0 -> - %% F1 is F01*2.0^NbUlp - %% IL FAUT CONDITIONNER CE CALCUL CAR - %% NbUlp PEUT ETRE >>> 1024 QUAND F01 < 1.0 - (F01 < 1.0 -> - %% On est dans une puissance de 2 negative - L2F is floor_log2(F01), - %% -1021 =< L2F < 0 -%% F1 is (F01*2.0^(NbUlp+L2F))*2.0^(-L2F) - F1 is (F01*2.0^(1-L2F))*2.0^(NbUlp+L2F-1) - ; F1 is F01*2.0^NbUlp), - N1 is N01 mod DeuxP52 - ; F1 = F01, - N1 = N01), - %% On a moins d'une ulp mais on peut en franchir une - %% On recule jusqu'a La precedente puissance de 2 - L2F1 is floor_log2(F1), - F2 is 2.0^(L2F1+1), - D12 is get_number_of_double_floats_between(F1,F2)-1, - (N1 =< D12 -> - %% on s'arrete avant F2 - Step is 2.0^(L2F1-52), - NF is F1 + N1*Step - ; %% On avance en F2 et on consomme le reste de N - Step is 2.0^(L2F1-51), - N2 is N1 - D12, - NF is F2 + N2*Step))). + % N > 0 + MinNorm = 4.4501477170144028e-308, % 2^-1021 + OpMinNorm = -4.4501477170144028e-308, + DeuxP52 = 4503599627370496, + (F =< OpMinNorm -> + DOpMinNorm is get_number_of_double_floats_between(F,OpMinNorm) - 1, + (N < DOpMinNorm -> + % On avance dans les normalises negatifs + NbUlp is N div DeuxP52, + (NbUlp > 0 -> + F1 is F*2.0^(-NbUlp), + N1 is N mod DeuxP52 + ; F1 = F, + N1 = N), + % On a moins d'une ulp mais on peut en franchir une + % On avance jusqu'a la prochaine puissance de 2 + AF is abs(F1), + FL2AF is floor_log2(AF), + F02 is - (2^FL2AF), + norm_zero(real,F02,F2), + D12 is get_number_of_double_floats_between(F1,F2)-1, + (N1 =< D12 -> + % on s'arrete avant F2 + Step is 2.0^(FL2AF-52), + NF is F1 + N1*Step + ; % on franchit une puisance de 2 (F2) en allant vers 0 donc + % on divise par 2 l'ulp (on passe à 2^(FL2AF-53) pour ulp) + N2 is N1 - D12, + Step is 2.0^(FL2AF-53), + NF is F2 + N2*Step), + Stop = 1 + ; % N >= DOpMinNorm, on passe par les denormalises + D0 is get_number_of_double_floats_between(F,MinNorm)-1, + (N < D0 -> + % On reste dans les denormalises + F1 = OpMinNorm, + N1 is N - DOpMinNorm, + NF is F1 + N1* get_double_float_epsilon, + Stop = 1 + ; % On avance en MinNorm + F0 = MinNorm, + N0 is N - D0)) + ; F0 = F, + N0 = N), + (nonvar(Stop) -> + true + ; (F0 < MinNorm -> + % On passe par les denormalises + DMinNorm is get_number_of_double_floats_between(F0,MinNorm)-1, + (N0 > DMinNorm -> + % On avance en MinNorm + F01 = MinNorm, + N01 is N - DMinNorm + ; % On reste dans les denormalises + NF is F0 + N0*get_double_float_epsilon, + % On a fini + Stop = 1) + ; F01 = F0, + N01 = N0), + (nonvar(Stop) -> + true + ; % On est dans les normalises positifs + NbUlp is N01 div DeuxP52, + (NbUlp > 0 -> + % F1 is F01*2.0^NbUlp + % IL FAUT CONDITIONNER CE CALCUL CAR + % NbUlp PEUT ETRE >>> 1024 QUAND F01 < 1.0 + (F01 < 1.0 -> + % On est dans une puissance de 2 negative + L2F is floor_log2(F01), + % -1021 =< L2F < 0 + % F1 is (F01*2.0^(NbUlp+L2F))*2.0^(-L2F) + F1 is (F01*2.0^(1-L2F))*2.0^(NbUlp+L2F-1) + ; F1 is F01*2.0^NbUlp), + N1 is N01 mod DeuxP52 + ; F1 = F01, + N1 = N01), + % On a moins d'une ulp mais on peut en franchir une + % On recule jusqu'a La precedente puissance de 2 + L2F1 is floor_log2(F1), + F2 is 2.0^(L2F1+1), + D12 is get_number_of_double_floats_between(F1,F2)-1, + (N1 =< D12 -> + % on s'arrete avant F2 + Step is 2.0^(L2F1-52), + NF is F1 + N1*Step + ; % On avance en F2 et on consomme le reste de N + Step is 2.0^(L2F1-51), + N2 is N1 - D12, + NF is F2 + N2*Step))). %% Fin ZONE A COMMENTER POUR VERSION SANS FLOTTANTS %%:- setval(libdbg,1).%PMO @@ -1040,8 +1040,11 @@ int_to_simple_float_max(Int,DMax) :- % en real/double -is_pow2(C,PC) :- - abs(C) < 1.0Inf, +is_pow2(C0,PC) :- + float(C0,C), + abs(C,AC), + AC < 1.0Inf, + AC \== 0.0, get_double_float_parts(C,S,M,E), (E == -1023 -> % Denormalise diff --git a/Src/COLIBRI/realarith.pl b/Src/COLIBRI/realarith.pl index 879253379ebe74d5868bca3f5c6dc25a71eb7b6d..3dae31c41abe98e0933c23863ee25fde19574a38 100644 --- a/Src/COLIBRI/realarith.pl +++ b/Src/COLIBRI/realarith.pl @@ -743,11 +743,14 @@ check_round_floor_ceiling(Type,Round,A,B,EF,EC,FA,CA,_,Stop). round_rna_val(Type,A,B) :- (is_float_int_number(A) -> B = A - ; abs(A,AbsA), + ; (is_real_box_rat(A,RA0) -> + true + ; RA0 = A), + abs(RA0,AbsA), make_OCamlRat(AbsA,RA), simplex_ocaml_rat_round_integer_RNA(RA,IRB), float_of_OCamlRat(Type,rna,IRB,AbsB), - (A > 0.0 -> + (RA0 > 0.0 -> B = AbsB ; B is -AbsB)). @@ -2151,9 +2154,9 @@ check_before_susp_cast_float_to_double_bis(A,B) :- double_is_simple_float(B), protected_unify(A = B) ; cast_float_to_double_ineqs(A,B), - my_suspend(cast_float_to_double_bis(A,B),3,(A,B)->suspend:constrained))). +%cast_float_to_double_ineqs(A,B) :- !. cast_float_to_double_ineqs(A,B) :- var(A), var(B), @@ -2179,16 +2182,18 @@ cast_float_to_double_ineqs1([S|LSuspV],Seen,NSeen,A,B) :- get_suspension_data(S,goal,G), (G = cast_float_to_double_bis(AA,BB) -> get_rel_between_real_args(A,AA,RA), - % A =< AA ==> double(A) =< double(AA) + % Tous les float sont représentables en double + % A Rel AA ==> double(A) Rel double(AA) (RA \== ? -> launch_real_ineq(RA,float_double,B,BB) ; true), get_rel_between_real_args(B,BB,RB), - % double(A) =< double(AA) ==> A =< AA + % double(A) Rel double(AA) ==> A Rel AA (RB \== ? -> launch_real_ineq(RB,float_simple,A,AA) ; true) - ; (G = cast_double_to_float_bis(BB,AA) -> + ; (fail,G = cast_double_to_float_bis(BB,AA) -> + % A REVOIR !!! get_rel_between_real_args(B,BB,RB), % double(A) > BB ==> A >= float(BB) % double(A) >= BB ==> A >= float(BB) @@ -2507,6 +2512,7 @@ check_before_susp_cast_double_to_float_bis(A,B) :- ; cast_double_to_float_ineqs(A,B), my_suspend(cast_double_to_float_bis(A,B),3,(A,B)->suspend:constrained))). +%cast_double_to_float_ineqs(A,B) :- !. cast_double_to_float_ineqs(A,B) :- var(A), var(B), @@ -2776,12 +2782,16 @@ mult_rat_interval(LA,HA,LB,HB,LR,HR) :- max(H1,H2,HR))))). negative_rat(Rat) :- - simplex_ocaml_rat_num(Rat,SNum), - number_string(Num,SNum), + (number(Rat) -> + Num = Rat + ; simplex_ocaml_rat_num(Rat,SNum), + number_string(Num,SNum)), get_sign(Num,neg). positive_rat(Rat) :- - simplex_ocaml_rat_num(Rat,SNum), - number_string(Num,SNum), + (number(Rat) -> + Num = Rat + ; simplex_ocaml_rat_num(Rat,SNum), + number_string(Num,SNum)), get_sign(Num,pos). @@ -3375,10 +3385,15 @@ clear_Goals_add_real(Type,A,B,C) :- BB == B ; AA == B, BB == A), + % A+B = C et A+B = CC -> C=CC Kill == 1; - G = minus_real1(Type,AA,BB,CC), + Type == real, + % ATTENTION AUX ZEROS + % A+B = C et A-OpB = CC -> C=CC + G = minus_real1(Type,AA,OpB,CC), AA == A, - is_op_real(Type,BB,B))) + is_op_real(Type,A,OpBB), + OpBB == OpB)) -> (nonvar(Kill) -> kill_suspension(S) @@ -3615,9 +3630,8 @@ add_real_2_args_equal(Type,X,Y,Z,Continue) :- true ; Continue = 1, mreal:dvar_domain(B,DomB), - (not is_fzero(B) -> - true - ; % B <> 0 et A doit absorber B + (not_zero(B) -> + % B <> 0 et A doit absorber B % On peut enlever de A le plus grand intervalle autour de zero % qui n'absorbe pas les plus petites valeurs de B % Meme si B est une constante on doit continuer: @@ -3626,7 +3640,8 @@ add_real_2_args_equal(Type,X,Y,Z,Continue) :- greatest_interval_not_absorbing(add,Type,B,IAbsB), mreal:get_intervals(A,IA), mreal:finterval_difference(Type,IA,[IAbsB],NIA), - mreal:set_typed_intervals(A,Type,NIA))). + mreal:set_typed_intervals(A,Type,NIA) + ; true)). % Simplifications communes avec un "op_real" add_real_2_args_equal(Type,A,B,C,_) :- get_saved_cstr_suspensions(LSusp), @@ -3776,7 +3791,7 @@ add_real_zeroes(_,Z1,Z2,C) ?- !, protected_unify(C = -0.0) ; protected_unify(C = 0.0)). -add_real_inst(Type,A,B,C,_) ?- +add_real_inst(Type,A,B,C,Continue) ?- (B == A -> !, (C == A -> @@ -3791,6 +3806,7 @@ add_real_inst(Type,A,B,-0.0,_) ?- !, protected_unify(A,-0.0), protected_unify(B,-0.0). + add_real_inst(real,0.0,B,C,_) ?- !, protected_unify(B,C). add_real_inst(real,A,0.0,C,_) ?- !, @@ -3827,6 +3843,8 @@ add_real_inst(Type,A,B,C,Continue) :- ; % A = +0, B contient -0 et C contient +/-0 % mais C <> -0.0 mreal:dvar_remove_element(C,-0.0), + protected_unify(B,C))). +/* (C == 0.0 -> set_typed_intervals(B,Type,[-0.0 .. 0.0]) ; (float(C) -> @@ -3859,6 +3877,7 @@ add_real_inst(Type,A,B,C,Continue) :- ; Var = B), isZero(as(Var,Type)) #= as(Bool,bool), Continue = 1)))))). +*/ add_real_inst(Type,A,B,C,Continue) :- nonvar(B), B =:= 0.0, @@ -4149,16 +4168,24 @@ check_add_rat(A,B,C) :- fail) ; launch_box_rat(C,RatC)). safe_add_rat(A0,B0,RatC) :- - (var(A0) -> - A = A0 - ; A is A0), - (var(B0) -> - B = B0 - ; B is B0), - check_rbox_rat(A,RatA), - check_rbox_rat(B,RatB), - make_OCamlRat(RatA,RA), - make_OCamlRat(RatB,RB), + (((var(A0); + number(A0)), + A = A0; + compound(A0), + A is A0) + -> + check_rbox_rat(A,RatA), + make_OCamlRat(RatA,RA) + ; RA = A0), + (((var(B0); + number(B0)), + B = B0; + compound(B0), + B is B0) + -> + check_rbox_rat(B,RatB), + make_OCamlRat(RatB,RB) + ; RB = B0), add_rat(RA,RB,RC), simplex_ocaml_rat_num(RC,SCNum), simplex_ocaml_rat_den(RC,SCDen), @@ -4174,16 +4201,24 @@ check_minus_rat(A,B,C) :- fail) ; launch_box_rat(C,RatC)). safe_minus_rat(A0,B0,RatC) :- - (var(A0) -> - A = A0 - ; A is A0), - (var(B0) -> - B = B0 - ; B is B0), - check_rbox_rat(A,RatA), - check_rbox_rat(B,RatB), - make_OCamlRat(RatA,RA), - make_OCamlRat(RatB,RB), + (((var(A0); + number(A0)), + A = A0; + compound(A0), + A is A0) + -> + check_rbox_rat(A,RatA), + make_OCamlRat(RatA,RA) + ; RA = A0), + (((var(B0); + number(B0)), + B = B0; + compound(B0), + B is B0) + -> + check_rbox_rat(B,RatB), + make_OCamlRat(RatB,RB) + ; RB = B0), sub_rat(RA,RB,RC), simplex_ocaml_rat_num(RC,SCNum), simplex_ocaml_rat_den(RC,SCDen), @@ -4204,16 +4239,24 @@ check_mult_rat(A,B,C) :- fail) ; launch_box_rat(C,RatC)). safe_mult_rat(A0,B0,RatC) :- - (var(A0) -> - A = A0 - ; A is A0), - (var(B0) -> - B = B0 - ; B is B0), - check_rbox_rat(A,RatA), - check_rbox_rat(B,RatB), - make_OCamlRat(RatA,RA), - make_OCamlRat(RatB,RB), + (((var(A0); + number(A0)), + A = A0; + compound(A0), + A is A0) + -> + check_rbox_rat(A,RatA), + make_OCamlRat(RatA,RA) + ; RA = A0), + (((var(B0); + number(B0)), + B = B0; + compound(B0), + B is B0) + -> + check_rbox_rat(B,RatB), + make_OCamlRat(RatB,RB) + ; RB = B0), mult_rat(RA,RB,RC), simplex_ocaml_rat_num(RC,SCNum), simplex_ocaml_rat_den(RC,SCDen), @@ -4229,16 +4272,24 @@ check_div_rat(A,B,C) :- fail) ; launch_box_rat(C,RatC)). safe_div_rat(A0,B0,RatC) :- - (var(A0) -> - A = A0 - ; A is A0), - (var(B0) -> - B = B0 - ; B is B0), - check_rbox_rat(A,RatA), - check_rbox_rat(B,RatB), - make_OCamlRat(RatA,RA), - make_OCamlRat(RatB,RB), + (((var(A0); + number(A0)), + A = A0; + compound(A0), + A is A0) + -> + check_rbox_rat(A,RatA), + make_OCamlRat(RatA,RA) + ; RA = A0), + (((var(B0); + number(B0)), + B = B0; + compound(B0), + B is B0) + -> + check_rbox_rat(B,RatB), + make_OCamlRat(RatB,RB) + ; RB = B0), div_rat(RA,RB,RC), simplex_ocaml_rat_num(RC,SCNum), simplex_ocaml_rat_den(RC,SCDen), @@ -5547,8 +5598,6 @@ add_real_ineqs(Type,A,B,C) :- -> check_exists_lin_expr_giving_diff_args(real,C,0.0,_Stop) ; true), - % pour unsat/issue35.smt2 ???? - check_add_op_real(Type,A,B,C), average_add_real_ineqs(Type,A,B,C), bin_op_real_ineq(Type,add_real1,A,B,C)). @@ -5586,7 +5635,6 @@ add_real_ineqs0(Type,A,B,C) :- -> check_exists_lin_expr_giving_diff_args(real,C,0.0,_Stop) ; true), - %check_add_op_real(Type,A,B,C), average_add_real_ineqs(Type,A,B,C), bin_op_real_ineq(Type,add_real1,A,B,C). @@ -8258,17 +8306,110 @@ op_real(Type,A,B) :- op_real1(Type,A,B) :- get_priority(Prio), set_priority(1), + save_cstr_suspensions((A,B)), same_float_int_number_status(Type,A,B), + ((var(A), + var(B)) + -> + check_op_mult_div_real(Type,A,B) + ; true), op_real_bis(Type,A,B), set_priority(Prio), wake_if_other_scheduled(Prio). +check_op_mult_div_real(real,A,OpA) ?- !, + % -(X*Y) = -X*Y = X*-Y, idem pour / + % -(round(X)) = round(-X) + % -(truncate(X)) = truncate(-X) + get_saved_cstr_suspensions(LS), + (foreach((S,G),LS), + fromto([],IGs,OGs,LNGs), + param(A,OpA) do + get_suspension_data(S,state,State), + functor(G,FG,ArG), + ((State == 1; + not occurs(FG,(op_real1,mult_real1,div_real1,add_real1, + minus_real1,round_bis,truncate_bis,floor_bis,ceiling_bis)); + arg(ArG,G,Z), + Z \== A) + -> + OGs = IGs + ; (G = op_real1(real,X,Z) -> + NGs = protected_unify(X,OpA) + ; ((G = mult_real1(real,X,Y,Z), + fail,Z == A) + -> + NGs = ( set_lazy_domain(real,OpX), + op_real_bis(real,X,OpX), + mult_real(real,OpX,Y,OpA), + % -(X*Y) = X*-Y + set_lazy_domain(real,OpY), + op_real_bis(real,Y,OpY), + mult_real(real,X,OpY,OpA)), + OGs = [NGs|IGs] + ; (fail,G = div_real1(real,X,Y,Z) -> + NGs = ( % -(X/Y) = -X/Y + set_lazy_domain(real,OpX), + op_real_bis(real,X,OpX), + div_real(real,OpX,Y,OpA), + % -(X/Y) = X/-Y + set_lazy_domain(real,OpY), + op_real_bis(real,Y,OpY), + div_real(real,X,OpY,OpA)), + OGs = [NGs|IGs] + ; (fail,G = add_real1(real,X,Y,Z) -> + NGs = ( % -(X+Y) = -X+-Y + set_lazy_domain(real,OpX), + op_real_bis(real,X,OpX), + set_lazy_domain(real,OpY), + op_real_bis(real,Y,OpY), + add_real(real,OpX,OpY,OpA)), + OGs = [NGs|IGs] + ; (fail,G = minus_real1(real,X,Y,Z) -> + NGs = ( % -(X-Y) = -X+Y + set_lazy_domain(real,OpX), + op_real_bis(real,X,OpX), + add_real(real,OpX,Y,OpA)), + OGs = [NGs|IGs] + ; (G = round_bis(real,X,Z) -> + % -round(X) = round(-X) + NGs = (set_lazy_domain(real,OpX), + op_real_bis(real,X,OpX), + round(real,OpX,OpA)), + OGs = [NGs|IGs] + ; (G = truncate_bis(real,X,Z) -> + % -truncate(X) = truncate(-X) + NGs = (set_lazy_domain(real,OpX), + op_real_bis(real,X,OpX), + truncate(real,OpX,OpA)), + OGs = [NGs|IGs] + ; (G = floor_bis(real,X,Z) -> + NGs = (set_lazy_domain(real,OpX), + op_real_bis(real,X,OpX), + floor(real,OpX,OpA)), + OGs = [NGs|IGs] + ; (G = ceiling_bis(real,X,Z) -> + NGs = (set_lazy_domain(real,OpX), + op_real_bis(real,X,OpX), + ceiling(real,OpX,OpA)), + OGs = [NGs|IGs] + ; OGs = IGs))))))))))), + (LNGs \== [] -> + % -(X op Y) = OpA + % ou -round/truncate(X) = OpA + % on essaye de saturer + call(spy_here)@eclipse, + (foreach(NGs,LNGs) do + call_priority(NGs,2)) + ; true). +check_op_mult_div_real(_,_,_). + op_real_bis(Type,A,B) :- (A == B -> % fail en flottants Type == real, protected_unify(A,0.0) - ; save_cstr_suspensions((A,B)), + ; %save_cstr_suspensions((A,B)), (is_float_int_number(A) -> launch_float_int_number(B) ; (is_float_int_number(B) -> @@ -8618,10 +8759,6 @@ check_launch_op_int(Type,A,B,_,Continue) :- term_variables((A,B),[_,_]), is_float_int_number(A), is_float_int_number(B), -/* - not_inf_bounds(A), - not_inf_bounds(B)) -*/ is_inside_mantissa(Type,A), is_inside_mantissa(Type,B)) @@ -8641,20 +8778,14 @@ minus_real(A,B,C) :- minus_real_type(Type,A,B,C). minus_real_type(real,A,B,C) ?- !, - minus_real(real,A,B,C). +% minus_real(real,A,B,C). + op_real(real,B,OB), + add_real(real,A,OB,C). minus_real_type(Type,A,B,C) :- (getval(no_float_error,1)@eclipse -> minus_real(Type,A,B,C) ; fp_sub(rne,as(A,Type),as(B,Type)) $= as(C,Type)). -/* -minus_real(Type,A,B,C) :- - Type \== real, - !, - op_real(Type,B,OpB), - fp_eq(Type,OpB,OpBB), - add_real(Type,A,OpBB,C). -*/ minus_real(Type,A,B,C) :- ((Type == real, var(A), @@ -8858,11 +8989,17 @@ clear_Goals_minus_real(Type,A,B,C) :- get_saved_cstr_suspensions(LSusp), ((member((S,G),LSusp), (G = minus_real1(Type,AA,BB,CC), - AA == A, BB == B; - G = add_real1(Type,AA,BB,CC), - AA == A, is_op_real(Type,BB,B))) + AA == A, BB == B, + Kill = 1; + Type == real, + G = add_real1(Type,AA,OpB,CC), + AA == A, + is_op_real(Type,A,OpBB), + OpBB = OpB)) -> - kill_suspension(S), + (nonvar(Kill) -> + kill_suspension(S) + ; true), protected_unify(C,CC) ; true). clear_Goals_minus_real0(real,A,B,C) ?- !, @@ -8939,7 +9076,8 @@ check_launch_minus_int(Type,A,B,C,_,Continue) :- minus_real_2_args_equal(Type,A,A,C,_) ?- !, forbid_infinities(Type,[A]), protected_unify(C = 0.0). -minus_real_2_args_equal(Type,A,B,B,Continue) ?- !, +minus_real_2_args_equal(Type,A,B,B,Continue) ?- +fail, !, % En nearest, la projection inverse sur A % est B +|- ulp(B)/2 + B qui donne bien 2B % sauf si abs(B) = 1.0Inf (ou abs(B)) alors on doit echouer @@ -8949,71 +9087,74 @@ minus_real_2_args_equal(Type,A,B,C,Continue) :- exists_feq(Type,A,C), !, (Type == real -> - (not_inf_bounds(A) -> - protected_unify(B = 0.0) - ; true) - ; %% Type == float - %% -B est absorbe par A - %% On peut enlever de B tout ce qui n'est pas absorbable - %% par A - %% Les Min/Max de A et la projection inverse sur B - %% suffisent pour sur-approximer B - mreal:dvar_range(A,MinA,MaxA), - inv2_minus_float_same_interval(Type,MinA,MaxA,LB,HB), - mreal:set_typed_intervals(B,Type,[LB..HB]), - mreal:dvar_range(B,MinB,MaxB), - ((B == 0.0; - has_absorbed_range(Type,A,L,H), - L =< -MaxB, - H >= -MinB) - -> - %% -B est absorbe par A - true - ; Continue = 1, - mreal:dvar_domain(B,DomB), - (mreal:in_domain(DomB,0.0) -> - true - ; %% B <> 0 - %% On peut enlever de A l'intervalle autour de zero - %% qui n'absorbe pas la plus petite valeur absolue de B - %% Meme si B est une constante on doit continuer: - %% - on a travaille en valeurs absolues et les ulps - %% g/d sont inversees selon le signe - %% - l'arrondi nearest to even n'est pas continu si B est une - %% puissance de deux, il y a des valeurs de NIA - %% qui n'absorbent pas B - greatest_interval_not_absorbing(minus,Type,B,IAbsOpB), - mreal:get_intervals(A,IA), - mreal:finterval_difference(Type,IA,[IAbsOpB],NIA), - mreal:set_typed_intervals(A,Type,NIA)))). + (not_inf_bounds(A) -> + protected_unify(B = 0.0) + ; true) + ; % Type == float* + % -B est absorbe par A + % On peut enlever de B tout ce qui n'est pas absorbable + % par A + % Les Min/Max de A et la projection inverse sur B + % suffisent pour sur-approximer B + mreal:dvar_range(A,MinA,MaxA), + inv2_minus_float_same_interval(Type,MinA,MaxA,LB,HB), + mreal:set_typed_intervals(B,Type,[LB..HB]), + mreal:dvar_range(B,MinB,MaxB), + ((B == 0.0; + has_absorbed_range(Type,A,L,H), + L =< -MaxB, + H >= -MinB) + -> + % -B est absorbe par A + true + ; Continue = 1, + mreal:dvar_domain(B,DomB), + (not_zero(B) -> + % B <> 0 + % On peut enlever de A l'intervalle autour de zero + % qui n'absorbe pas la plus petite valeur absolue de B + % Meme si B est une constante on doit continuer: + % - on a travaille en valeurs absolues et les ulps + % g/d sont inversees selon le signe + % - l'arrondi nearest to even n'est pas continu si B est une + % puissance de deux, il y a des valeurs de NIA + % qui n'absorbent pas B + greatest_interval_not_absorbing(minus,Type,B,IAbsOpB), + mreal:get_intervals(A,IA), + mreal:finterval_difference(Type,IA,[IAbsOpB],NIA), + mreal:set_typed_intervals(A,Type,NIA) + ; true))). %% Simplifications communes avec un "op_real" minus_real_2_args_equal(Type,A,B,C,_) :- - get_saved_cstr_suspensions(LSusp), - member((Susp,op_real1(Type,X,Y)),LSusp), - ( A == X, - (B == Y, +fail, get_saved_cstr_suspensions(LSusp), + member((Susp,op_real1(Type,X,Y)),LSusp), + ( A == X, + (B == Y, Goal = mult_real_bis(Type,2.0,A,C); %% A - -A = C - C == Y, - Goal = (forbid_infinities(Type,[A,B]),mult_real_bis(Type,2.0,A,B))) %% A - B = -A - %% En nearest, la projection inverse sur B - %% est A +|- ulp(A)/2 + A qui donne bien 2A - ; A == Y, - (B == X, - Goal = mult_real_bis(Type,2.0,A,C); %% -B - B = C, ie A - -A = C - C == X, - Goal = (forbid_infinities(Type,[A,B]),mult_real_bis(Type,2.0,A,B))) %% -C - B = C, ie A - B = -A - ; B == X, - (A == Y, + C == Y, + Goal = (forbid_infinities(Type,[A,B]),mult_real_bis(Type,2.0,A,B))) + % A - B = -A + % En nearest, la projection inverse sur B + % est A +|- ulp(A)/2 + A qui donne bien 2A + ; A == Y, + (B == X, + Goal = mult_real_bis(Type,2.0,A,C); + % -B - B = C, ie A - -A = C + C == X, + Goal = (forbid_infinities(Type,[A,B]),mult_real_bis(Type,2.0,A,B))) + % -C - B = C, ie A - B = -A + ; B == X, + (A == Y, Goal = mult_real_bis(Type,2.0,A,C); %% -B - B = C, ie A - -A = C - C == Y, + C == Y, Goal = add_real_bis(Type,A,C,C)) %% A + -B = -B - ; B == Y, - (A == X, + ; B == Y, + (A == X, Goal = mult_real_bis(Type,2.0,A,C); %% A - -A = C - C == X, + C == X, Goal = add_real_bis(Type,A,C,C))), %% A - -C = C - !, - call_priority(Goal,2). + !, + call_priority(Goal,2). minus_real_2_args_equal(_,_,_,_,1). @@ -9401,6 +9542,8 @@ minus_real_inst(Type,0.0,B,C,Continue) ?- !, op_real(Type,B,C) ; % C <> -0.0 mreal:dvar_remove_element(C,-0.0), + op_real(Type,B,C)). +/* (not_unify(B,0.0) -> op_real(Type,B,C) ; (is_fzero(B) -> @@ -9418,7 +9561,7 @@ minus_real_inst(Type,0.0,B,C,Continue) ?- !, ; Var = B), isZero(as(Var,Type)) #= as(Bool,bool), Continue = 1))))). - +*/ minus_real_inst(Type,-0.0,B,C,_) ?- !, % Type <> real op_real(Type,B,C). @@ -10355,32 +10498,50 @@ mult_real_bis(Type,A,B,C) :- propagate_float_int_bin_op(Type,A,B,C), clean_inf_args_from_res(Type,C,[A,B]), clear_Goals_mult_real(Type,A,B,C), - check_zero_mult_real(Type,A,B,C), - mult_real_sign(Type,A,B,C), - mult_real_inst(Type,A,B,C,Continue), - (var(Continue) -> - true - ; mult_real_2_args_equal(Type,A,B,C,Continue1), - % PMO si les 3 args sont des float_int entre -2^53 et 2^53 on peut - % deleguer le calcul aux entiers - check_launch_mult_int(Type,A,B,C,Continue1,Continue2), - (var(Continue2) -> + ((Type == real, + member((Susp,mult_real1(real,AA,BB,CC)),LSusp), + CC == C, + (A == BB -> + exists_diff_Rel(B,AA), + Z = A + ; (A == AA -> + exists_diff_Rel(B,BB), + Z = A + ; B == BB, + exists_diff_Rel(A,AA), + Z = B))) + -> + % cas manquant + call(spy_here)@eclipse, + kill_suspension(Susp), + protected_unify(C,0.0), + protected_unify(Z,0.0) + ; check_zero_mult_real(Type,A,B,C), + mult_real_sign(Type,A,B,C), + mult_real_inst(Type,A,B,C,Continue), + (var(Continue) -> true - ; check_mult_real_rel(Type,A,B,C), - mult_real_rec(Type,A,B,C), - mult_real_ineqs(Type,A,B,C), - mult_real_inst(Type,A,B,C,Continue3), - (var(Continue3) -> + ; mult_real_2_args_equal(Type,A,B,C,Continue1), + % PMO si les 3 args sont des float_int entre -2^53 et 2^53 on peut + % deleguer le calcul aux entiers + check_launch_mult_int(Type,A,B,C,Continue1,Continue2), + (var(Continue2) -> true - ; check_2box(Type,[A,B,C]), - set_prio_inst([A,B,C],4,5,Prio0), - ((exists_congr(A,_,_), - exists_congr(B,_,_)) - -> - Prio is Prio0 - 1 - ; Prio = Prio0), - NewGoal = mult_real1(Type,A,B,C), - my_suspend(NewGoal,Prio,(A,B,C) -> suspend:constrained)))). + ; check_mult_real_rel(Type,A,B,C), + mult_real_rec(Type,A,B,C), + mult_real_ineqs(Type,A,B,C), + mult_real_inst(Type,A,B,C,Continue3), + (var(Continue3) -> + true + ; check_2box(Type,[A,B,C]), + set_prio_inst([A,B,C],4,5,Prio0), + ((exists_congr(A,_,_), + exists_congr(B,_,_)) + -> + Prio is Prio0 - 1 + ; Prio = Prio0), + NewGoal = mult_real1(Type,A,B,C), + my_suspend(NewGoal,Prio,(A,B,C) -> suspend:constrained))))). check_mult_real_rel(Type,A,B,C) :- @@ -13431,242 +13592,158 @@ div_real_float_intervals1(Type,ValInter1,ValInter2,L,EndL) :- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% A/B = C +%% real_int: A div B = Q, R = A - B*Q +%% définition SMT-LIB de div/mod %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -idiv_mod_real(A,B,Q,R) :- - % version integrale de mod_real + +idiv_mod_real(A,B,Q,R) :- !, + % version integrale de div/mod_real % pour la simulation des entiers non bornes par des reels get_priority(P), set_priority(1), - save_cstr_suspensions((A,B)), - get_saved_cstr_suspensions(LSusp), - ((member((Susp,check_divides_real(AA,BB,QQ,_,RR)),LSusp), - (B == BB -> - (A == AA; - Q == QQ, - R == RR) - ; A == AA, - Q == QQ, - R == RR, - (not_zero(Q) -> - true - ; exists_diff_Rel(B,BB), - ZQ = 1))) - -> - (nonvar(ZQ) -> - protected_unify(Q,0.0) - ; % Fact - protected_unify(A,AA), - protected_unify(B,BB), - protected_unify(Q,QQ), - protected_unify(R,RR)) - ; 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]), - diff_real(real,B,0.0), - % R positif - mreal:dvar_remove_smaller(R,0.0), - % abs(R) est borné strictement par B en valeur absolue - as(R,real) $< abs(as(B,real)), - - % cas à gérer explicitement pour éviter que le labelling - % parte sur Q sans les considérer - 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(abs(as(B,real)) $= as(1.0,real), - (abs(as(A,real)) $= abs(as(Q,real))) and - (as(R,real) $= as(0.0,real)), - chk_nan(as(R,real) $= as(0.0,real), - as(BQ,real) $= as(A,real), - as(A,real) $\= as(0.0,real)))), - % R = A-BQ, mais pas de lien direct sur A et B ? - mult_real(real,B,Q,BQ), - minus_real(real,A,BQ,R), - % on garde une trace de idiv_mod_real - % qui teste la divisibilite - % et propage d'autres réductions - check_divides_real(A,B,Q,BQ,R)), + 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), set_priority(P), - wake_if_other_scheduled(P). - + wake_if_other_scheduled(P). -check_divides_real(A,A,Q,BQ,R) ?- !, +check_idiv_mod_real(A,A,Q,BQ,R) ?- !, protected_unify(Q,1.0), protected_unify(BQ,A), protected_unify(R,0.0). -check_divides_real(A,B,Q,BQ,A) ?- !, +check_idiv_mod_real(A,B,Q,BQ,A) ?- !, protected_unify(Q,0.0), protected_unify(BQ,0.0). -check_divides_real(A,B,Q,A,R) ?- !, +check_idiv_mod_real(A,B,Q,A,R) ?- !, protected_unify(R,0.0). -check_divides_real(0.0,B,Q,BQ,R) ?- !, +check_idiv_mod_real(0.0,B,Q,BQ,R) ?- !, protected_unify(Q,0.0), protected_unify(BQ,0.0), protected_unify(R,0.0). -check_divides_real(A,1.0,Q,BQ,R) ?- !, +check_idiv_mod_real(A,1.0,Q,BQ,R) ?- !, protected_unify(Q,A), protected_unify(BQ,A), protected_unify(R,0.0). -check_divides_real(A,-1.0,Q,BQ,R) ?- !, +check_idiv_mod_real(A,-1.0,Q,BQ,R) ?- !, op_real(real,A,Q), protected_unify(BQ,A), protected_unify(R,0.0). -check_divides_real(A,B,Q,BQ,0.0) ?- !, +check_idiv_mod_real(A,B,Q,BQ,0.0) ?- !, protected_unify(A,BQ). -check_divides_real(A,B,Q,0.0,R) ?- !, +check_idiv_mod_real(A,B,Q,0.0,R) ?- !, protected_unify(Q,0.0), protected_unify(A,R). -check_divides_real(X,Y,Q,YQ,R) :- - check_rbox_rat(X,RX), - check_rbox_rat(Y,RY), - !, - (RY > 0 -> - RQ is floor(RX/RY) - ; RQ is ceiling(RX/RY)), - launch_box_rat(Q,RQ), - % RR is RX - (RY*RQ), - safe_mult_rat(RY,RQ,RYQ), - launch_box_rat(YQ,RYQ), - safe_minus_rat(RX,RYQ,RR), - launch_box_rat(R,RR). - -check_divides_real(X,Y,Q,YQ,R) :- +check_idiv_mod_real(X,Y,Q,YQ,R) :- + (number(X);check_rbox_rat(X,RX)), + (number(Y);check_rbox_rat(Y,RY)), + !. +check_idiv_mod_real(X,Y,Q,YQ,R) :- get_priority(P), set_priority(1), - (exists_abs_op(real,X,AOXs) -> - (exists_abs_op(real,Y,AOYs) -> - Vars = (AOXs,AOYs) - ; Vars = (Y,AOXs)) - ; (exists_abs_op(real,Y,AOYs) -> - Vars = (X,AOYs) - ; Vars = (X,Y))), - save_cstr_suspensions(Vars), + save_cstr_suspensions((X,Y,Q,R)), get_saved_cstr_suspensions(LSusp), - - (not_zero(Q) -> - mreal:dvar_remove_element(X,0.0) - ; true), - (not_zero(R) -> + + ((not_zero(Q); + not_zero(R)) + -> mreal:dvar_remove_element(X,0.0) ; true), - - congr_mult_inverse(real,YQ,Y,Q), - congr_mult_inverse(real,YQ,Q,Y), - - (same_abs(real,X,Y,LSusp,_,_) -> - abs_val_real(real,Q,1.0), - protected_unify(R,0.0) - ; true), % factorisation - ((member((Susp,check_divides_real(XX,YY,QQ,YYQQ,RR)),LSusp), + ((member((Susp,check_idiv_mod_real(XX,YY,QQ,YYQQ,RR)),LSusp), (YY == Y -> - once (XX == X; % Fact - QQ == Q, - RR == R), - % X = YQ + R et XX = YQ + R -> Fact + XX == X, Fact = 1 ; XX == X, - QQ == Q, - RR == R, - % X = YQ + R et X = YYQ + R -> YQ = YYQ - (exists_diff_Rel(YY,Y) -> - % Y <> YY donc Q = 0 et R = X - % et abs(X) < abs(Y) et abs(X) < abs(YY) - DiffY = 1 - ; true), - (not_zero(Q) -> - % YQ = YYQ - NZQ = 1 - ; true), - (nonvar(DiffY); - nonvar(NZQ)))) + is_abs_real(real,Y,OY), + OY == YY, + % abs(YY) = Y + % R = X - Y*Q et RR = X - abs(Y)*QQ + % donc R = RR + Goal = protected_unify(R,RR))) -> - kill_suspension(Susp), (nonvar(Fact) -> - % on continue - protected_unify(X,XX), - protected_unify(Y,YY), + Stop = 1, protected_unify(Q,QQ), protected_unify(YQ,YYQQ), protected_unify(R,RR) - ; (nonvar(DiffY) -> - Stop = 1, - protected_unify(Q,0.0), - protected_unify(YQ,0.0), - protected_unify(YYQQ,0.0), - protected_unify(X,R), - abs_val_real(real,X,AX), - abs_val_real(real,Y,AY), - abs_val_real(real,YY,AYY), - gt_real(real,AY,AX), - gt_real(real,AYY,AX) - ; nonvar(NZQ), - % X = XX, Q = QQ, R = RR, Q <> 0 - % X = YQ + R et X = YYQ + R - % donc YQ == YYQ et Y == YY - Stop = 1, - protected_unify(Y,YY), - protected_unify(YQ,YYQ))) + ; call_priority(Goal,2)) ; true), % X et/ou Y variable - (divides_real_vars(Y,X,[]) -> + ((var(Stop), + divides_real_vars(Y,X,[])) + -> % R = 0 et X = YQ protected_unify(R,0.0), protected_unify(X,YQ), Stop = 1 ; true), (var(Stop) -> - % congruence - ((member((_,check_divides_real(XX,YY,QQ,_,RR)),LSusp), - once (YY == Y, - OO = XX, - O = X; - XX == X, - OO = YY, - O = Y), - - (exists_diff_Rel(QQ,Q); - exists_diff_Rel(RR,R))) - -> - launch_diff_real(real,OO,O) - ; true), - % matching d'autres div_mod avec des op entre arguments - % utile pour issue60 adacore et ses variantes - ((not_zero(X), - member_begin_end((_,check_divides_real(CX,CY,CQ,CYQ,CR)), - LSusp,NLS,ELS,ELS), - % voire solve.pl - % Rel* = eq|op|abs, on beaucoup de cas ici - same_abs(real,X,CX,NLS,RelX,NNLS), - RelX == eq, - same_abs(real,Y,CY,NNLS,RelY,_), - RelY == op) - -> - % AUTRES CAS DE Rel* INUTILES - % X = CX et Y = -CY - % et on observe (prouvé par cvc5) Q = -CQ - % X-CX = 0 = YQ + Y*CQ + R-CR - % donc R = CR (ca tue l'issue60) - op_real(real,Q,CQ), - protected_unify(R,CR) - ; true), + % contre apposée congruence + % X div Y = Q et X div YY = QQ et QQ <> Q => Y <> YY + % X mod Y = R et X mod YY = RR et RR <> R => Y <> YY + % X div Y = Q et XX div Y = QQ et QQ <> Q => X <> XX + % X mod Y = R et XX mod Y = RR et RR <> R => X <> XX + + (foreach((_,G),LSusp), + param(X,Y,Q,R) do + ((G = check_idiv_mod_real(NX,NY,NQ,_,NR), + (X == NX -> + (exists_diff_Rel(Q,NQ); + exists_diff_Rel(R,NR)), + D1 = Y, + D2 = NY + ; Y == NY, + (exists_diff_Rel(Q,NQ); + exists_diff_Rel(R,NR)), + D1 = X, + D2 = NX)) + -> + launch_diff_real(real,D1,D2) + ; true)), + (var(Stop) -> - my_suspend(check_divides_real(X,Y,Q,YQ,R),4,(X,Y,Q,YQ,R)-> + my_suspend(check_idiv_mod_real(X,Y,Q,YQ,R),4,(X,Y,Q,YQ,R)-> suspend:constrained) ; true) ; true), set_priority(P), wake_if_other_scheduled(P). +is_abs_real(real,AbsA,A) :- + get_saved_cstr_suspensions(LS), + member((_,abs_val_real1(real,CA,CAbsA)),LS), + AbsA == CAbsA, + protected_unify(A,CA), + !. + divides_real_vars(X,X,_) ?- !. divides_real_vars(Y,X,Seen) :- ((exists_congr(Y,CY,MY), @@ -13706,7 +13783,6 @@ divides_real_vars(Y,X,Seen) :- (var(A),divides_real_vars(Y,A,[S|Seen]); var(B),divides_real_vars(Y,B,[S|Seen]))). - div_real(A,B,C) :- getval(float_eval,Type)@eclipse, div_real_type(Type,A,B,C). @@ -16439,6 +16515,52 @@ check_is_e(Type,A) :- exp_val(Type,1.0,E), A == E. +power_real(Type,A,N,B) :- + var(N), + !, + save_cstr_suspensions((A,N,B)), + ((Type == real, + is_float_int_number(A), + is_float_int_number(B), + get_sign(N,pos)) + -> + (get_sign(B,SB) -> + (SB == neg -> + % A neg et N impair + launch_congr(N,1,2), + set_intervals(real,A,[-1.0Inf..0.0]) + ; % B pos + (get_sign(A,neg) -> + % N pair + launch_congr(N,0,2) + ; true)) + ; ((get_sign(A,pos); + get_congr(N,0,2)) + -> + % B pos + set_intervals(real,B,[0.0..1.0Inf]) + ; true)) + ; true), + get_saved_cstr_suspensions(LSusp), + ((member((S,power_real(Type,AA,NN,BB)),LSusp), + (A == AA -> + (N == NN -> + U1 = B, + U2 = BB + ; Type == real, + B == BB, + U1 = N, + U2 = NN) + ; Type == real, + not_zero(N), + N == NN, + B == BB, + U1 = A, + U2 = B)) + -> + protected_unify(U1,U2) + ; my_suspend(power_real(Type,A,N,B),0,N->suspend:inst)). + power_real(Type,A,0,B) ?- !, protected_unify(B,1.0). power_real(Type,A,1,B) ?- !, @@ -16471,30 +16593,51 @@ power_real(Type,A,N,B) :- power_real(Type,A,N,B) :- integer(N), N >= 0, - %N =< 2^53, - mreal:set_typed_intervals(A,Type,[-1.0Inf..1.0Inf]), - mreal:set_typed_intervals(B,Type,[-1.0Inf..1.0Inf]), - ensure_not_NaN((A,B)), - (Type == real -> - true - ; launch_float_number(A), - launch_float_number(B)), - (N == 0 -> - protected_unify(B = 1.0) - ; (N == 1 -> - protected_unify(A = B) - ; (is_float_int_number(A) -> - launch_float_int_number(B) - ; true), - power_real_interval(Type,A,N,B), - (mod(N,2,0) -> - mreal:set_typed_intervals(B,Type,[0.0..1.0Inf]) - ; true), - power_real1(Type,A,N,B))). + %N =< 2^64, + (check_max_exponent(A,N) -> + mreal:set_typed_intervals(A,Type,[-1.0Inf..1.0Inf]), + mreal:set_typed_intervals(B,Type,[-1.0Inf..1.0Inf]), + ensure_not_NaN((A,B)), + ((Type == real, + is_float_int_number(A), + is_float_int_number(B), + get_sign(B,neg)) + -> + % A neg et N impair + launch_congr(N,1,2), + set_intervals(real,A,[-1.0Inf..0.0]) + ; true), + (Type == real -> + true + ; launch_float_number(A), + launch_float_number(B)), + (N == 0 -> + protected_unify(B = 1.0) + ; (N == 1 -> + protected_unify(A = B) + ; (is_float_int_number(A) -> + launch_float_int_number(B) + ; true), + power_real_interval(Type,A,N,B), + (mod(N,2,0) -> + mreal:set_typed_intervals(B,Type,[0.0..1.0Inf]) + ; true), + power_real1(Type,A,N,B))) + ; setval(unknown_if_unsat,1)@eclipse, + fail). power_real1(Type,A,N,B) :- get_priority(Prio), set_priority(1), + ((Type == real, + is_float_int_number(A), + is_float_int_number(B), + get_sign(B,neg)) + -> + % A neg et N impair + launch_congr(N,1,2), + set_intervals(real,A,[-1.0Inf..0.0]) + ; true), (is_float_int_number(A) -> launch_float_int_number(B) ; true), @@ -16813,55 +16956,55 @@ check_other_odd_power_ineqs_from_res(Type,Pow,Val,ValPow) :- power_real_inst(Type,Val1,N,Val,Continue) :- - (float(Val1) -> - power_real_value(Type,Val1,N,L,H), - %% lance une rbox en mode real si L <> H - %% sinon L=H et instanciation de Val - set_interval_box(Val,L,H), + (float(Val1) -> + power_real_value(Type,Val1,N,L,H), + % lance une rbox en mode real si L <> H + % sinon L=H et instanciation de Val + set_interval_box(Val,L,H), (var(Val) -> check_rbox_cstrs(3,power_real(Type,Val1,N,Val)) ; true) - ; (float(Val) -> - % on verifie l atteignabilite - abs(Val,AVal), - check_reachable_from_pow0(Type,AVal,N,Unreachable,ALow,AHigh,_), - (nonvar(Unreachable) -> - Type == real, - (Val < 0.0 -> - Low is -AHigh, - High is -ALow, - mreal:set_typed_intervals(Val1,Type,[Low..High]), - launch_box(Val1), + ; (float(Val) -> + % on verifie l atteignabilite + abs(Val,AVal), + check_reachable_from_pow0(Type,AVal,N,Unreachable,ALow,AHigh,_), + (nonvar(Unreachable) -> + Type == real, + (Val < 0.0 -> + Low is -AHigh, + High is -ALow, + mreal:set_typed_intervals(Val1,Type,[Low..High]), + launch_box(Val1), (var(Val1) -> check_rbox_cstrs(3,inv_power_real(Type,Val,N, Val1)) ; true) - ; Low = ALow, - High = AHigh, - (mod(N,2,1) -> - mreal:set_typed_intervals(Val1,Type,[Low..High]), - launch_box(Val1), + ; Low = ALow, + High = AHigh, + (mod(N,2,1) -> + mreal:set_typed_intervals(Val1,Type,[Low..High]), + launch_box(Val1), (var(Val1) -> check_rbox_cstrs(3,inv_power_real(Type,Val,N, Val1)) ; true) - ; OpLow is norm_zero_op(Type,High), - OpHigh is norm_zero_op(Type,Low), - mreal:set_typed_intervals(Val1,Type,[OpLow..OpHigh,Low..High]), - mreal:dvar_range(Val1,L,H), - ((L >= 0.0; - H =< 0.0) - -> - launch_box(Val1), + ; OpLow is norm_zero_op(Type,High), + OpHigh is norm_zero_op(Type,Low), + mreal:set_typed_intervals(Val1,Type,[OpLow..OpHigh,Low..High]), + mreal:dvar_range(Val1,L,H), + ((L >= 0.0; + H =< 0.0) + -> + launch_box(Val1), (var(Val1) -> check_rbox_cstrs(3,inv_power_real(Type,Val,N, Val1)) ; true) - ; Continue = 1))) - ; inv_power_real_interval(Type,Val,N,LInter1,[]), - list_to_intervals(Type,LInter1,NLInter1), - mreal:set_typed_intervals(Val1,Type,NLInter1)) - ; Continue = 1)). + ; Continue = 1))) + ; inv_power_real_interval(Type,Val,N,LInter1,[]), + list_to_intervals(Type,LInter1,NLInter1), + mreal:set_typed_intervals(Val1,Type,NLInter1)) + ; Continue = 1)). power_real_rec(Type,Val1,N,Val) :- mreal:dvar_domain(Val1,Dom1), @@ -16889,7 +17032,6 @@ power_real_rec(Type,Val1,N,Val,Dom1,Dom) :- true ; power_real_rec(Type,Val1,N,Val,NewDom1,NewDom)). - %% Typage et calcul de la projection directe %% Utilise aussi pour l'evaluation power_real_interval(A,2,B) ?- !, @@ -16910,11 +17052,11 @@ power_real_interval_type(Type,A,N,B) :- ; set_lazy_domain(Type,B))). power_real_interval(_,A,0,B) ?- !, - protected_unify(B = 1.0). + protected_unify(B;1.0). power_real_interval(Type,A,1,B) ?- !, % set_lazy_domain(Type,A), mreal:set_typed_intervals(A,Type,[-1.0Inf..1.0Inf]), - protected_unify(B = A). + protected_unify(B,A). power_real_interval(Type,A,N,B) :- N > 1, ((Type == real, @@ -16994,12 +17136,33 @@ power_real_value(0.0,N,0.0,0.0) :- !. power_real_value(Val,N,L,H) :- pow_real_min_max(Val,N,L,H). +pow_real_min_max(0.0,N,L,H) ?- !, + (N == 0 -> + L = 1.0, + H = 1.0 + ; L = 0.0, + H = 0.0). +pow_real_min_max(1.0,N,L,H) ?- !, + L = 1.0, + H = 1.0. +pow_real_min_max(-1.0,N,L,H) ?- !, + (N mod 2 =:= 0 -> + L = 1.0, + H = 1.0 + ; L = -1.0, + H = -1.0). pow_real_min_max(Val,N,L,H) :- rational(Val,RatVal), power_rat(RatVal,N,Rat), float_of_rat(real,rtn,Rat,L), float_of_rat(real,rtp,Rat,H). +check_max_exponent(Var,N) :- + mreal:dvar_range(Var,L,H), + Abs is max(abs(L),abs(H)), + log2(Abs,LAbs), + ceiling(N * LAbs) < 10000. + power_rat(RatVal,N,Rat) :- numerator(RatVal,Num), RNum is Num^integer(N), @@ -17008,21 +17171,27 @@ power_rat(RatVal,N,Rat) :- Rat is rational(RNum)/rational(RDen). power_real_min(real,Val,N,L) :- !, + pow_real_min_max(Val,N,L,_). +/* rational(Val,RatVal), power_rat(RatVal,N,Rat), float_of_rat(real,rtn,Rat,L). +*/ power_real_min(Type,Val,N,L) :- power_real_value(Type,Val,N,L,_). power_real_max(real,Val,N,H) :- !, + pow_real_min_max(Val,N,_,H). +/* rational(Val,RatVal), power_rat(RatVal,N,Rat), float_of_rat(real,rtp,Rat,H). +*/ power_real_max(Type,Val,N,H) :- power_real_value(Type,Val,N,_,H). - +% ???? inv_power_real_interval_list(Type,[],N,[]). inv_power_real_interval_list(Type,[I|L],N,NL) :- inv_power_real_interval(Type,I,N,NL,ENL), @@ -17270,18 +17439,16 @@ choose_start_narrow_pow(Type,ValpInvN0,Delta,Val,N,OEnd,Start,End) :- ; Start = Start0, End = OEnd). - - -min_inv_power_real(Type,0.0,N,Min) :- !, - max_inv_power_real(Type,0.0,N,Max), - Min is -Max. min_inv_power_real(real,Val,N,Min) :- !, - check_reachable_from_pow0(Type,Val,N,Unreachable,Min0,_,HMin), + check_reachable_from_pow0(real,Val,N,Unreachable,Min0,_,HMin), (nonvar(Unreachable) -> Min = Min0 ; % en real HMin est le seul a atteindre Val (Err == 0) Min = HMin). % double ou simple +min_inv_power_real(Type,0.0,N,Min) ?- !, + max_inv_power_real(Type,0.0,N,Max), + Min is -Max. min_inv_power_real(Type,Val,N,Min) :- check_reachable_from_pow0(Type,Val,N,Unreachable,Min0,Max0,HMin), (nonvar(Unreachable) -> @@ -17398,6 +17565,7 @@ square_real(Type,A,B) :- check_no_float_error(Type,(A,B)), same_float_int_number_status(Type,A,B), square_real_interval(Type,A,B), + ((member(Susp,LS), (Goal = add_real1(real,X,Y,AA), FG = add_real; @@ -19091,13 +19259,14 @@ abs_val_real_bis(Type,Val,Abs) :- (var(Continue1) -> true ; ((Type == real, - is_float_int_number(A)) + is_float_int_number(Val)) -> congr_abs_directe(Val,Abs,Stop), (var(Stop) -> congr_abs_inverse(Val,Abs,Stop) ; true) ; true), + check_dist_abs_mult_div(Type,Val,Abs,Stop), (var(Stop) -> % Propagation de Val vers Abs abs_val_real_interval(Type,Val,Abs), @@ -19111,6 +19280,27 @@ abs_val_real_bis(Type,Val,Abs) :- check_before_susp_abs_val_real(Type,Val,Abs) ; true))). +check_dist_abs_mult_div(Type,Val,Abs,1) ?- !. +check_dist_abs_mult_div(real,Val,Abs,Stop) ?- !, + get_saved_cstr_suspensions(LS), + ((member((S,G),LS), + (G = mult_real1(real,A,B,VVal); % abs(A*B) = abs(A)*abs(B) + G = div_real1(real,A,B,VVal); % abs(A/B) = abs(A)/abs(B) + G = truncate_bis(real,A,VVal)), % vers 0, abs(truncate(A)) = truncate(abs(A)) + VVal == Val) + -> + % Pas de Stop, on sature + functor(G,FG,Ar), + (Ar == 4 -> + % mult|div + NG0 =.. [FG,real,AbsA,AbsB,Abs], + NG = (abs_val_real_bis(real,B,AbsB),NG0) + ; NG =.. [FG,real,AbsA,Abs]), + call(spy_here)@eclipse, + call_priority((abs_val_real1(Type,A,AbsA),NG),2) + ; true). +check_dist_abs_mult_div(Type,Val,Abs,_). + abs_val_real_inst(Type,Val,Abs,Continue) :- (number(Val) -> Abs0 is abs(Val), @@ -19688,14 +19878,22 @@ fp_eq1(Type,A,B) :- kill_suspension(S), protected_unify(Bool1,1) ; true), - mreal:get_intervals(A,IA), - mreal:get_intervals(B,IB), - intervals_intersection(Type,IA,IB,Inter), - % Inter peut etre vide si zeros - NInter = [-0.0 .. 0.0|Inter], - set_typed_intervals(A,Type,NInter), - set_typed_intervals(B,Type,NInter), + ((is_op_real(Type,A,BB), + B == BB) + -> + % NEW + Zero = 1, + % en real on obtient 0.0 + NInter = [-0.0 .. 0.0] + ; mreal:get_intervals(A,IA), + mreal:get_intervals(B,IB), + intervals_intersection(Type,IA,IB,Inter), + % Inter peut etre vide si zeros + NInter = [-0.0 .. 0.0|Inter]), + set_intervals(Type,A,NInter), + set_intervals(Type,B,NInter), ((A == B; + nonvar(Zero), number(A); number(B)) -> @@ -19922,12 +20120,12 @@ check_geq_real(_,_,_,1,_) ?- !. check_geq_real(Type,A,B,_,Suspend) :- (A == B -> true - ; geq_real_number_box(Type,A,B,Continue), - (var(Continue) -> + ; mreal:mindomain(A,MinA), + mreal:maxdomain(B,MaxB), + (MinA >= MaxB -> true - ; mreal:mindomain(A,MinA), - mreal:maxdomain(B,MaxB), - (MinA >= MaxB -> + ; geq_real_number_box(Type,A,B,Continue), + (var(Continue) -> true ; Suspend = 1))). @@ -20281,17 +20479,17 @@ gt_real_int_ineq(A,B). check_gt_real(_,_,_,1,_) ?- !. check_gt_real(Type,A,B,_,Suspend) :- A \== B, - % En "real", on ne doit pas reduire trop le domaine - % d'un intervalle par rapport a une valeur - % sinon, l'ordre des contraintes influe sur le resultat - % On doit donc faire comme pour geq_real, mais en conservant - % le gt_real quand on s'est freine. - gt_real_number_box(Type,A,B,Continue), - (var(Continue) -> + mreal:mindomain(A,MinA), + mreal:maxdomain(B,MaxB), + (MinA > MaxB -> true - ; mreal:mindomain(A,MinA), - mreal:maxdomain(B,MaxB), - (MinA > MaxB -> + ; % En "real", on ne doit pas reduire trop le domaine + % d'un intervalle par rapport a une valeur + % sinon, l'ordre des contraintes influe sur le resultat + % On doit donc faire comme pour geq_real, mais en conservant + % le gt_real quand on s'est freine. + gt_real_number_box(Type,A,B,Continue), + (var(Continue) -> true ; Suspend = 1)). diff --git a/Src/COLIBRI/smt_import.pl b/Src/COLIBRI/smt_import.pl index 1df6acae2f76055a806f4d436c2988af3a1e5e5c..51496686c66e1dd460c1d86e610dac4981a715e4 100644 --- a/Src/COLIBRI/smt_import.pl +++ b/Src/COLIBRI/smt_import.pl @@ -9,9 +9,41 @@ % pour indiquer une abstaction de forall/exists :- setval(quantifier,0). +:- (current_array(quant_abs,_) -> + true + ; local reference(quant_abs)). +:- export quant_abs/1. +quant_abs(Expr) :- + setval(quantifier,1), + (var(Expr) -> + Var = Expr, + protected_set_var_name(Var,"ColQuant"), + int_vars(bool,Var) + ; (number(Expr) -> + (occurs(Expr,(0,1)) -> + Var = Expr + ; exit_block(syntax)) + ; Var = 1, + call(as(Var,bool) #= as(Expr,bool)))), + getval(quant_abs,TL), + (TL == 0 -> + NTL = [] + ; NTL = TL), + NewTL = [Var|NTL], + setval(quant_abs,NewTL). +:- export get_quant_abs/1. +get_quant_abs(NTL) :- + getval(quant_abs,TL), + (TL == 0 -> + NTL = [] + ; NTL = TL). +:- export check_quant_abs/0. +check_quant_abs :- + get_quant_abs(TL), + not occurs(0,TL). + % pour activer le scrambler en mode test :- setval(scrambler,0)@eclipse. - :- set_stream_property(error,flush,end_of_line). :- include([new_parser_builtins]). @@ -39,6 +71,8 @@ parse_smtlib_file(File,Res) :- % defaut pour la simulation des entiers non bornes getval(def_real_for_int,RI), setval(real_for_int,RI)@eclipse, + setval(quantifier,0), + setval(unknown_if_unsat,0)@eclipse, get_flag(hostarch,ARCH), ((ARCH == "i386_nt"; ARCH == "x86_64_nt") @@ -106,6 +140,12 @@ dolmen_to_colibri_term(error(String),_) ?- !, concat_string(["(error \"",NString,"\")"],Error), writeln(error,Error), exit_block(syntax). +dolmen_to_colibri_term(get_info(String),Term) ?- !, + (getval(no_dolmen_warning,1)@eclipse -> + true + ; concat_string(["(unsupported (get-info \"",String,"\"))"],Error), + writeln(error,Error)), + Term = 'set-info'("Info",""). dolmen_to_colibri_term(warn(String),Term) ?- !, (getval(no_dolmen_warning,1)@eclipse -> true @@ -693,8 +733,19 @@ check_sat0 :- ; writeln(output,Diag)). check_sat_vars :- -% not not check_sat_vars0. - check_sat_vars0. + (getval(quantifier,1) -> + % pas fiable ? + (check_quant_abs -> + % sat fiable pour l'instant + setval(unknown_quantifier_abstraction,0)@eclipse, + check_sat_vars0 + ; setval(diag_code,(unknown,2))@eclipse) + ; (getval(smt_status,unsat)@eclipse -> + writeln(error,wrong_sat), + setval(diag_code,(unknown,2))@eclipse + ; setval(unknown_quantifier_abstraction,0)@eclipse, + check_sat_vars0)). + check_sat_vars0 :- init_real_cst, init_seen_expr, @@ -709,25 +760,27 @@ check_sat_vars0 :- CV = V ; CV = as(V,Type))), (foreach(Goal,Goals) do - (fail,check_only_real_box_rat(Goal) -> - % BUG rationnels !! - true - ; block((call(Goal) -> - true - ; spy_here, - call(Goal)), - Tag, - (exit_block(Tag), - spy_here, - call(Goal))))), + block((call(Goal) -> + true + ; spy_here, + call(Goal)), + Tag, + (exit_block(Tag), + spy_here, + call(Goal)))), setval(diag_code,(sat,1))@eclipse, delayed_goals(NGoals), - term_variables(NGoals,GoalsVars), - (foreach(GV,GoalsVars), - foreach((GV,0,[]),NGoalsVars) do - trans_no_rat(GV)), - once solve_cstrs_list([NGoalsVars]), + (NGoals == [] -> + true + ; %writeln(output,NGoals), + %halt, + term_variables(NGoals,GoalsVars), + (foreach(GV,GoalsVars), + foreach((GV,0,[]),NGoalsVars) do + trans_no_rat(GV)), + seed(0), + once solve_cstrs_list([NGoalsVars])), % pas de residue,sinon wrong_sat suspensions(LSusp), @@ -1637,7 +1690,7 @@ defined_smt_func(F/Ar,IArgs,Type,IExpr) :- -> NIArg = IArg ; NIArg = as(IArg,IArgType)), - call(spy_here)@eclipse, + % call(spy_here)@eclipse, (nonvar(IArgType) -> findall(Sort,cgiveInstanceAndPath(sort(_),IArgType, sort(Sort),_),LSs), @@ -1667,6 +1720,8 @@ restore_seen_expr(SeenExpr) :- setval(seen_expr,SeenExpr). add_seen_expr(let(_,_),_,_) ?- !. +add_seen_expr(exists(_,_),_,_) ?- !. +add_seen_expr(forall(_,_),_,_) ?- !. add_seen_expr(Expr,IExpr,Type) :- getval(in_let,0), compound(Expr), @@ -1683,6 +1738,8 @@ add_seen_expr(Expr,IExpr,Type). check_seen_expr(let(_,_),_,_) ?- !, fail. +check_seen_expr(new_quantified_var(_,_),_,_) ?- !, + fail. check_seen_expr(forall(_,_),_,_) ?- !, fail. check_seen_expr(exists(_,_),_,_) ?- !, @@ -1904,12 +1961,15 @@ smt_interp(Expr,IExpr,Type) :- add_seen_expr(Expr,IExpr,Type)). :- setval(logic,"ALL")@eclipse. +:- setval(in_assert,0). % INTERPRETATION smt_interp0(exit,true,bool) :- !. smt_interp0('set-logic'(SLogic),true,bool) :- !, setval(logic,SLogic)@eclipse. -smt_interp0('get-info'(Key),get_info(Key),bool) :- !. +smt_interp0('get-info'(Key),true,bool) :- + call(spy_here)@eclipse, + !. smt_interp0('set-info'(K,S),true,bool) :- !, (K == ':status' -> setval(smt_status,S)@eclipse @@ -1948,6 +2008,7 @@ smt_interp0(set_default_int_bounds(L,H),set_default_int_bounds(Low,High),bool) ; unsupported_error("set_default_int_bounds needs min/max integer values")). smt_interp0(assert(A0),NewDecl,bool) :- !, + setval(in_assert,true), getval(decl,OD), setval(decl,End-End), reset_let_vars, @@ -2005,7 +2066,8 @@ smt_interp0(assert(A0),NewDecl,bool) :- !, ; NDecl = Decl))), reset_let_vars, remove_true_decl(NDecl,NewDecl), - setval(decl,OD). + setval(decl,OD), + setval(in_assert,0). smt_interp0(array_def(Var,Def),array_def(IVar,IDef),bool) :- !, smt_interp(Var,IVar,Type), smt_interp(Def,IDef,Type). @@ -2203,7 +2265,10 @@ smt_interp0(let(Pairs,Expr),IExprLet,Type) :- !, ; OK = IK), smt_interp0(EV,IEV,TypeV), check_eval(TypeV,IEV,Res), - (ground(Res) -> + ((ground(Res), + remove_upper_as(Res,Res0,_), + Res0 \= new_quantified_var(_,_)) + -> NV = Res, OT = IT ; OT = [(NV,TypeV,IEV)|IT])), @@ -2218,14 +2283,27 @@ smt_interp0(let(Pairs,Expr),IExprLet,Type) :- !, (foreach((V,ONV,OTypeV),Known) do add_let_var(V,NV,TypeV))), setval(in_let,OIL). -smt_interp0(forall(L,E),Res,bool) :- !, + +% forall Vars P = not(exists Vars not(P)) +smt_interp0(forall(Vars,P),Res,bool) :- !, %unsupported_error(forall). % Abstraction, plus de sat fiable - new_quantifier_abstraction(Res). -smt_interp0(exists(L,E),Res,bool) :- !, + % new_quantifier_abstraction(Res). + call(spy_here)@eclipse, + smt_interp(exists(Vars,not(P)),NotRes,bool), + Res = neg(NotRes). +smt_interp0(exists(Vars,P),Res,bool) :- !, %unsupported_error(exists). % Abstraction, plus de sat fiable - new_quantifier_abstraction(Res). + %new_quantifier_abstraction(Res). + call(spy_here)@eclipse, + (foreach((V,Type),Vars), + foreach((V,new_quantified_var(QV,Type)),Pairs) do + true), + smt_interp(let(Pairs,P),Res0,bool), + % pas fiable si R0 false + Res = as(quant_abs(Res0),bool). + smt_interp0(as(Id,Sort),Res,Type) :- !, get_type_from_sort(Sort,Type,_), smt_interp(Id,IId,Type), @@ -2242,7 +2320,6 @@ smt_interp0(A,IA,Type) :- (integer(A) -> rational(A,RA), term_string(RA,SRA), -% IA = realString(SRA) IA = as(realString(SRA),real_int) ; float(A), %?? IA = as(A,real)) @@ -2254,7 +2331,6 @@ smt_interp0(A,IA,Type) :- Type = real_int, rational(A,RA), term_string(RA,SRA), -% IA = realString(SRA) IA = as(realString(SRA),real_int) ; Type = int, IA = A) @@ -2297,11 +2373,16 @@ smt_interp0(Atom,IAtom,Type) :- ; IAtom = Val). smt_interp0(not(A),NegIA,bool) :- !, ((nonvar(A), - A = let(Pairs,Expr)) + remove_upper_as(A,AA,_), + (AA = let(Pairs,Expr), + NA = let(Pairs,not(Expr)); + AA = forall(Pairs,Expr), + NA = exists(Pairs,not(Expr)))) -> - smt_interp(let(Pairs,not(Expr)),NegIA,bool) + smt_interp(NA,NegIA,bool) ; ((nonvar(A), - A = not(B)) + remove_upper_as(A,AA,_), + AA = not(B)) -> smt_interp(B,NegIA,bool) ; ((nonvar(A), @@ -3168,12 +3249,32 @@ smt_interp0(T,IT,Type) :- % instanciation/liaison parametres defined_smt_func(F/Ar,IArgs,Type,IT))), !. +smt_interp0(new_quantified_var(V,Type),IT,IType) ?- !, + IT = as(new_quantified_var(V,IType),IType), + get_type_from_sort(Type,IType,_). + smt_interp0(T,IT,Type) :- compound(T), functor(T,F,Ar), concat_string(["Unknown function:",F,/,Ar],Err), unsupported_error(Err). +/* +new_quantified_var(Type,Res) :- + % On cree une variable + get_decl_type_from_sort(Type,NVar,Decl,IType), + set_var_name(NVar,"ColQuantV"), + protected_get_var_name(NVar,VS), + atom_string(Id,VS), + add_binding(Id,IType,NVar), + (getval(decl,ODecl-End) -> + true + ; setval(decl,End-End), + ODecl = End), + End = (Decl,NEnd), + setval(decl,ODecl-NEnd), + Res = as(Id,Type). + new_quantifier_abstraction(Res) :- setval(quantifier,1), % On cree une variable @@ -3189,7 +3290,7 @@ new_quantifier_abstraction(Res) :- End = (Decl,NEnd), setval(decl,ODecl-NEnd), Res = as(NVar,bool). - +*/ is_quantifier_abstraction(Var) :- var(Var), protected_get_var_name(Var,VS), @@ -3198,6 +3299,8 @@ is_quantifier_abstraction(Var) :- % on garde les realString check_eval(Type,realString(Str),RE) ?- !, RE = as(realString(Str),Type). +check_eval(Type,new_quantified_var(V,T),RE) ?- !, + RE = as(new_quantified_var(V,T),Type). % on traverse les as check_eval(_Type,as(E,Type),RE) ?- !, check_eval(Type,E,RE). @@ -3717,7 +3820,7 @@ remove_true_decl((Beg,End),Decl) ?- !, Decl0 = as(1,bool)) -> remove_true_decl(Beg,Decl) - ; remove_true_decl(End,Decl1), + ; remove_true_decl(Beg,Decl1), make_conj(Decl0,Decl1,Decl)). remove_true_decl(D,D). diff --git a/Src/COLIBRI/solve.pl b/Src/COLIBRI/solve.pl index 5904f11c12b2b6b9e09ebc0363a85b73b7370608..759b7a66a6ce6f39ee6855a8aa6a5a232818da61 100644 --- a/Src/COLIBRI/solve.pl +++ b/Src/COLIBRI/solve.pl @@ -158,6 +158,8 @@ trans_col(or_seq_reif(X,_,Y,Z),(X or Y) #= Z). % TODO : ajouter declaration type pour BV unfold_int_expr_block(E,D,C,T,R) :- get_priority(P), + use_norm_expr, +% no_norm_expr, call_priority( block(once unfold_int_expr(E,D,C,T,R), Tag, @@ -170,6 +172,7 @@ unfold_int_expr_block(E,D,C,T,R) :- set_priority(P), wake. + '#:'(L,I) :- (I == bool -> mfd:(L :: [0,1]) @@ -178,39 +181,8 @@ unfold_int_expr_block(E,D,C,T,R) :- '#='(L,R) :- unfold_int_expr_block(L #= R,0,C,bool,1), call(C). -/* -'#='(L,R) :- - (var(L) -> - get_variable_type(L,Type), - ((Type = array(_,_), - occurs(L,R)) - -> - unfold_int_expr_block(L #= R,0,C,bool,1) - ; unfold_int_expr_block(R,0,C,Type,L)) - ; (L = as(V,Type) -> - ((var(V), - Type = array(_,_), - occurs(V,R)) - -> - unfold_int_expr_block(L #= R,0,C,bool,1) - ; unfold_int_expr_block(R,0,C,Type,V)) - ; (var(R) -> - get_variable_type(R,Type), - ((Type = array(_,_), - occurs(R,L)) - -> - unfold_int_expr_block(L #= R,0,C,bool,1) - ; unfold_int_expr_block(L,0,C,Type,R)) - ; (R = as(V,Type) -> - ((var(V), - Type = array(_,_), - occurs(V,R)) - -> - unfold_int_expr_block(L #= R,0,C,bool,1) - ; unfold_int_expr_block(L,0,C,Type,V)) - ; unfold_int_expr_block(L #= R,0,C,bool,1))))), - call(C). -*/% version specifique pour les definitions de tableaux + +% version specifique pour les definitions de tableaux array_def(Var,Def) :- (((var(Var),V = Var; Var = as(V,Type),var(V)), @@ -428,7 +400,7 @@ set_int_type(sort(S),X) ?- !, set_int_type(rnd,X) ?- !, rnd_vars(X). set_int_type(Type,X) :- - call(spy_here)@eclipse, + % call(spy_here)@eclipse, write(error,"Type error for variable "), writeln(error,X:Type), exit_block(syntax). @@ -449,7 +421,7 @@ add_typed_var(V,Type) :- (hash_get(Hash,VA,(_,Type0)) -> (Type == Type0 -> true - ; call(spy_here)@eclipse, + ; % call(spy_here)@eclipse, write(error,"Type error for variable "), writeln(error,V:Type0), exit_block(syntax)) @@ -474,13 +446,15 @@ get_variable_from_name(Name,Var) :- protected_get_var_name(V,Name) :- (var(V) -> get_var_name(V,Name) - ; call(spy_here)@eclipse, + ; % call(spy_here)@eclipse, fail,writeln(error,"Error: variable needed as first argument of get_var_name/2"), exit_block(syntax)). protected_set_var_name(V,Name) :- (var(V) -> - set_var_name(V,Name) - ; call(spy_here)@eclipse, + (protected_get_var_name(V,Name0) -> + true + ; set_var_name(V,Name)) + ; % call(spy_here)@eclipse, writeln(error,"Error: variable needed as first argument of set_var_name/2"), exit_block(syntax)). @@ -498,7 +472,7 @@ check_int_var_type(V,Type) :- hash_get(Hash,VA,(_,Type0)), (compatible_types(Type,Type0) -> true - ; call(spy_here)@eclipse, + ; % call(spy_here)@eclipse, write(error,"Type error for variable "), writeln(error,V:Type0), exit_block(syntax)). @@ -519,14 +493,14 @@ compatible_types(T1,T2) :- get_int_var_type(V,Type) :- getval(typed_vars,Hash), (Hash == 0 -> - call(spy_here)@eclipse, + % call(spy_here)@eclipse, writeln(error,"Type unknown for variable":X), exit_block(syntax) ; get_variable_atom(V,VA), (hash_get(Hash,VA,(_,Type0)) -> (compatible_types(Type,Type0) -> true - ; call(spy_here)@eclipse, + ; % call(spy_here)@eclipse, write(error,"Type error for variable "), writeln(error,VA:Type0), exit_block(syntax)) @@ -536,7 +510,7 @@ get_int_var_type(V,Type) :- get_type(V,_)) -> true - ; call(spy_here)@eclipse, + ; % call(spy_here)@eclipse, writeln(error,"Type unknown for variable":X), exit_block(syntax)))). @@ -756,18 +730,6 @@ power1(uint(N),D,A,P,B,UO) :- insert_dep_inst(dep(A,D,[UO])), insert_dep_inst(dep(B,D,[UO])). -power_real0(Type,A,P,B) :- - set_lazy_domain(Type,A), - set_lazy_domain(int,P), - mfd:dvar_remove_smaller(P,0), - set_lazy_domain(Type,B), - (is_float_int_number(A) -> - launch_float_int_number(B) - ; true), - (var(P) -> - my_suspend(power_real0(Type,A,P,B),0,P->suspend:inst) - ; power_real(Type,A,P,B)). - make_conj(true,C,NC) ?- !, NC = C. make_conj(C,true,NC) ?- !, @@ -800,19 +762,30 @@ unfold_int_expr(X,_D,Cstr,Type,R) :- nonvar(Type), int_vars(Type,X)) -> - blocked_unify(X = R) - ; call(spy_here)@eclipse, + blocked_call(X = R) + ; % call(spy_here)@eclipse, writeln(error,"Type unknown for variable":X), exit_block(syntax)), Cstr = true. %insert_dep_inst(inst_cstr(D,X)). +unfold_int_expr(quant_abs(Let),D,Cstr,Type,R) ?- !, + Type = bool, + !, + unfold_int_expr(Let,D,Cstr0,Type,R), + % au début pour le nom ColQuantX + make_conj(quant_abs(R),Cstr0,Cstr). +unfold_int_expr(new_quantified_var(R0,Type0),D,Cstr,Type,R) ?- !, +% call(spy_here)@eclipse, + Type = Type0, + unfold_int_expr(R0,D,Cstr,Type,R). unfold_int_expr(X,_,Cstr,Type,R) :- integer(X),!, (nonvar(Type) -> Cstr = true, - to_int(Type,X,R0), - blocked_unify(R,R0) - ; % A typer plus tard +% to_int(Type,X,R0), +% blocked_unify(R,R0) + blocked_call(to_int(Type,X,R)) + ; % A typer plus tard Cstr = to_int(Type,X,R)). unfold_int_expr(as(EA,Type0),D,Cstr,Type,R) ?- !, Type = Type0, @@ -884,8 +857,9 @@ unfold_int_expr(select(EA,EI), D, Cstr, Type, R) ?- let_int_vars(TI,I)), !, % les resultats de select sont eligibles - eval_select(TA,A,I,R0,Start,CES), - blocked_unify(R0,R), +% eval_select(TA,A,I,R0,Start,CES), +% blocked_unify(R0,R), + blocked_call(eval_select(TA,A,I,R,Start,CES)), make_conj(CI,CA,CIA), let_int_vars(Type,R), % insert_dep_inst(dep(R,D,[I,Start])), @@ -926,8 +900,8 @@ unfold_int_expr(bvand(Size,EA,EB), D, Cstr, Type, R) ?- ; ((number(A), number(B)) -> - bvand(Size,A,B,R0), - blocked_unify(R,R0), + blocked_call(bvand(Size,A,B,R)), +% blocked_unify(R,R0), Cstr = CAB ; set_int_type(Type,A), set_int_type(Type,B), @@ -950,8 +924,8 @@ unfold_int_expr(bvor(Size,EA,EB), D, Cstr, Type, R) ?- ((number(A), number(B)) -> - bvor(Size,A,B,R0), - blocked_unify(R,R0), + blocked_call(bvor(Size,A,B,R)), +% blocked_unify(R,R0), Cstr = CAB ; set_int_type(Type,A), set_int_type(Type,B), @@ -976,8 +950,8 @@ unfold_int_expr(xorb(Size,EA,EB), D, Cstr, Type, R) ?- ((number(A), number(B)) -> - bvxor(Size,A,B,R0), - blocked_unify(R,R0), + blocked_call(bvxor(Size,A,B,R)), +% blocked_unify(R,R0), Cstr = CAB ; set_int_type(Type,A), set_int_type(Type,B), @@ -993,8 +967,13 @@ unfold_int_expr(bvnot(Size,EA), D, Cstr, Type, R) ?- Type = uint(Size), !, unfold_int_expr(EA,D,CA,Type,A), + % on sature au ou + Max is 2^Size - 1, + unfold_int_expr(bvsub(Size,as(Max,uint(Size)),EA),D,CB,Type,CR), + blocked_unify(R,CR), insert_dep_inst(dep(R,D,[A])), - make_conj(CA, bvnot(Size,A,R),Cstr). + make_conj(CA,CB,CAB), + make_conj(CAB,bvnot(Size,A,R),Cstr). unfold_int_expr(bvnand(Size,EA,EB), D, Cstr, Type, R) ?- !, unfold_int_expr(bvnot(Size,bvand(Size,EA,EB)), D, Cstr, Type, R). @@ -1018,8 +997,8 @@ unfold_int_expr(bvcomp(Size,EA,EB), D, Cstr, RType, R) ?- ((number(A), number(B)) -> - eq_int_reif(Type,A,B,R0), - blocked_unify(R,R0), + blocked_call(eq_int_reif(Type,A,B,R)), +% blocked_unify(R,R0), Cstr = CAB ; set_int_type(Type,R), get_reif_var_depth_from_labchoice(DD), @@ -1040,12 +1019,16 @@ unfold_int_expr(bvneg(Size,EA), D, Cstr, Type, R) ?- !, integer(Size), Size > 0, Type = uint(Size), - % ça risque pas de fail parce qu'on est en unsigned? - (Size == 1 -> - get_reif_var_depth_from_labchoice(DD), - insert_dep_inst(dep(inst_cstr(DD,R))) - ; true), - unfold_int_expr(-EA, D, Cstr, Type, R). + % ça risque pas de fail parce qu'on est en unsigned + get_norm_expr(Norm), + (normalize_expr(Norm,Type,bvneg(Size,EA),D,Cstr,R,Goal) -> + call(Goal) + ; (Size == 1 -> + get_reif_var_depth_from_labchoice(DD), + insert_dep_inst(dep(inst_cstr(DD,R))) + ; true), + unfold_int_expr(-EA, D, Cstr, Type, R), + set_norm_expr(Norm)). /* Size = 8, int_vars(uint(Size),[A,B]), @@ -1057,7 +1040,11 @@ unfold_int_expr(bvadd(Size,EA,EB), D, Cstr, Type, R) ?- Size > 0, !, Type = uint(Size), - unfold_int_expr(EA + EB, D, Cstr, Type, R). + get_norm_expr(Norm), + (normalize_expr(Norm,Type,bvadd(Size,EA,EB),D,Cstr,R,Goal) -> + call(Goal) + ; unfold_int_expr(EA + EB, D, Cstr, Type, R), + set_norm_expr(Norm)). /* Size = 8, int_vars(uint(Size),[A,B]), @@ -1077,7 +1064,11 @@ unfold_int_expr(bvsub(Size,EA,EB), D, Cstr, Type, R) ?- Size > 0, !, Type = uint(Size), - unfold_int_expr(EA - EB, D, Cstr, Type, R). + get_norm_expr(Norm), + (normalize_expr(Norm,Type,bvsub(Size,EA,EB),D,Cstr,R,Goal) -> + call(Goal) + ; unfold_int_expr(EA - EB, D, Cstr, Type, R), + set_norm_expr(Norm)). /* @@ -1090,7 +1081,11 @@ unfold_int_expr(bvmul(Size,EA,EB), D, Cstr, Type, R) ?- Size > 0, !, Type = uint(Size), - unfold_int_expr(EA * EB, D, Cstr, Type, R). + get_norm_expr(Norm), + (normalize_expr(Norm,Type,bvmul(Size,EA,EB),D,Cstr,R,Goal) -> + call(Goal) + ; unfold_int_expr(EA * EB, D, Cstr, Type, R), + set_norm_expr(Norm)). /* Size = 6, int_vars(uint(Size),[A,B,Q]), @@ -1297,6 +1292,12 @@ unfold_int_expr(bvashr(Size,EA,EB), D, Cstr, Type, R) ?- integer(Size), Size > 0, Type = uint(Size), + Sm1 is Size - 1, + unfold_int_expr(ite(extract(Size,Sm1,Sm1,EA) #= as(0,uint(1)), + bvlshr(Size,EA,EB), + bvnot(Size,bvlshr(Size,bvnot(Size,EA),EB))), + D,Cstr,Type,R). +/* unfold_int_expr(EA,ND,CA,Type,A), unfold_int_expr(EB,ND,CB,Type,B), !, @@ -1310,6 +1311,7 @@ unfold_int_expr(bvashr(Size,EA,EB), D, Cstr, Type, R) ?- ; set_int_type(Type,R), insert_dep_inst(dep(R,D,[A,B])), make_conj(CAB,bvasr(Size,A,B,R),Cstr)). +*/ /* % preuve bvudiv @@ -1340,8 +1342,8 @@ unfold_int_expr(bvlshr(Size,EA,EB), D, Cstr, Type, R) ?- ((number(A), number(B)) -> - bvlsr(Size,A,B,R0), - blocked_unify(R,R0), + blocked_call(bvlsr(Size,A,B,R)), +% blocked_unify(R,R0), Cstr = CAB ; set_int_type(Type,R), insert_dep_inst(dep(R,D,[A,B])), @@ -1379,8 +1381,8 @@ unfold_int_expr(bvshl(Size,EA,EB), D, Cstr, Type, R) ?- ((number(A), number(B)) -> - bvsl(Size,A,B,R0), - blocked_unify(R,R0), + blocked_call(bvsl(Size,A,B,R)), +% blocked_unify(R,R0), Cstr = CAB ; insert_dep_inst(dep(R,D,[A,B])), make_conj(CAB,bvsl(Size,A,B,R),Cstr)). @@ -1425,8 +1427,12 @@ solve_cstrs. */ unfold_int_expr(extract(SizeA,I,J,EA), D, Cstr, Type, R) ?- Type = uint(N), - integer(SizeA), integer(I), integer(J), - SizeA > I, I >= J, J >= 0, + integer(SizeA), + integer(I), + integer(J), + SizeA > I, + I >= J, + J >= 0, N is I - J + 1, ND is D + 1, Type0 = uint(SizeA), @@ -1451,8 +1457,8 @@ unfold_int_expr(rotate_left(Size,I,EA), D, Cstr, Type, R) ?- unfold_int_expr(EA,ND,CA,uint(Size),A), !, (integer(A) -> - bvrotatel(Size,I,A,R0), - blocked_unify(R,R0), + blocked_call(bvrotatel(Size,I,A,R)), +% blocked_unify(R,R0), Cstr = CA ; set_int_type(Type,R), insert_dep_inst(dep(R,D,[A])), @@ -1467,8 +1473,8 @@ unfold_int_expr(rotate_right(Size,I,EA), D, Cstr, Type, R) ?- unfold_int_expr(EA,ND,CA,uint(Size),A), !, (integer(A) -> - bvrotater(Size,I,A,R0), - blocked_unify(R,R0), + blocked_call(bvrotater(Size,I,A,R)), +% blocked_unify(R,R0), Cstr = CA ; set_int_type(Type,R), insert_dep_inst(dep(R,D,[A])), @@ -1484,8 +1490,8 @@ unfold_int_expr(repeat(Size,I,EA), D, Cstr, Type, R) ?- !, SizeR is Size * I, (integer(A) -> - repeat(Size,I,A,R0), - blocked_unify(R,R0), + blocked_call(repeat(Size,I,A,R)), +% blocked_unify(R,R0), Cstr = CA ; set_int_type(Type,R), insert_dep_inst(dep(R,D,[A])), @@ -1511,8 +1517,8 @@ unfold_int_expr(zero_extend(Size,I,EA), D, Cstr, Type, R) ?- !, SizeR is Size + I, (integer(A) -> - zero_extend(Size,I,A,R0), - blocked_unify(R,R0), + blocked_call(zero_extend(Size,I,A,R)), +% blocked_unify(R,R0), Cstr = CA ; (I == 0 -> R = A, @@ -1553,8 +1559,8 @@ unfold_int_expr(sign_extend(Size,I,EA), D, Cstr, Type, R) ?- unfold_int_expr(EA,ND,CA,uint(Size),A), !, (integer(A) -> - sign_extend(Size,I,A,R0), - blocked_unify(R,R0), + blocked_call(sign_extend(Size,I,A,R)), +% blocked_unify(R,R0), Cstr = CA ; (I == 0 -> R = A, @@ -1621,7 +1627,6 @@ unfold_int_expr(bvslt(N, EA, EB), D, Cstr, Type, R) ?- bvult(as(A,uint(N)),as(B,uint(N))))), D, Cstr, Type, R). */ - /* Size = 5,PSize is Size - 1, int_vars(uint(Size),(S,T)), @@ -1666,23 +1671,28 @@ unfold_int_expr(bvsgt(N, EA, EB), D, Cstr, Type, R) ?- unfold_int_expr(bvslt(N, EB, EA), D, Cstr, Type, R). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% unfold_int_expr(- EA,D,Cstr,Type,R) ?- - ND is D + 1, - unfold_int_expr(EA,ND,CA,Type,A), - !, - (number(A) -> - opp(Type,D,A,R0,UO), - blocked_unify(R,R0), - Cstr = CA - ; insert_dep_inst(dep(R,D,[A])), - make_conj(CA,opp(Type,D,A,R,UO),Cstr)). + get_norm_expr(Norm), + (normalize_expr(Norm,Type,-EA,D,Cstr,R,Goal) -> + !, + call(Goal) + ; ND is D + 1, + unfold_int_expr(EA,ND,CA,Type,A), + !, + set_norm_expr(Norm), + (number(A) -> + blocked_call(opp(Type,D,A,R,UO)), +% blocked_unify(R,R0), + Cstr = CA + ; insert_dep_inst(dep(R,D,[A])), + make_conj(CA,opp(Type,D,A,R,UO),Cstr))). unfold_int_expr(int(EA),D,Cstr,Type,R) ?- ND is D + 1, unfold_real_expr(EA,ND,CA,RType,A), !, (number(A) -> - cast_real_int(RType,A,R0), - to_int(Type,R0,R1), - blocked_unify(R,R1), + blocked_call((cast_real_int(RType,A,R0), + to_int(Type,R0,R))), +% blocked_unify(R,R1), Cstr = CA ; insert_dep_inst(dep(R,D,[A])), make_conj(CA,(cast_real_int(RType,A,R0),to_int(Type,R0,R)),Cstr)). @@ -1694,8 +1704,8 @@ unfold_int_expr(intN_from_int(N,EA),D,Cstr,Type,R) ?- !, Type = int(N), (number(A) -> - to_intNs(N,A,R0), - blocked_unify(R,R0), + blocked_call(to_intNs(N,A,R)), +% blocked_unify(R,R0), Cstr = CA ; insert_dep_inst(dep(R,D,[A])), make_conj(CA,to_intNs(N,A,R),Cstr)). @@ -1709,8 +1719,8 @@ unfold_int_expr(intN_from_uint(N,EA),D,Cstr,Type,R) ?- !, Type = int(N), (number(A) -> - uintN_to_intN(N,A,R0,UO), - blocked_unify(R,R0), + blocked_call(uintN_to_intN(N,A,R,UO)), +% blocked_unify(R,R0), Cstr = CA ; %get_reif_var_depth_from_labchoice(DD), %insert_dep_inst(inst_cstr(DD,UO)), @@ -1726,8 +1736,8 @@ unfold_int_expr(uintN_from_int(N,EA),D,Cstr,Type,R) ?- !, Type = uint(N), (number(A) -> - to_intNu(N,A,R0), - blocked_unify(R,R0), + blocked_call(to_intNu(N,A,R)), +% blocked_unify(R,R0), Cstr = CA ; insert_dep_inst(dep(R,D,[A])), make_conj(CA,to_intNu(N,A,R),Cstr)). @@ -1753,8 +1763,8 @@ unfold_int_expr(uintN_from_intN(N,EA),D,Cstr,Type,R) ?- !, Type = uint(N), (number(A) -> - intN_to_uintN(N,A,R0,UO), - blocked_unify(R,R0), + blocked_call(intN_to_uintN(N,A,R,UO)), +% blocked_unify(R,R0), Cstr = CA ; %get_reif_var_depth_from_labchoice(DD), %insert_dep_inst(inst_cstr(DD,UO)), @@ -1783,8 +1793,8 @@ unfold_int_expr(int_from_real(EA),D,Cstr,Type,R) ?- !, Type = int, (number(A) -> - cast_real_int(real,A,R0), - blocked_unify(R,R0), + blocked_call(cast_real_int(real,A,R)), +% blocked_unify(R,R0), Cstr = CA ; insert_dep_inst(dep(R,D,[A])), make_conj(CA,cast_real_int(real,A,R),Cstr)). @@ -1794,8 +1804,8 @@ unfold_int_expr(int_from_float(EA),D,Cstr,Type,R) ?- !, Type = int, (number(A) -> - cast_real_int(float_simple,A,R0), - blocked_unify(R,R0), + blocked_call(cast_real_int(float_simple,A,R)), +% blocked_unify(R,R0), Cstr = CA ; insert_dep_inst(dep(R,D,[A])), make_conj(CA,cast_real_int(float_simple,A,R),Cstr)). @@ -1817,23 +1827,52 @@ unfold_int_expr(abs(EA),D,Cstr,Type,R) ?- nonvar(Type), !, (number(A) -> - abs_val(Type,D,A,R0,UO), - blocked_unify(R,R0), + blocked_call(abs_val(Type,D,A,R,UO)), +% blocked_unify(R,R0), Cstr = CA ; set_int_type(Type,R), insert_dep_inst(dep(R,D,[A])), make_conj(CA,abs_val(Type,D,A,R,UO),Cstr)). unfold_int_expr(EA + EB,D,Cstr,Type,R) ?- - ((nonvar(EB), - EB = - OpEB) - -> + get_norm_expr(Norm), + (normalize_expr(Norm,Type,EA+EB,D,Cstr,R,Goal) -> !, - unfold_int_expr(EA - OpEB,D,Cstr,Type,R) - ; ((nonvar(EA), - EA = - OpEA) + call(Goal) + ; ((nonvar(EB), + EB = - OpEB) + -> + !, + unfold_int_expr(EA - OpEB,D,Cstr,Type,R) + ; ((nonvar(EA), + EA = - OpEA) + -> + !, + unfold_int_expr(EB - OpEA,D,Cstr,Type,R) + ; ND is D + 1, + unfold_int_expr(EA,ND,CA,Type,A), + unfold_int_expr(EB,ND,CB,Type,B), + !, + make_conj(CA,CB,CAB), + ((number(A), + number(B)) + -> + blocked_call(add(Type,D,A,B,R,UO)), +% blocked_unify(R,R0), + Cstr = CAB + ; set_int_type(Type,R), + insert_dep_inst(dep(R,D,[A,B])), + make_conj(CAB,add(Type,D,A,B,R,UO),Cstr))))), + set_norm_expr(Norm). +unfold_int_expr(EA - EB,D,Cstr,Type,R) ?- + get_norm_expr(Norm), + (normalize_expr(Norm,Type,EA-EB,D,Cstr,R,Goal) -> + !, + call(Goal) + ; ((nonvar(EB), + EB = - OpEB) -> !, - unfold_int_expr(EB - OpEA,D,Cstr,Type,R) + unfold_int_expr(EA + OpEB,D,Cstr,Type,R) ; ND is D + 1, unfold_int_expr(EA,ND,CA,Type,A), unfold_int_expr(EB,ND,CB,Type,B), @@ -1842,32 +1881,14 @@ unfold_int_expr(EA + EB,D,Cstr,Type,R) ?- ((number(A), number(B)) -> - add(Type,D,A,B,R0,UO), - blocked_unify(R,R0), + blocked_call(minus(Type,D,A,B,R,UO)), +% blocked_unify(R,R0), Cstr = CAB ; set_int_type(Type,R), insert_dep_inst(dep(R,D,[A,B])), - make_conj(CAB,add(Type,D,A,B,R,UO),Cstr)))). -unfold_int_expr(EA - EB,D,Cstr,Type,R) ?- - ((nonvar(EB), - EB = - OpEB) - -> - !, - unfold_int_expr(EA + OpEB,D,Cstr,Type,R) - ; ND is D + 1, - unfold_int_expr(EA,ND,CA,Type,A), - unfold_int_expr(EB,ND,CB,Type,B), - !, - make_conj(CA,CB,CAB), - ((number(A), - number(B)) - -> - minus(Type,D,A,B,R0,UO), - blocked_unify(R,R0), - Cstr = CAB - ; set_int_type(Type,R), - insert_dep_inst(dep(R,D,[A,B])), - make_conj(CAB,minus(Type,D,A,B,R,UO),Cstr))). + make_conj(CAB,minus(Type,D,A,B,R,UO),Cstr)))), + set_norm_expr(Norm). +/* unfold_int_expr((EA * EB) * EC,D,Cstr,Type,R) ?- Type == int, (remove_all_as(EA,A), @@ -1887,21 +1908,27 @@ unfold_int_expr((EA * EB) * EC,D,Cstr,Type,R) ?- Z = EB), !, unfold_int_expr(X * (Y * Z),D,Cstr,Type,R). +*/ unfold_int_expr(EA * EB,D,Cstr,Type,R) ?- - ND is D + 1, - unfold_int_expr(EA,ND,CA,Type,A), - unfold_int_expr(EB,ND,CB,Type,B), - !, - make_conj(CA,CB,CAB), - ((number(A), - number(B)) - -> - mult(Type,D,A,B,R0,UO), - blocked_unify(R,R0), - Cstr = CAB - ; set_int_type(Type,R), - insert_dep_inst(dep(R,D,[A,B])), - make_conj(CAB,mult(Type,D,A,B,R,UO),Cstr)). + get_norm_expr(Norm), + (normalize_expr(Norm,Type,EA*EB,D,Cstr,R,Goal) -> + !, + call(Goal) + ; ND is D + 1, + unfold_int_expr(EA,ND,CA,Type,A), + unfold_int_expr(EB,ND,CB,Type,B), + !, + make_conj(CA,CB,CAB), + ((number(A), + number(B)) + -> + blocked_call(mult(Type,D,A,B,R,UO)), +% blocked_unify(R,R0), + Cstr = CAB + ; set_int_type(Type,R), + insert_dep_inst(dep(R,D,[A,B])), + make_conj(CAB,mult(Type,D,A,B,R,UO),Cstr))), + set_norm_expr(Norm). % Surcharge pour les Int ! unfold_int_expr(EA / EB,D,Cstr,Type,R) ?- !, @@ -1989,6 +2016,7 @@ unfold_int_expr(EA mod EB,D,Cstr,Type,R) ?- make_conj(CABCond,chk_undef_ediv_mod(Bool,Type,A,B,Q,R),Cstr). unfold_int_expr(colibri_pow_int(EA,EN),D,Cstr,Type,R) ?- + Type == int, ND is D + 1, unfold_int_expr(EN,ND,CN,int,N), !, @@ -2007,8 +2035,8 @@ unfold_int_expr(EA ^ EN,D,Cstr,Type,R) ?- ((number(A), number(N)) -> - power(Type,D,A,N,R0,UO), - blocked_unify(R,R0), + blocked_call(power(Type,D,A,N,R,UO)), +% blocked_unify(R,R0), Cstr = CAN ; make_conj(CAN,power(Type,D,A,N,R,UO),Cstr)). unfold_int_expr(min(EA,EB),D,Cstr,Type,R) ?- @@ -2021,8 +2049,8 @@ unfold_int_expr(min(EA,EB),D,Cstr,Type,R) ?- ((number(A), number(B)) -> - min_int(A,B,R0), - blocked_unify(R,R0), + blocked_call(min_int(A,B,R)), +% blocked_unify(R,R0), Cstr = CAB ; make_conj(CAB,min_int(A,B,R),Cstr)). unfold_int_expr(max(EA,EB),D,Cstr,Type,R) ?- @@ -2035,8 +2063,8 @@ unfold_int_expr(max(EA,EB),D,Cstr,Type,R) ?- ((number(A), number(B)) -> - max_int(A,B,R0), - blocked_unify(R,R0), + blocked_call(max_int(A,B,R)), +% blocked_unify(R,R0), Cstr = CAB ; make_conj(CAB,max_int(A,B,R),Cstr)). % Les inegalites entieres, les arguments @@ -2222,7 +2250,7 @@ unfold_int_expr(alldiff(Type,L),D,Cstr,Bool,R) :- unfold_int_expr(E,ND,CE,Type,RE) ; % pas de NaN ici (IType == real -> - ensure_not_NaN(RE) %???? + ensure_not_NaN(RE) ; true), unfold_real_expr(E,ND,CE,Type,RE)), insert_dep_inst(dep(RE,ND,[R])), @@ -2460,15 +2488,21 @@ 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, - (number(A),C = A; - number(EA),to_real(Type,EA,C)), + (((Type \== real; + fail,is_float_int_number(B)), + (number(A), + C = A; + number(EA), + to_real(Type,EA,C)), var(B)) -> Goal = in_intervals_reif(Type,B,[C],R) - ; ((Type \== real, - (number(B),C = B; - number(EB),to_real(Type,EB,C)), + ; (((Type \== real; + fail,is_float_int_number(A)), + (number(B), + C = B; + number(EB), + to_real(Type,EB,C)), var(A)) -> Goal = in_intervals_reif(Type,A,[C],R) @@ -2479,42 +2513,9 @@ unfold_int_expr(EA $= EB,D,Cstr,Type0,R) ?- make_conj(CA,CB,Cstr) ; % R == 0 make_conj(CA,CB,CAB), - make_conj(CAB,launch_diff_real(Type,A,B),Cstr))). + + make_conj(CAB,diff_real_float(Type,A,B),Cstr))). -/* -unfold_int_expr(fp_eq(EA,EB),D,Cstr,Type0,R) ?- - ND is D + 1, - Type0 = bool, - (R == 1 -> - ensure_not_NaN(A), - ensure_not_NaN(B) - ; true), - unfold_real_expr(EA,ND,CA,Type,A), - unfold_real_expr(EB,ND,CB,Type,B), - !, - int_vars(bool,R), - unfold_int_expr( - chk_nan(isNaN(as(A,Type)) or isNaN(as(B,Type)), - as(0,bool), - chk_nan(as(R,bool), - chk_nan(isZero(as(A,Type)) and isZero(as(B,Type)), - as(1,bool), - as(A,Type) $= as(B,Type)), - chk_nan(isZero(as(A,Type)) and isZero(as(B,Type)), - % pour echouer avec R = 0 - as(1,bool), - % pour faire un diff_real avec R = 0 - as(A,Type) $= as(B,Type)))), - D, - Cond,bool,R), - get_reif_var_depth_from_labchoice(DD), - insert_dep_inst(inst_cstr(DD,R)), - insert_dep_inst(dep(R,D,[A,B])), - insert_dep_inst(dep(A,D,[R])), - insert_dep_inst(dep(B,D,[R])), - make_conj(CA,CB,CAB), - make_conj(CAB,Cond,Cstr). -*/ % Ancienne version unfold_int_expr(fp_eq(EA,EB),D,Cstr,Type0,R) ?- ND is D + 1, @@ -2587,9 +2588,12 @@ 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, - (number(B),C = B; - number(EB),to_real(Type,EB,C)), + ; (((Type \== real; + fail,is_float_int_number(A)), + (number(B), + C = B; + number(EB), + to_real(Type,EB,C)), var(A)) -> % A < CB @@ -2608,7 +2612,7 @@ unfold_int_expr(EA $\= EB,D,Cstr,Type0,R) ?- !, make_conj(CA,CB,Cstr) ; % R == 1 make_conj(CA,CB,CAB), - make_conj(CAB,launch_diff_real(Type,A,B),Cstr))). + make_conj(CAB,diff_real_float(Type,A,B),Cstr))). unfold_int_expr(EA $< EB,D,Cstr,Type0,R) ?- Type0 = bool, @@ -2638,22 +2642,30 @@ 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, + (((Type \== real; + fail,is_float_int_number(B), + FI = 1), (number(A),C = A; number(EA),to_real(Type,EA,C)), var(B)) -> % CA < B - get_next_float(Type,C,NA), + (var(FI) -> + get_next_float(Type,C,NA) + ; NA = C), Inter = [NA..Max], Goal = in_intervals_reif(Type,B,Inter,R) - ; ((Type \== real, + ; (((Type \== real; + fail,is_float_int_number(A), + FI = 1), (number(B),C = B; number(EB),to_real(Type,EB,C)), var(A)) -> % A < CB - get_previous_float(Type,C,PB), + (var(FI) -> + get_previous_float(Type,C,PB) + ; PB = C), Inter = [Min..PB], Goal = in_intervals_reif(Type,A,Inter,R) ; Goal = gt_real_reif(Type,B,A,R))), @@ -2733,7 +2745,8 @@ 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, + (((Type \== real; + fail,is_float_int_number(B)), (number(A),C = A; number(EA),to_real(Type,EA,C)), var(B)) @@ -2746,7 +2759,8 @@ unfold_int_expr(EA $=< EB,D,Cstr,Type0,R) ?- ; NC = C), Inter = [NC..Max], Goal = in_intervals_reif(Type,B,Inter,R) - ; ((Type \== real, + ; (((Type \== real; + fail,is_float_int_number(A)), (number(B),C = B; number(EB),to_real(Type,EB,C)), var(A)) @@ -2851,6 +2865,7 @@ unfold_int_expr(neg(EA),D,Cstr,Type,R) ?- !, make_conj(CA,not_int(A,R),Cstr) ; Cstr = CA)). + /* unfold_int_expr(((EA1 and EA2) and EB),D,Cstr,Type,R) ?- nonvar(R), @@ -2893,10 +2908,11 @@ unfold_int_expr((EA and EB),D,Cstr,Type,R) ?- insert_dep_inst(dep(R,D,[A,B])), insert_dep_inst(dep(A,D,[R])), insert_dep_inst(dep(B,D,[R])), - ((TA \== real, - is_intervals_def(CA,TA,VA,IA,BA,RestA), + ((is_intervals_def(CA,TA,VA,IA,BA,RestA), is_intervals_def(CB,_TB,VB,IB,BB,RestB), VA == VB, + (TA \== real; + fail,is_float_int_number(VA)), var(BA), var(BB)) -> @@ -2917,11 +2933,13 @@ unfold_int_expr((EA and EB),D,Cstr,Type,R) ?- + +/* unfold_int_expr((EA or EB),D,Cstr,Type,R) ?- var(R), !, unfold_int_expr(chk_nan(EA,as(1,bool),EB),D,Cstr,Type,R). - +*/ unfold_int_expr((EA or EB),D,Cstr,Type,R) ?- Type = bool, ND is D + 1, @@ -2958,10 +2976,11 @@ unfold_int_expr((EA or EB),D,Cstr,Type,R) ?- insert_dep_inst(dep(R,D,[A,B])), insert_dep_inst(dep(A,D,[R])), insert_dep_inst(dep(B,D,[R])), - ((TA \== real, - is_intervals_def(CA,TA,VA,IA,BA,RestA), + ((is_intervals_def(CA,TA,VA,IA,BA,RestA), is_intervals_def(CB,_TB,VB,IB,BB,RestB), VA == VB, + (TA \== real; + fail,is_float_int_number(VA)), var(BA), var(BB)) -> @@ -2984,6 +3003,7 @@ unfold_int_expr((EA xor EB),D,Cstr,Type,R) ?- !, Type = bool, unfold_int_expr((EA \= EB),D,Cstr,Type,R). unfold_int_expr((EA => EB),D,Cstr,Type,R) ?- !, +/* Type = bool, ND is D + 1, (R == 0 -> @@ -3015,7 +3035,8 @@ unfold_int_expr((EA => EB),D,Cstr,Type,R) ?- !, insert_dep_inst(dep(A,D,[R])), insert_dep_inst(dep(B,D,[R])), make_conj(CAB,imply_reif(A,B,R),Cstr)))))). -% unfold_int_expr((neg(EA) or EB),D,Cstr,Type,R). +*/ + unfold_int_expr((neg(EA) or EB),D,Cstr,Type,R). unfold_int_expr(ite(Cond,Then,Else),D,Cstr,Type,R) ?- ND is D + 1, unfold_int_expr(Cond,ND,CC,bool,RCond), @@ -3067,7 +3088,8 @@ unfold_int_expr(chk_nan(Cond,Then,Else),D,Cstr,Type,R) ?- unfold_int_expr(Else,ND,CE,Type,RE), !, int_vars(bool,RCond), - int_vars(bool,R), +% int_vars(bool,R), + int_vars(Type,R), insert_dep_inst(dep(R,D,[RCond,RT,RE])), insert_dep_inst(dep(RT,D,[RCond])), insert_dep_inst(dep(RE,D,[RCond])), @@ -3416,6 +3438,7 @@ unfold_let(From,[(V,TypeV,EV)|T],E,D,Cstrs,Cstr,Type,R) :- ; (real_type(TypeV,_) -> unfold_real_expr(EV,D,CV,TypeV,V) ; unfold_int_expr(EV,D,CV,TypeV,V)), + % call(spy_here)@eclipse, make_conj(Cstrs,CV,NCstrs))), (real_type(TypeV,_) -> real_vars(TypeV,V) @@ -3427,16 +3450,17 @@ get_reif_var_depth_from_labchoice(D) :- D = 0 ; D is 2^32). -/* + bvnot_expr(Size,bvnot(Size,EA),E) ?- !, E = EA. -*/ %bvnot_expr(_,_,_) :- !,fail. bvnot_expr(Size,bvand(Size,EA,EB),E) ?- !, E = bvor(Size,bvnot(Size,EA),bvnot(Size,EB)). +/* bvnot_expr(Size,bvor(Size,EA,EB),E) ?- !, E = bvand(Size,bvnot(Size,EA),bvnot(Size,EB)). +*/ bvnot_expr(1,as(0,_),R) ?- !, blocked_unify(R,1). bvnot_expr(1,as(1,_),R) ?- !, @@ -3450,10 +3474,7 @@ not_expr(1,B) ?- !, blocked_unify(B,0). not_expr(neg(A),NA) ?- !, NA = A. -not_expr(A => B,E) ?- - (cgiveInstancePath(neg(_),A,_); - cgiveInstancePath(neg(_),B,_)), - !, +not_expr(A => B,E) ?- !, E = A and neg(B). not_expr(A and B,E) ?- (cgiveInstancePath(neg(_),A,_); @@ -3466,6 +3487,12 @@ not_expr(A or B,E) ?- !, E = neg(A) and neg(B). +/* +not_expr(let(Vars,P),E) ?- !, + E = let(Vars,neg(P)). +not_expr(quant_abs(P),E) ?- !, + E = quant_abs(neg(P)). +*/ not_expr(A xor B,E) ?- !, E = (A #= B). not_expr(A #= B,E) ?- !, @@ -3526,10 +3553,10 @@ not_expr(alldiff(Type,[A,B]),E) ?- % PAS DE real !!! in_intervals_reif(Type,Var,Inter0,1) ?- !, functor(Type,FType,_), - (occurs(FType,(float_simple,float_double)) -> - (Inter0 = [0.0] -> - Inter = [-0.0..0.0] - ; Inter = Inter0), + ((occurs(FType,(float_simple,float_double)); + is_float_int_number(Var)) + -> + Inter = Inter0, NType = FType ; set_int_type(Type,Var), Int = 1, @@ -3540,13 +3567,18 @@ in_intervals_reif(Type,Var,Inter0,1) ?- !, in_intervals_reif(Type,Var,Inter0,0) ?- !, functor(Type,FType,_), - (occurs(FType,(float_simple,float_double)) -> - (Inter0 = [0.0] -> - Inter = [-0.0..0.0] - ; Inter = Inter0), + ((occurs(FType,(float_simple,float_double)); + is_float_int_number(Var)) + -> + Inter = Inter0, NType = Type ; NType = int, Inter = Inter0), + ((FType \== real; + is_float_int_number(Var)) + -> + reduce_sub_intervals + ; true), (NType == int -> set_int_type(Type,Dummy), mfd:get_intervals(Dummy,InitInter), @@ -3560,12 +3592,12 @@ in_intervals_reif(Type,Var,Inter0,Bool) :- set_priority(1), save_cstr_suspensions(Var), functor(Type,FType,_), - (occurs(FType,(float_simple,float_double)) -> + ((occurs(FType,(float_simple,float_double)); + is_float_int_number(Var)) + -> set_real_type(Type,Var), mreal:get_intervals(Var,IVar), - (Inter0 = [0.0] -> - Inter = [-0.0..0.0] - ; Inter = Inter0), + Inter = Inter0, T = Type ; set_int_type(Type,Var), mfd:get_intervals(Var,IVar), @@ -3591,6 +3623,11 @@ in_intervals_reif(Type,Var,Inter0,Bool) :- mfd:set_intervals(Var,Inter) ; set_typed_intervals(Var,Type,Inter)) ; % Bool == 0 + ((FType \== real; + is_float_int_number(Var)) + -> + reduce_sub_intervals + ; true), (nonvar(Int) -> (nonvar(Diff) -> true @@ -3611,7 +3648,8 @@ in_intervals_reif(Type,Var,Inter0,Bool) :- (Type == Type1 -> true ; % attention aux bveq ! - call(spy_here)@eclipse), + % call(spy_here)@eclipse), + true), protected_unify(Bool,BBool) ; my_suspend(in_intervals_reif(Type,Var,Com,Bool),0,(Var,Bool)-> suspend:constrained))), @@ -3660,7 +3698,7 @@ is_intervals_def((R,eq_int_reif(Type,X,Y,Bool)),T,V,I,B,Rest) ?- B = Bool, Rest = R. -/* DANGER en real sauf real_int ? +% DANGER en real sauf real_int ? is_intervals_def(eq_real_reif(real,X,Y,Bool),T,V,I,B,Rest) ?- (number(X) -> var(Y), @@ -3688,7 +3726,6 @@ is_intervals_def((R,eq_real_reif(real,X,Y,Bool)),T,V,I,B,Rest) ?- T = real, B = Bool, Rest = R. -*/ intervals_union(Type,Inter1,Inter2,Union) :- functor(Type,FType,_), @@ -3982,6 +4019,7 @@ diff_reif(Type,_Kill,A,B,1) ?- !, set_priority(P), wake_if_other_scheduled(P)) ; (real_type(Type,_) -> + % on est sur un distinct nan=nan et -0<>0 diff_real_chk_nan(Type,A,B) ; launch_diff_int(A,B))). diff_reif(Type,Kill,A,B,Bool) :- !, @@ -4002,68 +4040,71 @@ diff_reif(Type,Kill,A,B,Bool) :- !, protected_unify(Bool,BBool) ; my_suspend(diff_reif(Type,Kill,A,B,Bool),0,(Kill,Bool,A,B)->suspend:constrained))). - -diff_real_chk_nan(_Type,A,A) ?- !, - fail. -diff_real_chk_nan(real_int,A,B) :- !, +% On est sur un distinct pour real/float/double ! +% Pas de nan ici +diff_real_chk_nan(real_int,A,B) ?- !, real_vars(real_int,[A,B]), launch_diff_real(real,A,B). -diff_real_chk_nan(real,A,B) :- !, +diff_real_chk_nan(real,A,B) ?- !, launch_diff_real(real,A,B). +diff_real_chk_nan(_Type,A,A) ?- !, + % meme pour nan + % distinct(nan,nan) = false + fail. + +% Tout non nan est <> d'un nan +diff_real_chk_nan(Type,A,nan) ?- + set_lazy_domain(Type,A), + check_not_NaN(A), + !. +diff_real_chk_nan(Type,nan,A) ?- + set_lazy_domain(Type,A), + check_not_NaN(A), + !. +% On passe aux autres cas float/double diff_real_chk_nan(Type,A,B) :- + set_lazy_domain(Type,A), + set_lazy_domain(Type,B), get_priority(P), set_priority(1), - (A == nan -> + % Si A|B <> nan -> B|A <> nan + (check_not_NaN(A) -> ensure_not_NaN(B) - ; (B == nan -> + ; (check_not_NaN(B) -> ensure_not_NaN(A) - ; ((number(A) -> - check_not_NaN(B), - Val = A, - Var = B - ; number(B), - check_not_NaN(A), - Val = B, - Var = A) - -> - mreal:dvar_remove_element(Var,Val) - ; ((check_not_NaN(A), - check_not_NaN(B), - (not_zero(A); - not_zero(B))) - -> - launch_diff_real(Type,A,B) - ; save_cstr_suspensions((A,B)), - get_saved_cstr_suspensions(LSusp), - ((member((Susp,diff_real_chk_nan(Type,AA,BB)),LSusp), - get_suspension_data(Susp,state,State), - State \= 2, - (AA == A -> - BB == B - ; AA == B, - BB == A)) - -> - true - ; % on est bloque par un NaN ou zero ? - (check_not_NaN(A) -> - (check_not_NaN(B) -> - % A et B peuvent valoir zero 0 - true - ; ChkNan = 1, - VNaN = B) - ; ChkNan = 1, - VNaN = A), - (nonvar(ChkNan) -> - int_vars(bool,Bool), - set_lazy_domain(Type,VNaN), - isNaN(VNaN,Bool), - insert_dep_inst(dep(Bool,0,[])) - ; true), - (var(Bool) -> - my_suspend(diff_real_chk_nan(Type,A,B),0, - (A,B,Bool)->suspend: - constrained) - ; diff_real_chk_nan(Type,A,B))))))), + ; (A == nan -> + B \== nan, + VNaN = B + ; VNaN = A), + Continue = 1)), + (var(Continue) -> + % On n'a plus de pb sur nan + launch_diff_real(Type,A,B) + ; % Pas de statut nan connu + % on est bloqué par le statut nan de VNaN + save_cstr_suspensions((A,B)), + get_saved_cstr_suspensions(LSusp), + (((Goal = diff_real_chk_nan(Type,AA,BB); + Goal = diff_real(Type,AA,BB), + NoNaN = 1), + member((Susp,diff_real_chk_nan(Type,AA,BB)),LSusp), + (AA == A -> + BB == B + ; AA == B, + BB == A)) + -> + % on factorise + (NoNaN == 1 -> + % call(spy_here)@eclipse, + ensure_not_NaN(A), + ensure_not_NaN(B) + ; true) + ; my_suspend(diff_real_chk_nan(Type,A,B),0, + [(A,B)->suspend:constrained, + Bool->suspend:inst]), + int_vars(bool,Bool), + insert_dep_inst(dep(Bool,0,[VNaN])), + isNaN(VNaN,Bool))), set_priority(P), wake_if_other_scheduled(P). @@ -4109,7 +4150,7 @@ get_array_type(A,Type) :- ; (nonvar(Type) -> Type = array(TI,TE), array_vars(TI,TE,Start) - ; spy_here, + ; % spy_here, fail))). get_array_start(const_array(TI,TE,Const),Start) ?- !, @@ -4183,11 +4224,11 @@ smtlib_select_bis(A,I,E,TypeI,TypeE) :- NewA = storec(_,J,_), ((TypeI \= sort(_), %var(I),var(J), - not is_float_int_number(I), + not is_float_int_number(I), % pourquoi ??? % indice numérique %dvar_size(TypeI,I,SI), %SI =< 32, - suspensions(I,LS), % les contraintes sur I vont plus vite + suspensions(I,LS), % les contraintes pretes sur I vont plus vite LS \== []) -> % E et EJ ne sont pas traités mais les contraintes de J @@ -4243,6 +4284,7 @@ smtlib_select0(Type,storec(A,J,EJ),I,E,SeenI,VarsI,NewA,Start,Suspend) ?- !, VarsI = SeenI, % I variable ou bien Ground = 0 (SeenI == [] -> + % on a fini (TypeE \= array(_,_) -> protected_unify(E,VEJ) @@ -4260,10 +4302,13 @@ smtlib_select0(Type,storec(A,J,EJ),I,E,SeenI,VarsI,NewA,Start,Suspend) ?- !, % over-write, on peut ignorer cet etage sur J smtlib_select0(Type,A,I,E,SeenI,VarsI,NewA,Start,Suspend) ; ((TypeE \= array(_,_), - not_unify(VEJ,E)) + not_unify(VEJ,E), + CstrEJ == true) -> - alldiff(TypeI,[as(I,TypeI),as(J,TrypeI)]) #= as(1,bool), + % cet étage peut disparaitre, le diff suffit pour échouer + alldiff(TypeI,[as(I,TypeI),as(J,TypeI)]) #= as(1,bool), NSeenI = SeenI, + %NSeenI = [J|SeenI], NewA = ENewA ; NewA = storec(ENewA,J,EJ), NSeenI = [J|SeenI]), @@ -4305,6 +4350,13 @@ check_seen_upper_index(J,SeenI) :- occurs(J,SeenI) ; member(JJ,SeenI), JJ == J). + +diff_each_seen_upper_index(J,SeenI) :- + (foreach(I,SeenI), + param(Unif) do + (not_unify(I,J) -> + true + ; Unif = 1)). @@ -4479,7 +4531,7 @@ eq_clean_array(Type,Diff,A,B,Seen,SureA,SureB) :- eq_array0(Type,Diff,A,B,NA,_IA,Seen,SureA,Seen1,Work), eq_array0(Type,Diff,B,A,NB,_IB,Seen1,SureB,NSeen,Work), (nonvar(Work) -> - % on a lancee des select qui ont pu modifier + % on a lancé des select qui ont pu modifier % A ou B, SureA ou Sure B % on relance clean_eq_array(Diff,NA,NewA,SureA,NewSureA), @@ -6193,7 +6245,7 @@ real_vars(Type,T) :- (get_type(X,Type0) -> (RType == Type0 -> true - ; call(spy_here)@eclipse, + ; % call(spy_here)@eclipse, write(error,"Type error for variable "), writeln(error,X:RType), exit_block(syntax)) @@ -6257,11 +6309,17 @@ unfold_real_expr(X,_D,Cstr,Type,R) :- real_vars(Type,X)) -> blocked_unify(X=R) - ; call(spy_here)@eclipse, + ; % call(spy_here)@eclipse, writeln(error,"Type unknown for variable":X), exit_block(syntax)), %insert_dep_inst(inst_cstr(D,X)), Cstr = true. +unfold_real_expr(new_quantified_var(R0,Type0),D,Cstr,Type,R) ?- !, +% call(spy_here)@eclipse, + (nonvar(Type) -> + true + ; real_type(Type0,Type)), + unfold_real_expr(R0,D,Cstr,Type,R). unfold_real_expr(pi,D,Cstr,Type,R) ?- Type = real, !, @@ -6385,40 +6443,45 @@ unfold_real_expr(select(EA,EI), D, Cstr, Type, R) ?- make_conj(CIA,CES,Cstr). unfold_real_expr(- EA,D,Cstr,Type,R) ?- - ND is D + 1, - (check_not_NaN(R) -> - ensure_not_NaN(A) - ; true), - unfold_real_expr(EA,ND,CA,Type,A), - !, - insert_dep_inst(dep(R,D,[A])), - real_type(Type,RType), - ((RType == real; - check_not_NaN(A); - check_not_NaN(R)) - -> - ensure_not_NaN(A), - ensure_not_NaN(R), - make_conj(CA,op_real(RType,A,R),Cstr) - ; make_conj(CA,(ensure_not_NaN((A,R)),op_real(RType,A,R)),Cstr)). -unfold_real_expr(fp_neg(EA),D,Cstr,Type,R) ?- - (check_not_NaN(R) -> + get_norm_expr(Norm), + (normalize_expr(Norm,Type,-EA,D,Cstr,R,Goal) -> !, - unfold_real_expr(- EA,D,Cstr,Type,R) + call(Goal) ; ND is D + 1, + (check_not_NaN(R) -> + ensure_not_NaN(A) + ; true), unfold_real_expr(EA,ND,CA,Type,A), - unfold_int_expr(isNaN(as(A,Type)),D,Cond,bool,BCond), !, + insert_dep_inst(dep(R,D,[A])), + real_type(Type,RType), + ((RType == real; + check_not_NaN(A); + check_not_NaN(R)) + -> + ensure_not_NaN(A), + ensure_not_NaN(R), + make_conj(CA,op_real(RType,A,R),Cstr) + ; make_conj(CA,(ensure_not_NaN((A,R)),op_real(RType,A,R)), + Cstr))), + set_norm_expr(Norm). +unfold_real_expr(fp_neg(EA),D,Cstr,Type,R) ?- + ND is D + 1, + unfold_real_expr(EA,ND,CA,Type,A), + !, + ((check_not_NaN(A), + float(A)) + -> + fp_neg(0,Type,A,R), + Cstr = CA + ; unfold_int_expr(isNaN(as(A,Type)),D,Cond,bool,BCond), int_vars(bool,BCond), get_reif_var_depth_from_labchoice(DD), insert_dep_inst(inst_cstr(DD,BCond)), insert_dep_inst(dep(A,D,[BCond])), insert_dep_inst(dep(R,D,[A,BCond])), - (float(A) -> - R is -A, - Cstr = CA - ; make_conj(CA,Cond,CACond), - make_conj(CACond,fp_neg(BCond,Type,A,R),Cstr))). + make_conj(CA,Cond,CACond), + make_conj(CACond,fp_neg(BCond,Type,A,R),Cstr)). % round to nearest integral unfold_real_expr(round(EA),D,Cstr,Type,R) :- !, unfold_real_expr(round(rne,EA),D,Cstr,Type,R). @@ -6533,7 +6596,9 @@ unfold_real_expr(float_from_raw_uintN(EA),D,Cstr,Type,R) :- ; Size == 64, Type = float_double), !, - (number(A) -> + ((number(A); + number(R)) + -> Cstr = CA, blocked_call(float_from_raw_uintN(Type,A,R)) ; insert_dep_inst(dep(R,D,[A])), @@ -6771,46 +6836,52 @@ unfold_real_expr(fp_abs(EA),D,Cstr,Type,R) ?- make_conj(CA,CR,Cstr). unfold_real_expr(EA + EB,D,Cstr,Type,R) ?- - ((nonvar(EA), - EA = - NE, - OE = EB; - nonvar(EB), - EB = - NE, - OE = EA) - -> + get_norm_expr(Norm), + (normalize_expr(Norm,Type,EA+EB,D,Cstr,R,Goal) -> !, - unfold_real_expr(OE - NE,D,Cstr,Type,R) - ; ND is D + 1, - (Type == real -> - ensure_not_NaN((A,B,R)) - ; (check_not_NaN(R) -> - ensure_not_NaN((A,B)) - ; true)), - unfold_real_expr(EA,ND,CA,Type,A), - unfold_real_expr(EB,ND,CB,Type,B), - !, - ((fail, - nonvar(Type), - real_type(Type,real), - ((CA = (PC,op_real(_,Op,_)); - CA = op_real(_,Op,_), - PC = true), - X = B, - make_conj(PC,CB,CAB); - (CB = (PC,op_real(_,Op,_)); - CB = op_real(_,Op,_), - PC = true), - X = A, - make_conj(CA,PC,CAB))) + call(Goal) + ; ((nonvar(EA), + EA = - NE, + OE = EB; + nonvar(EB), + EB = - NE, + OE = EA) -> - % X + -Op = R, pattern frequent dans QF_NIA - make_conj(CAB,minus_real(real,X,Op,R),Cstr), - insert_dep_inst(dep(R,D,[X,Op])) - ; insert_dep_inst(dep(R,D,[A,B])), - make_conj(CA,CB,CAB), - (real_type(Type,real) -> - make_conj(CAB,add_real(real,A,B,R),Cstr) - ; make_conj(CAB,(ensure_not_NaN((A,B,R)),add_real(Type,A,B,R)),Cstr)))). + !, + unfold_real_expr(OE - NE,D,Cstr,Type,R) + ; ND is D + 1, + (Type == real -> + ensure_not_NaN((A,B,R)) + ; (check_not_NaN(R) -> + ensure_not_NaN((A,B)) + ; true)), + unfold_real_expr(EA,ND,CA,Type,A), + unfold_real_expr(EB,ND,CB,Type,B), + !, + ((fail, + nonvar(Type), + real_type(Type,real), + ((CA = (PC,op_real(_,Op,_)); + CA = op_real(_,Op,_), + PC = true), + X = B, + make_conj(PC,CB,CAB); + (CB = (PC,op_real(_,Op,_)); + CB = op_real(_,Op,_), + PC = true), + X = A, + make_conj(CA,PC,CAB))) + -> + % X + -Op = R, pattern frequent dans QF_NIA + make_conj(CAB,minus_real(real,X,Op,R),Cstr), + insert_dep_inst(dep(R,D,[X,Op])) + ; insert_dep_inst(dep(R,D,[A,B])), + make_conj(CA,CB,CAB), + (real_type(Type,real) -> + make_conj(CAB,add_real(real,A,B,R),Cstr) + ; make_conj(CAB,(ensure_not_NaN((A,B,R)), + add_real(Type,A,B,R)),Cstr))))), + set_norm_expr(Norm). unfold_real_expr(fp_add(EA,EB),D,Cstr,Type,R) ?- !, unfold_real_expr(fp_add(rne,EA,EB),D,Cstr,Type,R). @@ -6828,29 +6899,28 @@ unfold_real_expr(fp_add(Rnd0,EA,EB),D,Cstr,Type,R) ?- !, unfold_real_expr(fp_sub(Rnd,OE,NE),D,ECstr,Type,R), make_conj(CRnd,ECstr,Cstr) - ; ((check_not_NaN(R), - Rnd == rne) + ; (check_not_NaN(R) -> + ensure_not_NaN((A,B)) + ; true), + unfold_real_expr(EA,ND,CA,Type,A), + unfold_real_expr(EB,ND,CB,Type,B), + int_vars(bool,BCond), + unfold_int_expr(chk_nan(isNaN(as(A,Type)) or isNaN(as(B,Type)), + as(1,bool), + chk_nan(isInfinite(as(A,Type)) and + isInfinite(as(B,Type)), + (as(A,Type) $\= as(B,Type)), + as(0,bool))), + D,Cond,bool,BCond), + !, + ((BCond == 0, + nonvar(Rnd), + float(A), + float(B)) -> - !, - make_conj(CRnd,ECstr,Cstr), - unfold_real_expr(EA + EB,D,ECstr,Type,R) - ; (check_not_NaN(R) -> - ensure_not_NaN((A,B)), - BCond = 0 - ; true), - unfold_real_expr(EA,ND,CA,Type,A), - unfold_real_expr(EB,ND,CB,Type,B), - - unfold_int_expr(chk_nan(isNaN(as(A,Type)) or isNaN(as(B,Type)), - as(1,bool), - chk_nan(isInfinite(as(A,Type)) and - isInfinite(as(B,Type)), - (as(A,Type) $\= as(B,Type)), - as(0,bool))), - D,Cond,bool,BCond), - !, - int_vars(bool,BCond), - get_reif_var_depth_from_labchoice(DD), + make_conj(CA,CB,Cstr), + fp_add(0,Rnd,Type,A,B,R) + ; get_reif_var_depth_from_labchoice(DD), insert_dep_inst(inst_cstr(DD,BCond)), insert_dep_inst(dep(A,D,[Rnd,BCond])), insert_dep_inst(dep(B,D,[Rnd,BCond])), @@ -6861,25 +6931,33 @@ unfold_real_expr(fp_add(Rnd0,EA,EB),D,Cstr,Type,R) ?- make_conj(CABCond,fp_add(BCond,Rnd,Type,A,B,R),Cstr))). unfold_real_expr(EA - EB,D,Cstr,Type,R) ?- - ((nonvar(EB), - EB = - NEB) - -> - !, - unfold_real_expr(EA + NEB,D,Cstr,Type,R) - ; ND is D + 1, - (Type == real -> - ensure_not_NaN((A,B,R)) - ; (check_not_NaN(R) -> - ensure_not_NaN((A,B)) - ; true)), - unfold_real_expr(EA,ND,CA,Type,A), - unfold_real_expr(EB,ND,CB,Type,B), + get_norm_expr(Norm), + (normalize_expr(Norm,Type,EA-EB,D,Cstr,R,Goal) -> !, - insert_dep_inst(dep(R,D,[A,B])), - make_conj(CA,CB,CAB), - (real_type(Type,real) -> - make_conj(CAB,minus_real(real,A,B,R),Cstr) - ; make_conj(CAB,(ensure_not_NaN((A,B,R)),minus_real(Type,A,B,R)),Cstr))). + call(Goal) + ; ((nonvar(EB), + EB = - NEB) + -> + !, + unfold_real_expr(EA + NEB,D,Cstr,Type,R) + ; ND is D + 1, + (Type == real -> + ensure_not_NaN((A,B,R)) + ; (check_not_NaN(R) -> + ensure_not_NaN((A,B)) + ; true)), + unfold_real_expr(EA,ND,CA,Type,A), + unfold_real_expr(EB,ND,CB,Type,B), + !, + insert_dep_inst(dep(R,D,[A,B])), + make_conj(CA,CB,CAB), + (real_type(Type,real) -> + make_conj(CAB,minus_real(real,A,B,R),Cstr) + ; make_conj(CAB,(ensure_not_NaN((A,B,R)),minus_real(Type, + A,B, + R)), + Cstr)))), + set_norm_expr(Norm). unfold_real_expr(fp_sub(EA,EB),D,Cstr,Type,R) ?- !, unfold_real_expr(fp_sub(rne,EA,EB),D,Cstr,Type,R). @@ -6893,36 +6971,28 @@ unfold_real_expr(fp_sub(Rnd0,EA,EB),D,Cstr,Type,R) ?- !, unfold_real_expr(fp_add(Rnd,EA,NEB),D,ECstr,Type,R), make_conj(CRnd,ECstr,Cstr) - ; mfd:set_intervals(Rnd,[rna,rne,rtn,rtp,rtz]), - ((check_not_NaN(R), - Rnd == rne) - -> - !, - make_conj(CRnd,ECstr,Cstr), - unfold_real_expr(EA - EB,D,ECstr,Type,R) - ; (check_not_NaN(R) -> - ensure_not_NaN((A,B)), - BCond = 0 - ; true), - unfold_real_expr(EA,ND,CA,Type,A), - unfold_real_expr(EB,ND,CB,Type,B), - - unfold_int_expr(chk_nan(isNaN(as(A,Type)) or isNaN(as(B,Type)), - as(1,bool), - chk_nan(isInfinite(as(A,Type)), - (as(A,Type) $= as(B,Type)), - as(0,bool))), -/* - unfold_int_expr(chk_nan(isNaN(as(A,Type)) or isNaN(as(B,Type)), - as(1,bool), - (isInfinite(as(A,Type)) and - (as(A,Type) $= as(B,Type)))), -*/ - D,Cond,bool,BCond), - + ; (check_not_NaN(R) -> + ensure_not_NaN((A,B)) + ; true), + unfold_real_expr(EA,ND,CA,Type,A), + unfold_real_expr(EB,ND,CB,Type,B), + int_vars(bool,BCond), + unfold_int_expr(chk_nan(isNaN(as(A,Type)) or isNaN(as(B,Type)), + as(1,bool), + chk_nan(isInfinite(as(A,Type)), + (as(A,Type) $= as(B,Type)), + as(0,bool))), + D,Cond,bool,BCond), + !, - int_vars(bool,BCond), - get_reif_var_depth_from_labchoice(DD), + ((BCond == 0, + nonvar(Rnd), + float(A), + float(B)) + -> + make_conj(CA,CB,Cstr), + fp_sub(0,Rnd,Type,A,B,R) + ; get_reif_var_depth_from_labchoice(DD), insert_dep_inst(inst_cstr(DD,BCond)), insert_dep_inst(dep(A,D,[Rnd,BCond])), insert_dep_inst(dep(B,D,[Rnd,BCond])), @@ -6932,6 +7002,7 @@ unfold_real_expr(fp_sub(Rnd0,EA,EB),D,Cstr,Type,R) ?- make_conj(CAB,Cond,CABCond), make_conj(CABCond,fp_sub(BCond,Rnd,Type,A,B,R),Cstr))). +/* unfold_real_expr((EA * EB) * EC,D,Cstr,Type,R) ?- real_type(Type,real), (remove_upper_as(EA,A,_Type), @@ -6996,38 +7067,47 @@ unfold_real_expr(EA * (EB / EC),D,Cstr,Type,R) ?- NExpr = (EB/EC)*EA), !, unfold_real_expr(NExpr,D,Cstr,Type,R). +*/ unfold_real_expr(EA * EB,D,Cstr,Type,R) ?- - ((nonvar(EA), - EA = fp_neg(NEA), - nonvar(EB), - EB = fp_neg(NEB)) - -> - true - ; NEA = EA, - NEB = EB), - ND is D + 1, - (Type == real -> - ensure_not_NaN((A,B,R)) - ; (check_not_NaN(R) -> - ensure_not_NaN((A,B)) - ; true)), - unfold_real_expr(NEA,ND,CA,Type,A), - unfold_real_expr(NEB,ND,CB,Type,B), - !, - make_conj(CA,CB,CAB), - ((nonvar(Type), - real_type(Type,real), - (A == -1.0, - Cst = A, X = B; - B == -1.0, - Cst = B, X = A)) - -> - % X * -1 = R, pattern frequent dans QF_NIA - make_conj(CAB,op_real(real,X,R),Cstr) - ; insert_dep_inst(dep(R,D,[A,B])), - (real_type(Type,real) -> - make_conj(CAB,mult_real(real,A,B,R),Cstr) - ; make_conj(CAB,(ensure_not_NaN((A,B,R)),mult_real(Type,A,B,R)),Cstr))). + get_norm_expr(Norm), + (normalize_expr(Norm,Type,EA*EB,D,Cstr,R,Goal) -> + !, + call(Goal) + ; ((nonvar(EA), + EA = fp_neg(NEA), + nonvar(EB), + EB = fp_neg(NEB)) + -> + true + ; NEA = EA, + NEB = EB), + ND is D + 1, + (Type == real -> + ensure_not_NaN((A,B,R)) + ; (check_not_NaN(R) -> + ensure_not_NaN((A,B)) + ; true)), + unfold_real_expr(NEA,ND,CA,Type,A), + unfold_real_expr(NEB,ND,CB,Type,B), + !, + make_conj(CA,CB,CAB), + ((nonvar(Type), + real_type(Type,real), + (A == -1.0, + Cst = A, X = B; + B == -1.0, + Cst = B, X = A)) + -> + % X * -1 = R, pattern frequent dans QF_NIA + make_conj(CAB,op_real(real,X,R),Cstr) + ; insert_dep_inst(dep(R,D,[A,B])), + (real_type(Type,real) -> + make_conj(CAB,mult_real(real,A,B,R),Cstr) + ; make_conj(CAB,(ensure_not_NaN((A,B,R)),mult_real(Type, + A,B, + R)), + Cstr)))), + set_norm_expr(Norm). unfold_real_expr(fp_mul(EA,EB),D,Cstr,Type,R) ?- !, unfold_real_expr(fp_mul(rne,EA,EB),D,Cstr,Type,R). unfold_real_expr(fp_mul(Rnd0,EA,EB),D,Cstr,Type,R) ?- @@ -7043,42 +7123,33 @@ unfold_real_expr(fp_mul(Rnd0,EA,EB),D,Cstr,Type,R) ?- ; NEA = EA, NEB = EB), (check_not_NaN(R) -> - ensure_not_NaN((A,B)) + ensure_not_NaN((A,B)), + BCond = 0 ; true), - ((check_not_NaN(R), - Rnd == rne) - -> - !, - unfold_real_expr(NEA * NEB,D,ECstr,Type,R), - make_conj(CRnd,ECstr,Cstr) - ; (check_not_NaN(R) -> - ensure_not_NaN((A,B)) - ; true), - (NEA == NEB -> - unfold_real_expr(NEA,ND,CAB,Type,A), - A = B, - (check_not_NaN(A) -> - ensure_not_NaN(R), - BCond = 0, - Cond = true - ; unfold_int_expr(isNaN(as(A,Type)),D,Cond,bool,BCond)) - ; unfold_real_expr(NEA,ND,CA,Type,A), - unfold_real_expr(NEB,ND,CB,Type,B), - make_conj(CA,CB,CAB), - - unfold_int_expr(chk_nan(isNaN(as(A,Type)) or isNaN(as(B,Type)), - as(1,bool), - chk_nan(isInfinite(as(A,Type)), + unfold_real_expr(NEA,ND,CA,Type,A), + unfold_real_expr(NEB,ND,CB,Type,B), + make_conj(CA,CB,CAB), + + unfold_int_expr(chk_nan(isNaN(as(A,Type)) or isNaN(as(B,Type)), + as(1,bool), + chk_nan(isInfinite(as(A,Type)), isZero(as(B,Type)), chk_nan(isInfinite(as(B,Type)), - isZero(as(A,Type)), - as(0,bool)))), - D,Cond,bool,BCond)), - !, - (BCond == 0 -> - ensure_not_NaN((A,B,R)) - ; int_vars(bool,BCond)), - get_reif_var_depth_from_labchoice(DD), + isZero(as(A,Type)), + as(0,bool)))), + D,Cond,bool,BCond), + !, + (BCond == 0 -> + ensure_not_NaN((A,B,R)) + ; int_vars(bool,BCond)), + ((BCond == 0, + nonvar(Rnd), + float(A), + float(B)) + -> + Cstr = CAB, + fp_mul(0,Rnd,Type,A,B,R) + ; get_reif_var_depth_from_labchoice(DD), insert_dep_inst(inst_cstr(DD,BCond)), insert_dep_inst(dep(A,D,[Rnd,BCond])), insert_dep_inst(dep(B,D,[Rnd,BCond])), @@ -7169,33 +7240,34 @@ unfold_real_expr(fp_div(Rnd0,EA,EB),D,Cstr,Type,R) ?- ; NEA = EA, NEB = EB), (check_not_NaN(R) -> - ensure_not_NaN((A,B)), - BCond = 0 + ensure_not_NaN((A,B)) ; true), unfold_real_expr(NEA,ND,CA,Type,A), unfold_real_expr(NEB,ND,CB,Type,B), nonvar(Type), make_conj(CRnd,CA,CRndA), make_conj(CRndA,CB,CAB), - ((check_not_NaN(R), - Rnd == rne) - -> - !, - make_conj(CAB,div_real(Type,A,B,R),Cstr) - ; unfold_int_expr(chk_nan(isNaN(as(A,Type)) or + unfold_int_expr(chk_nan(isNaN(as(A,Type)) or isNaN(as(B,Type)), as(1,bool), chk_nan(isInfinite(as(A,Type)), - isInfinite(as(B,Type)), - chk_nan(isZero(as(A,Type)), - isZero(as(B,Type)), - as(0,bool)))), - D,Cond,bool,BCond), - !, - (BCond == 0 -> - ensure_not_NaN((A,B,R)) - ; int_vars(bool,BCond)), - get_reif_var_depth_from_labchoice(DD), + isInfinite(as(B,Type)), + chk_nan(isZero(as(A,Type)), + isZero(as(B,Type)), + as(0,bool)))), + D,Cond,bool,BCond), + !, + (BCond == 0 -> + ensure_not_NaN((A,B,R)) + ; int_vars(bool,BCond)), + ((BCond == 0, + nonvar(Rnd), + float(A), + float(B)) + -> + Cstr = CAB, + fp_div(0,Rnd,Type,A,B,R) + ; get_reif_var_depth_from_labchoice(DD), insert_dep_inst(inst_cstr(DD,BCond)), insert_dep_inst(dep(A,D,[Rnd,BCond])), insert_dep_inst(dep(B,D,[Rnd,BCond])), @@ -7232,7 +7304,7 @@ unfold_real_expr(colibri_cdiv(EA,EB),D,Cstr,RType,Q) ?- nonvar(RType), real_type(RType,real), make_conj(CA,CB,CAB), - unfold_int_expr(as(0.0,RType) $= as(B,RType),ND,Cond,bool,Bool), + unfold_int_expr(as(0.0,RType) $\= as(B,RType),ND,Cond,bool,Bool), !, get_reif_var_depth_from_labchoice(DD), insert_dep_inst(inst_cstr(DD,Bool)), @@ -7253,7 +7325,7 @@ unfold_real_expr(colibri_crem(EA,EB),D,Cstr,RType,R) ?- nonvar(RType), real_type(RType,real), make_conj(CA,CB,CAB), - unfold_int_expr(as(0.0,RType) $= as(B,RType),ND,Cond,bool,Bool), + unfold_int_expr(as(0.0,RType) $\= as(B,RType),ND,Cond,bool,Bool), !, get_reif_var_depth_from_labchoice(DD), insert_dep_inst(inst_cstr(DD,Bool)), @@ -7796,8 +7868,432 @@ unfold_real_expr(Expr,_,_,_,_) :- writeln(error,"Syntax error on real expression":Expr), exit_block(syntax). -:- local reference(real_cst). +diff_real_float(_,A,A) ?- !, + fail. +diff_real_float(real,A,B) ?- !, + launch_diff_real(real,A,B). +diff_real_float(Type,nan,B) ?- !, + ensure_not_NaN(B). +diff_real_float(Type,A,nan) ?- !, + ensure_not_NaN(A). +diff_real_float(Type,A,B) :- + ((check_not_NaN(A), + check_not_NaN(B)) + -> + launch_diff_real(Type,A,B) + ; my_suspend(diff_real_float(Type,A,B),0,(A,B)->suspend:constrained)). + +:- setval(norm_expr,1). + +:- export + get_norm_expr/1, + set_norm_expr/1, + use_norm_expr/0, + no_norm_expr/0. + +get_norm_expr(N) :- + getval(norm_expr,N). +set_norm_expr(N) :- + setval(norm_expr,N). +use_norm_expr :- + setval(norm_expr,1). +no_norm_expr :- + setval(norm_expr,0). + +%normalize_expr(Norm,Type,EA,D,Cstr,R,Goal) :- !,fail. +normalize_expr(1,int,EA,D,Cstr,R,Goal) ?- !, + normalize_expr0(int,EA,CstNEA,NEA), + (NEA \== EA -> + true + ; no_norm_expr, + fail), + Goal = (unfold_int_expr(NEA,D,Cstr0,int,R0), + (CstNEA == 0_1 -> + Cstr = Cstr0, + R = R0 + ; numerator(CstNEA,ICstNEA), + (is_val(R0,_) -> + true + ; insert_dep_inst(dep(R,D,[R0]))), + make_conj(Cstr0,add(ICstNEA,R0,R),Cstr))). + +normalize_expr(1,uint(N),EA,D,Cstr,R,Goal) ?- !, + normalize_expr0(uint(N),EA,CstNEA,NEA), + (NEA \== EA -> + true + ; no_norm_expr, + fail), + Goal = (unfold_int_expr(NEA,D,Cstr0,uint(N),R0), + (CstNEA == 0_1 -> + Cstr = Cstr0, + R = R0 + ; numerator(CstNEA,ICstNEA), + CR is ICstNEA mod 2^N, + (is_val(R0,_) -> + true + ; insert_dep_inst(dep(R,D,[R0]))), + make_conj(Cstr0,add(uint(N),D,CR,R0,R,_),Cstr))). + +normalize_expr(1,Type0,EA,D,Cstr,R,Goal) ?- + atomic(Type0), + occurs(Type0,(real,real_int)), + real_type(Type0,Type), + normalize_expr0(Type,EA,CstNEA,NEA), + % les realString peuvent créer la <> !! + % on travaille trop dans ce cas + (NEA \== EA -> + true + ; no_norm_expr, + fail), + Goal = (unfold_real_expr(NEA,D,Cstr0,Type,R0), + (CstNEA == 0_1 -> + Cstr = Cstr0, + R = R0 + ; real_from_rat(CstNEA,RCstNEA), + (is_val(R0,_) -> + true + ; insert_dep_inst(dep(R,D,[R0]))), + make_conj(Cstr0,add_real(real,RCstNEA,R0,R),Cstr))). + +is_val(as(as(V,_),_),R) ?- !, + is_val(V,R). +is_val(as(V,_),R) ?- !, + is_val(V,R). +is_val(realString(V),R) ?- !, + unfold_real_expr(realString(V),_D,_Cstr,real,R). +is_val(V,R) :- + number(V), + !, + R = V. +is_val(V,R) :- + is_real_box_rat(V,_), + R = V. + +assoc_cst_mult(RV0,V*P,NewRV,NewP) ?- + is_val(V,VV), + !, + (var(VV) -> + is_real_box_rat(VV,RV) + ; rational(VV,RV)), + NRV is RV0*RV, + assoc_cst_mult(NRV,P,NewRV,NewP). +assoc_cst_mult(RV0,P*V,NewRV,NewP) ?- + is_val(V,VV), + !, + assoc_cst_mult(RV0,V*P,NewRV,NewP). +assoc_cst_mult(RV,P,RV,P). + +get_Z_type(int,0). +get_Z_type(uint(_),0). +get_Z_type(real,0.0). +get_Z_type(real_int,0.0). + +normalize_expr0(Type,EA,C,NEA) ?- + var(EA), + !, + C = 0_1, + (real_type(Type,NType) -> + true + ; NType = Type), + NEA = as(EA,NType). +normalize_expr0(Type,EA,C,NEA) :- + number(EA), + !, + rational(EA,C), + (real_type(Type,NType) -> + true + ; NType = Type), + get_Z_type(NType,Z), + NEA = as(Z,NType). +normalize_expr0(Treal,realString(EA),C,NEA) ?- !, + unfold_real_expr(realString(EA),_D,_Cstr,real,R), + (var(R) -> + % C = 0_1, + is_real_box_rat(R,C), + NEA = as(0.0,real) + ; rational(R,C), + NEA = as(0.0,real)). + +normalize_expr0(_,as(EA,Type0),Cst,NEA) ?- !, + (real_type(Type0,Type) -> + true + ; Type = Type0), + normalize_expr0(Type,EA,Cst,NEA0), + NEA = NEA0. +normalize_expr0(Type,-EA,CstOpEA,OpEA) ?- !, + get_Z_type(Type,Z), + normalize_expr0(Type,as(Z,Type)-EA,CstOpEA,OpEA). +normalize_expr0(Type,bvneg(S,EA),CstOpEA,OpEA) ?- !, + Type = uint(S), + normalize_expr0(Type,-EA,CstOpEA,OpEA). + +normalize_expr0(Type,(EA + EB),CstApB,EApB) ?- !, + normalize_expr0(Type,EA,CstA,NEA), + normalize_expr0(Type,EB,CstB,NEB), + CstApB is CstA+CstB, + get_Z_type(Type,Z), + ((NEA == as(Z,Type), + EApB = NEB; + NEB == as(Z,Type), + EApB = NEA) + -> + true + ; EApB = NEA+NEB). +normalize_expr0(Type,bvadd(S,EA,EB),CstApB,EApB) ?- !, + Type = uint(S), + normalize_expr0(Type,(EA + EB),CstApB,EApB). + +normalize_expr0(Type,(EA - EB),CstAmB,EApB) ?- !, + normalize_expr0(Type,EA,CstA,NEA), + normalize_expr0(Type,EB,CstB,NEB), + CstAmB is CstA-CstB, + get_Z_type(Type,Z), + ((NEA == as(Z,Type), + EApB = -NEB; + NEB == as(Z,Type), + EApB = NEA) + -> + true + ; EApB = NEA-NEB). +normalize_expr0(Type,bvsub(S,EA,EB),CstApB,EApB) ?- !, + Type = uint(S), + normalize_expr0(Type,(EA - EB),CstApB,EApB). + +normalize_expr0(Type,bvmul(S,EA,EA),CAA,AA) ?- !, + Type = uint(S), + normalize_expr0(Type,EA * EA,CAA,AA). +normalize_expr0(Type,EA * EA,CAA,AA) ?- !, + CAA = 0_1, + AA = EA*EA. + +normalize_expr0(Type,bvmul(S,EA,bvmul(S,EB,EC)),C,P) ?- + is_val(EA,_), + !, + Type = uint(S), + normalize_expr0(Type,EA * (EB * EC),C,P). + +normalize_expr0(Type,EV * (EB * EC),C,P) ?- + is_val(EV,V), + !, + (var(V) -> + is_real_box_rat(V,RV) + ; rational(V,RV)), + get_Z_type(Type,Z), + (Z == V -> + C = 0_1, + P = as(Z,Type) + ; normalize_expr0(Type,EB*EC,C0,P0), + assoc_cst_mult(RV,P0,NV,NP), + C is RV*C0, + (NV =:= 1 -> + P = NP + ; functor(Type,FT,_), + (occurs(FT,(int,uint)) -> + numerator(NV,NRV) + ; real_from_rat(NV,NRV)), + P = as(NRV,Type)*NP)). +normalize_expr0(Type,EA * (EV * EC),C,P) ?- + is_val(EV,V), + !, + normalize_expr0(Type,EV*(EA*EC),C,P). +normalize_expr0(Type,EA * (EB * EV),C,P) ?- + is_val(EV,V), + !, + normalize_expr0(Type,EV*(EA*EB),C,P). + +normalize_expr0(Type,bvmul(S,bvmul(S,EA,EB),EC),C,P) ?- + is_val(EC,_), + !, + Type = uint(S), + normalize_expr0(Type,EC*(EA*EB),C,P). + +normalize_expr0(Type,(EV * EB) * EC,C,P) ?- + is_val(EV,V), + !, + normalize_expr0(Type,EV*(EB*EC),C,P). +normalize_expr0(Type,(EA * EV) * EC,C,P) ?- + is_val(EV,V), + !, + normalize_expr0(Type,EV*(EA*EC),C,P). +normalize_expr0(Type,(EA * EB) * EV,C,P) ?- + is_val(EV,V), + !, + normalize_expr0(Type,EV*(EA*EB),C,P). + +% Distributivité +normalize_expr0(Type,(EA*(EB+EC)),C,R) ?- + is_val(EA,_), + once (is_val(EB,_); + is_val(EC,_)), + !, + normalize_expr0(Type,(EA*EB)+(EA*EC),C,R). +normalize_expr0(Type,(EA*(EB-EC)),C,R) ?- + is_val(EA,_), + once (is_val(EB,_); + is_val(EC,_)), + !, + normalize_expr0(Type,(EA*EB)-(EA*EC),C,R). +normalize_expr0(Type,((EA+EB)*EC),C,R) ?- + is_val(EC,_), + once (is_val(EA,_); + is_val(EB,_)), + !, + normalize_expr0(Type,(EA*EC)+(EB*EC),C,R). +normalize_expr0(Type,((EA-EB)*EC),C,R) ?- + is_val(EC,_), + once (is_val(EA,_); + is_val(EB,_)), + !, + normalize_expr0(Type,(EA*EC)-(EB*EC),C,R). + +normalize_expr0(Type,(EA*bvadd(S,EB,EC)),C,R) ?- + is_val(EA,_), + once (is_val(EB,_); + is_val(EC,_)), + !, + Type = uint(S), + normalize_expr0(Type,bvadd(S,bvmul(S,EA,EB),bvmul(S,EA,EC)),C,R). +normalize_expr0(Type,bvmul(S,EA*bvadd(S,EB,EC)),C,R) ?- + is_val(EA,_), + once (is_val(EB,_); + is_val(EC,_)), + !, + Type = uint(S), + normalize_expr0(Type,bvadd(S,bvmul(S,EA,EB),bvmul(S,EA,EC)),C,R). +normalize_expr0(Type,(EA*bvsub(S,EB,EC)),C,R) ?- + is_val(EA,_), + once (is_val(EB,_); + is_val(EC,_)), + !, + Type = uint(S), + normalize_expr0(Type,bvsub(S,bvmul(S,EA,EB),bvmul(S,EA,EC)),C,R). +normalize_expr0(Type,bvmul(S,EA,bvsub(S,EB,EC)),C,R) ?- + is_val(EA,_), + once (is_val(EB,_); + is_val(EC,_)), + !, + Type = uint(S), + normalize_expr0(Type,bvsub(S,bvmul(S,EA,EB),bvmul(S,EA,EC)),C,R). +normalize_expr0(Type,(bvadd(S,EA,EB)*EC),C,R) ?- + is_val(EC,_), + once (is_val(EA,_); + is_val(EB,_)), + !, + Type = uint(S), + normalize_expr0(Type,bvadd(S,bvmul(S,EA,EC),bvmul(S,EB,EC)),C,R). +normalize_expr0(Type,bvmul(S,bvadd(S,EA,EB),EC),C,R) ?- + is_val(EC,_), + once (is_val(EA,_); + is_val(EB,_)), + !, + Type = uint(S), + normalize_expr0(Type,bvadd(S,bvmul(S,EA,EC),bvmul(S,EB,EC)),C,R). +normalize_expr0(Type,(bvsub(S,EA,EB)*EC),C,R) ?- + is_val(EC,_), + once (is_val(EA,_); + is_val(EB,_)), + !, + Type = uint(S), + normalize_expr0(Type,bvsub(S,bvmul(S,EA,EC),bvmul(S,EB,EC)),C,R). +normalize_expr0(Type,bvmul(S,bvsub(S,EA,EB),EC),C,R) ?- + is_val(EC,_), + once (is_val(EA,_); + is_val(EB,_)), + !, + Type = uint(S), + normalize_expr0(Type,bvsub(S,bvmul(S,EA,EC),bvmul(S,EB,EC)),C,R). + + +normalize_expr0(Type,bvmul(S,EA,EB),CAB,AB) ?- !, + Type = uint(S), + normalize_expr0(Type,(EA * EB),CAB,AB). +normalize_expr0(Type0,(EA * EB),NCAB,NAB) ?- !, + real_type(Type0,Type), + normalize_expr0(Type,EA,CA,A), + normalize_expr0(Type,EB,CB,B), + get_Z_type(Type,Z), + ((nonvar(A), + A = as(ZA,Type), + ZA == Z) + -> + true + ; true), + ((nonvar(B), + B = as(ZB,Type), + ZB == Z) + -> + true + ; true), + functor(Type,FT,_), + (CA == 0_1 -> + (CB == 0_1 -> + CAB = 0_1, + ((nonvar(ZA); + nonvar(ZB)) + -> + AB = as(Z,Type) + ; AB = A*B) + ; % A*(CB+B) = CB*A + A*B + CAB = 0_1, + (nonvar(ZA) -> + AB = as(Z,Type) + ; (occurs(FT,(int,uint)) -> + numerator(CB,RCB) + ; real_from_rat(CB,RCB)), + (nonvar(ZB) -> + AB = as(RCB,Type)*A + ; AB = as(RCB,Type)*A+A*B))) + ; (CB == 0_1 -> + % (CA+A)*B = CA*B + A*B + CAB = 0_1, + (nonvar(ZB) -> + AB = as(Z,Type) + ; (occurs(FT,(int,uint)) -> + numerator(CA,RCA) + ; real_from_rat(CA,RCA)), + (nonvar(ZA) -> + AB = as(RCA,Type)*B + ; AB = as(RCA,Type)*B+A*B)) + ; CAB is CA*CB, + (nonvar(ZA) -> + (nonvar(ZB) -> + AB = as(Z,Type) + ; (occurs(FT,(int,uint)) -> + numerator(CA,RCA) + ; real_from_rat(CA,RCA)), + AB = as(RCA,Type)*B) + ; (occurs(FT,(int,uint)) -> + numerator(CB,RCB) + ; real_from_rat(CB,RCB)), + (nonvar(ZB) -> + AB = as(RCB,Type)*A + ; (occurs(FT,(int,uint)) -> + numerator(CA,RCA) + ; real_from_rat(CA,RCA)), + % (CA+A)*(CB+B) = CA*CB + CA*B + A*CB + A*B + AB = as(RCA,Type)*B+ + as(RCB,Type)*A+ + A*B)))), + (CAB =:= Z -> + ((remove_upper_as(EA,EA0,_), + remove_upper_as(EB,EB0,_), + AB = NEA*NEB, + remove_upper_as(NEA,EA1,_), + remove_upper_as(NEB,EB1,_), + EA0 == EA1, + EB0 == EB1) + -> + NCAB = CAB, + NAB = AB + ; normalize_expr0(Type,AB,NCAB,NAB)) + ; (occurs(Type,(int,uint)) -> + numerator(CAB,CAB1) + ; real_from_rat(CAB,CAB1)), + normalize_expr0(Type,as(CAB1,Type)+AB,NCAB,NAB)). +% Pas intéressant pour "/" +normalize_expr0(_,EA,0_1,EA). +:- local reference(real_cst). init_real_cst :- hash_create(RCst), setval(real_cst,RCst). @@ -9501,7 +9997,8 @@ eq_real_reif(Type,A,B,Bool) :- (Bool == 1 -> protected_unify(A,B) ; % Bool = 0 - launch_diff_real(Type,A,B)) + diff_real_float(Type,A,B)) +% launch_diff_real(Type,A,B)) ; eq_real_reif_bis(Type,A,B,Bool)). eq_real_reif_bis(Type,A,B,Bool) :- @@ -9749,8 +10246,8 @@ float_from_raw_uintN(Type,Size,Int,Res) :- float_from_raw_uintN_inst(Type,Size,Int,Res,Continue), (var(Continue) -> true - ; float_from_raw_uintN_rec(Type,Size,Int,Res), - get_saved_cstr_suspensions(LSusp), + ; get_saved_cstr_suspensions(LSusp), + float_from_raw_uintN_rec(Type,Size,Int,Res), ((member((S,float_from_raw_uintN(Type,Size,IInt,R)),LSusp), (IInt == Int; Res == R, @@ -9768,13 +10265,21 @@ check_before_susp_float_from_raw_uintN(Type,Size,Int,Res) :- float_from_raw_uintN_inst(Type,Size,Int,Res,Continue), (var(Continue) -> true - ; my_suspend(float_from_raw_uintN(Type,Size,Int,Res), - 0,(Int,Res)->suspend:constrained), - (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 + ; % A VERIFIER SUR UnitTest QF_*BVFP* !!! + chk_nan(not(isZero((as(Res,Type)))), + chk_nan(isNegative(as(Res,Type)), + as(0.0,Type) $>= as(Res,Type), + as(Res,Type) $>= as(0.0,Type)), + as(1,bool))) ; int_vars(bool,Bool), - isNaN(Res,Bool), - insert_dep_inst(dep(Bool,0,[])))). + my_suspend(float_from_raw_uintN(Type,Size,Int,Res), + 0,Bool->suspend:inst), + isNaN(Res,Bool))). float_from_raw_uintN_inst(Type,Size,Int,Res,Continue) :- (integer(Int) -> @@ -10527,6 +11032,8 @@ undef_div_rem(Type,A,Q,R) :- protected_unify(R,A). % colibri_cdiv|crem +% Q est l'entier arrondi vers O de A/B (truncate(A/B)) +% et A = B*Q + R chk_undef_cdiv_crem(Bool,A,B,Q,R) :- set_lazy_domain(real,A), set_lazy_domain(real,B), @@ -10537,28 +11044,19 @@ chk_undef_cdiv_crem(Bool,A,B,Q,R) :- launch_float_int_number(B), launch_float_int_number(Q), launch_float_int_number(R), - save_cstr_suspensions((A,B)), ((nonvar(Bool); nonvar(B)) -> - ((Bool == 1; + ((Bool == 0; B == 0.0) -> - protected_unify(Bool,1), + protected_unify(Bool,0), protected_unify(B,0.0), undef_cdiv_crem(A,Q,R) - ; get_saved_cstr_suspensions(LSusp), - ((member((_,cdiv_crem(AA,BB,QQ,RR)),LSusp), - A == AA, - B == BB) - -> - protected_unify(Q,QQ), - protected_unify(R,RR) - ; protected_unify(Bool,0), - % invariant - abs(as(R,real)) $< abs(as(B,real)), - cdiv_crem(A,B,Q,R))) - ; get_saved_cstr_suspensions(LSusp), + ; protected_unify(Bool,1), + cdiv_crem(A,B,Q,R)) + ; save_cstr_suspensions((Bool,A,B)), + get_saved_cstr_suspensions(LSusp), ((member((_,chk_undef_cdiv_crem(BBool,AA,BB,QQ,RR)),LSusp), A == AA, B == BB) @@ -10573,7 +11071,21 @@ undef_cdiv_crem(A,Q,R) :- uninterp_trigger(cdiv_crem,[real],real,Trigger), uninterp(cdiv_crem,Trigger,[real],real,[A],(Q,R)). +/* +% def computer_division adacore +cdiv_crem(A,B,Q,R) :- + get_priority(P), + set_priority(1), + ite(as(A,real) $>= as(0.0,real), + (as(Q,real) $= irdiv(as(A,real),as(B,real))) and + (as(R,real) $= irmod(as(A,real),as(B,real))), + (as(Q,real) $= (- irdiv((- as(A,real)),as(B,real)))) and + (as(Q,real) $= (- irmod((- as(A,real)),as(B,real))))), + set_priority(P), + wake_if_other_scheduled(P). +*/ +% def C cdiv_crem(0.0,_B,Q,R) ?- !, protected_unify(Q,0.0), protected_unify(R,0.0). @@ -10588,558 +11100,142 @@ cdiv_crem(A,B,Q,0.0) ?- !, cdiv_crem(A,A,Q,R) ?- !, protected_unify(Q,1.0), protected_unify(R,0.0). - -cdiv_crem(A,B,Q,A) ?- !, - % B*Q = 0 et abs(B) > abs(A) - (as(Q,real) $= as(0.0,real)) and (abs(as(B,real)) $> abs(as(A,real))). cdiv_crem(A,B,Q,R) :- - % B <> 0.0 get_priority(P), set_priority(1), - save_cstr_suspensions((A,B,Q,R)), - % Congruences: pas de point fixe ici ? - % Pas de congruences pour cdiv et crem directement - % car div/mod inutilisables sauf dans le cas de mêmes signes ? - ((exists_congr(A,_,_), - exists_congr(B,_,_)) - -> - congr_div_directe(real,A,B,Q), - congr_mod_directe(real,A,B,R) - ; true), - ((exists_congr(B,CB,MB), - exists_congr(Q,CQ,MQ)) - -> - congr_mult(CB,MB,CQ,MQ,CBQ,MBQ), - (exists_congr(A,CA,MA) -> - % R = A - BQ - inv_congr_add(CA,MA,CBQ,MBQ,CR,MR), - launch_congr(R,CR,MR) - ; true), - (exists_congr(R,NCR,NMR) -> - % A = BQ + R - congr_add(CBQ,MBQ,NCR,NMR,NCA,NMA), - launch_congr(A,NCA,NMA) - ; true) - ; true), - check_exists_cdiv_crem(A,B,Q,R,Continue), - (var(Continue) -> - true - ; (not_unify(R,0.0) -> - % donc A <> 0.0 et B ne divise pas A - mreal:dvar_remove_element(A,0.0) - ; true), - (Q == 0.0 -> - protected_unify(A,R) - ; true), - (A == R -> - protected_unify(Q,0.0) - ; true), - (not_unify(A,R) -> - launch_diff_real(real,Q,0.0) - ; true), - % A est du signe de R - mreal:dvar_range(R,LR,HR), - (LR >= 0.0 -> - mreal:dvar_remove_smaller(A,0.0) - ; (HR =< 0.0 -> - mreal:dvar_remove_greater(A,0.0) - ; mreal:dvar_range(A,LA,HA), - (LA >= 0.0 -> - mreal:dvar_remove_smaller(R,0.0) - ; (HA =< 0.0 -> - mreal:dvar_remove_greater(R,0.0) - ; true)))), - (get_sign(B,SB) -> % <> 0 - mreal:dvar_range(A,NLA,NHA), - (NLA >= 0.0 -> - SA = pos - ; (NHA =< 0.0 -> - SA = neg - ; true)), - (SB == pos -> - % A et Q de meme signe ou nuls - (nonvar(SA) -> - (SA == pos -> - mreal:dvar_remove_smaller(Q,0.0) - ; mreal:dvar_remove_greater(Q,0.0)) - ; mreal:dvar_range(Q,LQ,HQ), - ((LQ >= 0.0, - SQ = pos; - HQ =< 0.0, - SQ = neg) - -> - (SQ == pos -> - mreal:dvar_remove_smaller(A,0.0) - ; mreal:dvar_remove_greater(A,0.0)) - ; true)) - ; % A et Q de signes opposes ou nuls - (nonvar(SA)-> - (SA == pos -> - mreal:dvar_remove_greater(Q,0.0) - ; mreal:dvar_remove_smaller(Q,0.0)) - ; mreal:dvar_range(Q,LQ,HQ), - ((LQ >= 0.0, - SQ = pos; - HQ =< 0.0, - SQ = neg) - -> - (SQ == pos -> - mreal:dvar_remove_greater(A,0.0) - ; mreal:dvar_remove_smaller(A,0.0)) - ; true))) - ; % on attend B signé - true), - ((not_unify(A,0.0), - not_unify(R,0.0)) - -> - NZAR = 1, - ensure_real_absR_leq_absA(R,A,Q) - ; true), - refute_real_A_equals_R(A,B,Q,R), - % au cas où - cdiv_crem_inst_free(A,B,Q,R,Continue1), - (var(Continue1) -> - true - ; cdiv_crem_rec(A,B,Q,R), - (((%not_inf_bounds(A); - is_inside_mantissa(float_double,A); - is_real_box_rat(A,_RA)), - (%not_inf_bounds(B); - is_inside_mantissa(float_double,B); - is_real_box_rat(B,_RB))) - -> - % délégation aux entiers bornés - cast_real_int(real,A,IA), - cast_real_int(real,B,IB), - div_mod(IA,IB,IQ,IR), - cast_int_real(real,IQ,Q), - cast_int_real(real,IR,R) - ; ((nonvar(B), - nonvar(R), - not_zero(A)) - -> - as(A,Real) $= (as(B,real)*as(Q,Real)) + as(R,real) - ; (nonvar(SB) -> - Prio = 4 - ; Prio = 5), - term_variables((A,B,Q,R),Vars), - my_suspend(cdiv_crem(A,B,Q,R), - Prio, - Vars->suspend:constrained))))), + set_lazy_domain(real,RQ), + % en C: B <> 0 et Q = truncate(A/B) et A = B*Q + R + div_real(real,A,B,RQ), + truncate(real,RQ,Q), + set_lazy_domain(real,BQ), + launch_float_int_number(BQ), + 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), + (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_cdiv_crem(A,B,Q,BQ,R), set_priority(P), wake_if_other_scheduled(P). -ensure_real_absR_leq_absA(R,A,Q) :- !, - % A,R <> 0 - (not_unify(Q,0.0) -> - abs(as(R,real)) $< abs(as(A,real)) - ; abs(as(R,real)) $=< abs(as(A,real))). -/* -ensure_real_absA_lt_absB(A,B) :- - A \== B, - % B <> 0, - (number(A) -> - (number(B) -> - abs(A) < abs(B) - ; OpA is -A, - (A >= 0.0 -> - RInt = [OpA..A] - ; RInt = [A..OpA]), - mreal:get_intervals(B,IntB), - mreal:finterval_difference(float_double,IntB,RInt,NIntB), - set_typed_intervals(B,real,NIntB)) - ; (number(B) -> - (B > 0.0 -> - Bp is B - 1.0, - OpBp is -Bp, - IntA = OpBp..Bp - ; % B < 0, - Bm is B + 1.0, - OpBm is -Bm, - IntA = Bm..OpBm), - set_typed_intervals(A,real,[IntA]) - ; mreal:dvar_range(A,LA,HA), - ((get_sign(B,SB), - once (HA =< 0.0, - SA = neg; - LA >= 0.0, - SA = pos)) - -> - (SA == SB -> - % A et B de meme signe - (SA == pos -> - % pos x pos - launch_gt_real(real,B,A) - ; % neg x neg - launch_gt_real(real,A,B)) - ; (SA == pos -> - % SB = neg, OpB pos donc A < OpB - op_real(real,B,OpB), - launch_gt_real(real,OpB,A) - ; % SA = Neg, OpA pos donc OpA < B - op_real(real,A,OpA), - launch_gt_real(real,B,OpA))) - ; ((get_rel_between_real_args(A,B,Rel), - Rel \== '#', - Rel \== '?') - -> - (occurs(Rel,('>','>=')) -> - % |A| < |B| et A >= B - % si B positif alors |A| >= |B| -> fail - % donc B negatif - mreal:dvar_remove_greater(B,-1.0) - ; % occurs(Rel,('<','=<')) - % |A| < |B| et A =< B - % si A negatif alors B positif et - % si A positif alors B positif - mreal:dvar_remove_smaller(B,1.0)) - ; true), - % On fait le menage dans A gt(abs(B),abs(A)) - % absmin(A) < absmin(B), - % On peut retirer de B -MinAbsA..MinAbsA - mreal:mindomain(A,MinA), - mreal:get_intervals(A,IntA), - real_abs_min(IntA,MinA,MinAbsA), - OpMinAbsA is -MinAbsA, - RInt = [OpMinAbsA..MinAbsA], - mreal:get_intervals(B,IntB), - mreal:finterval_difference(float_double,IntB,RInt,NIntB), - set_typed_intervals(B,real,NIntB), - % absmax(A) < absmax(B), - % On peut retirer de A -MaxAbsB..MaxAbsB - mreal:dvar_range(B,MinB,MaxB), - AbsMaxBm1 is max(abs(MinB),abs(MaxB))-1.0, - OpAbsMaxBm1 is - AbsMaxBm1, - mreal:dvar_remove_smaller(A,OpAbsMaxBm1), - mreal:dvar_remove_greater(A,AbsMaxBm1)))). -*/ +check_cdiv_crem(A,B,Q,BQ,R) :- + get_priority(P), + set_priority(1), + check_cdiv_crem1(A,B,Q,BQ,R), + set_priority(P), + wake_if_other_scheduled(P). -real_abs_min([],AbsMin,AbsMin). -real_abs_min([Int|LInt],Abs,AbsMin) :- - min_max_inter(Int,Min,Max), - (Min >= 0.0 -> - AbsMin is min(Abs,Min) - ; % Min < 0 - (Max =< 0.0 -> - NAbs is abs(Max), - real_abs_min(LInt,NAbs,AbsMin) - ; % Max > 0 - AbsMin = 0.0)). - -%cdiv_crem_rec(A,B,Q,R) :- !. -cdiv_crem_rec(A,B,Q,R) :- - mult_real_interval(real,B,Q,BQ), - cdiv_crem_rec(3,A,B,BQ,Q,R). - -cdiv_crem_rec(0,A,B,BQ,Q,R) ?- !. -cdiv_crem_rec(N,A,B,BQ,Q,R) :- - % A = B*Q + R - (var(A) -> - mreal:get_intervals(A,IA), - add_real_interval(real,BQ,R,A), - check_red_inter(A,IA,Red) - ; true), - (var(R) -> - mreal:get_intervals(R,IR), - minus_real_interval(real,A,BQ,R), - check_red_inter(R,IR,Red) - ; true), - (var(BQ) -> - mreal:get_intervals(BQ,IBQ), - minus_real_interval(real,A,R,BQ), - check_red_inter(BQ,IBQ,Red) - ; true), - ((not_zero(Q), - var(B)) +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_crem1(A,B,Q,BQ,R) :- + ((not not_zero(A), + not not_zero(Q), + (nonvar(A); + is_real_box_rat(A,_)), + (nonvar(B); + is_real_box_rat(B,_))) -> - mreal:get_intervals(B,IB), - div_real_interval(real,BQ,Q,B), - check_red_inter(B,IB,Red) - ; true), - (var(Q) -> - mreal:get_intervals(Q,IQ), - div_real_interval(real,BQ,B,Q), - check_red_inter(Q,IQ,Red) - ; true), - (var(BQ) -> - mreal:get_intervals(BQ,NIBQ), - mult_real_interval(real,B,Q,BQ), - check_red_inter(BQ,NIBQ,Red) - ; true), - (var(Red) -> true - ; NN is N - 1, - cdiv_crem_rec(NN,A,B,BQ,Q,R)). - -check_red_inter(V,IV,1) ?- !. -check_red_inter(V,IV,Red) :- - mreal:get_intervals(V,NIV), - (NIV == IV -> - true - ; Red = 1). - -% pour unsat.issue35.smt -refute_real_A_equals_R(A,B,Q,R) :- - getval(refutation_chk,0)@eclipse, - !, - % A et R de meme signe et <> 0.0 - setval(refutation_chk,1)@eclipse, - set_priority(4), - block((not (protected_unify(Q,0.0), - protected_unify(A,R), - wake) - -> - setval(refutation_chk,0)@eclipse, - set_priority(1), - launch_diff_real(real,A,R), - mreal:dvar_remove_element(Q,0.0), - force_lin_solve_var(A) - ; (not (diff_real(real,A,R), - mreal:dvar_remove_element(Q,0.0), - wake) - -> - setval(refutation_chk,0)@eclipse, - set_priority(1), - protected_unify(Q,0.0), - protected_unify(A,R), - force_lin_solve_var(A) - ; (not_zero(A) -> - setval(refutation_chk,0)@eclipse, - set_priority(1) - ; (not (protected_unify(A,0.0), - protected_unify(R,0.0), - protected_unify(Q,0.0), - wake) - -> - call(spy_here)@eclipse, - setval(refutation_chk,0)@eclipse, - set_priority(1), - launch_diff_real(real,A,0.0) - ; setval(refutation_chk,0)@eclipse, - set_priority(1))))), - Tag, - (setval(refutation_chk,0)@eclipse, - set_priority(1), - exit_block(Tag))), - % pour unsat/issue35.smt2 ???? - get_cstr_suspensions(A,LA), - get_cstr_suspensions(B,LB), - get_cstr_suspensions(R,LR), - append(LA,LB,LAB), - append(LR,LAB,LS), - %get_saved_cstr_suspensions(LS), - (foreach(Susp,LS) do - (get_suspension_data(Susp,goal,add_real1(real,X,Y,Z)) -> - check_add_op_real(real,X,Y,Z) + ; % 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)), + (foreach((S,G),LS), + foreach(Unif,LUnif), + param(A,B,Q,BQ,R) do + (G = check_cdiv_crem(AA,BB,QQ,BBQQ,RR) -> + (AA == A -> + (BB == B -> + % factorisation + Stop = 1, + Unif = (protected_unify(Q,QQ), + protected_unify(BQ,BBQQ), + protected_unify(R,RR)) + ; (RR == R -> + % R = A - BBQQ et R = A - BQ + % donc BBQQ = BQ + (QQ == Q -> + % R = A - BBQ et R = A - BQ + % donc BB == B + Stop = 1, + Unif = (protected_unify(B,BB), + protected_unify(BQ,BBQQ)) + ; % ? + Unif = protected_unify(BQ,BBQQ)) + ; ((is_op_real(real,B,OpB), + BB == OpB) + -> + Stop = 1, + unif = (set_lazy_domain(real,QQ), + op_real_bis(real,Q,QQ), + protected_unify(R,RR)) + ; BBQQ == BQ, + % R = A - BQ et RR = A - BQ + Stop = 1, + Unif = protected_unify(R,RR)))) + ; ((is_op_real(real,A,OpA), + AA == OpA) + -> + (B == BB -> + % RR = OpA - BQQ et R = A -BQ + % truncate(A/B) = Q + % truncate(-A/B) = -truncate(A/B), + % donc QQ = -Q et BQQ = -BQ + % 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), + op_real_bis(real,R,RR)) + ; ((is_op_real(real,B,OpB), + BB == OpB) + -> + % RR = OpA - opBQQ et R = A -BQ + % truncate(A/B) = truncate(-A/-B) = Q, + % donc QQ = Q et opBQQ = -BQ + % donc RR = OpA + BQ + % 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)). -refute_real_A_equals_R(A,B,Q,R). - -check_add_op_real(Type,A,B,C) :- - ((var(A), - get_sign(A,SA), - var(B), - get_sign(B,SB), - % var(C) - get_sign(C,SC), - op_sign(SB,SA), - (SC == SA -> - % abs(A) >= abs(B) - check_add_op_real(Type,SC,A,B,C,Goal) - ; SC == SB, - % abs(B) >= abs(A) - check_add_op_real(Type,SC,B,A,C,Goal))) - -> - call(Goal) - ; true). - -check_add_op_real(Type,SC,A,B,C,Goal) :- - % SC + SB -> SC - % si C pos alors A pos, B neg et A >= op(B) - % si C neg alors A neg, B pos et op(A) >= B - (not_zero(C) -> - Rel = '>' - ; Rel = '>='), - (SC == pos -> - (has_op_real(B,OpB) -> - call(spy_here)@eclipse, - Goal = launch_real_ineq(Rel,Type,A,OpB) - ; % si C pos alors A pos, B neg et op(A) =< B - has_op_real(A,OpA), - Goal = launch_real_ineq(Rel,Type,B,OpA)) - ; SC == neg, - (has_op_real(A,OpA) -> - Goal = launch_real_ineq(Rel,Type,OpA,B) - ; % si C neg alors A neg, B pos et A =< op(B) - has_op_real(B,OpB), - Goal = launch_real_ineq(Rel,Type,OpB,A))). - -has_op_real(Var,OpVar) :- - suspensions(Var,LSusp), - Goal = op_real1(_,X,OpX), - member(Susp,LSusp), - get_suspension_data(Susp,goal,Goal), - (Var == X -> - OpVar = OpX - ; Var == OpX, - OpVar = X), - !. - -cdiv_crem_inst_free(A,B,Q,R,Continue) :- - (A == 0.0 -> - protected_unify(Q,0.0), - protected_unify(R,0.0) - ; (B == 1.0 -> - protected_unify(A,Q), - protected_unify(R,0.0) - ; (B == -1.0 -> - op_real(real,A,Q), - protected_unify(R,0.0) - ; (A == B -> - protected_unify(Q,1.0), - protected_unify(R,0.0) - ; (A == R -> - % BQ = 0 donc Q = 0 - abs_val_real(real,A,AbsA), - abs_val_real(real,B,AbsB), - gt_real(real,AbsB,AbsA), - protected_unify(Q,0.0) - ; (Q == 0.0 -> - abs_val_real(real,A,AbsA), - abs_val_real(real,B,AbsB), - gt_real(real,AbsB,AbsA), - protected_unify(A,R) - ; % convergence lente sur cdiv_test_zero_sat.smt2 - % car on manque des congruences ici - % A ajouter/adapter ? - (R == 0.0 -> - mult_real(real,B,Q,A) - ; cdiv_crem_inst(A,B,Q,R,Continue)))))))). -cdiv_crem_inst(A,B,Q,R,Continue) :- - (check_rbox_rat(A,RA) -> - (check_rbox_rat(B,RB) -> - integer(RA,IA), - integer(RB,IB), - IQ is IA // IB, - IR is IA rem IB, - rational(IQ,RQ), - launch_box_rat(Q,RQ), - rational(IR,RR), - launch_box_rat(R,RR) - ; ((check_rbox_rat(Q,RQ), - check_rbox_rat(R,RR)) - -> - integer(RA,IA), - integer(RQ,IQ), - integer(RR,IR), - IBQ is IA - IR, - IB is IBQ // IQ, - % parano - mult(IB,IQ,IBQ), - %IQ is IA // IB, - IR is IA rem IB, - rational(IB,RB), - launch_box_rat(B,RB) - ; Continue = 1)) - ; ((check_rbox_rat(B,RB), - check_rbox_rat(Q,RQ), - check_rbox_rat(R,RR)) - -> - integer(RB,IB), - integer(RQ,IQ), - integer(RR,IR), - IA is IB*IQ + IR, - % parano - IQ is IA // IB, - IR is IA rem IB, - rational(IA,RA), - launch_box_rat(A,RA) - ; Continue = 1)). - -check_exists_cdiv_crem(A,B,Q,R,Suspend) :- - get_saved_cstr_suspensions(LSusp), - ((member((_,cdiv_crem(AA,BB,QQ,RR)),LSusp), - (AA == A; BB == B), - (B == BB -> - (A == AA; - Q == QQ, - R == RR) - ; A == AA, - Q == QQ, - R == RR, - (not_zero(Q) -> - true - ; exists_diff_Rel(B,BB), - ZQ = 1))) - -> - (nonvar(ZQ) -> - Suspend = 1, - % A = B*Q + R, A = BB*Q + R et B <> BB - % donc B*Q = BB*Q avec B et BB <> 0.0 - % et donc Q = 0.0 et A = R - protected_unify(Q,0.0), - protected_unify(BQ,0.0), - protected_unify(A,R) - ; % Factorisation - protected_unify(A,AA), - protected_unify(B,BB), - protected_unify(Q,QQ), - protected_unify(R,RR)) - ; % issue 40: cas diviseur <> 0 - % abs(X) = abs(A), abs(Y) = abs(B) => - % abs(X // Y) = abs(A // B) et abs(X rem Y) = abs(A rem B) - % capture aussi les 3 propagateurs suivants - % A // B = Q et -A // B = -Q et R = -RR - % A // B = Q et A // -B = -Q et R = RR - % A // B = Q et -A // -B = Q et R = -RR - ((once (member_begin_end((_,cdiv_crem(X,Y,QQ,RR)),LSusp,LSusp1,E1,E1), - same_abs(real,A,X,LSusp1,RelAX,LSusp2), - same_abs(real,B,Y,LSusp2,RelBY,_)); - (var(A) -> - Var = A - ; Var = B), - once (member((AbsOpVar,Rel1),[(abs_val_real1(real,V,OpAbsV),abs), - (op_real1(real,V,OpAbsV),op)]), - member_begin_end((_,AbsOpVar),LSusp,LSusp1,E1,E1), - (Var == V, NVar = OpAbsV; - Var == OpAbsV, NVar = V)), - get_cstr_suspensions(NVar,NLSusp), - once (member(Susp,NLSusp), - get_suspension_data(Susp,goal,cdiv_crem(X,Y,QQ,RR)), - (var(A) -> - % same_abs(A,X) - RelAX = Rel1, - same_abs(real,B,Y,LSusp,RelBY,_) - ; % same_abs(B,Y), - RelBY = Rel1, - same_abs(real,A,X,LSusp,RelAX,_)))) - -> - (RelAX == op -> - % A et R de même signe - op_real(real,R,RR), - (RelBY == eq -> - % A // B = Q et -A // B = -Q et R = -RR - op_real(real,Q,QQ) - ; (RelBY == op -> - % A // B = Q et -A // -B = Q et R = -RR - protected_unify(Q,QQ) - ; % abs - abs_val(Q,AQ), - abs_val(QQ,AQ))) - ; (RelAX == eq -> - % A et R de même signe - protected_unify(R,RR), - (RelBY == op -> - % A // B = Q et A // -B = -Q et R = RR - op_real(real,Q,QQ) - ; abs_val(Q,AQ), - abs_val(QQ,AQ)) - ; abs_val_real(real,Q,AQ), - abs_val_real(real,QQ,AQ), - abs_val_real(real,R,AR), - abs_val_real(real,RR,AR))), - Suspend = 1 - ; Suspend = 1)). same_abs(Type,A,X,LSusp,Rel,NLSusp) :- (Type = real -> @@ -11176,6 +11272,7 @@ same_abs(Type,A,X,LSusp,Rel,NLSusp) :- ; A == Y, B == X)). + chk_min_real(1,_Type,_A,_B,R) ?- !, protected_unify(R,nan). chk_min_real(_NaN,_Type,nan,B,R) ?- !, @@ -11779,6 +11876,7 @@ get_range(V,_,V,V). ; (local reference(new_dep))). solve_cstrs :- + % use_3B, % la TRIGO peut désactiver le simplex getval(use_simplex,US)@eclipse, garbage_collect, @@ -11791,16 +11889,24 @@ solve_cstrs :- (DepConstraints \= [] -> clear_single_inst_cstr(DepConstraints,NDepConstraints), build_single_use_list(NDepConstraints,NSplitUseList), - (solve_cstrs_list([NSplitUseList]) -> - setval(use_simplex,US)@eclipse - ; setval(use_simplex,US)@eclipse, - fail), + delayed_goals(DGS), + (DGS == [] -> + % on peut ignorer les quantificateurs + setval(quantifier,0)@colibri + ; % term_variables(DGS,VDGs), + (solve_cstrs_list([NSplitUseList]) -> + setval(use_simplex,US)@eclipse + ; setval(use_simplex,US)@eclipse, + fail)), + % show_vdgs(VDGs), % Si on continue dans la ligne de requete init_dep_constraints(_NPC) ; true), attached_suspensions(diff_array,LS), (foreach(S,LS) do kill_suspension(S)). +show_vdgs(_). + try_noNaN :- attached_suspensions(isNaN,LS), (foreach(S,LS) do @@ -11822,7 +11928,8 @@ add_last_var_fail(Var) :- getval(last_var_fail,LVN)@eclipse, append(LVN,[VN],NLVN), setval(last_var_fail,NLVN)@eclipse - ; call(spy_here)@eclipse). + ; % call(spy_here)@eclipse, + true). solve_cstrs_list([]) :- !, % on peut avoir un wake_lin_solve qui "traine" @@ -11841,12 +11948,15 @@ solve_cstrs_list([UseList|SplitUseList]) :- solve_cstrs2(UseList,CVars,D) :- call(smt_check_disabled_delta)@eclipse, + % ça a l'air utile de voir si on a des réductions supplémentaires + % en essayant les sous-intervalles des variables + try_vars_sub_intervals, % on peut avoir un wake_lin_solve qui "traine" trigger(lin_solve), % Problème à voir sur sat/bignum_lia2.smt2 avec mult_real ? lin_solve(Status), ((Status == solved, - spy_here@eclipse, + % spy_here@eclipse, getval(gdbg,1)@eclipse) -> writeln(output,Status) @@ -12173,6 +12283,7 @@ choose_fd_var(UseList0,Var,Size,NUseList) :- % NMinVars = MinVars, + %leaf_var_with_max_cstr_min_dom(MinVars,Leaves,Var0,Size0), leaf_var_with_max_cstr_min_dom(MinVars,[],Var0,Size0), (is_real_pow_prod_res(Var0,Size0,Var,Size) -> true @@ -12594,7 +12705,8 @@ leaf_var_with_max_cstr_min_dom(L,Leaves,Var,MinSize) :- ; OL = IL)), (Leaves == [] -> var_with_max_cstr_min_dom(NL,Var,MinSize) - ; NL = [NV|ENL], + ; %Leaves = [NV|ENL] + NL = [NV|ENL], get_type(NV,Type), dvar_size_check_real(Type,NV,Size0), (ENL == [] -> @@ -12604,8 +12716,8 @@ leaf_var_with_max_cstr_min_dom(L,Leaves,Var,MinSize) :- Leaf = 1 ; true), constraints_number(NV,NbV0), - leaf_var_with_max_cstr_min_dom0(ENL,Leaves,NV,NbV0,Size0,Leaf, - Var,MinSize))). + %leaf_var_with_max_cstr_min_dom0(Leaves,Leaves,NV,NbV0,Size0,Leaf,Var,MinSize) + leaf_var_with_max_cstr_min_dom0(ENL,Leaves,NV,NbV0,Size0,Leaf,Var,MinSize))). leaf_var_with_max_cstr_min_dom0([V|LV],Leaves,Var0,NbV0,Size0,Leaf0,Var,MinSize) :- (((occurs(V,Leaves) -> @@ -12822,7 +12934,7 @@ simple_solve_var_type(sort(_),Var,_) ?- !, simple_solve_var_sort(Var). simple_solve_var_type(T,Var,_) :- writeln(pb_simple_solve_var_type(T,Var)), - call(spy_here)@eclipse, + % call(spy_here)@eclipse, exit_block(abort). simple_solve_var_sort(Var) :- @@ -12832,8 +12944,8 @@ simple_solve_var_sort(Var) :- simple_solve_var_float(Type,Var) :- call_priority( - (Var = -0.0; - Var = 0.0; + (Var = 0.0; + Var = -0.0; forbid_zero(Type,Var), simple_resol_float(Var)), 1). @@ -12902,7 +13014,8 @@ simple_resol_int1(Int) :- ( protected_unify(Int,Min0) ; mfd:dvar_remove_element(Int,Min0), protected_unify(Int,Max0) - ; mfd:dvar_remove_element(Int,Max0), + ; mfd:dvar_remove_element(Int,Min0), + mfd:dvar_remove_element(Int,Max0), mfd:get_intervals(Int,NIList), (NIList = [_,_|_] -> simple_resol_int(Int) @@ -12915,7 +13028,8 @@ simple_resol_int1(Int) :- get_small_random_value_in_interval(NInter,Size,C,Mod,Value), */ ( protected_unify(Int,Value) - ; mfd:dvar_remove_element(Int,Value))))) + ; % call(spy_here)@eclipse, + mfd:dvar_remove_element(Int,Value))))) ; true). /* @@ -13052,7 +13166,10 @@ simple_resol_float(Var) :- (is_float_int_number(Var) -> % On reutilise le choix de la version entiere get_small_random_value_in_real_interval_float_int(Type,Min..Max,Value) - ; get_small_random_value_in_real_interval(Type,Min..Max,Size,Value)), +% ; get_small_random_value_in_real_interval(Type,Min..Max,Size,Value)), + ; mreal:dvar_domain(Var,NDom), + mreal:dom_size(NDom,NSize), + get_mid_random_value_in_real_interval(Type,Min..Max,NSize,Value)), random_less(2,Rand), % On essaye Value, puis au dessus/dessous de Value ( Var = Value @@ -13082,16 +13199,11 @@ get_previous_zfloat(Type,V,P) :- -/* simple_resol_real(Var) :- var(Var), is_float_int_number(Var), - mreal:dvar_range(Var,L,H), - get_next_double_float(L,NL), - NL \== H, !, simple_resol_real_int(Var). -*/ simple_resol_real(Var) :- once (is_trans_no_rat(Var); @@ -13235,31 +13347,34 @@ simple_resol_real_int1(Int) :- ; % Un seul intervalle IList = [Inter], min_max_inter(Inter,Min0,Max0), - (Min0 == -1.0Inf -> - get_next_double_float(Min0,Min1), - (set_typed_intervals(Int,real,[Min1..Max0]); - set_typed_intervals(Int,real,[Min0..Min1]), - launch_box(Int)) - ; (Max0 == 1.0Inf -> - get_previous_double_float(Max0,Max1), - (set_typed_intervals(Int,real,[Min0..Max1]); - set_typed_intervals(Int,real,[Max1..Max0]), + (is_real_box(Int) -> + get_rand_rat_in_rbox(Int,Min0,Max0,Rat), + launch_box_rat(Int,Rat) + ; (Min0 == -1.0Inf -> + get_next_double_float(Min0,Min1), + (set_typed_intervals(Int,real,[Min1..Max0]); + set_typed_intervals(Int,real,[Min0..Min1]), launch_box(Int)) - ; - ( protected_unify(Int,Min0) - ; mreal:dvar_remove_element(Int,Min0), - protected_unify(Int,Max0) - ; mreal:dvar_remove_element(Int,Max0), - mreal:get_intervals(Int,NIList), - (NIList = [_,_|_] -> - simple_resol_real_int1(Int) - ; NIList = [NInter], - min_max_inter(NInter,L,H), - get_number_of_floats_between(float_double,L,H,Dist), - DistD2 is Dist div 2, - get_nth_double_float_from(L,DistD2,Value), - ( protected_unify(Int,Value) - ; mreal:dvar_remove_element(Int,Value))))))). + ; (Max0 == 1.0Inf -> + get_previous_double_float(Max0,Max1), + (set_typed_intervals(Int,real,[Min0..Max1]); + set_typed_intervals(Int,real,[Max1..Max0]), + launch_box(Int)) + ; + ( protected_unify(Int,Min0) + ; mreal:dvar_remove_element(Int,Min0), + protected_unify(Int,Max0) + ; mreal:dvar_remove_element(Int,Max0), + mreal:get_intervals(Int,NIList), + (NIList = [_,_|_] -> + simple_resol_real_int1(Int) + ; NIList = [NInter], + min_max_inter(NInter,L,H), + get_number_of_floats_between(float_double,L,H,Dist), + DistD2 is Dist div 2, + get_nth_double_float_from(L,DistD2,Value), + ( protected_unify(Int,Value) + ; mreal:dvar_remove_element(Int,Value)))))))). % ESSAI : instanciation pas un rat random dans une rbox finie get_rand_rat_in_rbox(Var,Value,NV,Rat) :- @@ -13541,6 +13656,8 @@ smt_check_disabled_delta :- writeln(output,"Delay/Steps disabled delta":Diff/Steps1/Steps2) ; true), smt_disable_delta_check, + no_reduce_sub_intervals, + no_3B, ((getval(keep_deltas_if_arrays_or_reals,1)@eclipse) -> no_simplex ; no_delta) % donc no_simplex diff --git a/Src/COLIBRI/solve_util.pl b/Src/COLIBRI/solve_util.pl index 6e269a5f53b8fc40da2de1b951bb76ba483f1e23..b765320cff5e7cbc71487aac5e77d26a11169ec1 100755 --- a/Src/COLIBRI/solve_util.pl +++ b/Src/COLIBRI/solve_util.pl @@ -428,31 +428,31 @@ get_interval_at_rank_congr([Inter|IList],Rank,Mod,Interval) :- %% Value est une valeur de la fraction ("Fract" ou centree sur 0) %% contenant les plus petites valeurs absolues get_small_random_value_in_interval(Inter,Size,C,Mod,Value) :- - Fract = 1000, - min_max_inter(Inter,Low,High), - (Size < Fract -> - random_less(Size,Rank), - Value1 is Low + Rank - ; ( Low >= 0, - !, - random_less(Fract,Rank), - Value1 is Low + Rank - ; - High =< 0, - !, - random_less(Fract,Rank), - Value1 is High - Rank - ; - %% On encadre 0, on se centre autour - NLow is max(Low, -High), - NHigh is min(High, -Low), - NSize is (NHigh - NLow) + 1, - NFract is min(Fract,NSize), - random_less(NFract,Rank), - Value1 is Rank - (NFract div 2))), - %% On avance a la premiere valeur compatible - %% avec la congruence - Value is ((Value1 div Mod) * Mod) + C. + Fract = 1000, + min_max_inter(Inter,Low,High), + (Size < Fract -> + random_less(Size,Rank), + Value1 is Low + Rank + ; (Low >= 0, + !, + random_less(Fract,Rank), + Value1 is Low + Rank + ; + High =< 0, + !, + random_less(Fract,Rank), + Value1 is High - Rank + ; + % On encadre 0, on se centre autour + NLow is max(Low, -High), + NHigh is min(High, -Low), + NSize is (NHigh - NLow) + 1, + NFract is min(Fract,NSize), + random_less(NFract,Rank), + Value1 is Rank - (NFract div 2))), + % On avance a la premiere valeur compatible + % avec la congruence + Value is ((Value1 div Mod) * Mod) + C. %% Value est une valeur du tier central de Inter @@ -525,8 +525,8 @@ signed_interval_real(Min,Max) :- %% contenant les plus petites valeurs absolues % Pour compatibilite on recupere le type dans float_eval get_small_random_value_in_real_interval(Inter,Size,Res) :- - getval(float_eval,Type)@eclipse, - get_small_random_value_in_real_interval(Type,Inter,Size,Res). + getval(float_eval,Type)@eclipse, + get_small_random_value_in_real_interval(Type,Inter,Size,Res). %%:- mode get_small_random_value_in_real_interval(++,++,++,?). get_small_random_value_in_real_interval(Type,LH..LH,_Size,Res) ?- !, @@ -585,19 +585,19 @@ get_small_random_value_in_real_interval(_,Res,_Size,Res). %% contenant les plus petites valeurs absolues % Pour compatibilite on recupere le type dans float_eval get_small_random_value_in_real_interval_float_int(Inter,Res) :- - getval(float_eval,Type)@eclipse, - get_small_random_value_in_real_interval_float_int(Type,Inter,Res). + getval(float_eval,Type)@eclipse, + get_small_random_value_in_real_interval_float_int(Type,Inter,Res). %%:- mode get_small_random_value_in_real_interval_float_int(++,++,?). get_small_random_value_in_real_interval_float_int(Type,Low..High,Res) :- !, - ILow is protected_fix(Type,Low), - IHigh is protected_fix(Type,High), - ISize is (IHigh - ILow) + 1, - get_small_random_value_in_interval(ILow..IHigh,ISize,0,1,IValue), - %% BM meme si IValue n'est pas representable (hors de -2^53..2^53) - %% l'arrondi nearest dans la conversion retombe sur un representable - %% entre Low et High - int_to_float(Type,IValue,Res). + ILow is protected_fix(Type,Low), + IHigh is protected_fix(Type,High), + ISize is (IHigh - ILow) + 1, + get_small_random_value_in_interval(ILow..IHigh,ISize,0,1,IValue), + % BM meme si IValue n'est pas representable (hors de -2^53..2^53) + % l'arrondi nearest dans la conversion retombe sur un representable + % entre Low et High + int_to_float(Type,IValue,Res). get_small_random_value_in_real_interval_float_int(_,Res,Res). @@ -626,23 +626,23 @@ protected_rational(Type,F,R) :- R is rational(NF). get_integer_interval_and_accurracy_bis(L,H,IL,IH,Exp) :- - FH is floor(H), - CL is ceiling(L), - (CL < FH -> - %% On a au moins 2 entiers - Exp = 0, - IL is integer(CL), - IH is integer(FH) - ; %% On estime l'exposant (negatif ou nul) de la difference - Diff is H - L, - Exp1 is integer(floor(ln(Diff)/ln(10))), - %% Exp1 peut valoir 0 is CL = FH - Exp2 is min(-1,Exp1), - Shift is 10^(-1*Exp2), - SL is L*Shift, - SH is H*Shift, - get_integer_interval_and_accurracy_bis(SL,SH,IL,IH,NExp), - Exp is Exp2 + NExp). + FH is floor(H), + CL is ceiling(L), + (CL < FH -> + % On a au moins 2 entiers + Exp = 0, + IL is integer(CL), + IH is integer(FH) + ; % On estime l'exposant (negatif ou nul) de la difference + Diff is H - L, + Exp1 is integer(floor(ln(Diff)/ln(10))), + % Exp1 peut valoir 0 is CL = FH + Exp2 is min(-1,Exp1), + Shift is 10^(-1*Exp2), + SL is L*Shift, + SH is H*Shift, + get_integer_interval_and_accurracy_bis(SL,SH,IL,IH,NExp), + Exp is Exp2 + NExp). %% ANCIENNE VERSION AVEC CHOIX CENTRAL @@ -651,6 +651,24 @@ get_mid_random_value_in_real_interval(Inter,Size,Value) :- getval(float_eval,Type)@eclipse, get_mid_random_value_in_real_interval(Type,Inter,Size,Value). +get_mid_random_value_in_real_interval(Type,Inter,Size,Value) :- !, + min_max_inter(Inter,Low,High), + (get_mid_random_value_in_real_interval(Type,Low,High,Size,Value) -> + true + ; call(spy_here)@eclipse, + get_mid_random_value_in_real_interval(Type,Low,High,Size,Value)). + +get_mid_random_value_in_real_interval(Type,Low,High,Size,Value) :- + (Size > 2 -> + Mid is fix(floor(Size/2.0)), + ((get_nth_float_from(Type,Low,Mid,Value), + Value >= Low, + Value =< High) + -> + true + ; Value = Low) + ; Value = Low). +/* get_mid_random_value_in_real_interval(Type,Inter,Size,Value) :- min_max_inter(Inter,Low,High), Diff is High - Low, @@ -711,7 +729,7 @@ get_mid_random_value_in_real_interval(Type,Inter,Size,Value) :- cast_double_to_simple_float(Value0,Value) ; % real ou float_double Value = Value0)). - +*/ integral_bounds(Low,High,ILow,IHigh) :- not_inf_val(Low), @@ -735,28 +753,28 @@ try_to_keep_precision(_Val,Inter,Res) :- try_to_keep_precision(Val,Inter,Res) :- round_to_nearest_precision(Val,Inter,Res). - round_to_nearest_precision(Val,Min..Max,Res) :- !, - getval(precision,Prec)@eclipse, - DixPuisPrec is 10^(Prec), - round_to_smallest_precision(Val,Min,Max,DixPuisPrec,Res). - round_to_nearest_precision(_Val,Res,Res). - - round_to_smallest_precision(Val,Min..Max,Res) :- !, - round_to_smallest_precision(Val,Min,Max,1,Res). - round_to_smallest_precision(_Val,Res,Res). - - round_to_smallest_precision(Val,Min,Max,DixPuisPrec,Res) :- - PVal is Val * DixPuisPrec, - (not_inf_val(PVal) -> - IPVal is fix(PVal), - Res1 is IPVal / DixPuisPrec, - ((Res1 =< Max, - Res1 >= Min) - -> - Res = Res1 - ; NDixPuisPrec is 10 * DixPuisPrec, - round_to_smallest_precision(Val,Min,Max,NDixPuisPrec,Res)) - ; Res = Val). +round_to_nearest_precision(Val,Min..Max,Res) :- !, + getval(precision,Prec)@eclipse, + DixPuisPrec is 10^(Prec), + round_to_smallest_precision(Val,Min,Max,DixPuisPrec,Res). +round_to_nearest_precision(_Val,Res,Res). + +round_to_smallest_precision(Val,Min..Max,Res) :- !, + round_to_smallest_precision(Val,Min,Max,1,Res). +round_to_smallest_precision(_Val,Res,Res). + +round_to_smallest_precision(Val,Min,Max,DixPuisPrec,Res) :- + PVal is Val * DixPuisPrec, + (not_inf_val(PVal) -> + IPVal is fix(PVal), + Res1 is IPVal / DixPuisPrec, + ((Res1 =< Max, + Res1 >= Min) + -> + Res = Res1 + ; NDixPuisPrec is 10 * DixPuisPrec, + round_to_smallest_precision(Val,Min,Max,NDixPuisPrec,Res)) + ; Res = Val). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -796,60 +814,87 @@ force_narrow_vars(L) :- ; O = I)), narrow_vars_bounds(NewL). -try_vars_sub_intervals([],[]). -try_vars_sub_intervals([Var|L],NL) :- +:- export reduce_sub_intervals/0. +reduce_sub_intervals :- + setval(reduce_sub_intervals,1)@eclipse. +:- export no_reduce_sub_intervals/0. +no_reduce_sub_intervals :- + setval(reduce_sub_intervals,0)@eclipse. + +:- export try_vars_sub_intervals/0. +%try_vars_sub_intervals :- !. +try_vars_sub_intervals :- + (getval(reduce_sub_intervals,1)@eclipse -> + delayed_goals(DGs), + term_variables(DGs,DGVars0), + (foreach(V,DGVars0), + fromto(DGVars,O,I,[]) do + ((get_type(V,TV), + get_Mod_from_Type(TV,Mod), + delayed_goals_number(V) > 0) + -> + O = [V|I] + ; O = I)), + (try_vars_sub_intervals(DGVars,_) -> + true + ; getval(gdbg,1)@eclipse, + writeln(output,fail_try_sub_intervals), + fail) + ; true). + +% on fait un point fixe (cher ?) +try_vars_sub_intervals(L,NL) :- + try_vars_sub_intervals(L,NL0,Work), + (fail,nonvar(Work) -> + try_vars_sub_intervals(L,NL) + ; NL = NL0). + +%:- import col_timeout/3 from eclipse. +try_vars_sub_intervals([],[],_). +try_vars_sub_intervals([Var|L],NL,Work) :- ((var(Var), get_type(Var,Type), + delayed_goals_number(Var) > 0, get_Mod_from_Type(Type,Mod)) -> - try_sub_intervals(Var,Type,Mod), + try_var_sub_intervals(Var,Type,Mod,Work), NL = [(l,Var,Type,Mod),(r,Var,Type,Mod)|ENL] ; NL = ENL), - try_vars_sub_intervals(L,ENL). + try_vars_sub_intervals(L,ENL,Work). get_Mod_from_Type(int,mfd) :- !. get_Mod_from_Type(real,mreal) :- !. get_Mod_from_Type(float_simple,mreal) :- !. get_Mod_from_Type(float_double,mreal) :- !. -try_sub_intervals(Var,Type,Mod) :- +try_var_sub_intervals(Var,Type,Mod,Work) :- Mod:get_intervals(Var,LInter), (LInter = [_,_|_] -> - try_sub_intervals(Var,Type,Mod,LInter) + try_var_sub_intervals(Var,Type,Mod,LInter,Work) + ; true). + +try_var_sub_intervals(Var,Type,Mod,LInter,Work) :- + try_sub_intervals(Var,Type,Mod,LInter,NLInter), + set_intervals(Type,Var,NLInter), + (NLInter \== LInter -> + Work = 1 ; true). -try_sub_intervals(Var,int,mfd,LInter) :- - try_int_sub_intervals(Var,LInter,NLInter), - mfd:set_intervals(Var,NLInter). -try_sub_intervals(Var,Type,mreal,LInter) :- - try_real_sub_intervals(Var,Type,LInter,NLInter), - mreal:set_typed_intervals(Var,Type,NLInter). - -try_int_sub_intervals(_Var,[],[]). -try_int_sub_intervals(Var,[I|LI],NLI) :- +try_sub_intervals(_Var,_Type,_Mod,[],[]). +try_sub_intervals(Var,Type,Mod,[I|LI],NLI) :- ((not ( - mfd:set_intervals(Var,[I]), + set_intervals(Type,Var,[I]), wake, - mfd:get_intervals(Var,LInter), + Mod:get_intervals(Var,LInter), setval(saved_intervals,LInter))) -> - try_int_sub_intervals(Var,LI,NLI) - ; getval(saved_intervals,BegNLI), + % on peut oublier cet intervalle + try_sub_intervals(Var,Type,Mod,LI,NLI) + ; % on garde une éventuelle réduction + getval(saved_intervals,BegNLI), append(BegNLI,EndNLI,NLI), - try_int_sub_intervals(Var,LI,EndNLI)). + try_sub_intervals(Var,Type,Mod,LI,EndNLI)). -try_real_sub_intervals(_,_,[],[]). -try_real_sub_intervals(Var,Type,[I|LI],NLI) :- - ((not ( - mreal:set_typed_intervals(Var,Type,[I]), - wake, - mreal:get_intervals(Var,LInter), - setval(saved_intervals,LInter))) - -> - try_real_sub_intervals(Var,Type,LI,NLI) - ; getval(saved_intervals,BegNLI), - append(BegNLI,EndNLI,NLI), - try_real_sub_intervals(Var,Type,LI,EndNLI)). % on rogne a gauche et a droite dans la limite du threshold general T % pour les reels/flottants et entiers (dimensionner T selon la taille @@ -858,9 +903,10 @@ try_real_sub_intervals(Var,Type,[I|LI],NLI) :- narrow_vars_bounds([]) :- !. narrow_vars_bounds(L) :- get_threshold(T), - NT is T*1e-2, + %NT is T*1e-2, + NT is T, set_threshold(NT), - block((narrow_vars_bounds(L,1.0,T) -> + block((narrow_vars_bounds(L,1.0,0.008) -> set_threshold(T) ; set_threshold(T), fail), @@ -871,6 +917,8 @@ narrow_vars_bounds(L) :- narrow_vars_bounds(L,R,MinR) :- L = [_|_], R >= MinR, + call(smt_check_disabled_delta)@eclipse, + getval(use_3B,1), !, NR is R*0.5, (getval(gdbg,1)@eclipse -> diff --git a/Src/COLIBRI/trans.pl b/Src/COLIBRI/trans.pl index 4de64b17b4709a17c23ce842cb1aa9dae8b35d38..9ced0105616e7cc137792711094ac4f0ab820187 100644 --- a/Src/COLIBRI/trans.pl +++ b/Src/COLIBRI/trans.pl @@ -20,8 +20,8 @@ no_trans :- %:- import launch_box_prio/2 from colibri. :- export trans/11. trans(DPi,OpDPi,Pi,OpPi,Pid2,OpPid2,Pid4,OpPid4,TPid4,OTPid4,E) :- - getval(trans,Trans), - (Trans == 0 -> + getval(trans,OTrans), + (OTrans == 0 -> (getval(use_trans,0)@colibri -> DPi is 2.0*pi, OpDPi is -DPi, @@ -90,7 +90,8 @@ trans(DPi,OpDPi,Pi,OpPi,Pid2,OpPid2,Pid4,OpPid4,TPid4,OTPid4,E) :- (foreach(Trans,[DPi,OpDPi,Pi,OpPi,Pid2,OpPid2,Pid4,OpPid4,TPid4,OTPid4,E]) do trans_no_rat(Trans)), setval(trans,(DPi,OpDPi,Pi,OpPi,Pid2,OpPid2,Pid4,OpPid4,TPid4,OTPid4,E)) - ; Trans = (DPi,OpDPi,Pi,OpPi,Pid2,OpPid2,Pid4,OpPid4,TPid4,OTPid4,E)). + ; % déjà fait + (DPi,OpDPi,Pi,OpPi,Pid2,OpPid2,Pid4,OpPid4,TPid4,OTPid4,E) = OTrans). m2pi(DPi) :- trans(DPi0,_,_,_,_,_,_,_,_,_,_),