Warning, /education/kalzium/src/solver/datastruct.ml is written in an unsupported language. File is not indexed.
0001 (* 0002 SPDX-FileCopyrightText: 2004 Thomas Nagy <tnagy2^8@yahoo.fr> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 *) 0006 0007 open List;; 0008 open Chemset;; 0009 open Hashtbl;; 0010 open Array;; 0011 0012 class eqtable = 0013 object (self) 0014 0015 (* columns : vars + formula | lines : chemical elements *) 0016 val mutable numtbl = Array.make_matrix 0 0 0 0017 val mutable strtbl = Array.make 0 "" 0018 val mutable vartbl = Array.make 0 "" 0019 val mutable soltbl = Array.make 0 0 0020 val mutable m_solved = false 0021 val mutable m_middle = 0 0022 0023 (* val mutable (table:int array array) = [||] *) 0024 0025 (* lines : i : chem element *) 0026 (* columns : vars j *) 0027 method getsize_i () = Array.length numtbl 0028 method getsize_j () = if (self#getsize_i () > 0) then Array.length numtbl.(0) else 0 0029 0030 method getline j = numtbl.(j) 0031 0032 method getformula k = strtbl.(k) 0033 method getvar k = vartbl.(k) 0034 method getsol k = soltbl.(k) 0035 0036 method setsol k v = soltbl.(k) <- v 0037 method isSolved () = m_solved 0038 0039 method get_eq_sol () = 0040 let str = ref "" in 0041 for j=0 to (self#getsize_j () -1) do 0042 if (j == m_middle) then str := (!str)^" -> " 0043 else if (j>0 && j<self#getsize_j ()) then str := (!str)^" + "; 0044 0045 str := (!str)^"<b>"^string_of_int(self#getsol j)^"</b> "^(self#getformula j); 0046 done; 0047 !str 0048 0049 method get_eq_orig () = 0050 let str = ref "" in 0051 for j=0 to (self#getsize_j () -1) do 0052 if (j == m_middle) then str := (!str)^" -> " 0053 else if (j>0 && j<self#getsize_j ()) then str := (!str)^" + "; 0054 0055 str := (!str)^"<b>"^(self#getvar j)^"</b> "^(self#getformula j); 0056 done; 0057 !str 0058 0059 method private init i j = numtbl <- Array.make_matrix i j 0; 0060 strtbl <- Array.make j ""; 0061 vartbl <- Array.make j ""; 0062 soltbl <- Array.make j 0 0063 0064 method clear () = 0065 self#init 0 0; 0066 0067 method print_all () = 0068 Printf.printf "--- start print_all ---\n"; 0069 for i = 0 to (self#getsize_i ())-1 do 0070 for j = 0 to (self#getsize_j ())-1 do 0071 Printf.printf "%d " (numtbl.(i).(j)); 0072 done; 0073 Printf.printf "\n"; 0074 done; 0075 Printf.printf "--- end print_all ---\n"; 0076 flush_all () 0077 0078 (* build the matrix to solve *) 0079 method build (lst:listitems) = 0080 let nb_symbols = ref 0 in 0081 let item_array = Array.of_list lst in 0082 let record:(string, int) Hashtbl.t = Hashtbl.create 10 in 0083 let nb_items = ref (Array.length item_array) in 0084 for i=0 to !nb_items-1 do 0085 Hashtbl.iter (fun sym _ -> 0086 (* take all chemical elements but simplify ions (+ or -) into + *) 0087 let symprocessed = if String.contains sym '+' || String.contains sym '-' 0088 then "+" else sym in 0089 0090 if not (Hashtbl.mem record symprocessed) then begin 0091 Hashtbl.add record symprocessed !nb_symbols; 0092 nb_symbols := !nb_symbols+1 0093 end 0094 ) item_array.(i).itbl.hashtbl 0095 done; 0096 0097 (* initialize the matrix *) 0098 self#init (!nb_symbols) (!nb_items); 0099 0100 (* process each atom*) 0101 for i=0 to !nb_items-1 do 0102 (* find the middle (->) - nothing to do with the others things in this loop *) 0103 if (item_array.(i).sign<0 && i>0) then (if (item_array.(i-1).sign>0) then m_middle<-i); 0104 0105 (* store the molecule formula *) 0106 vartbl.(i) <- item_array.(i).ikey; 0107 strtbl.(i) <- item_array.(i).itbl.formula; 0108 0109 (* for each molecule, process the atoms *) 0110 Hashtbl.iter (fun sym qte -> 0111 0112 if String.contains sym '+' || String.contains sym '-' then begin 0113 (* it is an electric charge *) 0114 let chargesign = if String.contains sym '-' then -1 else 1 in 0115 let line_idx = (Hashtbl.find record "+") in 0116 numtbl.(line_idx).(i) <- qte * item_array.(i).sign * chargesign 0117 end 0118 else begin 0119 (* check if the atom is already there *) 0120 let line_idx = (Hashtbl.find record sym) in 0121 numtbl.(line_idx).(i) <- (qte * item_array.(i).sign) 0122 end 0123 ) item_array.(i).itbl.hashtbl 0124 done 0125 0126 end;;