We take two tcl access scripts, presuming presence of [Maxima] and [PostgreSQL] on a system or in the latter case on some system in the network: proc domaxima { {m} } { set t "display2d:false;\n$m;" # return [string range [exec maxima << $t | tail -2 ] 6 end-7] return [string range [exec maxima -q << $t ] 32 end-7] #return [exec maxima --real-quiet << $t ] } proc dosql {s} { global db if {[catch {pg_exec $db $s} reply]} { puts "sql error : $reply,[pg_result $reply -error]" return "Error" } if {[pg_result $reply -status] == "PGRES_COMMAND_OK"} { return {} } if {[pg_result $reply -status] != "PGRES_TUPLES_OK"} { puts "sql error: [pg_result $reply -error]" return "Error" } return [pg_result $reply -llist] # pg_result $reply -clear return } # You could use another with similar results, it appears: package require pgintcl # connect to your sql server: set db [pg_connect -conninfo [list host = 192.168.0.1 user = zxy dbname = somedb password = 0x987654]] # Now create a table for formulas dosql "create table formula (f varchar(256))" Now we can try to make a nice database with formulas: dosql "insert into formula values ([pg_quote "x^2"])" dosql "insert into formula values ([pg_quote "x^3"])" But we can also use maxima to help us, for instance the optimizer will reorder terms and at request also simplify so we can keep formulas unique for instance: dosql "insert into formula values ([pg_quote [domaxima "x^4"]])" dosql "insert into formula values ([pg_quote [domaxima "x^3"]])" Now lets look at the nice lil' list of math work: foreach i [dosql "select distinct f from formula"] {puts |$i} |x^2 |x^3 |x^4 A more interesting example, a list of repeated derivatives of a products of two functions, a well known formula for case 1: dosql "create table derivatives (ref varchar(64), f varchar(10000), df varchar(10000))" set i 1; set fo "q(x)*r(x)"; dosql "insert into derivatives values ( [pg_quote "prod$i"], [pg_quote [domaxima $fo]], [pg_quote [domaxima "diff($fo)"]] )" incr i; set fo "diff($fo)"; dosql "insert into derivatives values ( [pg_quote "prod$i"], [pg_quote [domaxima $fo]], [pg_quote [domaxima "diff($fo)"]] )" incr i; set fo "diff($fo)"; dosql "insert into derivatives values ( [pg_quote "prod$i"], [pg_quote [domaxima $fo]], [pg_quote [domaxima "diff($fo)"]] )" incr i; set fo "diff($fo)"; dosql "insert into derivatives values ( [pg_quote "prod$i"], [pg_quote [domaxima $fo]], [pg_quote [domaxima "diff($fo)"]] )" Of course that could be easily put in a loop, but it's to prove the principle. Now: % foreach i [dosql "select * from derivatives"] {puts $i} prod1 q(x)*r(x) (q(x)*'diff(r(x),x,1)+r(x)*'diff(q(x),x,1))*del(x) prod2 (q(x)*'diff(r(x),x,1)+r(x)*'diff(q(x),x,1))*del(x) {((q(x)*'diff(r(x),x,2)+2*'diff(q(x),x,1)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,2)) *del(x) +(q(x)*'diff(r(x),x,1)+r(x)*'diff(q(x),x,1))*'diff(del(x),x,1)) *del(x)} prod3 {((q(x)*'diff(r(x),x,2)+2*'diff(q(x),x,1)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,2)) *del(x) +(q(x)*'diff(r(x),x,1)+r(x)*'diff(q(x),x,1))*'diff(del(x),x,1)) *del(x)} {(((q(x)*'diff(r(x),x,3)+3*'diff(q(x),x,1)*'diff(r(x),x,2) +3*'diff(q(x),x,2)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,3)) *del(x) +(q(x)*'diff(r(x),x,1)+r(x)*'diff(q(x),x,1))*'diff(del(x),x,2) +2*(q(x)*'diff(r(x),x,2)+2*'diff(q(x),x,1)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,2))*'diff(del(x),x,1)) *del(x) +'diff(del(x),x,1)*((q(x)*'diff(r(x),x,2) +2*'diff(q(x),x,1)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,2)) *del(x) +(q(x)*'diff(r(x),x,1)+r(x)*'diff(q(x),x,1)) *'diff(del(x),x,1))) *del(x)} prod4 {(((q(x)*'diff(r(x),x,3)+3*'diff(q(x),x,1)*'diff(r(x),x,2) +3*'diff(q(x),x,2)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,3)) *del(x) +(q(x)*'diff(r(x),x,1)+r(x)*'diff(q(x),x,1))*'diff(del(x),x,2) +2*(q(x)*'diff(r(x),x,2)+2*'diff(q(x),x,1)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,2))*'diff(del(x),x,1)) *del(x) +'diff(del(x),x,1)*((q(x)*'diff(r(x),x,2) +2*'diff(q(x),x,1)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,2)) *del(x) +(q(x)*'diff(r(x),x,1)+r(x)*'diff(q(x),x,1)) *'diff(del(x),x,1))) *del(x)} {((((q(x)*'diff(r(x),x,4)+4*'diff(q(x),x,1)*'diff(r(x),x,3) +6*'diff(q(x),x,2)*'diff(r(x),x,2) +4*'diff(q(x),x,3)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,4)) *del(x) +(q(x)*'diff(r(x),x,1)+r(x)*'diff(q(x),x,1))*'diff(del(x),x,3) +3*(q(x)*'diff(r(x),x,2)+2*'diff(q(x),x,1)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,2))*'diff(del(x),x,2) +3*(q(x)*'diff(r(x),x,3)+3*'diff(q(x),x,1)*'diff(r(x),x,2) +3*'diff(q(x),x,2)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,3))*'diff(del(x),x,1)) *del(x) +2*'diff(del(x),x,1) *((q(x)*'diff(r(x),x,3)+3*'diff(q(x),x,1)*'diff(r(x),x,2) +3*'diff(q(x),x,2)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,3)) *del(x) +(q(x)*'diff(r(x),x,1)+r(x)*'diff(q(x),x,1))*'diff(del(x),x,2) +2*(q(x)*'diff(r(x),x,2)+2*'diff(q(x),x,1)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,2))*'diff(del(x),x,1)) +'diff(del(x),x,2)*((q(x)*'diff(r(x),x,2) +2*'diff(q(x),x,1)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,2)) *del(x) +(q(x)*'diff(r(x),x,1)+r(x)*'diff(q(x),x,1)) *'diff(del(x),x,1))) *del(x) +'diff(del(x),x,1)*(((q(x)*'diff(r(x),x,3) +3*'diff(q(x),x,1)*'diff(r(x),x,2) +3*'diff(q(x),x,2)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,3)) *del(x) +(q(x)*'diff(r(x),x,1)+r(x)*'diff(q(x),x,1)) *'diff(del(x),x,2) +2*(q(x)*'diff(r(x),x,2) +2*'diff(q(x),x,1)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,2))*'diff(del(x),x,1)) *del(x) +'diff(del(x),x,1) *((q(x)*'diff(r(x),x,2) +2*'diff(q(x),x,1)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,2)) *del(x) +(q(x)*'diff(r(x),x,1)+r(x)*'diff(q(x),x,1)) *'diff(del(x),x,1)))) *del(x)} More intelligently we can now look up in our little database what the general form is of a certain derivative of a product of functions, and what the original was from that derivative (the integral except for a constant), for instance: (Tcl) 69 % dosql "select ref, f from derivatives where df = [pg_quote "(q(x)*'diff(r(x),x,1)+r(x)*'diff(q(x),x,1))*del(x)"]" {prod1 q(x)*r(x)} Or case 4: dosql "select ref from derivatives where df = [pg_quote [domaxima "((((q(x)*'diff(r(x),x,4)+4*'diff(q(x),x,1)*'diff(r(x),x,3) +6*'diff(q(x),x,2)*'diff(r(x),x,2) +4*'diff(q(x),x,3)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,4)) *del(x) +(q(x)*'diff(r(x),x,1)+r(x)*'diff(q(x),x,1))*'diff(del(x),x,3) +3*(q(x)*'diff(r(x),x,2)+2*'diff(q(x),x,1)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,2))*'diff(del(x),x,2) +3*(q(x)*'diff(r(x),x,3)+3*'diff(q(x),x,1)*'diff(r(x),x,2) +3*'diff(q(x),x,2)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,3))*'diff(del(x),x,1)) *del(x) +2*'diff(del(x),x,1) *((q(x)*'diff(r(x),x,3)+3*'diff(q(x),x,1)*'diff(r(x),x,2) +3*'diff(q(x),x,2)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,3)) *del(x) +(q(x)*'diff(r(x),x,1)+r(x)*'diff(q(x),x,1))*'diff(del(x),x,2) +2*(q(x)*'diff(r(x),x,2)+2*'diff(q(x),x,1)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,2))*'diff(del(x),x,1)) +'diff(del(x),x,2)*((q(x)*'diff(r(x),x,2) +2*'diff(q(x),x,1)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,2)) *del(x) +(q(x)*'diff(r(x),x,1)+r(x)*'diff(q(x),x,1)) *'diff(del(x),x,1))) *del(x) +'diff(del(x),x,1)*(((q(x)*'diff(r(x),x,3) +3*'diff(q(x),x,1)*'diff(r(x),x,2) +3*'diff(q(x),x,2)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,3)) *del(x) +(q(x)*'diff(r(x),x,1)+r(x)*'diff(q(x),x,1)) *'diff(del(x),x,2) +2*(q(x)*'diff(r(x),x,2) +2*'diff(q(x),x,1)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,2))*'diff(del(x),x,1)) *del(x) +'diff(del(x),x,1) *((q(x)*'diff(r(x),x,2) +2*'diff(q(x),x,1)*'diff(r(x),x,1) +r(x)*'diff(q(x),x,2)) *del(x) +(q(x)*'diff(r(x),x,1)+r(x)*'diff(q(x),x,1)) *'diff(del(x),x,1)))) *del(x)"]]" prod4 It finds the correct f for df, with the help of an additional 'domaxima' it doesn't matter what the formatting of the text of the formula is. Try for yourself. ---- To remember manipulations easier adn centrally, I've made a history table which can contain all succesfully executed sql commands with timestamp on the sql server: proc dosql { {s} } { global db if {[catch {pg_exec $db $s} reply]} { puts "sql error : $reply,[pg_result $reply -error]" return "Error" } if {[pg_result $reply -status] == "PGRES_COMMAND_OK"} { catch {pg_exec $db "insert into history values (DEFAULT, [pg_quote $s] , 'now' , NULL)"} return {} } if {[pg_result $reply -status] != "PGRES_TUPLES_OK"} { puts "sql error: [pg_result $reply -error]" return "Error" } set res [pg_result $reply -llist] catch {pg_exec $db "insert into history values (DEFAULT, [pg_quote $s] , 'now' , NULL)"} return $res # we only put non-errors in the history # pg_result $reply -clear return } # once only: dosql "create table history (i serial, l text, date timestamp , comment text)" Now we can for instance dosql "select date,l from history" ---- !!!!!! %| enter categories here |% !!!!!!