110 lines
4.4 KiB
OCaml
110 lines
4.4 KiB
OCaml
open Leibniz
|
|
|
|
let print_help () =
|
|
print_endline "leibniz - symbolic differentiation engine";
|
|
print_endline "";
|
|
print_endline "commands:";
|
|
print_endline " diff <var> <expr> - differentiate expression";
|
|
print_endline " partial <var1,var2> <expr> - partial derivative";
|
|
print_endline " integrate <var> <expr> - symbolic integration";
|
|
print_endline " simplify <expr> - simplify expression";
|
|
print_endline " eval <var=val,...> <expr> - evaluate numerically";
|
|
print_endline " taylor <var> <center> <order> <expr> - taylor series expansion";
|
|
print_endline " gradient <var1,var2> <expr> - compute gradient";
|
|
print_endline " latex <expr> - output latex format";
|
|
print_endline " graphviz <expr> - output graphviz format";
|
|
print_endline " help - show this help";
|
|
print_endline " quit - exit";
|
|
print_endline ""
|
|
|
|
let parse_env str =
|
|
let pairs = String.split_on_char ',' str in
|
|
List.map (fun p ->
|
|
match String.split_on_char '=' p with
|
|
| [var; value] -> (String.trim var, float_of_string (String.trim value))
|
|
| _ -> failwith "invalid environment format"
|
|
) pairs
|
|
|
|
let () =
|
|
print_help ();
|
|
|
|
let rec loop () =
|
|
print_string "> ";
|
|
flush stdout;
|
|
try
|
|
let line = read_line () in
|
|
let parts = String.split_on_char ' ' line in
|
|
match parts with
|
|
| [] -> loop ()
|
|
| "quit" :: _ -> ()
|
|
| "help" :: _ -> print_help (); loop ()
|
|
| "diff" :: var :: rest ->
|
|
let expr_str = String.concat " " rest in
|
|
let expr = Parser.parse expr_str in
|
|
let result = Diff.diff var expr in
|
|
print_endline (Expr.to_string result);
|
|
loop ()
|
|
| "partial" :: vars :: rest ->
|
|
let var_list = String.split_on_char ',' vars in
|
|
let expr_str = String.concat " " rest in
|
|
let expr = Parser.parse expr_str in
|
|
let result = List.fold_left (fun e v -> Diff.diff (String.trim v) e) expr var_list in
|
|
print_endline (Expr.to_string result);
|
|
loop ()
|
|
| "integrate" :: var :: rest ->
|
|
let expr_str = String.concat " " rest in
|
|
let expr = Parser.parse expr_str in
|
|
(match Integrate.integrate var expr with
|
|
| Some result -> print_endline (Expr.to_string result)
|
|
| None -> print_endline "integration failed: no closed form found");
|
|
loop ()
|
|
| "simplify" :: rest ->
|
|
let expr_str = String.concat " " rest in
|
|
let expr = Parser.parse expr_str in
|
|
let result = Simplify.simplify expr in
|
|
print_endline (Expr.to_string result);
|
|
loop ()
|
|
| "eval" :: env_str :: rest ->
|
|
let env = parse_env env_str in
|
|
let expr_str = String.concat " " rest in
|
|
let expr = Parser.parse expr_str in
|
|
let result = Eval.eval env expr in
|
|
print_endline (string_of_float result);
|
|
loop ()
|
|
| "taylor" :: var :: center_str :: order_str :: rest ->
|
|
let center = float_of_string center_str in
|
|
let order = int_of_string order_str in
|
|
let expr_str = String.concat " " rest in
|
|
let expr = Parser.parse expr_str in
|
|
let result = Series.taylor var expr (Expr.Const center) order in
|
|
print_endline (Expr.to_string result);
|
|
loop ()
|
|
| "gradient" :: vars :: rest ->
|
|
let var_list = List.map String.trim (String.split_on_char ',' vars) in
|
|
let expr_str = String.concat " " rest in
|
|
let expr = Parser.parse expr_str in
|
|
let grad = Multivariate.gradient var_list expr in
|
|
print_endline "[";
|
|
List.iter (fun g -> print_endline (" " ^ Expr.to_string g)) grad;
|
|
print_endline "]";
|
|
loop ()
|
|
| "latex" :: rest ->
|
|
let expr_str = String.concat " " rest in
|
|
let expr = Parser.parse expr_str in
|
|
print_endline (Format.to_latex expr);
|
|
loop ()
|
|
| "graphviz" :: rest ->
|
|
let expr_str = String.concat " " rest in
|
|
let expr = Parser.parse expr_str in
|
|
print_endline (Format.to_graphviz expr);
|
|
loop ()
|
|
| _ ->
|
|
print_endline "unknown command (type 'help' for commands)";
|
|
loop ()
|
|
with
|
|
| End_of_file -> ()
|
|
| e ->
|
|
print_endline ("error: " ^ Printexc.to_string e);
|
|
loop ()
|
|
in
|
|
loop ()
|