symbolic mathematics engine in OCaml with differentiation, integration, simplification, and numerical methods
1type token =
2 | Num of float
3 | Var of string
4 | Ident of string
5 | Plus | Minus | Star | Slash | Caret
6 | LParen | RParen
7 | EOF
8
9let is_digit c = c >= '0' && c <= '9'
10let is_alpha c = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
11let is_alphanum c = is_alpha c || is_digit c
12
13let tokenize str =
14 let len = String.length str in
15 let rec aux i acc =
16 if i >= len then List.rev (EOF :: acc)
17 else
18 match str.[i] with
19 | ' ' | '\t' | '\n' -> aux (i + 1) acc
20 | '+' -> aux (i + 1) (Plus :: acc)
21 | '-' -> aux (i + 1) (Minus :: acc)
22 | '*' -> aux (i + 1) (Star :: acc)
23 | '/' -> aux (i + 1) (Slash :: acc)
24 | '^' -> aux (i + 1) (Caret :: acc)
25 | '(' -> aux (i + 1) (LParen :: acc)
26 | ')' -> aux (i + 1) (RParen :: acc)
27 | c when is_digit c || c = '.' ->
28 let j = ref (i + 1) in
29 while !j < len && (is_digit str.[!j] || str.[!j] = '.') do
30 incr j
31 done;
32 let num_str = String.sub str i (!j - i) in
33 aux !j (Num (float_of_string num_str) :: acc)
34 | c when is_alpha c ->
35 let j = ref (i + 1) in
36 while !j < len && is_alphanum str.[!j] do
37 incr j
38 done;
39 let id = String.sub str i (!j - i) in
40 let tok = if !j < len && str.[!j] = '(' then Ident id else Var id in
41 aux !j (tok :: acc)
42 | c -> failwith (Printf.sprintf "unexpected character: %c" c)
43 in
44 aux 0 []