Remove integer division from the language

it's unlikely to be used in any law, and likely to be cause for confusion.

best of all, the new operator has a different return type, which
ensures no inconsistency with the change can get overlooked.
This commit is contained in:
Louis Gesbert 2022-12-12 17:55:53 +01:00
parent dcb422302d
commit c94509e0bb
14 changed files with 44 additions and 40 deletions

View File

@ -256,7 +256,7 @@ and evaluate_operator :
| Mult_mon_rat, [LMoney x; LRat y] -> LMoney (o_mult_mon_rat x y)
| Mult_dur_int, [LDuration x; LInt y] ->
LDuration (o_mult_dur_int x y)
| Div_int_int, [LInt x; LInt y] -> LInt (protect o_div_int_int x y)
| Div_int_int, [LInt x; LInt y] -> LRat (protect o_div_int_int x y)
| Div_rat_rat, [LRat x; LRat y] -> LRat (protect o_div_rat_rat x y)
| Div_mon_mon, [LMoney x; LMoney y] ->
LRat (protect o_div_mon_mon x y)

View File

@ -435,7 +435,7 @@ let resolved_type (op, pos) =
| Mult_rat_rat -> TRat @- TRat @-> TRat
| Mult_mon_rat -> TMoney @- TRat @-> TMoney
| Mult_dur_int -> TDuration @- TInt @-> TDuration
| Div_int_int -> TInt @- TInt @-> TInt
| Div_int_int -> TInt @- TInt @-> TRat
| Div_rat_rat -> TRat @- TRat @-> TRat
| Div_mon_mon -> TMoney @- TMoney @-> TRat
| Div_mon_rat -> TMoney @- TRat @-> TMoney

View File

@ -177,12 +177,11 @@ subtraction "-", multiplication "*" and division (slash).
However, in the Catala code, you should be aware that these operators can behave
differently depending on the quantities considered: indeed, money for example is
rounded at the cent ; integers are rounded down on division. The Catala compiler
is able to automatically select the appropriate operation: here it can detect
that money is being multiplied by a decimal (percentage) which is a known
operation that yields an amount of money, rounded at the cent. Some other
operations are not allowed, like multiplying two amounts of money together, or
adding two dates.
rounded at the cent. The Catala compiler is able to automatically select the
appropriate operation: here it can detect that money is being multiplied by a
decimal which is a known operation that yields an amount of money, rounded at
the cent. Some other operations are not allowed, like multiplying two amounts of
money together, or adding two dates.
Coming back to article 1, one question remains unknown: what is the value
of the fixed percentage? Often, precise values are defined elsewhere in the
@ -742,9 +741,9 @@ declaration scope IntegerValues:
internal value2 content integer
scope IntegerValues:
definition value1 under condition 12 - (5 * 3) < 65 consequence equals 45 / 9
definition value1 under condition 12 - (5 * 3) < 65 consequence equals 45 * 9
# The / operators corresponds to an integer division that truncates towards 0.
definition value2 equals value1 * value1 * 65 / 100
definition value2 equals value1 * value1 * 65 * 100
```
### Decimals
@ -761,8 +760,9 @@ declaration scope DecimalValues:
scope DecimalValues:
definition value1 under condition
12.655465446655426 - 0.45265426541654 < 12.3554654652 consequence
equals (integer_to_decimal of 45) / (integer_to_decimal of 9)
# The / operators corresponds to an exact division.
equals 45 / 9
# The / operator corresponds to an exact division. The division of integers
# yields a decimal.
definition value2 equals value1 * value1 * 65%
# Percentages are decimal numbers (0.65 here)
```

View File

@ -147,12 +147,12 @@ et division (barre oblique).
Toutefois, dans le code Catala, ces opérateurs peuvent avoir un sens légèrement
différent suivant unités concernées. En effet, l'argent par exemple est arrondi
au centime ; les entiers sont tronqués lors de leur division. Le compilateur
Catala sélectionne automatiquement l'opération appropriée: ici, de l'argent est
multiplié par un pourcentage (soit un nombre décimal), ce qui est une opération
connue dont le résultat est une quantité d'argent, arrondie au centime. D'autres
opérations sont rejetées, comme la multiplication de deux quantités d'argent
entre elles, ou bien l'addition de deux dates.
au centime. Le compilateur Catala sélectionne automatiquement l'opération
appropriée: ici, de l'argent est multiplié par un pourcentage (soit un nombre
décimal), ce qui est une opération connue dont le résultat est une quantité
d'argent, arrondie au centime. D'autres opérations sont rejetées, comme la
multiplication de deux quantités d'argent entre elles, ou l'addition de deux
dates.
Revenons à l'article 1, dont une question reste sans réponse: quelle est la
valeur de la pourcentage fixe? Souvent, des valeurs précises sont définis

View File

@ -639,7 +639,11 @@ module Oper = struct
else Z.(res * of_int sign_int)
let o_mult_dur_int d m = Dates_calc.Dates.mul_period d (Z.to_int m)
let o_div_int_int i1 i2 = Z.div i1 i2 (* raises Division_by_zero *)
let o_div_int_int i1 i2 =
(* It's not on the ocamldoc, but Q.div likely already raises this ? *)
if Z.zero = i2 then raise Division_by_zero
else Q.div (Q.of_bigint i1) (Q.of_bigint i2)
let o_div_rat_rat i1 i2 =
if Q.zero = i2 then raise Division_by_zero else Q.div i1 i2

View File

@ -326,7 +326,7 @@ module Oper : sig
val o_mult_rat_rat : decimal -> decimal -> decimal
val o_mult_mon_rat : money -> decimal -> money
val o_mult_dur_int : duration -> integer -> duration
val o_div_int_int : integer -> integer -> integer
val o_div_int_int : integer -> integer -> decimal
val o_div_rat_rat : decimal -> decimal -> decimal
val o_div_mon_mon : money -> money -> decimal
val o_div_mon_rat : money -> decimal -> money

View File

@ -39,8 +39,8 @@ class Integer:
def __mul__(self, other: 'Integer') -> 'Integer':
return Integer(self.value * other.value)
def __truediv__(self, other: 'Integer') -> 'Integer':
return Integer(self.value // other.value)
def __truediv__(self, other: 'Integer') -> 'Decimal':
return Decimal (self.value) / Decimal (other.value)
def __neg__(self: 'Integer') -> 'Integer':
return Integer(- self.value)

View File

@ -4,7 +4,7 @@
```catala
declaration scope Int:
context i content integer
context i content decimal
scope Int:
definition i equals 1 / 0

View File

@ -3,13 +3,13 @@ declaration scope A:
output w content integer
output x content integer
output y content integer
output z content integer
output z content decimal
scope A:
definition w equals 4 - 2 - 2
definition x equals 4 - (2 - 2)
definition y equals 4 - 2 - -2
definition z equals 200 / 2 * 4 - 50 / - (5 - 20 / 2)
definition z equals 200 / 2 * 4. - 50. / - (5. - 20 / 2)
```
```catala-test-inline
@ -18,5 +18,5 @@ $ catala Interpret -s A
[RESULT] w = 0
[RESULT] x = 4
[RESULT] y = 4
[RESULT] z = 390
[RESULT] z = 390.
```

View File

@ -8,7 +8,7 @@ declaration scope A:
context y content integer
scope A:
definition x under condition (6*7 = 42) and (false or (true and 1458 / 27 = 54))
definition x under condition (6*7 = 42) and (false or (true and 1458 / 27 = 54.))
consequence equals 0
definition y under condition x <= 0 consequence equals -1

View File

@ -7,7 +7,7 @@ declaration scope A:
context y content integer
scope A:
definition x under condition (6*7 = 42) and (false or (true and 1458 / 27 = 54))
definition x under condition (6*7 = 42) and (false or (true and 1458 / 27 = 54.))
consequence equals 1
definition y under condition x <= 0 consequence equals -1

View File

@ -5,7 +5,7 @@ declaration scope A:
context x content integer
scope A:
definition x under condition (6*7 = 42) and (false or (true and 1458 / 27 = 54))
definition x under condition (6*7 = 42) and (false or (true and 1458 / 27 = 54.))
consequence equals 0
```
```catala-test-inline

View File

@ -7,7 +7,7 @@ scope S:
Structure { -- i: 4 -- e: y };
Structure { -- i: 5 -- e: Dat content |1970-01-01| }
]
definition a equals number of (z ++ z) / 2
definition a equals number of (z ++ z) * 2
```
```catala-test-inline
@ -19,14 +19,14 @@ $ catala Typecheck
Error coming from typechecking the following expression:
┌─⯈ tests/test_typing/bad/err3.catala_en:10.41-42:
└──┐
10 │ definition a equals number of (z ++ z) / 2
10 │ definition a equals number of (z ++ z) * 2
│ ‾
Type integer coming from expression:
┌─⯈ tests/test_typing/bad/err3.catala_en:10.41-42:
└──┐
10 │ definition a equals number of (z ++ z) / 2
10 │ definition a equals number of (z ++ z) * 2
│ ‾
@ -50,14 +50,14 @@ $ catala ocaml
Error coming from typechecking the following expression:
┌─⯈ tests/test_typing/bad/err3.catala_en:10.41-42:
└──┐
10 │ definition a equals number of (z ++ z) / 2
10 │ definition a equals number of (z ++ z) * 2
│ ‾
Type integer coming from expression:
┌─⯈ tests/test_typing/bad/err3.catala_en:10.41-42:
└──┐
10 │ definition a equals number of (z ++ z) / 2
10 │ definition a equals number of (z ++ z) * 2
│ ‾

View File

@ -29,8 +29,8 @@ scope S:
definition t1 equals |2022-01-09|
definition t2 equals |2022-01-10|
definition o_i equals -i1 + i2 - i1 * i2 / (i1 + i2)
definition o_x equals -x1 + x2 - x1 * x2 / (x1 + x2)
definition o_i equals -i1 + i2 - i1 * i2 * (i1 + i2)
definition o_x equals -x1 + x2 - x1 * x2 / (x1 + x2) * (i1 / i2)
definition o_m equals -m1 + m2 - m1 * x2 / (x1 * m1 / m2) + m1 / x2
definition o_d equals -d1 + d2 - d1 * i2
definition o_t equals d1 + t1 + d1 + (t2 - t1)
@ -42,8 +42,8 @@ scope S:
i1 >= i2 or x1 >= x2 or m1 >= m2 or d1 >= d2 or t1 >= t2
)
assertion o_i = -i1 +! i2 -! i1 *! i2 /! (i1 +! i2)
assertion o_x = -.x1 +. x2 -. x1 *. x2 /. (x1 +. x2)
assertion o_i = -i1 +! i2 -! i1 *! i2 *! (i1 +! i2)
assertion o_x = -.x1 +. x2 -. x1 *. x2 /. (x1 +. x2) *. (i1 /! i2)
assertion o_m = -$m1 +$ m2 -$ m1 *$ x2 / (m1 *$ x1 /$ m2) +$ m1 / x2
assertion o_d = -^d1 +^ d2 -^ d1 *^ i2
assertion o_t = t1 +@ d1 +@ (t2 -@ t1) +@ d1
@ -61,8 +61,8 @@ $ catala Interpret -s S
[RESULT] Computation successful! Results:
[RESULT] o_b = true
[RESULT] o_d = [0 years, 0 months, -13 days]
[RESULT] o_i = 1
[RESULT] o_i = -5
[RESULT] o_m = $-5.75
[RESULT] o_t = 2022-01-24
[RESULT] o_x = -0.71428571428571428571…
[RESULT] o_x = 0.14285714285714285714
```