1
+ """
2
+ Custom Mathematical Operations Tool Module
3
+ This module provides a unified tool call interface for various mathematical operations.
4
+ """
5
+
6
+ import json
7
+ import re
8
+ import math
9
+ from typing import Tuple , Optional , Any , Dict
10
+
11
+ # Define the custom mathematical operations with overflow protection
12
+ def operation_at (a : int , b : int ) -> float :
13
+ """@ operation: Returns a raised to the power of b, then adds a*b
14
+
15
+ Includes overflow protection for large numbers
16
+ """
17
+ try :
18
+ # For very large exponents, use log approximation
19
+ if b > 100 or (a > 20 and b > 10 ):
20
+ # Fall back to a simpler calculation for very large values
21
+ return a * b * 2 # Simplified approximation
22
+ power_result = a ** b
23
+ product_result = a * b
24
+ return power_result + product_result
25
+ except OverflowError :
26
+ # If overflow occurs, return a simplified approximation
27
+ return a * b * 2 # Simplified approximation
28
+
29
+ def operation_amp (a : int , b : int ) -> float :
30
+ """& operation: Returns the average of a and b, multiplied by their absolute difference"""
31
+ avg = (a + b ) / 2
32
+ diff = abs (a - b )
33
+ return avg * diff
34
+
35
+ def operation_dollar (a : int , b : int ) -> float :
36
+ """$ operation: Returns a factorial-like sum of a repeated b times: a + (a-1) + (a-2) + ... + (a-b+1)"""
37
+ if b <= 0 or b > a :
38
+ return a
39
+
40
+ # For large values, use arithmetic sequence sum formula
41
+ if b > 1000 :
42
+ # Sum of arithmetic sequence: n/2 * (first + last)
43
+ n = min (b , a )
44
+ first = a
45
+ last = a - n + 1
46
+ return n * (first + last ) / 2
47
+
48
+ return sum (a - i for i in range (int (min (b , a ))))
49
+
50
+ def operation_caret (a : int , b : int ) -> float :
51
+ """^ operation: Returns a * b if both are even, a + b if both are odd, a - b otherwise"""
52
+ if a % 2 == 0 and b % 2 == 0 :
53
+ return a * b
54
+ elif a % 2 == 1 and b % 2 == 1 :
55
+ return a + b
56
+ else :
57
+ return a - b
58
+
59
+ class TOOL_CALL :
60
+ def __call__ (self , completion : str ) -> Tuple [Any , bool , Optional [float ]]:
61
+ raise NotImplementedError
62
+
63
+ class MathOperation_Tool (TOOL_CALL ):
64
+ """Unified tool for handling all mathematical operations"""
65
+
66
+ def __init__ (self ):
67
+ self .operations = {
68
+ "at_operation" : operation_at ,
69
+ "amp_operation" : operation_amp ,
70
+ "dollar_operation" : operation_dollar ,
71
+ "caret_operation" : operation_caret
72
+ }
73
+
74
+ def __call__ (self , completion : str ) -> Tuple [float , bool , float ]:
75
+ try :
76
+ # Check for required strict format
77
+ pattern = r'^<think>(.*?)</think>\n<tool>(.*?)</tool>$'
78
+ match = re .match (pattern , completion .strip (), re .DOTALL )
79
+
80
+ if not match :
81
+ return "" , True , 0
82
+
83
+ tool_content = match .group (2 ).strip ()
84
+
85
+ # Parse JSON from tool content
86
+ try :
87
+ tool_data = json .loads (tool_content )
88
+ except json .JSONDecodeError :
89
+ return "" , True , 0
90
+
91
+ # Check if JSON has required fields
92
+ if not isinstance (tool_data , dict ) or "tool" not in tool_data or "a" not in tool_data or "b" not in tool_data :
93
+ return "" , True , 0
94
+
95
+ tool_name = tool_data ["tool" ]
96
+
97
+ # Check if the requested operation exists
98
+ if tool_name not in self .operations :
99
+ return "" , True , 0
100
+
101
+ # Get the operation function
102
+ operation_func = self .operations [tool_name ]
103
+
104
+ # Execute operation
105
+ try :
106
+ a , b = float (tool_data ["a" ]), float (tool_data ["b" ])
107
+ result = operation_func (a , b )
108
+ return f"<result>\n { result } \n </reuslt>" , False , 0.2
109
+ except (ValueError , TypeError ):
110
+ return "" , True , 0
111
+
112
+ except Exception as e :
113
+ print (f"Error in MathOperation_Tool: { e } " )
114
+ return "" , True , 0
115
+
116
+ # Parser for expressions with overflow protection
117
+ def parse_expression (expression : str ) -> float :
118
+ """
119
+ Parses and evaluates a custom mathematical expression.
120
+ Supports operations: @, &, $, ^
121
+ Example: "11@2&1$44^2"
122
+
123
+ Includes overflow protection for large numbers
124
+ """
125
+ # Tokenize the expression - find all numbers and operators
126
+ tokens = re .findall (r'(\d+|\@|\&|\$|\^)' , expression )
127
+
128
+ # Process tokens
129
+ result = None
130
+ current_op = None
131
+
132
+ for token in tokens :
133
+ if token in ['@' , '&' , '$' , '^' ]:
134
+ current_op = token
135
+ else :
136
+ try :
137
+ num = int (token )
138
+ if result is None :
139
+ result = num
140
+ elif current_op == '@' :
141
+ # Limit very large inputs for @ operation
142
+ if result > 10000 or num > 100 :
143
+ result = result * num * 2 # Simplified approximation
144
+ else :
145
+ result = operation_at (result , num )
146
+ elif current_op == '&' :
147
+ result = operation_amp (result , num )
148
+ elif current_op == '$' :
149
+ result = operation_dollar (result , num )
150
+ elif current_op == '^' :
151
+ result = operation_caret (result , num )
152
+ except (OverflowError , ValueError ):
153
+ # Handle overflow by using a simplified calculation
154
+ if current_op == '@' :
155
+ result = result * num * 2 # Simplified approximation
156
+ elif current_op == '&' :
157
+ result = result * num # Simplified approximation
158
+ elif current_op == '$' :
159
+ result = result + num # Simplified approximation
160
+ elif current_op == '^' :
161
+ result = max (result , num ) # Simplified approximation
162
+
163
+ return result
164
+
165
+ # Map symbols to operation names
166
+ SYMBOL_TO_OPERATION = {
167
+ '@' : 'at_operation' ,
168
+ '&' : 'amp_operation' ,
169
+ '$' : 'dollar_operation' ,
170
+ '^' : 'caret_operation'
171
+ }
172
+
173
+ # Operation definitions for reference
174
+ OPERATION_DEFINITIONS = {
175
+ "@" : "a@b = (a^b) + (a*b)" ,
176
+ "&" : "a&b = ((a+b)/2) * |a-b|" ,
177
+ "$" : "a$b = a + (a-1) + (a-2) + ... + (a-b+1)" ,
178
+ "^" : "a^b = a*b if both even, a+b if both odd, a-b otherwise"
179
+ }
0 commit comments