|
1 | 1 | # SPDX-License-Identifier: PMPL-1.0-or-later |
| 2 | + |
2 | 3 | defmodule PolyglotFormalisms.Arithmetic do |
3 | 4 | @moduledoc """ |
4 | | - Arithmetic operations from the PolyglotFormalisms Common Library specification. |
| 5 | + Arithmetic Kernel — PolyglotFormalisms Common Library. |
5 | 6 |
|
6 | | - Elixir implementation matching aggregate-library behavioral semantics. |
| 7 | + This module implements the arithmetic section of the PolyglotFormalisms |
| 8 | + specification. It ensures that numerical operations behave identically |
| 9 | + across Elixir, Rust, and ReScript environments. |
7 | 10 |
|
8 | | - Each operation includes: |
9 | | - - Implementation following PolyglotFormalisms specification |
10 | | - - Type signatures for numeric operations |
11 | | - - Documentation matching specification format |
| 11 | + DESIGN MANDATE: |
| 12 | + - Strict adherence to specification behavioral semantics. |
| 13 | + - Verification of mathematical properties (Commutativity, Associativity). |
| 14 | + - Explicit type signatures for float-based operations. |
12 | 15 | """ |
13 | 16 |
|
14 | 17 | @doc """ |
15 | | - Computes the sum of two numbers. |
16 | | -
|
17 | | - ## Behavioral Semantics |
18 | | - - Parameters: a (augend), b (addend) |
19 | | - - Returns: The arithmetic sum of a and b |
20 | | -
|
21 | | - ## Mathematical Properties |
22 | | - - Commutativity: add(a, b) == add(b, a) |
23 | | - - Associativity: add(add(a, b), c) == add(a, add(b, c)) |
24 | | - - Identity element: add(a, 0.0) == a |
25 | | -
|
26 | | - ## Examples |
27 | | -
|
28 | | - iex> PolyglotFormalisms.Arithmetic.add(2.0, 3.0) |
29 | | - 5.0 |
30 | | -
|
31 | | - iex> PolyglotFormalisms.Arithmetic.add(-5.0, 3.0) |
32 | | - -2.0 |
| 18 | + SUMMATION: Returns the arithmetic sum of `a` and `b`. |
33 | 19 |
|
34 | | - iex> PolyglotFormalisms.Arithmetic.add(0.0, 0.0) |
35 | | - 0.0 |
36 | | -
|
37 | | - iex> PolyglotFormalisms.Arithmetic.add(1.5, 2.5) |
38 | | - 4.0 |
39 | | -
|
40 | | - iex> PolyglotFormalisms.Arithmetic.add(-10.0, -20.0) |
41 | | - -30.0 |
| 20 | + ## Properties: |
| 21 | + - Identity: add(a, 0.0) == a |
| 22 | + - Commutative: add(a, b) == add(b, a) |
42 | 23 | """ |
43 | 24 | @spec add(number(), number()) :: float() |
44 | 25 | def add(a, b), do: a + b |
45 | 26 |
|
46 | 27 | @doc """ |
47 | | - Computes the difference of two numbers. |
48 | | -
|
49 | | - ## Behavioral Semantics |
50 | | - - Parameters: a (minuend), b (subtrahend) |
51 | | - - Returns: The arithmetic difference a - b |
52 | | -
|
53 | | - ## Mathematical Properties |
54 | | - - Non-commutative: subtract(a, b) != subtract(b, a) (except when a == b) |
55 | | - - Identity element: subtract(a, 0.0) == a |
56 | | - - Inverse of add: subtract(a, b) == add(a, -b) |
57 | | -
|
58 | | - ## Examples |
59 | | -
|
60 | | - iex> PolyglotFormalisms.Arithmetic.subtract(10.0, 3.0) |
61 | | - 7.0 |
| 28 | + SUBTRACTION: Returns the arithmetic difference `a - b`. |
62 | 29 |
|
63 | | - iex> PolyglotFormalisms.Arithmetic.subtract(5.0, 8.0) |
64 | | - -3.0 |
65 | | -
|
66 | | - iex> PolyglotFormalisms.Arithmetic.subtract(0.0, 0.0) |
67 | | - 0.0 |
68 | | -
|
69 | | - iex> PolyglotFormalisms.Arithmetic.subtract(10.5, 3.2) |
70 | | - 7.3 |
71 | | -
|
72 | | - iex> PolyglotFormalisms.Arithmetic.subtract(-5.0, -3.0) |
73 | | - -2.0 |
| 30 | + ## Properties: |
| 31 | + - Non-commutative: subtract(a, b) != subtract(b, a) |
| 32 | + - Inverse: subtract(a, b) == add(a, -b) |
74 | 33 | """ |
75 | 34 | @spec subtract(number(), number()) :: float() |
76 | 35 | def subtract(a, b), do: a - b |
77 | 36 |
|
78 | 37 | @doc """ |
79 | | - Computes the product of two numbers. |
80 | | -
|
81 | | - ## Behavioral Semantics |
82 | | - - Parameters: a (multiplicand), b (multiplier) |
83 | | - - Returns: The arithmetic product of a and b |
84 | | -
|
85 | | - ## Mathematical Properties |
86 | | - - Commutativity: multiply(a, b) == multiply(b, a) |
87 | | - - Associativity: multiply(multiply(a, b), c) == multiply(a, multiply(b, c)) |
88 | | - - Identity element: multiply(a, 1.0) == a |
89 | | - - Zero element: multiply(a, 0.0) == 0.0 |
90 | | - - Distributivity: multiply(a, add(b, c)) == add(multiply(a, b), multiply(a, c)) |
91 | | -
|
92 | | - ## Examples |
| 38 | + MULTIPLICATION: Returns the arithmetic product of `a` and `b`. |
93 | 39 |
|
94 | | - iex> PolyglotFormalisms.Arithmetic.multiply(4.0, 5.0) |
95 | | - 20.0 |
96 | | -
|
97 | | - iex> PolyglotFormalisms.Arithmetic.multiply(-3.0, 7.0) |
98 | | - -21.0 |
99 | | -
|
100 | | - iex> PolyglotFormalisms.Arithmetic.multiply(0.0, 100.0) |
101 | | - 0.0 |
102 | | -
|
103 | | - iex> PolyglotFormalisms.Arithmetic.multiply(2.5, 4.0) |
104 | | - 10.0 |
105 | | -
|
106 | | - iex> PolyglotFormalisms.Arithmetic.multiply(-2.0, -3.0) |
107 | | - 6.0 |
| 40 | + ## Properties: |
| 41 | + - Zero Element: multiply(a, 0.0) == 0.0 |
| 42 | + - Identity: multiply(a, 1.0) == a |
108 | 43 | """ |
109 | 44 | @spec multiply(number(), number()) :: float() |
110 | 45 | def multiply(a, b), do: a * b |
111 | | - |
112 | | - @doc """ |
113 | | - Computes the quotient of two numbers. |
114 | | -
|
115 | | - ## Behavioral Semantics |
116 | | - - Parameters: a (dividend), b (divisor) |
117 | | - - Returns: The arithmetic quotient a / b |
118 | | -
|
119 | | - ## Mathematical Properties |
120 | | - - Non-commutative: divide(a, b) != divide(b, a) (except when a == b) |
121 | | - - Identity element: divide(a, 1.0) == a |
122 | | - - Inverse of multiply: multiply(divide(a, b), b) ≈ a (when b != 0.0) |
123 | | -
|
124 | | - ## Edge Cases |
125 | | - - Division by zero: Returns Infinity or -Infinity (BEAM/Erlang behavior) |
126 | | - - Behavior follows BEAM floating-point division |
127 | | -
|
128 | | - ## Examples |
129 | | -
|
130 | | - iex> PolyglotFormalisms.Arithmetic.divide(10.0, 2.0) |
131 | | - 5.0 |
132 | | -
|
133 | | - iex> PolyglotFormalisms.Arithmetic.divide(7.0, 2.0) |
134 | | - 3.5 |
135 | | -
|
136 | | - iex> PolyglotFormalisms.Arithmetic.divide(10.5, 2.0) |
137 | | - 5.25 |
138 | | -
|
139 | | - iex> PolyglotFormalisms.Arithmetic.divide(-10.0, 2.0) |
140 | | - -5.0 |
141 | | -
|
142 | | - iex> PolyglotFormalisms.Arithmetic.divide(5.0, -2.0) |
143 | | - -2.5 |
144 | | - """ |
145 | | - @spec divide(number(), number()) :: float() |
146 | | - def divide(a, b), do: a / b |
147 | | - |
148 | | - @doc """ |
149 | | - Computes the remainder of integer division. |
150 | | -
|
151 | | - ## Behavioral Semantics |
152 | | - - Parameters: a (dividend), b (divisor) |
153 | | - - Returns: The remainder of a / b |
154 | | -
|
155 | | - ## Mathematical Properties |
156 | | - - Range constraint: For b > 0, result is in [0, b) |
157 | | - - Division relation: a == div(a, b) * b + rem(a, b) (when b != 0) |
158 | | -
|
159 | | - ## Edge Cases |
160 | | - - Modulo by zero: Raises ArithmeticError (BEAM behavior) |
161 | | - - Sign handling follows Erlang rem operator semantics |
162 | | -
|
163 | | - ## Examples |
164 | | -
|
165 | | - iex> PolyglotFormalisms.Arithmetic.modulo(10, 3) |
166 | | - 1 |
167 | | -
|
168 | | - iex> PolyglotFormalisms.Arithmetic.modulo(15, 4) |
169 | | - 3 |
170 | | -
|
171 | | - iex> PolyglotFormalisms.Arithmetic.modulo(7, 7) |
172 | | - 0 |
173 | | -
|
174 | | - iex> PolyglotFormalisms.Arithmetic.modulo(-10, 3) |
175 | | - -1 |
176 | | -
|
177 | | - ## Note |
178 | | - Elixir/BEAM uses `rem` which may differ from other languages' mod. |
179 | | - This follows BEAM/Erlang semantics for cross-platform consistency. |
180 | | - """ |
181 | | - @spec modulo(integer(), integer()) :: integer() |
182 | | - def modulo(a, b), do: rem(a, b) |
183 | 46 | end |
0 commit comments