trealla-prolog / trealla

A compact, efficient Prolog interpreter written in plain-old C.
MIT License
268 stars 13 forks source link

GSL: result inoperative #568

Closed flexoron closed 2 months ago

flexoron commented 2 months ago

v2.54.3

$ cat samples/test_matrix_det.mat
#4,2x2,0.0
2.0,3.0
3.0,4.0
#det=-1.0

$ tpl samples/test_matrix_det.pl
?- main.
-1.0
   true. % expected
?- halt.

$ cat samples/test_matrix_det.pl
: 
   write(Det), nl,
   -1.0 is Det.  % append this test, or Det is -1.0.

?- main.
-1.0
   false. % unexpected

?- trace, main.
[0:user:116:f1:fp7:cp0:sp39:hp84:tp17] EXIT nl
[0:user:117:f1:fp7:cp0:sp39:hp84:tp17] CALL -1.0 is -1.0
[0:user:118:f1:fp7:cp0:sp39:hp84:tp17] FAIL -1.0 is -1.0  % unexpected
   false.
?-
infradig commented 2 months ago

You can't do floating point direct equality comparisons.

On Mon, Jul 15, 2024 at 11:12 AM flexoron @.***> wrote:

v2.54.3

$ cat samples/test_matrix_det.mat

4,2x2,0.0

2.0,3.0 3.0,4.0

det=-1.0

$ tpl samples/test_matrix_det.pl ?- main. -1.0 true. % expected ?- halt.

$ cat samples/test_matrix_det.pl : write(Det), nl, -1.0 is Det. % append this test, or Det is -1.0.

?- main. -1.0 false. % unexpected

?- trace, main. [0:user:116:f1:fp7:cp0:sp39:hp84:tp17] EXIT nl [0:user:117:f1:fp7:cp0:sp39:hp84:tp17] CALL -1.0 is -1.0 [0:user:118:f1:fp7:cp0:sp39:hp84:tp17] FAIL -1.0 is -1.0 % unexpected false. ?-

— Reply to this email directly, view it on GitHub https://github.com/trealla-prolog/trealla/issues/568, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFNKSEXA7KTIOTLO77GAO23ZMMOXFAVCNFSM6AAAAABK3T7FE2VHI2DSMVQWIX3LMV43ASLTON2WKOZSGQYDONRZGM4DGNY . You are receiving this because you are subscribed to this thread.Message ID: @.***>

flexoron commented 2 months ago

?- -1.00009e-30 is -1.00009e-30. true. Not sure what you mean.

infradig commented 2 months ago

https://stackoverflow.com/questions/4915462/how-should-i-do-floating-point-comparison

On Mon, Jul 15, 2024 at 11:22 AM flexoron @.***> wrote:

?- -1.00009e-30 is -1.00009e-30. true. Not sure what you mean.

— Reply to this email directly, view it on GitHub https://github.com/trealla-prolog/trealla/issues/568#issuecomment-2227568161, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFNKSEWDFYCBJI5UJ52WGOTZMMP53AVCNFSM6AAAAABK3T7FE2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDEMRXGU3DQMJWGE . You are receiving this because you commented.Message ID: @.***>

flexoron commented 2 months ago
: 
mat_lup_det(M,Det),
mat_lup_det(M,Det1),
: 
write(Det/Det1), nl, Det is Det1.  % true or false?

?- main.
-1.0/ -1.0
   true.
?- 
[0:user:204:f1:fp10:cp0:sp66:hp165:tp30] EXIT nl
[0:user:205:f1:fp10:cp0:sp66:hp165:tp30] CALL -1.0 is -1.0
[0:user:206:f1:fp10:cp0:sp66:hp165:tp30] EXIT -1.0 is -1.0
?-
infradig commented 2 months ago

Constants or values calculated the same way will always test equal, of course. You have to test FP equality using +/- epsilon.

infradig commented 2 months ago

Logtalk uses this:

approximately_equal(Number1, Number2) :-
        context(Context),
        check(number, Number1, Context),
        check(number, Number2, Context),
        epsilon(Epsilon),
        abs(Number1 - Number2) =< max(abs(Number1), abs(Number2)) * Epsilon.

Though you can use the epsilon constant.

flexoron commented 2 months ago

ok, thank you.

flexoron commented 2 months ago
#include <stdio.h>
int main() {
  float f = 10.01;
  float g = -1.0;
  f *= -0.1; f += 0.001;
  if (g == f)
    printf("g:%f f:%f\n",g,f);
  return 0;
}
$ ./a.out
g:-1.000000 f:-1.000000
$ 

'g' and 'f' are calculated the same way? Det is -1.0 and -1.00 and -1.000..... no?

infradig commented 2 months ago

A floating point value & the printed representation of that value are not the same. Printing uses all sorts of tricks.

On Mon, Jul 15, 2024 at 12:18 PM flexoron @.***> wrote:

include

int main() { float f = 10.01; float g = -1.0; f *= -0.1; f += 0.001; if (g == f) printf("g:%f f:%f\n",g,f); return 0; } $ ./a.out g:-1.000000 f:-1.000000 $

'g' and 'f' are calculated the same way? Det is -1.0 and -1.00 and -1.000..... no?

— Reply to this email directly, view it on GitHub https://github.com/trealla-prolog/trealla/issues/568#issuecomment-2227602433, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFNKSETYJJ34SCSYRFX2OJTZMMWQPAVCNFSM6AAAAABK3T7FE2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDEMRXGYYDENBTGM . You are receiving this because you commented.Message ID: @.***>

flexoron commented 2 months ago

Don't you think the trick is here: if (g == f) that is these bytes are filled with equivalent bits at the same positions.

infradig commented 2 months ago

Yes, but only because you use float, doesn't work with double.

flexoron commented 2 months ago

Anyway, write_term_to_atom(DetA,Det,[]), DetA = '-1.0'. is true.

or : write(Det), nl, Det is -1.0000000000000004. : $ main. -1.0 true.