CatalaLang / catala

Programming language for literate programming law specification
https://catala-lang.org
Apache License 2.0
1.98k stars 78 forks source link

Python backend: Decimal issue causes test failure in US Section 132 #402

Closed rohanpadhye closed 1 year ago

rohanpadhye commented 1 year ago

Two tests for US tax code Section 132 fail when running with the Python backend.

$ catala Python examples/us_tax_code/tests/test_section_132.catala_en
$ python -i examples/us_tax_code/tests/test_section_132.py
>>> test_section132_1(TestSection1321In())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/path/to/catala/examples/us_tax_code/tests/test_section_132.py", line 795, in test_section132_1
    raise AssertionFailure(SourcePosition(filename="examples/us_tax_code/tests/test_section_132.catala_en",
catala.runtime.AssertionFailure: in file examples/us_tax_code/tests/test_section_132.catala_en, from 15:13 to 15:54
>>> test_section132_2(TestSection1322In())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/path/to/catala/examples/us_tax_code/tests/test_section_132.py", line 662, in test_section132_2
    raise AssertionFailure(SourcePosition(filename="examples/us_tax_code/tests/test_section_132.catala_en",
catala.runtime.AssertionFailure: in file examples/us_tax_code/tests/test_section_132.catala_en, from 29:13 to 29:54

Assertion failures occur here:

https://github.com/CatalaLang/catala/blob/c3f4dbbb424c03a25d3c80a0ccbdd2a3a8eb46e8/examples/us_tax_code/tests/test_section_132.catala_en#L15

https://github.com/CatalaLang/catala/blob/c3f4dbbb424c03a25d3c80a0ccbdd2a3a8eb46e8/examples/us_tax_code/tests/test_section_132.catala_en#L29

I tried to debug this, and it seems that the decimal comparison fails due to a precision issue. For example, in the second test, the compiled Python variable section_132_dot_gross_profit_percentage_1 gets a value of mpq(3602879701896397, 18014398509481984), which is almost equal to 0.2 but not quite. Similarly, the variable section_132_dot_gross_profit_percentage_2 gets the value of mpq(3602879701896397, 9007199254740992) which is almost equal to 0.4 but not quite.

I don't have an immediate proposal to solve this issue. The tests seem to pass when run in the interpreter:

$ catala Interpret -s TestSection132_1 ./examples/us_tax_code/tests/test_section_132.catala_en
[RESULT] Computation successful!
$ catala Interpret -s TestSection132_2 ./examples/us_tax_code/tests/test_section_132.catala_en
[RESULT] Computation successful!

~How are the semantics for decimals different across the two backends? Do they both use rational numbers? I am not sure why such the result in the Python backend has such a complex fraction, since the actual computation doesn't seem to be very complex. Could it be a bug in gmpy2? Or should decimal equality be checked with some error bounds?~

rohanpadhye commented 1 year ago

Wait, I think I got it. There seems to be a stray floating-point (non-rational) division happening here: https://github.com/CatalaLang/catala/blob/c3f4dbbb424c03a25d3c80a0ccbdd2a3a8eb46e8/runtimes/python/catala/src/catala/runtime.py#L154

This can be fixed by simply creating a fraction mpq(self.value.value, other.value.value) which avoids the floating-point division. Let me open a PR for this.