modelicac 1.12.1
Allan CORNET [Wed, 6 Jan 2010 07:55:11 +0000 (08:55 +0100)]
34 files changed:
scilab/modules/scicos/src/modelica_compiler/.depend [changed mode: 0755->0644]
scilab/modules/scicos/src/modelica_compiler/README.txt
scilab/modules/scicos/src/modelica_compiler/bipartiteGraph.ml
scilab/modules/scicos/src/modelica_compiler/bipartiteGraph.mli
scilab/modules/scicos/src/modelica_compiler/causalityGraph.ml
scilab/modules/scicos/src/modelica_compiler/causalityGraph.mli
scilab/modules/scicos/src/modelica_compiler/compilation.ml
scilab/modules/scicos/src/modelica_compiler/compilation.mli
scilab/modules/scicos/src/modelica_compiler/graphNodeSet.ml
scilab/modules/scicos/src/modelica_compiler/graphNodeSet.mli
scilab/modules/scicos/src/modelica_compiler/hungarianMethod.ml
scilab/modules/scicos/src/modelica_compiler/hungarianMethod.mli
scilab/modules/scicos/src/modelica_compiler/instantiation.ml
scilab/modules/scicos/src/modelica_compiler/instantiation.mli
scilab/modules/scicos/src/modelica_compiler/lexer.mll
scilab/modules/scicos/src/modelica_compiler/linenum.mll [changed mode: 0755->0644]
scilab/modules/scicos/src/modelica_compiler/optimization.ml
scilab/modules/scicos/src/modelica_compiler/optimization.mli
scilab/modules/scicos/src/modelica_compiler/optimizingCompiler.ml
scilab/modules/scicos/src/modelica_compiler/optimizingCompiler.mli
scilab/modules/scicos/src/modelica_compiler/parseTree.ml
scilab/modules/scicos/src/modelica_compiler/parseTree.mli
scilab/modules/scicos/src/modelica_compiler/parser.mly
scilab/modules/scicos/src/modelica_compiler/precompilation.ml
scilab/modules/scicos/src/modelica_compiler/precompilation.mli
scilab/modules/scicos/src/modelica_compiler/scicosCodeGeneration.ml
scilab/modules/scicos/src/modelica_compiler/scicosCodeGeneration.mli
scilab/modules/scicos/src/modelica_compiler/scicosOptimizingCompiler.ml
scilab/modules/scicos/src/modelica_compiler/squareSparseMatrix.ml
scilab/modules/scicos/src/modelica_compiler/squareSparseMatrix.mli
scilab/modules/scicos/src/modelica_compiler/symbolicExpression.ml
scilab/modules/scicos/src/modelica_compiler/symbolicExpression.mli
scilab/modules/scicos/src/modelica_compiler/xMLCodeGeneration.ml [changed mode: 0755->0644]
scilab/modules/scicos/src/modelica_compiler/xMLCodeGeneration.mli [changed mode: 0755->0644]

old mode 100755 (executable)
new mode 100644 (file)
index 2842b89..38b57fb
@@ -39,8 +39,8 @@ optimizingCompiler.cmx: xMLCodeGeneration.cmx precompilation.cmx parser.cmx \
     optimization.cmx lexer.cmx instantiation.cmx compilation.cmx \
     optimizingCompiler.cmi 
 scicosCodeGeneration.cmo: symbolicExpression.cmi optimization.cmi \
-    scicosCodeGeneration.cmi 
+    instantiation.cmi scicosCodeGeneration.cmi 
 scicosCodeGeneration.cmx: symbolicExpression.cmx optimization.cmx \
-    scicosCodeGeneration.cmi 
+    instantiation.cmx scicosCodeGeneration.cmi 
 scicosOptimizingCompiler.cmo: scicosCodeGeneration.cmi optimizingCompiler.cmi 
 scicosOptimizingCompiler.cmx: scicosCodeGeneration.cmx optimizingCompiler.cmx 
index fc922ba..ae47738 100644 (file)
-1. Introduction
-===============
-
-This document describes the Modelica compiler Modelicac.
-Modelicac is a tool that compiles a subset of the Modelica 2.0 language (see
-section 4). This subset allows the description of continuous-time physical
-models that can be simulated under the Scicos environment.
-
-
-2. How to compile Modelicac
-===========================
-
-Be sure to have a recent Objective Caml (v.3.06 or later) properly installed
-on the machine.
-In the source directory, type:
-
-  make depend
-
-then:
-
-  make (to compile a bytecode version of Modelicac)
-or:
-  make opt (to compile a native-code version of Modelicac)
-
-Ocaml code HTML documentation can be automatically generated from module types
-by typing:
-
- make doc
-
-This will create a directory named "doc" in the current directory. "index.html"
-is the entry point of the documentation.
-
-
-3. How to use Modelicac
-=======================
-
-Modelicac compiles Modelica files whose name ends by ".mo".
-The modelicac command, when invoked with the appropriate options, may produce:
-- A C file containing a function suitable to be called by the Scicos tool in
-  order to perform a model simulation;
-- A "*.moc" file which is the format of a precompiled Modelica class stored for
-  later instantiation.
-
-It is required that each "*.mo" file contains exactly one Modelica class
-(see section 4) and that the name of the class matches the name of the file that
-contains its definition.
-
-By default, Modelicac removes every variable that is not reinitialized in a
-"when" section and for which it can express its value with respect to the
-remaining variables of the system. It is possible to disable this option by
-specifying "-keep-all-variables" when calling Modelicac (see below).
-
-Usage
------
-
-modelicac [-c] [-o <outputfile>] <inputfile> [other options]
-
--c: Compile only, do not instantiate. Modelicac produces a "*.moc" file when
-    invoked with that option.
--o <outputfile>: Set output file name to <outputfile> (this option also works
-                 with -c option but is somewhat useless because of the class
-                 name restrictions given above).
-Other options include:
--L <directory>: Add <directory> to the list of directories to be searched when
-                producing a C file (no effect when used with -c).
--hpath <directory>: Specify a path to be added to #include directives in the
-                    generated C code.
--keep-all-variables: Do not remove any variable from the initial system.
--jac: Generate analytic jacobian matrix code.
--no-parameter-removal: Do not remove any parameter
--no-simplifs: Same as -keep-all-variables -no-parameter-removal
--trace <filename>: Generate tracing information for external function calls
-                   into <filename>
--xml: Generate an XML version of the model instead of target code
-
-Examples
--------
-
-+------------------------------------------------------------------------------+
-| Modelicac invokation         | Result                                        |
-+------------------------------+-----------------------------------------------+
-| modelicac foo.mo             | Produces a file named "foo.c" containing a    |
-|                              | C function named "foo" to be called by Scicos.|
-+------------------------------+-----------------------------------------------+
-| modelicac -c foo.mo          | Produces a file named "foo.moc" containing a  |
-|                              | precompiled class named "foo".                |
-+------------------------------+-----------------------------------------------+
-| modelicac -o dir/bar.c       | Same as "modelicac foo.mo", but output file   |
-|  foo.mo                      | name is "bar.c" and the resulting file is     |
-|                              | located in directory "dir".                   |
-+------------------------------+-----------------------------------------------+
-| modelicac -L dir1 -L dir2 ...| Same as "modelicac foo.mo", but if some       |
-| -L dirN foo.mo               | precompiled class "bar" needed by class "foo" |
-|                              | isn't found in the current directory (i.e.    |
-|                              | there is no file named "bar.moc" in the       |
-|                              | current directory), it is searched into       |
-|                              | "dir1", and, if not found, into "dir2", ...,  |
-|                              | "dirN" until a file named "bar.moc" is found. |
-+------------------------------+-----------------------------------------------+
-
-
-3. The compiled Modelica subset
-===============================
-
- The Modelicac compiler compiles a subset of the Modelica language that allows
-the description of some countinuous equational models. Each Modelica class is
-stored in its own file whose name is the name of the class followed by the "mo"
-extension.
-
-Restrictions on the declaration of a modelica class header
-----------------------------------------------------------
- - only the keyword "class" is allowed to declare a Modelica class ("function"
-   is allowed to define functions, but in a very restrictive way, see below);
- - "within" is not allowed ;
- - a class cannot be "final" ;
- - short class definitions (type declarations) are not allowed ;
- - inheritance is not allowed ;
- - "encapsulated" and "partial" classes are not allowed ;
-
-Restrictions on the declaration of the components of a class
-------------------------------------------------------------
- - imports are not allowed ;
- - inner classes are not allowed ;
- - "inner", "outer" are not allowed ;
- - "protected" component lists are not allowed ;
- - "final" and "replaceable" are not allowed ;
- - "external" is restricted (see "Restrictions on external function
-   definitions") ;
- - "constant" is not allowed ;
- - "input" and "output" may only be used to define I/O ports of the toplevel
-   class beeing compiled to C code (see example below) ;
- - "algorithm" sections are not allowed ;
- - arrays must contain numerical types.
-
-Restrictions on modifications
------------------------------
- - modifications may only apply to base types, scalar or not ;
- - selections of subarrays are not allowed (i.e. a[:].b = ...) ;
- - "redeclare", "each" and "final" are not allowed.
-
-Restrictions on equations
--------------------------
- - equational "if" is not allowed in the specification of an equation.
-
-Restrictions on expressions
------------------------------
- - "for" expressions must have an integer range (since algorithms are not
-   allowed) ;
- - selection of subarrays is restricted to numerical arrays ;
- - array concatenation (using "[" and "]") is not allowed.
-
-Restrictions on external function definitions (to be implemented)
------------------------------------------------------------------
- Only functions taking zero or several Real scalars and returning exactly one
-Real scalar are supported.
- External functions must be declared in a separate file (one file per function).
-This file contains the prototype of the corresponding C function with the same
-name. For example:
-
-function Blackbox
-  input Real u;
-  output Rea y;
-external;
-end Blackbox;
-
- This function can be called from another modelica file using the following
-syntax (assuming Blackbox.mo to be defined in ./Foo/Bar):
-
-...Blackbox(42)...
-
-Modelicac assumes that both ./Foo/Bar/Blackbox.h and ./Foo/Bar/Blackbox.c exist
-(see "-hpath" option) and contain the C code corresponding to a C function with
-the following signature:
-
-double blackbox(double u);
+1. Introduction\r
+===============\r
+\r
+This document describes the Modelica compiler Modelicac.\r
+Modelicac is a tool that compiles a subset of the Modelica 2.0 language (see\r
+section 4). This subset allows the description of continuous-time physical\r
+models that can be simulated under AMESim.\r
+\r
+\r
+2. How to compile Modelicac\r
+===========================\r
+\r
+Be sure to have a recent Objective Caml (v.3.06 or later) properly installed\r
+on the machine.\r
+In the source directory, type:\r
+\r
+  make depend\r
+\r
+then:\r
+\r
+  make (to compile a bytecode version of Modelicac)\r
+or:\r
+  make opt (to compile a native-code version of Modelicac)\r
+\r
+Ocaml code HTML documentation can be automatically generated from module types\r
+by typing:\r
+\r
+ make doc\r
+\r
+This will create a directory named "doc" in the current directory. "index.html"\r
+is the entry point of the documentation.\r
+\r
+\r
+3. How to use Modelicac\r
+=======================\r
+\r
+Modelicac compiles Modelica files whose name ends by ".mo".\r
+The modelicac command, when invoked with the appropriate options, may produce:\r
+- A C file containing a function suitable to be called by AMESim in\r
+  order to perform a model simulation;\r
+- A "*.moc" file which is the format of a precompiled Modelica class stored for\r
+  later instantiation.\r
+\r
+It is required that each "*.mo" file contains exactly one Modelica class\r
+(see section 4) and that the name of the class matches the name of the file that\r
+contains its definition.\r
+\r
+By default, Modelicac removes every variable that is not reinitialized in a\r
+"when" section and for which it can express its value with respect to the\r
+remaining variables of the system. It is possible to disable this option by\r
+specifying "-keep-all-variables" when calling Modelicac (see below).\r
+\r
+Usage\r
+-----\r
+\r
+modelicac [-c] [-o <outputfile>] <inputfile> [other options]\r
+\r
+-c: Compile only, do not instantiate. Modelicac produces a "*.moc" file when\r
+    invoked with that option.\r
+-o <outputfile>: Set output file name to <outputfile> (this option also works\r
+                 with -c option but is somewhat useless because of the class\r
+                 name restrictions given above).\r
+Other options include:\r
+-L <directory>: Add <directory> to the list of directories to be searched when\r
+                producing a C file (no effect when used with -c).\r
+-hpath <directory>: Specify a path to be added to #include directives in the\r
+                    generated C code.\r
+-keep-all-variables: Do not remove any variable from the initial system.\r
+-jac: Generate analytic jacobian matrix code.\r
+-no-parameter-removal: Do not remove any parameter\r
+-no-simplifs: Same as -keep-all-variables -no-parameter-removal\r
+-xml: Generate an XML version of the model instead of target code\r
+-with-init-in <filename>: Generate code for 'separate initialization' mode\r
+                          (where initialization data is loaded from\r
+                          <filename>)\r
+-with-init-out <filename>: Generate code for 'separate initialization' mode\r
+                           (where initialization data is saved in\r
+                           <filename>)\r
+\r
+Examples\r
+-------\r
+\r
++------------------------------------------------------------------------------+\r
+| Modelicac invokation         | Result                                        |\r
++------------------------------+-----------------------------------------------+\r
+| modelicac foo.mo             | Produces a file named "foo.c" containing a    |\r
+|                              | C function named "foo" to be called by AMESim.|\r
++------------------------------+-----------------------------------------------+\r
+| modelicac -c foo.mo          | Produces a file named "foo.moc" containing a  |\r
+|                              | precompiled class named "foo".                |\r
++------------------------------+-----------------------------------------------+\r
+| modelicac -o dir/bar.c       | Same as "modelicac foo.mo", but output file   |\r
+|  foo.mo                      | name is "bar.c" and the resulting file is     |\r
+|                              | located in directory "dir".                   |\r
++------------------------------+-----------------------------------------------+\r
+| modelicac -L dir1 -L dir2 ...| Same as "modelicac foo.mo", but if some       |\r
+| -L dirN foo.mo               | precompiled class "bar" needed by class "foo" |\r
+|                              | isn't found in the current directory (i.e.    |\r
+|                              | there is no file named "bar.moc" in the       |\r
+|                              | current directory), it is searched into       |\r
+|                              | "dir1", and, if not found, into "dir2", ...,  |\r
+|                              | "dirN" until a file named "bar.moc" is found. |\r
++------------------------------+-----------------------------------------------+\r
+\r
+\r
+3. The compiled Modelica subset\r
+===============================\r
+\r
+ The Modelicac compiler compiles a subset of the Modelica language that allows\r
+the description of some countinuous equational models. Each Modelica class is\r
+stored in its own file whose name is the name of the class followed by the "mo"\r
+extension.\r
+\r
+Restrictions on the declaration of a modelica class header\r
+----------------------------------------------------------\r
+ - only the keyword "class" is allowed to declare a Modelica class ("function"\r
+   is allowed to define functions, but in a very restrictive way, see below);\r
+ - "within" is not allowed ;\r
+ - a class cannot be "final" ;\r
+ - short class definitions (type declarations) are not allowed ;\r
+ - inheritance is not allowed ;\r
+ - "encapsulated" and "partial" classes are not allowed ;\r
+\r
+Restrictions on the declaration of the components of a class\r
+------------------------------------------------------------\r
+ - imports are not allowed ;\r
+ - inner classes are not allowed ;\r
+ - "inner", "outer" are not allowed ;\r
+ - "protected" component lists are not allowed ;\r
+ - "final" and "replaceable" are not allowed ;\r
+ - "external" is restricted (see "Restrictions on external function\r
+   definitions") ;\r
+ - "constant" is not allowed ;\r
+ - "input" and "output" may only be used to define I/O ports of the toplevel\r
+   class beeing compiled to C code (see example below) ;\r
+ - "algorithm" sections are not allowed ;\r
+ - arrays must contain numerical types.\r
+\r
+Restrictions on modifications\r
+-----------------------------\r
+ - modifications may only apply to base types, scalar or not ;\r
+ - selections of subarrays are not allowed (i.e. a[:].b = ...) ;\r
+ - "redeclare", "each" and "final" are not allowed.\r
+\r
+Restrictions on equations\r
+-------------------------\r
+ - equational "if" is not allowed in the specification of an equation.\r
+\r
+Restrictions on expressions\r
+-----------------------------\r
+ - "for" expressions must have an integer range (since algorithms are not\r
+   allowed) ;\r
+ - selection of subarrays is restricted to numerical arrays ;\r
+ - array concatenation (using "[" and "]") is not allowed.\r
+\r
+Restrictions on external function definitions\r
+---------------------------------------------\r
+ Only functions taking zero or more Integer scalars, String scalars,\r
+Real scalars or Real arrays and returning exactly one\r
+Real scalar are supported.\r
+ External functions must be declared in the Modelica file that\r
+contains models that use them.\r
+The compiler assumes a corresponding C function with the same\r
+name to be provided by the simulation environment. For example:\r
+\r
+function Blackbox\r
+  input Real u[:];\r
+  output Real y;\r
+external;\r
+end Blackbox;\r
+\r
+ This function can be called from a Modelica model using the following\r
+syntax:\r
+\r
+...Blackbox(u)...\r
+\r
+ The corresponding C function is declared with the following signature:\r
+\r
+double blackbox(double *, int );\r
+\r
+(the last argument will be the size of the array whose first element\r
+is pointed to by the first argument, as specified in the Modelica\r
+Language Specification)\r
index 74c8a98..63ac596 100644 (file)
@@ -1,23 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 type t = Bipartite of node array * node array
 and node =
index 023a92f..57e202f 100644 (file)
@@ -1,23 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 (** This module provides the necessary structures and functions to solve a
 simple assignment problem using the Ford and Fulkerson method. *)
index 24800f6..45e574a 100644 (file)
@@ -1,23 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 (* Imperative implementation by Esko Nuutila and Eljas Soisalon-Soininen in   *)
 (* ON FINDING THE STRONGLY CONNECTED COMPONENTS IN A DIRECTED GRAPH (1994)    *)
index 552636d..3acaf5f 100644 (file)
@@ -1,19 +1,41 @@
-(** This module provides a graph structure over which it is possible to apply
-an algorithm that finds the strongly connected components of this graph. *)
-
-type t
-(** The type of the graph used to perform the strongly connected component
-finding algorithm. *)
-
-val create: int -> t
-(** [create size] creates a graph with [size] unconnected nodes. *)
-
-val connect: int -> int -> t -> unit
-(** [connect i j g] connects the [i]th node to the [j]th one in g. *)
-
-val strongly_connected_components: t -> int list list
-(** [strongly_connected_components g] returns the stronly connected components
-of [g] as a list of index lists. *)
-
-val print_with: (int -> unit) -> t -> unit
-(** [print_with print_fun g] prints the connexions in [g] using [print_fun]. *)
\ No newline at end of file
+(*\r
+ *  Modelicac\r
+ *\r
+ *  Copyright (C) 2005 - 2007 Imagine S.A.\r
+ *  For more information or commercial use please contact us at www.amesim.com\r
+ *\r
+ *  This program is free software; you can redistribute it and/or\r
+ *  modify it under the terms of the GNU General Public License\r
+ *  as published by the Free Software Foundation; either version 2\r
+ *  of the License, or (at your option) any later version.\r
+ *\r
+ *  This program is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU General Public License for more details.\r
+ *\r
+ *  You should have received a copy of the GNU General Public License\r
+ *  along with this program; if not, write to the Free Software\r
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
+ *\r
+ *)\r
+\r
+(** This module provides a graph structure over which it is possible to apply\r
+an algorithm that finds the strongly connected components of this graph. *)\r
+\r
+type t\r
+(** The type of the graph used to perform the strongly connected component\r
+finding algorithm. *)\r
+\r
+val create: int -> t\r
+(** [create size] creates a graph with [size] unconnected nodes. *)\r
+\r
+val connect: int -> int -> t -> unit\r
+(** [connect i j g] connects the [i]th node to the [j]th one in g. *)\r
+\r
+val strongly_connected_components: t -> int list list\r
+(** [strongly_connected_components g] returns the stronly connected components\r
+of [g] as a list of index lists. *)\r
+\r
+val print_with: (int -> unit) -> t -> unit\r
+(** [print_with print_fun g] prints the connexions in [g] using [print_fun]. *)\r
index 573ff2c..8872a41 100644 (file)
@@ -1,23 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 open Precompilation
 
@@ -41,7 +42,7 @@ type compilation_context =
   | ClassContext of compilation_context * compiled_class Lazy.t
   | ForContext of compilation_context * string
   | ModificationContext of compilation_context * compiled_class Lazy.t
-  | TopLevelContext
+  | TopLevelContext of (string * compiled_unit) list
 
 and compiled_unit =
   | CompiledClass of compiled_class Lazy.t
@@ -76,16 +77,20 @@ and compiled_subscript =
 
 and parameter =
   | IntegerParameter of parameter_attributes
+  | StringParameter of parameter_attributes
   | RealParameter of parameter_attributes
 
 and parameter_attributes =
   {
     pat_dimensions: compiled_subscript array;
     pat_comment: string;
-    pat_value: compiled_expression option
+    pat_value: compiled_expression option;
+    pat_infos: variable_infos
   }
 
 and variable =
+  | IntegerVariable of variable_attributes
+  | StringVariable of variable_attributes
   | DiscreteVariable of variable_attributes
   | RealVariable of variable_attributes
   | CompoundVariable of compiled_class Lazy.t * variable_attributes
@@ -96,7 +101,8 @@ and variable_attributes =
     vat_nature: nature;
     vat_inout: inout;
     vat_comment: string;
-    vat_modifications: compiled_modification list
+    vat_modifications: compiled_modification list;
+    vat_infos: variable_infos
   }
 
 and compiled_component =
@@ -112,6 +118,21 @@ and inout =
   | Output
   | Both
 
+and variable_infos =
+  {
+    var_name: string;
+    title: string;
+    unit: string;
+    quantity: string;
+    min: string;
+    max: string;
+    port_name: string;
+    port_type: string;
+    order: int;
+    io: int;
+    weight: float
+  }
+
 and compiled_equation =
   | CompiledEquality of compiled_expression * compiled_expression
   | CompiledFlowConnection of compiled_expression * compiled_expression
@@ -127,17 +148,24 @@ and compiled_when_expression =
 
 and compiled_expression =
   | Abs of compiled_expression
+  | Acos of compiled_expression
+  | Acosh of compiled_expression
   | Addition of compiled_expression * compiled_expression
   | And of compiled_expression * compiled_expression
+  | Asin of compiled_expression
+  | Asinh of compiled_expression
+  | Atan of compiled_expression
+  | Atanh of compiled_expression
   | Boolean of bool
   | Cardinality of compiled_expression
   | Cos of compiled_expression
+  | Cosh of compiled_expression
   | Der of compiled_expression
   | Division of compiled_expression * compiled_expression
   | Equals of compiled_expression * compiled_expression
   | Exp of compiled_expression
   | ExternalFunctionCall of string list * compiled_class Lazy.t *
-    compiled_expression list
+    compiled_argument list
   | Floor of compiled_expression
   | GreaterEqualThan of compiled_expression * compiled_expression
   | GreaterThan of compiled_expression * compiled_expression
@@ -154,9 +182,11 @@ and compiled_expression =
   | NotEquals of compiled_expression * compiled_expression
   | Or of compiled_expression * compiled_expression
   | Power of compiled_expression * compiled_expression
+  | Pre of compiled_expression
   | Real of float
   | Reference of compiled_reference
   | Sin of compiled_expression
+  | Sinh of compiled_expression
   | Sqrt of compiled_expression
   | String of string
   | Subtraction of compiled_expression * compiled_expression
@@ -165,6 +195,10 @@ and compiled_expression =
   | Time
   | Vector of compiled_expression array
 
+and compiled_argument =
+  | ScalarArgument of compiled_expression
+  | ArrayArgument of int list * compiled_expression array
+
 
 (* Marshaling *)
 
@@ -188,6 +222,11 @@ let read_class_file f =
           | Sys_error _ -> read_class_file' ss
   in read_class_file' !paths
 
+let rec last = function
+  | [] -> failwith "last"
+  | [x] -> x
+  | _ :: xs -> last xs
+
 let write_class_file f cu =
   let oc = open_out_bin f
   and flags = [Marshal.Closures] in
@@ -202,37 +241,58 @@ let create_filename name ext =
   let prefix, base = create_name [] name in
   List.fold_right Filename.concat prefix (base ^ ext)
 
+let rec get_compiled_class ctx name =
+  let name' = last name in
+  match ctx with
+  | ClassContext (ctx', _) | ForContext (ctx', _) |
+    ModificationContext (ctx', _) -> get_compiled_class ctx' name
+  | TopLevelContext funcs when List.mem_assoc name' funcs ->
+      List.assoc name' funcs
+  | TopLevelContext funcs ->
+      let f = create_filename name ".moc" in
+      read_class_file f
+
 
 (* Compilation *)
 
-let rec compile_main_class pcl = match pcl.public_classes with
-  | [] -> failwith "compile_main_class: No main class declared"
-  | [(_, pcl)] ->
-      begin match pcl.class_kind with
-        | ParseTree.Function ->
-            CompiledFunction (compile_compound_class TopLevelContext pcl)
-        | ParseTree.Class ->
-            CompiledClass (compile_compound_class TopLevelContext pcl)
-        | _ ->
-            failwith
-              "compile_main_class: Only external functions and classes allowed"
-      end
-  | _ -> failwith "compile_main_class: More than one class declared at toplevel"
+let rec compile_main_class pcls =
+  let add_class (cls, funcs) (id, pcl) = match pcl.class_kind with
+    | ParseTree.Function -> cls, (id, pcl) :: funcs
+    | ParseTree.Class | ParseTree.Model -> (id, pcl) :: cls, funcs
+    | _ ->
+        failwith "compile_main_class: Only external functions, models and \
+          classes allowed" in
+  let pcls =
+    List.flatten (List.map (function pcl -> pcl.public_classes) pcls) in
+  match List.fold_left add_class ([], []) pcls with
+  | [], _ -> failwith "compile_main_class: No main class declared"
+  | [id, pcl], funcs ->
+      let compile_function (id, pcl) =
+        id,
+        CompiledFunction (compile_compound_class (TopLevelContext []) pcl) in
+      let funcs' = List.map compile_function funcs in
+      id, CompiledClass (compile_compound_class (TopLevelContext funcs') pcl)
+  | _ :: _, _ ->
+      failwith "compile_main_class: More than one class declared at toplevel"
 
 and compile_compound_class ctx pcl =
   let rec ctx' = ClassContext (ctx, lccl)
   and defined_equs = lazy (compile_equation_clauses ctx' pcl.equs)
   and lccl = lazy
     {
-      ccl_public_cpnts = lazy (
-        List.map
-          (fun (id, cpnt) -> id, lazy (compile_component ctx' cpnt))
-          pcl.public_cpnts);
+      ccl_public_cpnts = lazy (compile_components ctx' 0 pcl.public_cpnts);
       ccl_initial_equs = lazy (fst (Lazy.force defined_equs));
-      ccl_equs = lazy (snd (Lazy.force defined_equs));
+      ccl_equs = lazy (snd (Lazy.force defined_equs))
     }
   in lccl
 
+and compile_components ctx i cpnts =
+  match cpnts with
+  | [] -> []
+  | (id, cpnt) :: cpnts ->
+      (id, lazy (compile_component ctx i id cpnt)) ::
+      compile_components ctx (i + 1) cpnts
+
 and compile_equation_clauses ctx equ_clauses =
   let rec compile_equation_clauses' init_equs equs = function
     | [] -> init_equs, equs
@@ -414,6 +474,10 @@ and compile_expression ctx expr =
         let cexpr = compile_expression' expr in
         Der cexpr
     | ParseTree.FunctionCall
+      ([("pre", [||])], Some (ParseTree.ArgList ([expr] , None))) ->
+        let cexpr = compile_expression' expr in
+        Pre cexpr
+    | ParseTree.FunctionCall
       ([("floor", [||])], Some (ParseTree.ArgList ([expr] , None))) ->
         let cexpr = compile_expression' expr in
         Floor cexpr
@@ -445,44 +509,89 @@ and compile_expression ctx expr =
         let cexpr = compile_expression' expr in
         Abs cexpr
     | ParseTree.FunctionCall
-      ([("Modelica", [||]); ("Math", [||]); ("cos", [||])],
+      ([("sin", [||])],
+      Some (ParseTree.ArgList ([expr] , None))) ->
+        let cexpr = compile_expression' expr in
+        Sin cexpr
+    | ParseTree.FunctionCall
+      ([("cos", [||])],
       Some (ParseTree.ArgList ([expr] , None))) ->
         let cexpr = compile_expression' expr in
         Cos cexpr
     | ParseTree.FunctionCall
-      ([("Modelica", [||]); ("Math", [||]); ("exp", [||])],
+      ([("tan", [||])],
       Some (ParseTree.ArgList ([expr] , None))) ->
         let cexpr = compile_expression' expr in
-        Exp cexpr
+        Tan cexpr
     | ParseTree.FunctionCall
-      ([("Modelica", [||]); ("Math", [||]); ("log", [||])],
+      ([("asin", [||])],
       Some (ParseTree.ArgList ([expr] , None))) ->
         let cexpr = compile_expression' expr in
-        Log cexpr
+        Asin cexpr
     | ParseTree.FunctionCall
-      ([("Modelica", [||]); ("Math", [||]); ("sin", [||])],
+      ([("acos", [||])],
       Some (ParseTree.ArgList ([expr] , None))) ->
         let cexpr = compile_expression' expr in
-        Sin cexpr
+        Acos cexpr
     | ParseTree.FunctionCall
-      ([("Modelica", [||]); ("Math", [||]); ("sqrt", [||])],
+      ([("atan", [||])],
       Some (ParseTree.ArgList ([expr] , None))) ->
         let cexpr = compile_expression' expr in
-        Sqrt cexpr
+        Atan cexpr
     | ParseTree.FunctionCall
-      ([("Modelica", [||]); ("Math", [||]); ("tan", [||])],
+      ([("sinh", [||])],
       Some (ParseTree.ArgList ([expr] , None))) ->
         let cexpr = compile_expression' expr in
-        Tan cexpr
+        Sinh cexpr
+    | ParseTree.FunctionCall
+      ([("cosh", [||])],
+      Some (ParseTree.ArgList ([expr] , None))) ->
+        let cexpr = compile_expression' expr in
+        Cosh cexpr
     | ParseTree.FunctionCall
-      ([("Modelica", [||]); ("Math", [||]); ("tanh", [||])],
+      ([("tanh", [||])],
       Some (ParseTree.ArgList ([expr] , None))) ->
         let cexpr = compile_expression' expr in
         Tanh cexpr
+    | ParseTree.FunctionCall
+      ([("asinh", [||])],
+      Some (ParseTree.ArgList ([expr] , None))) ->
+        let cexpr = compile_expression' expr in
+        Asinh cexpr
+    | ParseTree.FunctionCall
+      ([("acosh", [||])],
+      Some (ParseTree.ArgList ([expr] , None))) ->
+        let cexpr = compile_expression' expr in
+        Acosh cexpr
+    | ParseTree.FunctionCall
+      ([("atanh", [||])],
+      Some (ParseTree.ArgList ([expr] , None))) ->
+        let cexpr = compile_expression' expr in
+        Atanh cexpr
+    | ParseTree.FunctionCall
+      ([("exp", [||])],
+      Some (ParseTree.ArgList ([expr] , None))) ->
+        let cexpr = compile_expression' expr in
+        Exp cexpr
+    | ParseTree.FunctionCall
+      ([("log", [||])],
+      Some (ParseTree.ArgList ([expr] , None))) ->
+        let cexpr = compile_expression' expr in
+        Log cexpr
+    | ParseTree.FunctionCall
+      ([("log10", [||])],
+      Some (ParseTree.ArgList ([expr] , None))) ->
+        let cexpr = compile_expression' expr in
+        Division (Log cexpr, Log (Real 10.))
+    | ParseTree.FunctionCall
+      ([("sqrt", [||])],
+      Some (ParseTree.ArgList ([expr] , None))) ->
+        let cexpr = compile_expression' expr in
+        Sqrt cexpr
     | ParseTree.FunctionCall (path, Some (ParseTree.ArgList (exprs , None))) ->
         let cexprs = List.map compile_expression' exprs
         and name, lccl = get_function_from path
-        in ExternalFunctionCall (name, lccl, cexprs)
+        in ExternalFunctionCall (name, lccl, List.map to_argument cexprs)
     | ParseTree.FunctionCall _ ->
         failwith "compile_expression: invalid function call"
     | ParseTree.GreaterEqualThan (expr, expr') ->
@@ -551,8 +660,7 @@ and compile_expression ctx expr =
           | _ -> failwith "compile_expression: invalid function reference")
         path
     in
-    let f = create_filename name ".moc" in
-    let cu = read_class_file f in
+    let cu = get_compiled_class ctx name in
     match cu with
       | CompiledFunction lccl -> name, lccl
       | CompiledClass _ ->
@@ -574,9 +682,22 @@ and compile_expression ctx expr =
     cexpr, cexpr'
   in compile_expression' expr
 
+and to_argument cexpr =
+  let rec array_dimensions = function
+    | Vector cexprs -> Array.length cexprs :: array_dimensions cexprs.(0)
+    | _ -> [] in
+  let rec flatten = function
+    | Vector cexprs ->
+        Array.fold_right (fun cexpr acc -> flatten cexpr @ acc) cexprs []
+    | cexpr -> [cexpr] in
+  match cexpr with
+  | Vector _ ->
+      ArrayArgument (array_dimensions cexpr, Array.of_list (flatten cexpr))
+  | _ -> ScalarArgument cexpr
+
 and compile_component_reference ctx cpnt_ref =
   let rec compile_reference' ctx' level level' cpnt_ref = match ctx' with
-    | TopLevelContext -> raise Not_found
+    | TopLevelContext _ -> raise Not_found
     | ClassContext (ctx'', lccl) ->
         compile_component_path ctx ctx' level cpnt_ref
     | ModificationContext (ctx'', lccl) ->
@@ -614,13 +735,12 @@ and compile_component_path ctx ctx' level cpnt_ref =
   in match ctx' with
     | ClassContext (_, lccl) | ModificationContext (_, lccl) ->
         compile_component_path_in lccl cpnt_ref
-    | TopLevelContext | ForContext _ ->
+    | TopLevelContext _ | ForContext _ ->
         assert false (* Never applied to this kind of context *)
 
 and compile_subscripts ctx subscripts =
   let rec compile_subscript = function
-    | ParseTree.All ->
-        failwith "compile_subscripts: ranges not allowed"
+    | ParseTree.All -> Indefinite
     | ParseTree.Subscript expr ->
         Definite (compile_expression ctx expr)
   in Array.map compile_subscript subscripts
@@ -689,44 +809,66 @@ and compile_component_modification ctx modif = match ctx, modif with
       and modif = Modification (cpnt_ref, modifs, None) in
       let cmodif = compile_modification ctx' modif in
       CompiledModification ((id, cs), [cmodif], cexpr_opt)
-  | (TopLevelContext | ClassContext _), _ ->
+  | (TopLevelContext _ | ClassContext _), _ ->
       assert false (* Never applied to this kind of context *)
   | _ -> raise InvalidModification
 
 and compile_base_type_variable_modifications ctx = function
   | [] -> []
-  | Modification ([("start", [||])], [], Some expr) :: modifs ->
+  | Modification (["start", [||]], [], Some expr) :: modifs ->
       let cexpr = compile_expression ctx expr in
       CompiledModification (("start", [||]), [], Some cexpr) ::
       compile_base_type_variable_modifications ctx modifs
-  | _ ->
-      failwith "compile_base_type_variable_modifications: invalid modification"
+  | Modification (["unit", [||]], [], Some expr) :: modifs ->
+      let cexpr = compile_expression ctx expr in
+      CompiledModification (("unit", [||]), [], Some cexpr) ::
+      compile_base_type_variable_modifications ctx modifs
+  | Modification (["quantity", [||]], [], Some expr) :: modifs ->
+      let cexpr = compile_expression ctx expr in
+      CompiledModification (("quantity", [||]), [], Some cexpr) ::
+      compile_base_type_variable_modifications ctx modifs
+  | Modification (["min", [||]], [], Some expr) :: modifs ->
+      let cexpr = compile_expression ctx expr in
+      CompiledModification (("min", [||]), [], Some cexpr) ::
+      compile_base_type_variable_modifications ctx modifs
+  | Modification (["max", [||]], [], Some expr) :: modifs ->
+      let cexpr = compile_expression ctx expr in
+      CompiledModification (("max", [||]), [], Some cexpr) ::
+      compile_base_type_variable_modifications ctx modifs
+  | _ :: modifs ->
+      compile_base_type_variable_modifications ctx modifs
+      (*failwith "compile_base_type_variable_modifications: invalid modification"*)
 
-and compile_component ctx pcpnt = match pcpnt.variability with
-  | Some ParseTree.Parameter -> Parameter (compile_parameter ctx pcpnt)
-  | Some ParseTree.Discrete | None -> Variable (compile_variable ctx pcpnt)
+and compile_component ctx i id pcpnt = match pcpnt.variability with
+  | Some ParseTree.Parameter -> Parameter (compile_parameter ctx i id pcpnt)
+  | Some ParseTree.Discrete | None -> Variable (compile_variable ctx i id pcpnt)
   | _ -> failwith "compile_component: only variables and parameters allowed"
 
-and compile_parameter ctx pcpnt =
+and compile_parameter ctx i id pcpnt =
+  let cmodifs = match pcpnt.class_name, snd pcpnt.modification with
+    | ["Integer"], _ | ["Real"], _ | ["String"], _ ->
+        compile_base_type_variable_modifications ctx (fst pcpnt.modification)
+    | _ -> [] in
   let attrs =
     {
       pat_dimensions = compile_subscripts ctx pcpnt.subscripts;
       pat_comment = compile_comment pcpnt.comment;
       pat_value =
-        opt_map (compile_expression ctx) (snd pcpnt.modification)
+        opt_map (compile_expression ctx) (snd pcpnt.modification);
+      pat_infos = compile_infos i id pcpnt.comment cmodifs
     }
   in match pcpnt.class_name with
     | ["Integer"] -> IntegerParameter attrs
     | ["Real"] -> RealParameter attrs
+    | ["String"] -> StringParameter attrs
     | _ -> failwith "compile_parameter: only base types allowed"
 
-and compile_variable ctx pcpnt =
+and compile_variable ctx i id pcpnt =
   let cmodifs = match pcpnt.class_name, snd pcpnt.modification with
-    | ["Integer"], None | ["Real"], None ->
+    | ["Integer"], None | ["Real"], None | ["String"], None ->
         compile_base_type_variable_modifications ctx (fst pcpnt.modification)
     | name, None ->
-        let f = create_filename name ".moc" in
-        let cu = read_class_file f in
+        let cu = get_compiled_class ctx name in
         begin match cu with
           | CompiledClass lccl ->
               let ctx' = ModificationContext (ctx, lccl) in
@@ -744,14 +886,16 @@ and compile_variable ctx pcpnt =
       vat_nature = compile_nature pcpnt.flow;
       vat_inout = compile_inout pcpnt.inout;
       vat_comment = compile_comment pcpnt.comment;
-      vat_modifications = cmodifs
+      vat_modifications = start_modifications cmodifs;
+      vat_infos = compile_infos i id pcpnt.comment cmodifs
     }
   in match pcpnt.class_name, pcpnt.variability with
     | ["Real"], Some ParseTree.Discrete -> DiscreteVariable attrs
     | ["Real"], None -> RealVariable attrs
+    | ["Integer"], None -> IntegerVariable attrs
+    | ["String"], None -> StringVariable attrs
     | name, None ->
-        let f = create_filename name ".moc" in
-        let cu = read_class_file f in
+        let cu = get_compiled_class ctx name in
         begin match cu with
           | CompiledClass lccl -> CompoundVariable (lccl, attrs)
           | CompiledFunction _ ->
@@ -759,17 +903,126 @@ and compile_variable ctx pcpnt =
         end
     | _ -> failwith "compile_variable: invalid variable declaration"
 
+and start_modifications cmodifs = match cmodifs with
+  | [] -> []
+  | (CompiledModification (("start", _), _, _) as cmodif) :: cmodifs' ->
+      cmodif :: start_modifications cmodifs'
+  | _ :: cmodifs' -> start_modifications cmodifs'
+
 and compile_nature = function
   | Some ParseTree.Flow -> Flow
   | None -> Potential
 
-and compile_inout = function
+and compile_inout inout = match inout with
   | Some ParseTree.Input -> Input
   | Some ParseTree.Output -> Output
   | None -> Both
 
 and compile_comment = function
-  | ParseTree.Comment (ParseTree.StringComment ss, None) ->
+  | ParseTree.Comment (ParseTree.StringComment ss, _) ->
       List.fold_left ( ^ ) "" ss
-  | ParseTree.Comment (_, Some _) ->
-      failwith "compile_comment: Annotations not allowed"
+  (*| ParseTree.Comment (_, Some _) ->
+      failwith "compile_comment: Annotations not allowed"*)
+
+and compile_infos i id cmt cmodifs =
+  let weight, port_name, port_type = match cmt with
+    | ParseTree.Comment (_, Some ann) -> compile_annotation ann
+    | _ -> 1.0, "", "" in
+  let port_name = match port_name with
+    | "" -> id
+    | _ -> port_name in
+  let rec modif_infos (unit, qt, min, max) cmodifs = match cmodifs with
+    | [] -> unit, qt, min, max
+    | (CompiledModification (("unit", _), _, Some (String s)))
+      :: cmodifs' ->
+        modif_infos (s, qt, min, max) cmodifs'
+    | (CompiledModification (("quantity", _), _, Some (String s)))
+      :: cmodifs' ->
+        modif_infos (unit, s, min, max) cmodifs'
+    | (CompiledModification (("min", _), _, Some (String s)))
+      :: cmodifs' ->
+        modif_infos (unit, qt, s, max) cmodifs'
+    | (CompiledModification (("max", _), _, Some (String s)))
+      :: cmodifs' ->
+        modif_infos (unit, qt, min, s) cmodifs'
+    | _ :: cmodifs' -> modif_infos (unit, qt, min, max) cmodifs' in
+  let unit, qt, min, max = modif_infos ("null", "", "", "") cmodifs in
+  {
+    var_name = id;
+    title = id;
+    unit = unit;
+    quantity = qt;
+    min = min;
+    max = max;
+    port_name = port_name;
+    port_type = port_type;
+    order = i;
+    io = 1;
+    weight = weight
+  }
+
+and compile_annotation ann =
+  let rec compile_port_arguments (weight, port_name, port_type) args =
+    match args with
+    | [] -> weight, port_name, port_type
+    | ParseTree.ElementModification
+        (_, _, ["port_name", [||]],
+         ParseTree.Eq (ParseTree.Reference [id, [||]]), _) :: args' ->
+        compile_port_arguments (weight, id, port_type) args'
+    | ParseTree.ElementModification
+        (_, _, ["port_type", [||]],
+         ParseTree.Eq (ParseTree.Reference [id, [||]]), _) :: args' ->
+        compile_port_arguments (weight, port_name, id) args'
+    | _ :: args' ->
+        compile_port_arguments (weight, port_name, port_type) args'
+  and compile_initialization_arguments (weight, port_name, port_type) args =
+    match args with
+    | [] -> weight, port_name, port_type
+    | ParseTree.ElementModification
+        (_, _, ["weight", [||]],
+         ParseTree.Eq (ParseTree.Real s), _) :: args' ->
+        compile_initialization_arguments
+          (float_of_string s, port_name, port_type)
+          args'
+    | _ :: args' ->
+        compile_initialization_arguments
+          (weight, port_name, port_type)
+          args' in
+  let compile_port_annotation modif = match modif with
+    | ParseTree.Modification (ParseTree.ClassModification args, None) ->
+        compile_port_arguments (1.0, "", "") args
+    | _ -> 1.0, "", "" in
+  let compile_initialization_annotation modif = match modif with
+    | ParseTree.Modification (ParseTree.ClassModification args, None) ->
+        compile_initialization_arguments (1.0, "", "") args
+    | _ -> 1.0, "", "" in
+  let compile_imagine_annotation_argument (weight, port_name, port_type) arg =
+    match arg with
+    | ParseTree.ElementModification (_, _, ["port", [||]], modif, _) ->
+        compile_port_annotation modif
+    | ParseTree.ElementModification (_, _, ["initialization", [||]], modif, _) ->
+        compile_initialization_annotation modif
+    | _ -> weight, port_name, port_type in
+  let compile_imagine_annotation modif = match modif with
+    | ParseTree.Modification (ParseTree.ClassModification args, None) ->
+        List.fold_left compile_imagine_annotation_argument (1.0, "", "") args
+    | _ -> 1.0, "", "" in
+  let compile_scicos_annotation_argument (weight, port_name, port_type) arg =
+    match arg with
+    | ParseTree.ElementModification (_, _, ["initialization", [||]], modif, _) ->
+        compile_initialization_annotation modif
+    | _ -> weight, port_name, port_type in
+  let compile_scicos_annotation modif = match modif with
+    | ParseTree.Modification (ParseTree.ClassModification args, None) ->
+        List.fold_left compile_scicos_annotation_argument (1.0, "", "") args
+    | _ -> 1.0, "", "" in
+  let compile_argument arg = match arg with
+    | ParseTree.ElementModification (_, _, ["__imagine", [||]], modif, _) ->
+        compile_imagine_annotation modif
+    | ParseTree.ElementModification (_, _, ["__scicos", [||]], modif, _) ->
+        compile_scicos_annotation modif
+    | _ -> 1.0, "", "" in
+  match ann with
+  | ParseTree.Annotation (ParseTree.ClassModification [arg]) ->
+      compile_argument arg
+  | _ -> 1.0, "", ""
index cd17ba5..0d23c97 100644 (file)
@@ -1,23 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 (** This module performs the compilation of a subset of the Modelica language.
 *)
@@ -56,32 +57,56 @@ and compiled_subscript = Indefinite | Definite of compiled_expression
 
 and parameter =
     IntegerParameter of parameter_attributes
+  | StringParameter of parameter_attributes
   | RealParameter of parameter_attributes
 
 and parameter_attributes = {
   pat_dimensions : compiled_subscript array;
   pat_comment : string;
   pat_value : compiled_expression option;
+  pat_infos: variable_infos
 }
 
 and variable =
-    DiscreteVariable of variable_attributes
+    IntegerVariable of variable_attributes
+  | StringVariable of variable_attributes
+  | DiscreteVariable of variable_attributes
   | RealVariable of variable_attributes
   | CompoundVariable of compiled_class Lazy.t * variable_attributes
 
-and variable_attributes = {
-  vat_dimensions : compiled_subscript array;
-  vat_nature : nature;
-  vat_inout : inout;
-  vat_comment : string;
-  vat_modifications : compiled_modification list;
-}
+and variable_attributes =
+  {
+    vat_dimensions : compiled_subscript array;
+    vat_nature : nature;
+    vat_inout : inout;
+    vat_comment : string;
+    vat_modifications : compiled_modification list;
+    vat_infos: variable_infos
+  }
 
 and compiled_component = Parameter of parameter | Variable of variable
 
 and nature = Flow | Potential
 
-and inout = Input | Output | Both
+and inout =
+  | Input
+  | Output
+  | Both
+
+and variable_infos =
+  {
+    var_name: string;
+    title: string;
+    unit: string;
+    quantity: string;
+    min: string;
+    max: string;
+    port_name: string;
+    port_type: string;
+    order: int;
+    io: int;
+    weight: float
+  }
 
 and compiled_equation =
     CompiledEquality of compiled_expression * compiled_expression
@@ -98,17 +123,24 @@ and compiled_when_expression =
 
 and compiled_expression =
   | Abs of compiled_expression
+  | Acos of compiled_expression
+  | Acosh of compiled_expression
   | Addition of compiled_expression * compiled_expression
   | And of compiled_expression * compiled_expression
+  | Asin of compiled_expression
+  | Asinh of compiled_expression
+  | Atan of compiled_expression
+  | Atanh of compiled_expression
   | Boolean of bool
   | Cardinality of compiled_expression
   | Cos of compiled_expression
+  | Cosh of compiled_expression
   | Der of compiled_expression
   | Division of compiled_expression * compiled_expression
   | Equals of compiled_expression * compiled_expression
   | Exp of compiled_expression
   | ExternalFunctionCall of string list * compiled_class Lazy.t *
-    compiled_expression list
+    compiled_argument list
   | Floor of compiled_expression
   | GreaterEqualThan of compiled_expression * compiled_expression
   | GreaterThan of compiled_expression * compiled_expression
@@ -125,9 +157,11 @@ and compiled_expression =
   | NotEquals of compiled_expression * compiled_expression
   | Or of compiled_expression * compiled_expression
   | Power of compiled_expression * compiled_expression
+  | Pre of compiled_expression
   | Real of float
   | Reference of compiled_reference
   | Sin of compiled_expression
+  | Sinh of compiled_expression
   | Sqrt of compiled_expression
   | String of string
   | Subtraction of compiled_expression * compiled_expression
@@ -136,11 +170,15 @@ and compiled_expression =
   | Time
   | Vector of compiled_expression array
 
+and compiled_argument =
+  | ScalarArgument of compiled_expression
+  | ArrayArgument of int list * compiled_expression array
+
 val paths : string list ref
 (** Global variable used to store the paths where to find compiled Modelica
 classes. *)
 
-val read_class_file : string -> compiled_unit
+(*val read_class_file : string -> compiled_unit*)
 (** [read_class_file name] finds then loads the compiled class named [name].
 A compiled Modelica class named "Class" is usually stored in a file named
 "Class.moc". The search is performed in the file system using
@@ -151,6 +189,6 @@ val write_class_file : string -> compiled_unit -> unit
 named [name]. See {!Compilation.read_class_file} for more information about file
 naming conventions. *)
 
-val compile_main_class : Precompilation.precompiled_class -> compiled_unit
+val compile_main_class : Precompilation.precompiled_class list -> string * compiled_unit
 (** [compile_main_class pcl] yields the compiled Modelica class associated to
 [pcl]. *)
index 5a44bd9..1d27e2f 100644 (file)
@@ -1,23 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 (* Functorial interface *)
 
index 3dccbe5..813e2c6 100644 (file)
@@ -1,23 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 (** This module provides a structure that allow object sharing in order to
 create DAGs. Weak pointers are used to avoid keeping into the collection
index 00675c1..d21186e 100644 (file)
@@ -1,24 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
-
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 module type MatrixElement =
   sig
index b3b8e16..eb58976 100644 (file)
@@ -1,23 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 (** This modules provides structures and functions that performs the
 causality analysis using the Hungarian Method. *)
index 0c03fbd..51231db 100644 (file)
@@ -1,24 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
-
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 (* Datatypes *)
 
@@ -34,18 +34,26 @@ and instantiated_component =
   | InstantiatedVariable of instantiated_variable
 
 and instantiated_parameter =
-  | InstantiatedIntegerParameter of string * parameter_kind * typed_expression
-  | InstantiatedRealParameter of string * parameter_kind * typed_expression
+  | InstantiatedIntegerParameter of string * parameter_kind *
+      typed_expression * Compilation.variable_infos
+  | InstantiatedStringParameter of string * parameter_kind *
+      typed_expression * Compilation.variable_infos
+  | InstantiatedRealParameter of string * parameter_kind * typed_expression *
+       Compilation.variable_infos
 
 and parameter_kind =
   | Main
   | Sub
 
 and instantiated_variable =
+  | InstantiatedIntegerVariable of string * Compilation.inout *
+    typed_expression * Compilation.variable_infos
+  | InstantiatedStringVariable of string * Compilation.inout *
+    typed_expression * Compilation.variable_infos
   | InstantiatedDiscreteVariable of string * Compilation.inout *
-    typed_expression
+    typed_expression * Compilation.variable_infos
   | InstantiatedRealVariable of string * Compilation.inout *
-    Compilation.nature * typed_expression
+    Compilation.nature * typed_expression * Compilation.variable_infos
   | InstantiatedCompoundVariable of string * typed_expression
 
 and equation =
@@ -78,17 +86,26 @@ and expression_type =
 
 and expression =
   | Abs of typed_expression
+  | Acos of typed_expression
+  | Acosh of typed_expression
   | Addition of typed_expression * typed_expression
   | And of typed_expression * typed_expression
+  | Asin of typed_expression
+  | Asinh of typed_expression
+  | Atan of typed_expression
+  | Atanh of typed_expression
   | Boolean of bool
   | Cardinality of typed_expression
   | CompoundElement of instantiated_class
   | Cos of typed_expression
+  | Cosh of typed_expression
   | Der of typed_expression
   | Division of typed_expression * typed_expression
   | Equals of typed_expression * typed_expression
   | Exp of typed_expression
-  | ExternalFunctionCall of string list * typed_expression list
+  | ExternalFunctionCall of
+      string list * expression_type list * expression_type list *
+      typed_argument list
   | Floor of typed_expression
   | GreaterEqualThan of typed_expression * typed_expression
   | GreaterThan of typed_expression * typed_expression
@@ -106,8 +123,10 @@ and expression =
   | Or of typed_expression * typed_expression
   | ParameterValue of int * reference
   | Power of typed_expression * typed_expression
+  | Pre of typed_expression
   | Real of float
   | Sin of typed_expression
+  | Sinh of typed_expression
   | Sqrt of typed_expression
   | String of string
   | Subtraction of typed_expression * typed_expression
@@ -118,6 +137,10 @@ and expression =
   | VariableValue of int * reference
   | Vector of typed_expression array
 
+and typed_argument =
+  | ScalarArgument of typed_expression
+  | ArrayArgument of int list * typed_expression array
+
 and reference = (string * int array) list
 
 and instantiation_context =
@@ -137,6 +160,7 @@ let string_of_expression  iexpr =
     | Some expr -> string_of_expression'' expr
   and string_of_expression'' = function
     | Abs iexpr -> "(abs " ^ string_of_expression' iexpr ^ ")"
+    | Acos iexpr -> "(cos " ^ string_of_expression' iexpr ^ ")"
     | Addition (iexpr, iexpr') ->
         "(" ^
         string_of_expression' iexpr ^
@@ -166,7 +190,7 @@ let string_of_expression  iexpr =
         string_of_expression' iexpr' ^
         ")"
     | Exp iexpr -> "(exp " ^ string_of_expression' iexpr ^ ")"
-    | ExternalFunctionCall (name, iexprs) -> "<funcall>"
+    | ExternalFunctionCall (name, _, _, iexprs) -> "<funcall>"
     | GreaterEqualThan (iexpr, iexpr') ->
         "(" ^
         string_of_expression' iexpr ^
@@ -270,7 +294,8 @@ let separate_parameters_from_variables cpnts =
 let separate_inputs_from_others vars =
   let rec partition inputs others = function
     | [] -> List.rev inputs, List.rev others
-    | ((Compilation.DiscreteVariable attrs | Compilation.RealVariable attrs)
+    | ((Compilation.IntegerVariable attrs | Compilation.StringVariable attrs |
+      Compilation.DiscreteVariable attrs | Compilation.RealVariable attrs)
       as var) :: vars when attrs.Compilation.vat_inout = Compilation.Input ->
         partition (var :: inputs) others vars
     | var :: vars -> partition inputs (var :: others) vars
@@ -279,7 +304,8 @@ let separate_inputs_from_others vars =
 let separate_outputs_from_others vars =
   let rec partition outputs others = function
     | [] -> List.rev outputs, List.rev others
-    | ((Compilation.DiscreteVariable attrs | Compilation.RealVariable attrs)
+    | ((Compilation.IntegerVariable attrs | Compilation.StringVariable attrs |
+      Compilation.DiscreteVariable attrs | Compilation.RealVariable attrs)
       as var) :: vars when attrs.Compilation.vat_inout = Compilation.Output ->
         partition (var :: outputs) others vars
     | var :: vars -> partition outputs (var :: others) vars
@@ -328,8 +354,17 @@ and instantiate_main_parameter ctx modifs = function
           tex_type = IntegerType [||];
           tex_expression = Some (Integer Int32.zero)
         }
-      and make comment ivalue =
-        InstantiatedIntegerParameter (comment, Main, ivalue)
+      and make comment ivalue pat_infos =
+        InstantiatedIntegerParameter (comment, Main, ivalue, pat_infos)
+      in initialize_parameter ctx default modifs attrs make
+  | Compilation.StringParameter attrs ->
+      let default =
+        {
+          tex_type = StringType [||];
+          tex_expression = Some (String "")
+        }
+      and make comment ivalue pat_infos =
+        InstantiatedStringParameter (comment, Main, ivalue, pat_infos)
       in initialize_parameter ctx default modifs attrs make
   | Compilation.RealParameter attrs ->
       let default =
@@ -337,8 +372,8 @@ and instantiate_main_parameter ctx modifs = function
           tex_type = RealType [||];
           tex_expression = Some (Real 0.0)
         }
-      and make comment ivalue =
-        InstantiatedRealParameter (comment, Main, ivalue)
+      and make comment ivalue pat_infos =
+        InstantiatedRealParameter (comment, Main, ivalue, pat_infos)
       in initialize_parameter ctx default modifs attrs make
 
 and instantiate_class ctx modifs ccl =
@@ -387,8 +422,19 @@ and instantiate_parameter ctx modifs = function
           tex_type = IntegerType [||];
           tex_expression = Some (Integer Int32.zero)
         }
-      and make comment ivalue =
-        InstantiatedIntegerParameter (comment, Sub, ivalue)
+      and make comment ivalue pat_infos =
+        InstantiatedIntegerParameter
+          (comment, Sub, ivalue, pat_infos)
+      in initialize_parameter ctx default modifs attrs make
+  | Compilation.StringParameter attrs ->
+      let default =
+        {
+          tex_type = StringType [||];
+          tex_expression = Some (String "")
+        }
+      and make comment ivalue pat_infos =
+        InstantiatedStringParameter
+          (comment, Sub, ivalue, pat_infos)
       in initialize_parameter ctx default modifs attrs make
   | Compilation.RealParameter attrs ->
       let default =
@@ -396,17 +442,18 @@ and instantiate_parameter ctx modifs = function
           tex_type = RealType [||];
           tex_expression = Some (Real 0.0)
         }
-      and make comment ivalue =
-        InstantiatedRealParameter (comment, Sub, ivalue)
+      and make comment ivalue pat_infos =
+        InstantiatedRealParameter (comment, Sub, ivalue, pat_infos)
       in initialize_parameter ctx default modifs attrs make
 
 and initialize_parameter ctx default modifs attrs make =
   let comment = attrs.Compilation.pat_comment
   and cdims = attrs.Compilation.pat_dimensions
-  and value_opt = attrs.Compilation.pat_value in
+  and value_opt = attrs.Compilation.pat_value
+  and pat_infos = attrs.Compilation.pat_infos in
   let dims = Array.map (compute_subscript ctx) cdims in
   let ivalue = calculate_initial_value ctx dims default modifs value_opt in
-  make comment ivalue
+  make comment ivalue pat_infos
 
 
 and calculate_initial_value ctx dims default modifs value_opt =
@@ -437,14 +484,35 @@ and calculate_initial_value ctx dims default modifs value_opt =
     | _ -> failwith "calculate_initial_value: invalid modification"
 
 and instantiate_variable ctx modifs = function
+    | Compilation.IntegerVariable attrs ->
+      let default =
+        {
+          tex_type = IntegerType [||];
+          tex_expression = None
+        }
+      and make comment inout flow ivalue vat_infos =
+        InstantiatedIntegerVariable
+          (comment, inout, ivalue, vat_infos)
+      in initialize_base_type_variable ctx default modifs attrs make
+    | Compilation.StringVariable attrs ->
+      let default =
+        {
+          tex_type = StringType [||];
+          tex_expression = None
+        }
+      and make comment inout flow ivalue vat_infos =
+        InstantiatedStringVariable
+          (comment, inout, ivalue, vat_infos)
+      in initialize_base_type_variable ctx default modifs attrs make
     | Compilation.DiscreteVariable attrs ->
       let default =
         {
           tex_type = RealType [||];
           tex_expression = None
         }
-      and make comment inout flow ivalue =
-        InstantiatedDiscreteVariable (comment, inout, ivalue)
+      and make comment inout flow ivalue vat_infos =
+        InstantiatedDiscreteVariable
+          (comment, inout, ivalue, vat_infos)
       in initialize_base_type_variable ctx default modifs attrs make
     | Compilation.RealVariable attrs ->
       let default =
@@ -452,8 +520,9 @@ and instantiate_variable ctx modifs = function
           tex_type = RealType [||];
           tex_expression = None
         }
-      and make comment inout flow ivalue =
-        InstantiatedRealVariable (comment, inout, flow, ivalue)
+      and make comment inout flow ivalue vat_infos =
+        InstantiatedRealVariable
+          (comment, inout, flow, ivalue, vat_infos)
       in initialize_base_type_variable ctx default modifs attrs make
     | Compilation.CompoundVariable (lccl, attrs) ->
         initialize_compound_variable ctx modifs lccl attrs
@@ -497,8 +566,7 @@ and init_array dims ctx modifs modifs' ccl =
 
 and merge_modifications modifs modifs' =
   let rec add_modif_to modifs modif = match modifs, modif with
-    | Compilation.CompiledModification (field, inners, cexpr_opt) as modif' ::
-      modifs',
+    | Compilation.CompiledModification (field, inners, cexpr_opt) :: modifs',
       Compilation.CompiledModification (field', inners', cexpr_opt')
       when field = field' ->
         let inners'' = merge_modifications inners inners'
@@ -519,6 +587,7 @@ and initialize_base_type_variable ctx default modifs attrs make =
   and inout = attrs.Compilation.vat_inout
   and flow = attrs.Compilation.vat_nature
   and cdims = attrs.Compilation.vat_dimensions
+  and vat_infos = attrs.Compilation.vat_infos
   and value_opt = match attrs.Compilation.vat_modifications with
     | [Compilation.CompiledModification (("value", [||]), [], cexpr_opt)] |
       [Compilation.CompiledModification (("start", [||]), [], cexpr_opt)] ->
@@ -528,7 +597,7 @@ and initialize_base_type_variable ctx default modifs attrs make =
   in
   let dims = Array.map (compute_subscript ctx) cdims in
   let ivalue = calculate_initial_value ctx dims default modifs value_opt in
-  make comment inout flow ivalue
+  make comment inout flow ivalue vat_infos
 
 and create_array dims default =
   let rec create_array' i value =
@@ -675,17 +744,43 @@ and instantiate_when_equations ctx cequs =
     | _ -> failwith "instantiate_when_equations: type error"
   in List.rev_map instantiate_when_equation cequs
 
+and instantiate_argument ctx = function
+  | Compilation.ScalarArgument cexpr ->
+      ScalarArgument (instantiate_expression ctx cexpr)
+  | Compilation.ArrayArgument (dims, cexprs) ->
+      ArrayArgument (dims, Array.map (instantiate_expression ctx) cexprs)
+
 and instantiate_expression ctx = function
   | Compilation.Abs cexpr ->
       let iexpr = instantiate_expression ctx cexpr in
       begin match iexpr.tex_type with
-        | RealType dims ->
+        | RealType dims | IntegerType dims ->
             {
               tex_type = RealType dims;
               tex_expression = Some (Abs iexpr)
             }
         | _ -> failwith "instantiate_expression: type error on abs"
       end
+  | Compilation.Acos cexpr ->
+      let iexpr = instantiate_expression ctx cexpr in
+      begin match iexpr.tex_type with
+        | RealType dims | IntegerType dims ->
+            {
+              tex_type = RealType dims;
+              tex_expression = Some (Acos iexpr)
+            }
+        | _ -> failwith "instantiate_expression: type error on acos"
+      end
+  | Compilation.Acosh cexpr ->
+      let iexpr = instantiate_expression ctx cexpr in
+      begin match iexpr.tex_type with
+        | RealType dims | IntegerType dims ->
+            {
+              tex_type = RealType dims;
+              tex_expression = Some (Acosh iexpr)
+            }
+        | _ -> failwith "instantiate_expression: type error on acosh"
+      end
   | Compilation.Addition (cexpr, cexpr') ->
       let iexpr = instantiate_expression ctx cexpr
       and iexpr' = instantiate_expression ctx cexpr' in
@@ -714,6 +809,46 @@ and instantiate_expression ctx = function
             }
         | _ -> failwith "instantiate_expression: type error on and"
       end
+  | Compilation.Asin cexpr ->
+      let iexpr = instantiate_expression ctx cexpr in
+      begin match iexpr.tex_type with
+        | RealType dims | IntegerType dims ->
+            {
+              tex_type = RealType dims;
+              tex_expression = Some (Asin iexpr)
+            }
+        | _ -> failwith "instantiate_expression: type error on asin"
+      end
+  | Compilation.Asinh cexpr ->
+      let iexpr = instantiate_expression ctx cexpr in
+      begin match iexpr.tex_type with
+        | RealType dims | IntegerType dims ->
+            {
+              tex_type = RealType dims;
+              tex_expression = Some (Asinh iexpr)
+            }
+        | _ -> failwith "instantiate_expression: type error on asinh"
+      end
+  | Compilation.Atan cexpr ->
+      let iexpr = instantiate_expression ctx cexpr in
+      begin match iexpr.tex_type with
+        | RealType dims | IntegerType dims ->
+            {
+              tex_type = RealType dims;
+              tex_expression = Some (Atan iexpr)
+            }
+        | _ -> failwith "instantiate_expression: type error on atan"
+      end
+  | Compilation.Atanh cexpr ->
+      let iexpr = instantiate_expression ctx cexpr in
+      begin match iexpr.tex_type with
+        | RealType dims | IntegerType dims ->
+            {
+              tex_type = RealType dims;
+              tex_expression = Some (Atanh iexpr)
+            }
+        | _ -> failwith "instantiate_expression: type error on atanh"
+      end
   | Compilation.Boolean b ->
       {
         tex_type = BooleanType [||];
@@ -732,17 +867,27 @@ and instantiate_expression ctx = function
   | Compilation.Cos cexpr ->
       let iexpr = instantiate_expression ctx cexpr in
       begin match iexpr.tex_type with
-        | RealType dims ->
+        | RealType dims | IntegerType dims ->
             {
               tex_type = RealType dims;
               tex_expression = Some (Cos iexpr)
             }
         | _ -> failwith "instantiate_expression: type error on cos"
       end
+  | Compilation.Cosh cexpr ->
+      let iexpr = instantiate_expression ctx cexpr in
+      begin match iexpr.tex_type with
+        | RealType dims | IntegerType dims ->
+            {
+              tex_type = RealType dims;
+              tex_expression = Some (Cosh iexpr)
+            }
+        | _ -> failwith "instantiate_expression: type error on cosh"
+      end
   | Compilation.Der cexpr ->
       let iexpr = instantiate_expression ctx cexpr in
       begin match iexpr.tex_type with
-        | RealType dims ->
+        | RealType dims | IntegerType dims ->
             {
               tex_type = RealType dims;
               tex_expression = Some (Der iexpr)
@@ -780,17 +925,22 @@ and instantiate_expression ctx = function
             }
         | _ -> failwith "instantiate_expression: type error on equals"
       end
-  | Compilation.ExternalFunctionCall (name, lccl, cexprs) ->
-      let iexprs = List.map (instantiate_expression ctx) cexprs in
-      let tex_type = check_function_type ctx lccl iexprs in
+  | Compilation.ExternalFunctionCall (name, lccl, cargs) ->
+      let iargs = List.map (instantiate_argument ctx) cargs in
+      let input_types, output_types = check_function_type ctx lccl iargs in
+      let tex_type = match output_types with
+        | [] -> failwith ""
+        | [t] -> t
+        | ts -> CartesianProduct ts in
       {
         tex_type = tex_type;
-        tex_expression = Some (ExternalFunctionCall (name, iexprs))
+        tex_expression =
+          Some (ExternalFunctionCall (name, input_types, output_types, iargs))
       }
   | Compilation.Exp cexpr ->
       let iexpr = instantiate_expression ctx cexpr in
       begin match iexpr.tex_type with
-        | RealType dims ->
+        | RealType dims | IntegerType dims ->
             {
               tex_type = RealType dims;
               tex_expression = Some (Exp iexpr)
@@ -859,7 +1009,7 @@ and instantiate_expression ctx = function
   | Compilation.Log cexpr ->
       let iexpr = instantiate_expression ctx cexpr in
       begin match iexpr.tex_type with
-        | RealType dims ->
+        | RealType dims | IntegerType dims ->
             {
               tex_type = RealType dims;
               tex_expression = Some (Log iexpr)
@@ -1064,6 +1214,16 @@ and instantiate_expression ctx = function
             }
         | _ -> failwith "instantiate_expression: type error on ^"
       end
+  | Compilation.Pre cexpr ->
+      let iexpr = instantiate_expression ctx cexpr in
+      begin match iexpr.tex_type with
+        | RealType dims | IntegerType dims ->
+            {
+              tex_type = RealType dims;
+              tex_expression = Some (Pre iexpr)
+            }
+        | _ -> failwith "instantiate_expression: type error on pre"
+      end
   | Compilation.Real f ->
       {
         tex_type = RealType [||];
@@ -1082,17 +1242,27 @@ and instantiate_expression ctx = function
   | Compilation.Sin cexpr ->
       let iexpr = instantiate_expression ctx cexpr in
       begin match iexpr.tex_type with
-        | RealType dims ->
+        | RealType dims | IntegerType dims ->
             {
               tex_type = RealType dims;
               tex_expression = Some (Sin iexpr)
             }
         | _ -> failwith "instantiate_expression: type error on sin"
       end
+  | Compilation.Sinh cexpr ->
+      let iexpr = instantiate_expression ctx cexpr in
+      begin match iexpr.tex_type with
+        | RealType dims | IntegerType dims ->
+            {
+              tex_type = RealType dims;
+              tex_expression = Some (Sinh iexpr)
+            }
+        | _ -> failwith "instantiate_expression: type error on sinh"
+      end
   | Compilation.Sqrt cexpr ->
       let iexpr = instantiate_expression ctx cexpr in
       begin match iexpr.tex_type with
-        | RealType dims ->
+        | RealType dims | IntegerType dims ->
             {
               tex_type = RealType dims;
               tex_expression = Some (Sqrt iexpr)
@@ -1124,7 +1294,7 @@ and instantiate_expression ctx = function
   | Compilation.Tan cexpr ->
       let iexpr = instantiate_expression ctx cexpr in
       begin match iexpr.tex_type with
-        | RealType dims ->
+        | RealType dims | IntegerType dims ->
             {
               tex_type = RealType dims;
               tex_expression = Some (Tan iexpr)
@@ -1134,7 +1304,7 @@ and instantiate_expression ctx = function
   | Compilation.Tanh cexpr ->
       let iexpr = instantiate_expression ctx cexpr in
       begin match iexpr.tex_type with
-        | RealType dims ->
+        | RealType dims | IntegerType dims ->
             {
               tex_type = RealType dims;
               tex_expression = Some (Tanh iexpr)
@@ -1154,12 +1324,13 @@ and instantiate_expression ctx = function
       }
 
 and check_function_type ctx lccl iexprs =
-  let compare_input_types iexpr tex_type =
-    iexpr.tex_type = tex_type ||
-    match iexpr.tex_type, tex_type with
-      | IntegerType dims, RealType dims' when dims = dims' -> true
-      | _ -> false
-  and extract_type = function
+  let extract_type = function
+    | Compilation.IntegerVariable { Compilation.vat_dimensions = cdims } ->
+        let dims = Array.map (compute_subscript ctx) cdims in
+        IntegerType dims
+    | Compilation.StringVariable { Compilation.vat_dimensions = cdims } ->
+        let dims = Array.map (compute_subscript ctx) cdims in
+        StringType dims
     | Compilation.DiscreteVariable { Compilation.vat_dimensions = cdims } ->
         let dims = Array.map (compute_subscript ctx) cdims in
         RealType dims
@@ -1175,17 +1346,9 @@ and check_function_type ctx lccl iexprs =
   let outputs, others = separate_outputs_from_others others in
   match pars, others with
     | [], [] ->
-        let input_types = List.map extract_type inputs in
-        begin try
-          if List.for_all2 compare_input_types iexprs input_types then
-            begin match List.map extract_type outputs with
-              | [] -> failwith "check_function_type: no return value"
-              | [t] -> t
-              | ts -> CartesianProduct ts
-            end
-          else failwith "check_function_type: type error"
-        with _ -> failwith "check_function_type: type error"
-        end
+        let input_types = List.map extract_type inputs
+        and output_types = List.map extract_type outputs in
+        input_types, output_types
     | _ -> failwith "check_function_type: invalid function declaration"
 
 and instantiate_if_alternatives ctx tex_type alts =
@@ -1282,14 +1445,21 @@ and search_into_parameter ctx s cs level path ipar =
   let ics = Array.map (compute_subscript ctx) cs in
   match path, ipar with
   | ([] | [("value", [||])] | [("start", [||])]),
-    InstantiatedIntegerParameter (_, _, iexpr) ->
+    InstantiatedIntegerParameter (_, _, iexpr, _) ->
       let dims = find_subvector_dims ics iexpr in
       {
         tex_type = IntegerType dims;
         tex_expression = Some (ParameterValue (level, [(s, ics)]))
       }
   | ([] | [("value", [||])] | [("start", [||])]),
-    InstantiatedRealParameter (_, _, iexpr) ->
+    InstantiatedStringParameter (_, _, iexpr, _) ->
+      let dims = find_subvector_dims ics iexpr in
+      {
+        tex_type = StringType dims;
+        tex_expression = Some (ParameterValue (level, [(s, ics)]))
+      }
+  | ([] | [("value", [||])] | [("start", [||])]),
+    InstantiatedRealParameter (_, _, iexpr, _) ->
       let dims = find_subvector_dims ics iexpr in
       {
         tex_type = RealType dims;
@@ -1300,25 +1470,37 @@ and search_into_parameter ctx s cs level path ipar =
 and search_into_variable ctx s cs level path ivar =
   let ics = Array.map (compute_subscript ctx) cs in
   match path, ivar with
-  | ([] | [("value", [||])]), InstantiatedDiscreteVariable (_, _, iexpr) ->
+  | ([] | [("value", [||])]), InstantiatedIntegerVariable (_, _, iexpr, _) ->
+      let dims = find_subvector_dims ics iexpr in
+      {
+        tex_type = IntegerType dims;
+        tex_expression = Some (VariableValue (level, [(s, ics)]))
+      }
+  | ([] | [("value", [||])]), InstantiatedStringVariable (_, _, iexpr, _) ->
+      let dims = find_subvector_dims ics iexpr in
+      {
+        tex_type = StringType dims;
+        tex_expression = Some (VariableValue (level, [(s, ics)]))
+      }
+  | ([] | [("value", [||])]), InstantiatedDiscreteVariable (_, _, iexpr, _) ->
       let dims = find_subvector_dims ics iexpr in
       {
         tex_type = RealType dims;
         tex_expression = Some (VariableValue (level, [(s, ics)]))
       }
-  | ([] | [("value", [||])]), InstantiatedRealVariable (_, _, _, iexpr) ->
+  | ([] | [("value", [||])]), InstantiatedRealVariable (_, _, _, iexpr, _) ->
       let dims = find_subvector_dims ics iexpr in
       {
         tex_type = RealType dims;
         tex_expression = Some (VariableValue (level, [(s, ics)]))
       }
-  | [("start", [||])], InstantiatedDiscreteVariable (_, _, iexpr) ->
+  | [("start", [||])], InstantiatedDiscreteVariable (_, _, iexpr, _) ->
       let dims = find_subvector_dims ics iexpr in
       {
         tex_type = RealType dims;
         tex_expression = Some (VariableStart (level, [(s, ics)]))
       }
-  | [("start", [||])], InstantiatedRealVariable (_, _, _, iexpr) ->
+  | [("start", [||])], InstantiatedRealVariable (_, _, _, iexpr, _) ->
       let dims = find_subvector_dims ics iexpr in
       {
         tex_type = RealType dims;
@@ -1365,8 +1547,7 @@ and search_into_compound_variable ctx s ics level path iexpr =
     | _ -> failwith "search_into_compound_variable: compilation error"
 
 and compute_subscript ctx = function
-  | Compilation.Indefinite ->
-      failwith "compute_subscript: invalid subscript"
+  | Compilation.Indefinite -> -1
   | Compilation.Definite cexpr ->
       begin match evaluate_integer_expression ctx cexpr with
         | Integer i when Int32.to_int i >= 0 -> Int32.to_int i
@@ -1448,7 +1629,7 @@ and flatten_instantiated_class path icl =
 and collect_flows icpnts =
   let collect_flow flows = function
     | s, InstantiatedVariable
-      (InstantiatedRealVariable (_, _, Compilation.Flow, _)) ->
+      (InstantiatedRealVariable (_, _, Compilation.Flow, _, _)) ->
         [{
           tex_type = RealType [||];
           tex_expression = Some (VariableValue (0, [(s, [||])]))
@@ -1464,35 +1645,47 @@ and flatten_components path icpnts =
         flatten_variable icpnts iinit_equs iequs s ivar
   and flatten_parameter icpnts s = function
     | InstantiatedIntegerParameter (cmt, kind,
-      ({ tex_type = IntegerType dims } as iexpr)) ->
+      ({ tex_type = IntegerType dims } as iexpr), pat_infos) ->
+        let make iexpr =
+          InstantiatedParameter
+            (InstantiatedIntegerParameter (cmt, kind, iexpr, pat_infos))
+        in
+        let ipars = flatten_component_tree make path s iexpr in
+        icpnts @ ipars
+    | InstantiatedStringParameter (cmt, kind,
+      ({ tex_type = StringType dims } as iexpr), pat_infos) ->
         let make iexpr =
           InstantiatedParameter
-            (InstantiatedIntegerParameter (cmt, kind, iexpr))
+            (InstantiatedStringParameter (cmt, kind, iexpr, pat_infos))
         in
         let ipars = flatten_component_tree make path s iexpr in
         icpnts @ ipars
-    | InstantiatedRealParameter (cmt, kind,
-      ({ tex_type = (IntegerType dims | RealType dims) } as iexpr)) ->
+    | InstantiatedRealParameter
+        (cmt,
+         kind,
+         ({ tex_type = (IntegerType dims | RealType dims) } as iexpr),
+         pat_infos) ->
         let make iexpr =
-          InstantiatedParameter (InstantiatedRealParameter (cmt, kind, iexpr))
+          InstantiatedParameter
+            (InstantiatedRealParameter (cmt, kind, iexpr, pat_infos))
         in
         let ipars = flatten_component_tree make path s iexpr in
         icpnts @ ipars
     | _ -> failwith "flatten_parameter: type error"
   and flatten_variable icpnts iinit_equs iequs s = function
     | InstantiatedDiscreteVariable (cmt, inout,
-      ({ tex_type = (IntegerType dims | RealType dims) } as iexpr)) ->
+      ({ tex_type = (IntegerType dims | RealType dims) } as iexpr), infos) ->
         let make iexpr =
           InstantiatedVariable (
-            InstantiatedDiscreteVariable (cmt, inout, iexpr))
+            InstantiatedDiscreteVariable (cmt, inout, iexpr, infos))
         in
         let ivars = flatten_component_tree make path s iexpr in
         icpnts @ ivars, iinit_equs, iequs
     | InstantiatedRealVariable (cmt, inout, flow,
-      ({ tex_type = (IntegerType dims | RealType dims) } as iexpr)) ->
+      ({ tex_type = (IntegerType dims | RealType dims) } as iexpr), infos) ->
         let make iexpr =
           InstantiatedVariable
-            (InstantiatedRealVariable (cmt, inout, flow, iexpr))
+            (InstantiatedRealVariable (cmt, inout, flow, iexpr, infos))
         in
         let ivars = flatten_component_tree make path s iexpr in
         icpnts @ ivars, iinit_equs, iequs
@@ -1610,6 +1803,8 @@ and update_expression path = function
 
 and update_expression' path = function
   | Abs iexpr -> Abs (update_typed_expression path iexpr)
+  | Acos iexpr -> Acos (update_typed_expression path iexpr)
+  | Acosh iexpr -> Acosh (update_typed_expression path iexpr)
   | Addition (iexpr, iexpr') ->
       let iexpr = update_typed_expression path iexpr
       and iexpr' = update_typed_expression path iexpr' in
@@ -1618,10 +1813,15 @@ and update_expression' path = function
       let iexpr = update_typed_expression path iexpr
       and iexpr' = update_typed_expression path iexpr' in
       And (iexpr, iexpr')
+  | Asin iexpr -> Asin (update_typed_expression path iexpr)
+  | Asinh iexpr -> Asinh (update_typed_expression path iexpr)
+  | Atan iexpr -> Atan (update_typed_expression path iexpr)
+  | Atanh iexpr -> Atanh (update_typed_expression path iexpr)
   | Boolean _ as iexpr -> iexpr
   | Cardinality iexpr -> Cardinality (update_typed_expression path iexpr)
   | CompoundElement _ as iexpr -> iexpr
   | Cos iexpr -> Cos (update_typed_expression path iexpr)
+  | Cosh iexpr -> Cosh (update_typed_expression path iexpr)
   | Der iexpr -> Der (update_typed_expression path iexpr)
   | Division (iexpr, iexpr') ->
       let iexpr = update_typed_expression path iexpr
@@ -1632,9 +1832,9 @@ and update_expression' path = function
       and iexpr' = update_typed_expression path iexpr' in
       Equals (iexpr, iexpr')
   | Exp iexpr -> Exp (update_typed_expression path iexpr)
-  | ExternalFunctionCall (name, iexprs) ->
-      let iexprs = List.map (update_typed_expression path) iexprs in
-      ExternalFunctionCall (name, iexprs)
+  | ExternalFunctionCall (name, in_types, out_types, iargs) ->
+      let iargs = List.map (update_typed_argument path) iargs in
+      ExternalFunctionCall (name, in_types, out_types, iargs)
   | Floor iexpr -> Floor (update_typed_expression path iexpr)
   | GreaterEqualThan (iexpr, iexpr') ->
       let iexpr = update_typed_expression path iexpr
@@ -1688,8 +1888,10 @@ and update_expression' path = function
       let iexpr = update_typed_expression path iexpr
       and iexpr' = update_typed_expression path iexpr' in
       Power (iexpr, iexpr')
+  | Pre iexpr -> Pre (update_typed_expression path iexpr)
   | Real _ as iexpr -> iexpr
   | Sin iexpr -> Sin (update_typed_expression path iexpr)
+  | Sinh iexpr -> Sinh (update_typed_expression path iexpr)
   | Sqrt iexpr -> Sqrt (update_typed_expression path iexpr)
   | String _ as iexpr -> iexpr
   | Subtraction (iexpr, iexpr') ->
@@ -1706,6 +1908,11 @@ and update_expression' path = function
   | Vector iexprs ->
       Vector (Array.map (update_typed_expression path) iexprs)
 
+and update_typed_argument path = function
+  | ScalarArgument iexpr -> ScalarArgument (update_typed_expression path iexpr)
+  | ArrayArgument (dims, iexprs) ->
+      ArrayArgument (dims, Array.map (update_typed_expression path) iexprs)
+
 and update_reference level path =
   let rec to_string = function
     | [] -> ""
@@ -1807,6 +2014,12 @@ and flatten_typed_expression' iexpr'' = function
   | Abs iexpr ->
       let iexpr = flatten_typed_expression iexpr in
       array_map (fun iexpr -> Abs iexpr) iexpr
+  | Acos iexpr ->
+      let iexpr = flatten_typed_expression iexpr in
+      array_map (fun iexpr -> Acos iexpr) iexpr
+  | Acosh iexpr ->
+      let iexpr = flatten_typed_expression iexpr in
+      array_map (fun iexpr -> Acosh iexpr) iexpr
   | Addition (iexpr, iexpr') ->
       let iexpr = flatten_typed_expression iexpr
       and iexpr' = flatten_typed_expression iexpr' in
@@ -1815,6 +2028,18 @@ and flatten_typed_expression' iexpr'' = function
       let iexpr = flatten_typed_expression iexpr
       and iexpr' = flatten_typed_expression iexpr' in
       array_map2 (fun iexpr iexpr' -> And (iexpr, iexpr')) iexpr iexpr'
+  | Asin iexpr ->
+      let iexpr = flatten_typed_expression iexpr in
+      array_map (fun iexpr -> Asin iexpr) iexpr
+  | Asinh iexpr ->
+      let iexpr = flatten_typed_expression iexpr in
+      array_map (fun iexpr -> Asinh iexpr) iexpr
+  | Atan iexpr ->
+      let iexpr = flatten_typed_expression iexpr in
+      array_map (fun iexpr -> Atan iexpr) iexpr
+  | Atanh iexpr ->
+      let iexpr = flatten_typed_expression iexpr in
+      array_map (fun iexpr -> Atanh iexpr) iexpr
   | Boolean _ -> iexpr''
   | Cardinality iexpr ->
       let iexpr = flatten_typed_expression iexpr in
@@ -1823,6 +2048,9 @@ and flatten_typed_expression' iexpr'' = function
   | Cos iexpr ->
       let iexpr = flatten_typed_expression iexpr in
       array_map (fun iexpr -> Cos iexpr) iexpr
+  | Cosh iexpr ->
+      let iexpr = flatten_typed_expression iexpr in
+      array_map (fun iexpr -> Cosh iexpr) iexpr
   | Der iexpr ->
       let iexpr = flatten_typed_expression iexpr in
       array_map (fun iexpr -> Der iexpr) iexpr
@@ -1838,12 +2066,15 @@ and flatten_typed_expression' iexpr'' = function
   | Exp iexpr ->
       let iexpr = flatten_typed_expression iexpr in
       array_map (fun iexpr -> Exp iexpr) iexpr
-  | ExternalFunctionCall (name, [iexpr]) ->
-      let iexpr = flatten_typed_expression iexpr in
-      array_map (fun iexpr -> ExternalFunctionCall (name, [iexpr])) iexpr
-  | ExternalFunctionCall (name, iexprs) ->
-      let iexprs = List.map flatten_typed_expression iexprs in
-      { iexpr'' with tex_expression = Some (ExternalFunctionCall (name, iexprs)) }
+(*  | ExternalFunctionCall (name, [iarg]) ->
+      let iarg = flatten_typed_argument iarg in
+      array_map (fun iarg -> ExternalFunctionCall (name, [iarg])) iarg*)
+  | ExternalFunctionCall (name, in_types, out_types, iargs) ->
+      let iargs = List.map flatten_typed_argument iargs in
+      { iexpr'' with
+        tex_expression =
+          Some (ExternalFunctionCall (name, in_types, out_types, iargs))
+      }
   | Floor iexpr ->
       let iexpr = flatten_typed_expression iexpr in
       array_map (fun iexpr -> Floor iexpr) iexpr
@@ -1907,10 +2138,16 @@ and flatten_typed_expression' iexpr'' = function
       let iexpr = flatten_typed_expression iexpr
       and iexpr' = flatten_typed_expression iexpr' in
       { iexpr'' with tex_expression = Some (Power (iexpr, iexpr')) }
+  | Pre iexpr ->
+      let iexpr = flatten_typed_expression iexpr in
+      array_map (fun iexpr -> Pre iexpr) iexpr
   | Real _ -> iexpr''
   | Sin iexpr ->
       let iexpr = flatten_typed_expression iexpr in
       array_map (fun iexpr -> Sin iexpr) iexpr
+  | Sinh iexpr ->
+      let iexpr = flatten_typed_expression iexpr in
+      array_map (fun iexpr -> Sinh iexpr) iexpr
   | Sqrt iexpr ->
       let iexpr = flatten_typed_expression iexpr in
       array_map (fun iexpr -> Sqrt iexpr) iexpr
@@ -1934,6 +2171,11 @@ and flatten_typed_expression' iexpr'' = function
       expand_identifier iexpr''.tex_type make level iref
   | Vector _ -> iexpr''
 
+and flatten_typed_argument = function
+  | ScalarArgument iexpr -> ScalarArgument (flatten_typed_expression iexpr)
+  | ArrayArgument (dims, iexprs) ->
+      ArrayArgument (dims, Array.map flatten_typed_expression iexprs)
+
 and flatten_multiplication iexpr iexpr' iexpr'' =
   let extract_subvector = function
     | { tex_expression = Some (Vector iexprs) } -> iexprs
@@ -2262,12 +2504,54 @@ and evaluate_cardinalities ss iequs =
           tex_type = RealType [||];
           tex_expression = Some (Abs iexpr)
         }
+    | Acos iexpr ->
+        let iexpr = evaluate_cardinalities_in_expression iexpr in
+        {
+          tex_type = RealType [||];
+          tex_expression = Some (Acos iexpr)
+        }
+    | Acosh iexpr ->
+        let iexpr = evaluate_cardinalities_in_expression iexpr in
+        {
+          tex_type = RealType [||];
+          tex_expression = Some (Acosh iexpr)
+        }
+    | Asin iexpr ->
+        let iexpr = evaluate_cardinalities_in_expression iexpr in
+        {
+          tex_type = RealType [||];
+          tex_expression = Some (Asin iexpr)
+        }
+    | Asinh iexpr ->
+        let iexpr = evaluate_cardinalities_in_expression iexpr in
+        {
+          tex_type = RealType [||];
+          tex_expression = Some (Asinh iexpr)
+        }
+    | Atan iexpr ->
+        let iexpr = evaluate_cardinalities_in_expression iexpr in
+        {
+          tex_type = RealType [||];
+          tex_expression = Some (Atan iexpr)
+        }
+    | Atanh iexpr ->
+        let iexpr = evaluate_cardinalities_in_expression iexpr in
+        {
+          tex_type = RealType [||];
+          tex_expression = Some (Atanh iexpr)
+        }
     | Cos iexpr ->
         let iexpr = evaluate_cardinalities_in_expression iexpr in
         {
           tex_type = RealType [||];
           tex_expression = Some (Cos iexpr)
         }
+    | Cosh iexpr ->
+        let iexpr = evaluate_cardinalities_in_expression iexpr in
+        {
+          tex_type = RealType [||];
+          tex_expression = Some (Cosh iexpr)
+        }
     | Der iexpr ->
         let iexpr = evaluate_cardinalities_in_expression iexpr in
         {
@@ -2310,12 +2594,24 @@ and evaluate_cardinalities ss iequs =
           tex_type = RealType [||];
           tex_expression = Some (Not iexpr)
         }
+    | Pre iexpr ->
+        let iexpr = evaluate_cardinalities_in_expression iexpr in
+        {
+          tex_type = RealType [||];
+          tex_expression = Some (Pre iexpr)
+        }
     | Sin iexpr ->
         let iexpr = evaluate_cardinalities_in_expression iexpr in
         {
           tex_type = RealType [||];
           tex_expression = Some (Sin iexpr)
         }
+    | Sinh iexpr ->
+        let iexpr = evaluate_cardinalities_in_expression iexpr in
+        {
+          tex_type = RealType [||];
+          tex_expression = Some (Sinh iexpr)
+        }
     | Sqrt iexpr ->
         let iexpr = evaluate_cardinalities_in_expression iexpr in
         {
@@ -2334,12 +2630,15 @@ and evaluate_cardinalities ss iequs =
           tex_type = RealType [||];
           tex_expression = Some (Tanh iexpr)
         }
-    | ExternalFunctionCall (name, [iexpr]) ->
+(*    | ExternalFunctionCall (name, [iexpr]) ->
         let iexpr = evaluate_cardinalities_in_expression iexpr in
-        { iexpr'' with tex_expression = Some (ExternalFunctionCall (name, [iexpr])) }
-    | ExternalFunctionCall (name, iexprs) ->
-        let iexprs = List.map evaluate_cardinalities_in_expression iexprs in
-        { iexpr'' with tex_expression = Some (ExternalFunctionCall (name, iexprs)) }
+        { iexpr'' with tex_expression = Some (ExternalFunctionCall (name, [iexpr])) }*)
+    | ExternalFunctionCall (name, in_types, out_types, iargs) ->
+        let iargs = List.map evaluate_cardinalities_in_argument iargs in
+        { iexpr'' with
+          tex_expression =
+            Some (ExternalFunctionCall (name, in_types, out_types, iargs))
+        }
     | If (iif_exprs, iexpr) ->
         { iexpr'' with tex_expression = Some (If (
           List.map
@@ -2349,4 +2648,10 @@ and evaluate_cardinalities ss iequs =
               iexpr, iexpr')
             iif_exprs,
           evaluate_cardinalities_in_expression iexpr)) }
-  in List.rev_map evaluate_cardinalities_in_equation iequs
+  and evaluate_cardinalities_in_argument = function
+    | ScalarArgument iexpr ->
+        ScalarArgument (evaluate_cardinalities_in_expression iexpr)
+    | ArrayArgument (dims, iexprs) ->
+        ArrayArgument
+          (dims, Array.map evaluate_cardinalities_in_expression iexprs) in
+  List.rev_map evaluate_cardinalities_in_equation iequs
index 67f2d8c..9c66426 100644 (file)
@@ -1,23 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 (** This module provides the functions that yield instances of compiled
 Modelica classes.*)
@@ -36,16 +37,23 @@ and instantiated_component =
 
 and instantiated_parameter =
     InstantiatedIntegerParameter of string * parameter_kind *
-      typed_expression
-  | InstantiatedRealParameter of string * parameter_kind * typed_expression
+      typed_expression * Compilation.variable_infos
+  | InstantiatedStringParameter of string * parameter_kind *
+      typed_expression * Compilation.variable_infos
+  | InstantiatedRealParameter of string * parameter_kind * typed_expression *
+      Compilation.variable_infos
 
 and parameter_kind = Main | Sub
 
 and instantiated_variable =
-    InstantiatedDiscreteVariable of string * Compilation.inout *
-      typed_expression
+    InstantiatedIntegerVariable of string * Compilation.inout *
+    typed_expression * Compilation.variable_infos
+  | InstantiatedStringVariable of string * Compilation.inout *
+    typed_expression * Compilation.variable_infos
+  | InstantiatedDiscreteVariable of string * Compilation.inout *
+      typed_expression * Compilation.variable_infos
   | InstantiatedRealVariable of string * Compilation.inout *
-      Compilation.nature * typed_expression
+      Compilation.nature * typed_expression * Compilation.variable_infos
   | InstantiatedCompoundVariable of string * typed_expression
 
 and equation =
@@ -76,18 +84,27 @@ and expression_type =
   | StringType of int array
 
 and expression =
-    Abs of typed_expression
+  | Abs of typed_expression
+  | Acos of typed_expression
+  | Acosh of typed_expression
   | Addition of typed_expression * typed_expression
   | And of typed_expression * typed_expression
+  | Asin of typed_expression
+  | Asinh of typed_expression
+  | Atan of typed_expression
+  | Atanh of typed_expression
   | Boolean of bool
   | Cardinality of typed_expression
   | CompoundElement of instantiated_class
   | Cos of typed_expression
+  | Cosh of typed_expression
   | Der of typed_expression
   | Division of typed_expression * typed_expression
   | Equals of typed_expression * typed_expression
   | Exp of typed_expression
-  | ExternalFunctionCall of string list * typed_expression list
+  | ExternalFunctionCall of
+      string list * expression_type list * expression_type list *
+      typed_argument list
   | Floor of typed_expression
   | GreaterEqualThan of typed_expression * typed_expression
   | GreaterThan of typed_expression * typed_expression
@@ -105,8 +122,10 @@ and expression =
   | Or of typed_expression * typed_expression
   | ParameterValue of int * reference
   | Power of typed_expression * typed_expression
+  | Pre of typed_expression
   | Real of float
   | Sin of typed_expression
+  | Sinh of typed_expression
   | Sqrt of typed_expression
   | String of string
   | Subtraction of typed_expression * typed_expression
@@ -117,6 +136,10 @@ and expression =
   | VariableValue of int * reference
   | Vector of typed_expression array
 
+and typed_argument =
+  | ScalarArgument of typed_expression
+  | ArrayArgument of int list * typed_expression array
+
 and reference = (string * int array) list
 
 (** The type of an instantiation context. *)
index 16e1841..9cc65d4 100644 (file)
@@ -1,23 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 {
 open Parser
@@ -32,7 +33,7 @@ let check_reserved = function
     | "block" -> BLOCK
     | "class" -> CLASS
     | "connect" -> CONNECT
-    | "connector" -> CLASS
+    | "connector" -> CONNECTOR
     | "constant" -> CONSTANT
     | "discrete" -> DISCRETE
     | "else" -> ELSE
@@ -54,7 +55,7 @@ let check_reserved = function
     | "inner" -> INNER
     | "input" -> INPUT
     | "loop" -> LOOP
-    | "model" -> CLASS
+    | "model" -> MODEL
     | "not" -> NOT
     | "or" -> OR
     | "outer" -> OUTER
@@ -102,11 +103,11 @@ rule token = parse
 
 
     | "/*" ( [^ '*'] | '*'+ [^ '*' '/'] )* '*'+ '/'
-                { let lxm = Lexing.lexeme lexbuf in
+                { let _ = Lexing.lexeme lexbuf in
                   token lexbuf }
 
     | "//" [^ '\n']* '\n'
-                { let lxm = Lexing.lexeme lexbuf in
+                { let _ = Lexing.lexeme lexbuf in
                   token lexbuf }
 
     | unsigned_integer
old mode 100755 (executable)
new mode 100644 (file)
index 4294662..d1f97b6
@@ -1,23 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 {
 
index 122bd92..608cc31 100644 (file)
@@ -1,23 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 open SymbolicExpression
 
@@ -68,11 +69,14 @@ type identifier_maps =
 and parameter =
   {
     parameter_kind: Instantiation.parameter_kind;
+    parameter_type: parameter_type;
     parameter_id: int;
     parameter_comment: string;
     parameter_start: t Lazy.t
   }
 
+and parameter_type = IntegerType | StringType | RealType
+
 and input =
   {
     input_id: int;
@@ -97,13 +101,18 @@ and model =
     mutable reinitializable_variables: t list;
     mutable when_clauses: (t * when_expression list) list;
     mutable io_dependency: bool;
-    mutable external_functions: (string list * int) list;
-    trace: string option
+    mutable external_functions:
+      (string list *
+      Instantiation.expression_type list *
+      Instantiation.expression_type list) list;
+    trace: string option;
+    variables_infos: (string * Compilation.variable_infos) list
   }
 
 and parameter_description =
   {
     mutable main: bool;
+    mutable p_type: parameter_type;
     mutable p_name: string;
     mutable p_comment: string;
     mutable value: t
@@ -122,6 +131,7 @@ and variable_description =
     mutable output: int option;
     mutable state: bool;
     mutable v_name: string;
+    mutable depth_in_hierarchy: int;
     mutable v_comment: string;
     mutable start_value: t option
   }
@@ -142,6 +152,12 @@ and when_expression =
 
 let scaling_factor = Num.power_num (Num.Int 10) (Num.Int 16)
 
+let exists_array p xs =
+  let l = Array.length xs in
+  let rec exists_array_from i =
+    i < l && (p xs.(i) || exists_array_from (i + 1)) in
+  exists_array_from 0
+
 let num_of_float f =
   let num_of_positive_float f =
     let m, e = frexp f in
@@ -178,7 +194,13 @@ let get_start_value id variables_map =
     | Some lexpr -> Lazy.force lexpr
 
 let rec symbolic_expression_of_expression inl_par maps iexpr =
-  let rec symbolic_expression_of_expression' iexpr =
+  let rec symbolic_argument_of_argument = function
+      | Instantiation.ScalarArgument iexpr ->
+          ScalarArgument (symbolic_expression_of_expression' iexpr)
+      | Instantiation.ArrayArgument (dims, iexprs) ->
+          ArrayArgument
+            (dims, Array.map symbolic_expression_of_expression' iexprs)
+  and symbolic_expression_of_expression' iexpr =
     match iexpr.Instantiation.tex_expression with
       | None -> assert false
       | Some expr -> symbolic_expression_of_expression'' expr
@@ -186,9 +208,13 @@ let rec symbolic_expression_of_expression inl_par maps iexpr =
       | Instantiation.Abs iexpr ->
           let expr = symbolic_expression_of_expression' iexpr in
           symbolic_if
-            (symbolic_gt expr zero)
+            (symbolic_ge expr zero)
             expr
             (symbolic_minus expr)
+      | Instantiation.Acos iexpr ->
+          symbolic_acos (symbolic_expression_of_expression' iexpr)
+      | Instantiation.Acosh iexpr ->
+          symbolic_acosh (symbolic_expression_of_expression' iexpr)
       | Instantiation.Addition (iexpr, iexpr') ->
           symbolic_add
             (symbolic_expression_of_expression' iexpr)
@@ -197,6 +223,14 @@ let rec symbolic_expression_of_expression inl_par maps iexpr =
           symbolic_and
             (symbolic_expression_of_expression' iexpr)
             (symbolic_expression_of_expression' iexpr')
+      | Instantiation.Asin iexpr ->
+          symbolic_asin (symbolic_expression_of_expression' iexpr)
+      | Instantiation.Asinh iexpr ->
+          symbolic_asinh (symbolic_expression_of_expression' iexpr)
+      | Instantiation.Atan iexpr ->
+          symbolic_atan (symbolic_expression_of_expression' iexpr)
+      | Instantiation.Atanh iexpr ->
+          symbolic_atanh (symbolic_expression_of_expression' iexpr)
       | Instantiation.Boolean false -> false_value
       | Instantiation.Boolean true -> true_value
       | Instantiation.Cardinality _ ->
@@ -205,6 +239,8 @@ let rec symbolic_expression_of_expression inl_par maps iexpr =
           invalid_arg "symbolic_expression_of_expression'"
       | Instantiation.Cos iexpr ->
           symbolic_cos (symbolic_expression_of_expression' iexpr)
+      | Instantiation.Cosh iexpr ->
+          symbolic_cosh (symbolic_expression_of_expression' iexpr)
       | Instantiation.Der iexpr ->
           symbolic_derivative (symbolic_expression_of_expression' iexpr)
       | Instantiation.Division (iexpr, iexpr') ->
@@ -217,10 +253,10 @@ let rec symbolic_expression_of_expression inl_par maps iexpr =
             (symbolic_expression_of_expression' iexpr')
       | Instantiation.Exp iexpr ->
           symbolic_exp (symbolic_expression_of_expression' iexpr)
-      | Instantiation.ExternalFunctionCall (path, iexprs) ->
+      | Instantiation.ExternalFunctionCall (path, _, _, iargs) ->
           symbolic_blackBox
             (function_name_of path)
-            (List.map symbolic_expression_of_expression' iexprs)
+            (List.map symbolic_argument_of_argument iargs)
       | Instantiation.Floor iexpr ->
           symbolic_floor (symbolic_expression_of_expression' iexpr)
       | Instantiation.GreaterEqualThan (iexpr, iexpr') ->
@@ -240,14 +276,7 @@ let rec symbolic_expression_of_expression inl_par maps iexpr =
                 expr)
             iif_exprs
             (symbolic_expression_of_expression' iexpr)
-      | Instantiation.Integer i ->
-          let i1 = Int32.to_int (Int32.shift_right i 16)
-          and i2 = Int32.to_int (Int32.logand i (Int32.of_int 0xffff)) in
-          let num =
-            Num.add_num
-              (Num.mult_num (Num.num_of_int i1) (Num.num_of_int 65536))
-              (Num.num_of_int i2)
-          in create_number num
+      | Instantiation.Integer i -> create_integer i
       | Instantiation.Log iexpr ->
           symbolic_log (symbolic_expression_of_expression' iexpr)
       | Instantiation.Max (iexpr, iexpr') ->
@@ -272,7 +301,9 @@ let rec symbolic_expression_of_expression inl_par maps iexpr =
             (symbolic_expression_of_expression' iexpr)
             (symbolic_expression_of_expression' iexpr')
       | Instantiation.NoEvent iexpr ->
-          create_blackBox "noEvent" [symbolic_expression_of_expression' iexpr]
+          create_blackBox
+            "noEvent"
+            [ScalarArgument (symbolic_expression_of_expression' iexpr)]
       | Instantiation.Not iexpr ->
           symbolic_not (symbolic_expression_of_expression' iexpr)
       | Instantiation.NotEquals (iexpr, iexpr') ->
@@ -298,12 +329,16 @@ let rec symbolic_expression_of_expression inl_par maps iexpr =
           symbolic_power
             (symbolic_expression_of_expression' iexpr)
             (symbolic_expression_of_expression' iexpr')
+      | Instantiation.Pre iexpr ->
+          symbolic_pre (symbolic_expression_of_expression' iexpr)
       | Instantiation.Real f -> create_number (num_of_float f)
       | Instantiation.Sin iexpr ->
           symbolic_sin (symbolic_expression_of_expression' iexpr)
+      | Instantiation.Sinh iexpr ->
+          symbolic_sinh (symbolic_expression_of_expression' iexpr)
       | Instantiation.Sqrt iexpr ->
           symbolic_sqrt (symbolic_expression_of_expression' iexpr)
-      | Instantiation.String s -> create_constant s
+      | Instantiation.String s -> create_string s
       | Instantiation.Subtraction (iexpr, iexpr') ->
           symbolic_sub
             (symbolic_expression_of_expression' iexpr)
@@ -349,11 +384,13 @@ let rec symbolic_expression_of_expression inl_par maps iexpr =
   in symbolic_expression_of_expression' iexpr
 
 let collect_external_function_names iequs =
-  let rec add_if_not_in (name, arity) = function
-    | [] -> [name, arity]
-    | ((name', _) :: _) as names when name = name' -> names
-    | name'_arity :: names -> name'_arity :: add_if_not_in (name, arity) names
-  in
+  let rec add_if_not_in (name, in_types, out_types) = function
+    | [] -> [name, in_types, out_types]
+    | ((name', _, _) :: _) as name_and_types when name = name' ->
+        name_and_types
+    | name_and_type :: name_and_types ->
+        name_and_type ::
+        add_if_not_in (name, in_types, out_types) name_and_types in
   let rec collect_in_equations funcalls = function
     | [] -> funcalls
     | Instantiation.Equation (iexpr, iexpr') :: iequs' ->
@@ -409,9 +446,9 @@ let collect_external_function_names iequs =
         Instantiation.Subtraction (iexpr, iexpr') ->
           let funcalls = collect_in_expressions funcalls iexpr in
           collect_in_expressions funcalls iexpr'
-      | Instantiation.ExternalFunctionCall (name, iexprs) ->
-          let funcalls = add_if_not_in (name, List.length iexprs) funcalls in
-          List.fold_left collect_in_expressions funcalls iexprs
+      | Instantiation.ExternalFunctionCall (name, in_types, out_types, iargs) ->
+          let funcalls = add_if_not_in (name, in_types, out_types) funcalls in
+          List.fold_left collect_in_arguments funcalls iargs
       | Instantiation.If (iif_exprs, iexpr) ->
           let funcalls =
             List.fold_left
@@ -423,11 +460,16 @@ let collect_external_function_names iequs =
           in collect_in_expressions funcalls iexpr
       | Instantiation.Minus iexpr | Instantiation.NoEvent iexpr |
         Instantiation.Not iexpr | Instantiation.Abs iexpr |
-        Instantiation.Cos iexpr | Instantiation.Exp iexpr |
+        Instantiation.Acos iexpr | Instantiation.Acosh iexpr |
+        Instantiation.Cos iexpr | Instantiation.Cosh iexpr |
+        Instantiation.Exp iexpr |
         Instantiation.Floor iexpr | Instantiation.Log iexpr |
-        Instantiation.Sin iexpr | Instantiation.Sqrt iexpr |
-        Instantiation.Tan iexpr | Instantiation.Tanh iexpr ->
-          collect_in_expressions funcalls iexpr
+        Instantiation.Asin iexpr | Instantiation.Asinh iexpr |
+        Instantiation.Sin iexpr | Instantiation.Sinh iexpr |
+        Instantiation.Sqrt iexpr |
+        Instantiation.Atan iexpr | Instantiation.Atanh iexpr |
+        Instantiation.Tan iexpr | Instantiation.Tanh iexpr |
+        Instantiation.Pre iexpr -> collect_in_expressions funcalls iexpr
       | Instantiation.ParameterValue _ | Instantiation.Real _ |
         Instantiation.String _ | Instantiation.Time |
         Instantiation.VariableStart _ | Instantiation.VariableValue _ |
@@ -435,6 +477,11 @@ let collect_external_function_names iequs =
           funcalls
       | Instantiation.Cardinality _ | Instantiation.CompoundElement _ |
         Instantiation.Vector _ -> assert false
+  and collect_in_arguments funcalls = function
+    | Instantiation.ScalarArgument iexpr ->
+        collect_in_expressions funcalls iexpr
+    | Instantiation.ArrayArgument (_, iexprs) ->
+        Array.fold_left collect_in_expressions funcalls iexprs
   in collect_in_equations [] iequs
 
 let separate_parameters_from_variables icpnts =
@@ -445,10 +492,18 @@ let separate_parameters_from_variables icpnts =
 
 let separate_inputs_from_others icpnts =
   let is_input = function
-    | Instantiation.InstantiatedDiscreteVariable (_, Compilation.Input, _) |
-      Instantiation.InstantiatedRealVariable (_, Compilation.Input, _, _) ->
+    | Instantiation.InstantiatedIntegerVariable
+        (_, Compilation.Input, _, _) |
+      Instantiation.InstantiatedStringVariable
+        (_, Compilation.Input, _, _) |
+      Instantiation.InstantiatedDiscreteVariable
+        (_, Compilation.Input, _, _) |
+      Instantiation.InstantiatedRealVariable
+        (_, Compilation.Input, _, _, _) ->
         true
-    | Instantiation.InstantiatedDiscreteVariable _ |
+    | Instantiation.InstantiatedIntegerVariable _ |
+      Instantiation.InstantiatedStringVariable _ |
+      Instantiation.InstantiatedDiscreteVariable _ |
       Instantiation.InstantiatedRealVariable _ |
       Instantiation.InstantiatedCompoundVariable _ -> false
   in
@@ -460,7 +515,9 @@ let separate_inputs_from_others icpnts =
 let separate_discrete_variables_from_others icpnts =
   let is_discrete = function
     | Instantiation.InstantiatedDiscreteVariable _ -> true
-    | Instantiation.InstantiatedRealVariable _ |
+    | Instantiation.InstantiatedIntegerVariable _ |
+      Instantiation.InstantiatedStringVariable _ |
+      Instantiation.InstantiatedRealVariable _ |
       Instantiation.InstantiatedCompoundVariable _ -> false
   in
   let filter_variable = function
@@ -470,10 +527,18 @@ let separate_discrete_variables_from_others icpnts =
 
 let separate_outputs_from_others icpnts =
   let is_output = function
-    | Instantiation.InstantiatedDiscreteVariable (_, Compilation.Output, _) |
-      Instantiation.InstantiatedRealVariable (_, Compilation.Output, _, _) ->
+    | Instantiation.InstantiatedIntegerVariable
+        (_, Compilation.Output, _, _) |
+      Instantiation.InstantiatedStringVariable
+        (_, Compilation.Output, _, _) |
+      Instantiation.InstantiatedDiscreteVariable
+        (_, Compilation.Output, _, _) |
+      Instantiation.InstantiatedRealVariable
+        (_, Compilation.Output, _, _, _) ->
         true
-    | Instantiation.InstantiatedDiscreteVariable _ |
+    | Instantiation.InstantiatedIntegerVariable _ |
+      Instantiation.InstantiatedStringVariable _ |
+      Instantiation.InstantiatedDiscreteVariable _ |
       Instantiation.InstantiatedRealVariable _ |
       Instantiation.InstantiatedCompoundVariable _ -> false
   in
@@ -503,6 +568,73 @@ let separate_whens_from_equations iequs =
       Instantiation.FlowConnection _ :: _ -> assert false
   in separate_whens_from_equations' [] [] iequs
 
+let rewrite_when_condition expr =
+  let rec contains_time expr = match nature expr with
+    | BooleanValue _  | Constant _ | DiscreteVariable _ | Number _ |
+      Parameter _ | Variable _ | Integer _ | String _ -> false
+    | TimeVariable  -> true
+    | ArcCosine node | ArcHyperbolicCosine node |
+      ArcHyperbolicSine node | ArcHyperbolicTangent node | ArcSine node |
+      ArcTangent node | Cosine node | Derivative (node, _) |
+      Exponential node | Floor node | HyperbolicCosine node |
+      HyperbolicSine node | HyperbolicTangent node | Logarithm node |
+      Not node | Pre node | RationalPower (node, _) | Sign node | Sine node |
+      Tangent node -> contains_time node
+    | Equality (node1, node2) | Greater (node1, node2) |
+      GreaterEqual (node1, node2) | PartialDerivative (node1, node2) ->
+        contains_time node1 || contains_time node2
+    | If (node1, node2, node3) ->
+        contains_time node1 || contains_time node2 || contains_time node3
+    | And nodes | Addition nodes | Multiplication nodes | Or nodes ->
+        List.exists contains_time nodes
+    | BlackBox (_, args) -> List.exists contains_time_argument args
+  and contains_time_argument = function
+    | ScalarArgument node -> contains_time node
+    | ArrayArgument (_, nodes) -> exists_array contains_time nodes in
+  let is_primary_condition expr =
+    assignable_variables_of expr <> [] || contains_time expr in
+  let rec rewrite expr = match nature expr with
+    | Addition nodes -> apply_addition (List.map rewrite nodes)
+    | And nodes -> apply_and (List.map rewrite nodes)
+    | ArcCosine node -> symbolic_acos (rewrite node)
+    | ArcHyperbolicCosine node -> symbolic_acosh (rewrite node)
+    | ArcHyperbolicSine node -> symbolic_asinh (rewrite node)
+    | ArcHyperbolicTangent node -> symbolic_atanh (rewrite node)
+    | ArcSine node -> symbolic_asin (rewrite node)
+    | ArcTangent node -> symbolic_atan (rewrite node)
+    | BlackBox (s, args) -> apply_blackBox s (List.map rewrite_argument args)
+    | Cosine node -> symbolic_cos (rewrite node)
+    | Derivative (node, num) -> symbolic_derive (rewrite node) num
+    | Equality (node, node') -> symbolic_eq (rewrite node) (rewrite node')
+    | Exponential node -> symbolic_exp (rewrite node)
+    | Floor node -> symbolic_floor (rewrite node)
+    | Greater (node, node') -> symbolic_gt (rewrite node) (rewrite node')
+    | GreaterEqual (node, node') -> symbolic_ge (rewrite node) (rewrite node')
+    | HyperbolicCosine node -> symbolic_cosh (rewrite node)
+    | HyperbolicSine node -> symbolic_sinh (rewrite node)
+    | HyperbolicTangent node -> symbolic_tanh (rewrite node)
+    | If (node, node', node'') ->
+        symbolic_if (rewrite node) (rewrite node') (rewrite node'')
+    | Logarithm node -> symbolic_log (rewrite node)
+    | Multiplication nodes -> apply_multiplication (List.map rewrite nodes)
+    | Not node -> symbolic_not (rewrite node)
+    | Or nodes -> apply_or (List.map rewrite nodes)
+    | PartialDerivative (node, node') ->
+        create_partialDerivative (rewrite node) (rewrite node')
+    | Pre node -> symbolic_pre (rewrite node)
+    | RationalPower (node, num) -> symbolic_rationalPower (rewrite node) num
+    | Sign node -> symbolic_sgn (rewrite node)
+    | Sine node -> symbolic_sin (rewrite node)
+    | Tangent node -> symbolic_tan (rewrite node)
+    | BooleanValue _ | Constant _ | Number _ | Parameter _ |
+      TimeVariable | Variable _ | Integer _ | String _ -> expr
+    | DiscreteVariable _ -> symbolic_pre expr
+  and rewrite_argument = function
+    | ScalarArgument expr -> ScalarArgument (rewrite expr)
+    | ArrayArgument (dims, exprs) ->
+        ArrayArgument (dims, Array.map rewrite exprs) in
+  if is_primary_condition expr then rewrite expr else expr
+
 let symbolic_equation inl_par maps = function
   | Instantiation.Equation (iexpr, iexpr') ->
       let expr =
@@ -522,7 +654,8 @@ let symbolic_equation inl_par maps = function
 let symbolic_surfaces inl_par maps when_clauses =
   List.map
     (fun (iexpr, surfaces) ->
-      symbolic_expression_of_expression inl_par maps iexpr,
+      let expr = symbolic_expression_of_expression inl_par maps iexpr in
+      rewrite_when_condition expr,
       List.map
         (function
           | Instantiation.Reinit (iexpr, iexpr') ->
@@ -537,6 +670,8 @@ let symbolic_surfaces inl_par maps when_clauses =
             begin match nature var with
               | DiscreteVariable i ->
                   Assign (var, symbolic_expression_of_expression inl_par maps iexpr')
+              | Variable i ->
+                  Reinit (var, symbolic_expression_of_expression inl_par maps iexpr')
               | _ -> assert false
             end)
         surfaces)
@@ -570,6 +705,10 @@ let propagate_noEvent expr =
         create_greater
           (propagate_noEvent' no_event expr')
           (propagate_noEvent' no_event expr'')
+    | GreaterEqual (expr', expr'') ->
+        create_greater_equal
+          (propagate_noEvent' no_event expr')
+          (propagate_noEvent' no_event expr'')
     | HyperbolicCosine expr' ->
         create_hyperbolicCosine (propagate_noEvent' no_event expr')
     | HyperbolicSine expr' ->
@@ -577,6 +716,7 @@ let propagate_noEvent expr =
     | HyperbolicTangent expr' ->
         create_hyperbolicTangent (propagate_noEvent' no_event expr')
     | Logarithm expr' -> create_logarithm (propagate_noEvent' no_event expr')
+    | Pre expr' -> create_pre (propagate_noEvent' no_event expr')
     | RationalPower (expr', num) ->
         create_rationalPower (propagate_noEvent' no_event expr') num
     | Sign expr' -> create_sign (propagate_noEvent' no_event expr')
@@ -584,9 +724,11 @@ let propagate_noEvent expr =
     | Tangent expr' -> create_tangent (propagate_noEvent' no_event expr')
     | Addition exprs' ->
         create_addition (sort (List.map (propagate_noEvent' no_event) exprs'))
-    | BlackBox ("noEvent", [expr']) -> propagate_noEvent' true expr'
-    | BlackBox (name, exprs') ->
-        create_blackBox name (List.map (propagate_noEvent' no_event) exprs')
+    | BlackBox ("noEvent", [ScalarArgument expr']) -> propagate_noEvent' true expr'
+    | BlackBox (name, args) ->
+        create_blackBox
+          name
+          (List.map (propagate_noEvent_into_argument no_event) args)
     | Multiplication exprs' ->
         create_multiplication
           (sort (List.map (propagate_noEvent' no_event) exprs'))
@@ -600,13 +742,20 @@ let propagate_noEvent expr =
     | If (expr', expr'', expr''') ->
         propagate_noEvent_into_if no_event expr' expr'' expr'''
     | BooleanValue _ | Constant _ | DiscreteVariable _ | Number _ |
-      Parameter _ | TimeVariable | Variable _ -> expr
+      Parameter _ | TimeVariable | Variable _ | Integer _ | String _ -> expr
+  and propagate_noEvent_into_argument no_event = function
+    | ScalarArgument expr -> ScalarArgument (propagate_noEvent' no_event expr)
+    | ArrayArgument (dims, exprs) ->
+        ArrayArgument (dims, Array.map (propagate_noEvent' no_event) exprs)
   and propagate_noEvent_into_if no_event expr expr' expr'' =
     let cond =
-      if no_event then create_blackBox "noEvent" [propagate_noEvent' false expr]
+      if no_event then
+        create_blackBox "noEvent" [ScalarArgument (propagate_noEvent' false expr)]
       else begin match nature expr with
-        | BlackBox ("noEvent", [expr']) ->
-            create_blackBox "noEvent" [propagate_noEvent' false expr]
+        | BlackBox ("noEvent", [ScalarArgument expr']) ->
+            create_blackBox
+              "noEvent"
+              [ScalarArgument (propagate_noEvent' false expr)]
         | _ -> propagate_noEvent' false expr
       end
     in
@@ -617,27 +766,49 @@ let propagate_noEvent expr =
   in propagate_noEvent' false expr
 
 let create_model' trace inl_par iexpr =
-  let lazy_symbolic_expression_of_expression maps iexpr = match iexpr.Instantiation.tex_expression with
+  let lazy_symbolic_expression_of_expression maps iexpr =
+    match iexpr.Instantiation.tex_expression with
     | None -> None
-    | Some _ -> Some (lazy (symbolic_expression_of_expression inl_par maps iexpr))
+    | Some _ ->
+        Some (lazy (symbolic_expression_of_expression inl_par maps iexpr))
   in
   let get_parameter_info maps s i = function
     | Instantiation.InstantiatedParameter (
-        Instantiation.InstantiatedIntegerParameter (s', kind, iexpr)) |
-      Instantiation.InstantiatedParameter (
-        Instantiation.InstantiatedRealParameter (s', kind, iexpr)) ->
+        Instantiation.InstantiatedIntegerParameter (s', kind, iexpr, _)) ->
+        {
+          parameter_kind = kind;
+          parameter_type = IntegerType;
+          parameter_id = i;
+          parameter_comment = s';
+          parameter_start = lazy
+            (symbolic_expression_of_expression inl_par maps iexpr)
+        }
+    | Instantiation.InstantiatedParameter (
+        Instantiation.InstantiatedStringParameter (s', kind, iexpr, _)) ->
+        {
+          parameter_kind = kind;
+          parameter_type = StringType;
+          parameter_id = i;
+          parameter_comment = s';
+          parameter_start = lazy
+            (symbolic_expression_of_expression inl_par maps iexpr)
+        }
+    | Instantiation.InstantiatedParameter (
+        Instantiation.InstantiatedRealParameter (s', kind, iexpr, _)) ->
         {
           parameter_kind = kind;
+          parameter_type = RealType;
           parameter_id = i;
           parameter_comment = s';
-          parameter_start = lazy (symbolic_expression_of_expression inl_par maps iexpr)
+          parameter_start = lazy
+            (symbolic_expression_of_expression inl_par maps iexpr)
         }
     | _ -> assert false
   and get_input_info maps s i = function
     | Instantiation.InstantiatedVariable (
-        Instantiation.InstantiatedDiscreteVariable (s', _, _)) |
+        Instantiation.InstantiatedDiscreteVariable (s', _, _, _)) |
       Instantiation.InstantiatedVariable (
-        Instantiation.InstantiatedRealVariable (s', _, _, _)) ->
+        Instantiation.InstantiatedRealVariable (s', _, _, _, _)) ->
         {
           input_id = i;
           input_name = s;
@@ -646,9 +817,9 @@ let create_model' trace inl_par iexpr =
     | _ -> assert false
   and get_variable_info maps s i = function
     | Instantiation.InstantiatedVariable (
-        Instantiation.InstantiatedDiscreteVariable (s', _, iexpr)) |
+        Instantiation.InstantiatedDiscreteVariable (s', _, iexpr, _)) |
       Instantiation.InstantiatedVariable (
-        Instantiation.InstantiatedRealVariable (s', _, _, iexpr)) ->
+        Instantiation.InstantiatedRealVariable (s', _, _, iexpr, _)) ->
         {
           variable_id = i;
           variable_comment = s';
@@ -669,17 +840,28 @@ let create_model' trace inl_par iexpr =
       []
       ders
   in
+  let add_variable_infos acc (id, icpnt) = match icpnt with
+    | Instantiation.InstantiatedVariable
+        (Instantiation.InstantiatedDiscreteVariable (_, _, _, var_infos) |
+         Instantiation.InstantiatedRealVariable (_, _, _, _, var_infos)) ->
+        (id, var_infos) :: acc
+    | Instantiation.InstantiatedParameter
+        (Instantiation.InstantiatedIntegerParameter (_, _, _, pat_infos) |
+         Instantiation.InstantiatedRealParameter (_, _, _, pat_infos)) ->
+        (id, pat_infos) :: acc
+    | _ -> acc
+  in
   let icpnts, iinit_equs, iequs = Instantiation.expand_class iexpr in
+  let variables_infos =
+    List.fold_left add_variable_infos [] icpnts in
   let parameters, variables = separate_parameters_from_variables icpnts in
   let inputs, non_inputs = separate_inputs_from_others variables in
   let discrete_variables, others =
-    separate_discrete_variables_from_others non_inputs
-  in
+    separate_discrete_variables_from_others non_inputs in
   let outputs, _ = separate_outputs_from_others non_inputs in
-  let function_names =
+  let name_and_types =
     collect_external_function_names iequs @
-    collect_external_function_names iinit_equs
-  in
+    collect_external_function_names iinit_equs in
   let rec maps =
     {
       parameters_map =
@@ -710,6 +892,7 @@ let create_model' trace inl_par iexpr =
         (fun _ ->
           {
             main = false;
+            p_type = IntegerType;
             p_name = "";
             p_comment = "";
             value = zero
@@ -733,6 +916,7 @@ let create_model' trace inl_par iexpr =
             output = None;
             state = true;
             v_name = "";
+            depth_in_hierarchy = 0;
             v_comment = "";
             start_value = Some zero
           })
@@ -755,6 +939,13 @@ let create_model' trace inl_par iexpr =
         | _ :: outputs' -> output_index' (i + 1) outputs'
       in output_index' 0 outputs
     in
+    let number_of_dots s =
+      let count = ref 0 in
+      for i = 0 to String.length s - 1 do
+        if s.[i] = '.' then incr count;
+      done;
+      !count
+    in
     let _ =
       List.fold_left
         (fun i equ ->
@@ -775,6 +966,7 @@ let create_model' trace inl_par iexpr =
         assert (param.parameter_id < Array.length parameters_array);
         let parameter = parameters_array.(param.parameter_id) in
         parameter.main <- param.parameter_kind = Instantiation.Main;
+        parameter.p_type <- param.parameter_type;
         parameter.p_name <- s;
         parameter.p_comment <- param.parameter_comment;
         parameter.value <- Lazy.force param.parameter_start)
@@ -804,6 +996,7 @@ let create_model' trace inl_par iexpr =
         variable.state <-
           List.memq (create_variable var.variable_id) derived_variables;
         variable.v_name <- s;
+        variable.depth_in_hierarchy <- number_of_dots s;
         variable.v_comment <- var.variable_comment;
         variable.start_value <-
           match var.variable_start with
@@ -835,8 +1028,9 @@ let create_model' trace inl_par iexpr =
       reinitializable_variables = reinitializable_variables;
       when_clauses = when_clauses_list;
       io_dependency = false;
-      external_functions = function_names;
-      trace = trace
+      external_functions = name_and_types;
+      trace = trace;
+      variables_infos = variables_infos
     }
 
 let create_model_with_parameters trace iexpr = create_model' trace false iexpr
@@ -887,6 +1081,15 @@ let create_index_array a p =
   Array.iteri (fun i x -> if p x then begin indexes.(i) <- !j; incr j end) a;
   indexes
 
+let final_index_of_integer_parameters model =
+  create_index_array model.parameters (fun par -> par.p_type = IntegerType)
+
+let final_index_of_string_parameters model =
+  create_index_array model.parameters (fun par -> par.p_type = StringType)
+
+let final_index_of_real_parameters model =
+  create_index_array model.parameters (fun par -> par.p_type = RealType)
+
 let final_index_of_variables model =
   create_index_array model.equations (fun equation -> not equation.solved)
 
@@ -917,7 +1120,7 @@ let perform_then_propagate_inversion model i =
   and equation = model.equations.(i) in
   let expr = equation.expression in
   try match invert_if_possible_with_respect_to var expr zero with
-    | None -> ()
+    | None -> false
     | Some expr' ->
         if not (List.memq var model.reinitializable_variables) then begin
           equation.expression <- expr';
@@ -933,6 +1136,7 @@ let perform_then_propagate_inversion model i =
             model.equations;
           model.when_clauses <- update_clauses var expr' model.when_clauses
         end;
+        true
   with Invalid_argument _ -> raise Can't_perform_inversion
 
 let compute_io_dependency model =
@@ -980,11 +1184,18 @@ let perform_hungarian_method model =
     let m = table.(i)
     and n = table.(j) in
     let var = create_variable m in
+    let discontinuous_state () =
+      let not_derivative_of_current_variable e = match nature e with
+        | Derivative (var', _) -> var' != var
+        | _ -> true in
+      List.for_all
+        not_derivative_of_current_variable
+        model.equations.(n).inner_derivatives &&
+      List.memq var model.reinitializable_variables in
     if not (List.memq var model.equations.(n).assignable_variables) then
       IntegerElement.Infinity
-    else if model.variables.(m).start_value <> None then
-      IntegerElement.Int (size * size + 1)
-      (* The user wants to see the variable in the generated code *)
+    else if discontinuous_state () then
+      IntegerElement.Int (size + 1)
     else match inversion_difficulty var model.equations.(n).expression zero with
         | 0 -> IntegerElement.zero
         | 1 -> IntegerElement.Int 1
@@ -1020,15 +1231,19 @@ let eliminate_trivial_relations max_simplifs model =
   let max_simplifs_ref = ref max_simplifs in
   let choose_variable i j =
     let sti = model.variables.(i).state
-    and stj = model.variables.(j).state in
+    and depi = model.variables.(i).depth_in_hierarchy
+    and stj = model.variables.(j).state
+    and depj = model.variables.(j).depth_in_hierarchy in
     match sti, stj with
-      | true, false -> i
-      | false, true -> j
-      | _ ->
+      | true, false -> j
+      | false, true -> i
+      | true, true | false, false ->
           let svi = model.variables.(i).start_value
           and svj = model.variables.(j).start_value in
           begin match svi, svj with
-            | _, None -> i
+            | None, Some _ -> i
+            | Some _, None -> j
+            | _ when depj > depi -> i
             | _ -> j
           end
   in
@@ -1040,19 +1255,10 @@ let eliminate_trivial_relations max_simplifs model =
   let update_variable_attributes i j =
     let svi = model.variables.(i).start_value
     and svj = model.variables.(j).start_value in
-    let sti = model.variables.(i).state
-    and stj = model.variables.(j).state in
-    let state = sti || stj in
-    model.variables.(i).state <- state;
-    model.variables.(j).state <- state;
-    match sti, stj with
-      | true, false -> model.variables.(j).start_value <- svi
-      | false, true -> model.variables.(i).start_value <- svj
-      | _ ->
-          begin match svi, svj with
-            | _, None -> model.variables.(j).start_value <- svi
-            | _ -> model.variables.(i).start_value <- svj
-          end
+    match svi, svj with
+      | None, _ -> model.variables.(i).start_value <- svj
+      | _, None -> model.variables.(j).start_value <- svi
+      | _ -> ()
   in
   let simplify_trivial_relation n =
     match nature model.equations.(n).expression with
@@ -1060,7 +1266,7 @@ let eliminate_trivial_relations max_simplifs model =
           begin match nature node, nature node' with
             | Variable i, Number _ | Number _, Variable i ->
                 permute_equations i n;
-                perform_then_propagate_inversion model i;
+                ignore (perform_then_propagate_inversion model i);
                 decr max_simplifs_ref
             | Variable i, Multiplication [node; node'] |
               Multiplication [node; node'], Variable i ->
@@ -1070,7 +1276,7 @@ let eliminate_trivial_relations max_simplifs model =
                       let k = choose_variable i j in
                       update_variable_attributes i j;
                       permute_equations k n;
-                      perform_then_propagate_inversion model k;
+                      ignore (perform_then_propagate_inversion model k);
                       decr max_simplifs_ref
                   | _ -> ()
                 end
@@ -1084,6 +1290,23 @@ let eliminate_trivial_relations max_simplifs model =
   !max_simplifs_ref
 
 let eliminate_explicit_variables max_simplifs model =
+  let is_continuous_state var =
+    not (List.memq var model.reinitializable_variables) in
+  let is_state_variable expr = match nature expr with
+    | Variable j -> model.variables.(j).state
+    | _ -> false in
+  let try_reducing_state var i =
+    let vars = model.equations.(i).assignable_variables
+    and ders = model.equations.(i).inner_derivatives in
+    if not (List.memq (symbolic_derive var (Num.Int 1)) ders) then begin
+      Printf.eprintf "\nTrying to reduce state...";
+      match ders with
+      | [] when List.for_all is_state_variable vars ->
+          let success = perform_then_propagate_inversion model i in
+          if success then Printf.eprintf " One state variable removed.%!"
+          else Printf.eprintf " Failed.%!"
+      | _ ->  Printf.eprintf " Failed.%!"
+    end in
   let rec eliminate_explicit_variables' simplifs =
     let assocs = perform_hungarian_method model in
     permute_equations model assocs;
@@ -1091,11 +1314,15 @@ let eliminate_explicit_variables max_simplifs model =
       List.fold_left
         (fun (bad_variable_choice, success, simplifs) assoc ->
           match assoc with
-            | (_, None) -> assert false
+            | _, None -> assert false
             | i, Some j when simplifs >= 0 ->
                 begin try
                   if not model.variables.(i).state then
-                    perform_then_propagate_inversion model i;
+                    ignore (perform_then_propagate_inversion model i)
+                  else begin
+                    let var = create_variable i in
+                    if is_continuous_state var then try_reducing_state var i
+                  end;
                   bad_variable_choice, model.equations.(i).solved, simplifs - 1
                 with
                   | Can't_perform_inversion -> true, success, simplifs
@@ -1108,86 +1335,74 @@ let eliminate_explicit_variables max_simplifs model =
       eliminate_explicit_variables' simplifs
   in eliminate_explicit_variables' max_simplifs
 
-let rec is_greater_equal expr = match nature expr with
-  | BlackBox ("noEvent", [expr']) -> is_greater_equal expr'
-  | Or [expr1; expr2] ->
-      begin match nature expr1, nature expr2 with
-        | Equality (expr11, expr12), Greater (expr21, expr22)
-          when expr11 == expr21 && expr12 == expr22 ||
-          expr11 == expr22 && expr12 == expr21 -> true
-        | Greater (expr11, expr12), Equality (expr21, expr22)
-          when expr11 == expr21 && expr12 == expr22 ||
-          expr11 == expr22 && expr12 == expr21 -> true
-        | _ -> false
-      end
-  | _ -> false
-
 let rec rewrite_conditions_in no_event expr =
-  let rec rewrite_if no_event expr expr' expr'' =
-    let no_event_if_necessary expr =
-      if no_event then create_blackBox "noEvent" [expr] else expr
-    in match nature expr with
-    | BlackBox ("noEvent", [expr1]) when nature expr1 = BooleanValue true ->
-        rewrite_conditions_in no_event expr'
-    | BlackBox ("noEvent", [expr1]) when nature expr1 = BooleanValue false ->
-        rewrite_conditions_in no_event expr''
-    | BlackBox ("noEvent", [expr1]) ->
-        create_if
-          (create_blackBox "noEvent" [rewrite_conditions_in true expr1])
-          (rewrite_conditions_in no_event expr')
-          (rewrite_conditions_in no_event expr'')
-    | Equality (expr1, expr2) ->
-        create_if
-          (no_event_if_necessary
-            (create_equality
-              (rewrite_conditions_in no_event expr1)
-              (rewrite_conditions_in no_event expr2)))
-          (rewrite_conditions_in no_event expr')
-          (rewrite_conditions_in no_event expr'')
-    | Greater (expr1, expr2) ->
-        create_if
-          (no_event_if_necessary
-            (create_greater
-              (rewrite_conditions_in no_event expr1)
-              (rewrite_conditions_in no_event expr2)))
-          (rewrite_conditions_in no_event expr')
-          (rewrite_conditions_in no_event expr'')
-    | And [] -> rewrite_conditions_in no_event expr'
-    | And [expr] ->
-        create_if
-          (no_event_if_necessary expr)
-          (rewrite_conditions_in no_event expr')
-          (rewrite_conditions_in no_event expr'')
-    | And (expr :: exprs) ->
-        rewrite_if no_event expr (create_if (create_and exprs) expr' expr'') expr''
-    | Or [] -> rewrite_conditions_in no_event expr''
-    | Or [expr] ->
-        create_if
-          (no_event_if_necessary expr)
-          (rewrite_conditions_in no_event expr')
-          (rewrite_conditions_in no_event expr'')
-    | Or [expr1; expr2] when is_greater_equal expr ->
-        begin match nature expr1, nature expr2 with
-          | Greater (expr1, expr2), _ | _, Greater (expr1, expr2) ->
-              let expr1' = rewrite_conditions_in no_event expr1
-              and expr2' = rewrite_conditions_in no_event expr2 in
-              create_if
-                (no_event_if_necessary
-                  (create_or
-                    [create_greater expr1' expr2'; create_equality expr1' expr2']))
-                (rewrite_conditions_in no_event expr')
-                (rewrite_conditions_in no_event expr'')
-          | _ -> assert false
-        end
-    | Or (expr :: exprs) ->
-        rewrite_if no_event expr expr' (create_if (create_or exprs) expr' expr'')
-    | Not expr ->
+  let rec remove_no_event expr = match nature expr with
+    | ArcCosine expr' -> create_arcCosine (remove_no_event expr')
+    | ArcHyperbolicCosine expr' ->
+        create_arcHyperbolicCosine (remove_no_event expr')
+    | ArcHyperbolicSine expr' ->
+        create_arcHyperbolicSine (remove_no_event expr')
+    | ArcHyperbolicTangent expr' ->
+        create_arcHyperbolicTangent (remove_no_event expr')
+    | ArcSine expr' -> create_arcSine (remove_no_event expr')
+    | ArcTangent expr' -> create_arcTangent (remove_no_event expr')
+    | Cosine expr' -> create_cosine (remove_no_event expr')
+    | Derivative (expr', num) ->
+        create_derivative (remove_no_event expr') num
+    | Exponential expr' -> create_exponential (remove_no_event expr')
+    | Floor expr' -> create_floor (remove_no_event expr')
+    | HyperbolicCosine expr' ->
+        create_hyperbolicCosine (remove_no_event expr')
+    | HyperbolicSine expr' ->
+        create_hyperbolicSine (remove_no_event expr')
+    | HyperbolicTangent expr' ->
+        create_hyperbolicTangent (remove_no_event expr')
+    | Logarithm expr' -> create_logarithm (remove_no_event expr')
+    | Pre expr' -> create_pre (remove_no_event expr')
+    | RationalPower (expr', num) ->
+        create_rationalPower (remove_no_event expr') num
+    | Sign expr' -> create_sign (remove_no_event expr')
+    | Sine expr' -> create_sine (remove_no_event expr')
+    | Tangent expr' -> create_tangent (remove_no_event expr')
+    | Addition exprs' ->
+        create_addition (sort (List.map remove_no_event exprs'))
+    | BlackBox ("noEvent", [ScalarArgument expr']) ->
+        rewrite_conditions_in true expr'
+    | BlackBox (name, args) ->
+        create_blackBox name (List.map remove_no_event_in_argument args)
+    | Multiplication exprs' ->
+        create_multiplication (sort (List.map remove_no_event exprs'))
+    | PartialDerivative (expr', expr'') ->
+        create_partialDerivative
+          (remove_no_event expr')
+          (remove_no_event expr'')
+    | If (expr', expr'', expr''') ->
         create_if
-          (no_event_if_necessary expr)
-          (rewrite_conditions_in no_event expr'')
-          (rewrite_conditions_in no_event expr')
-    | _ -> assert false
-  in match nature expr with
+          (remove_no_event expr')
+          (remove_no_event expr'')
+          (remove_no_event expr''')
+    | Equality (expr', expr'') ->
+        create_equality
+          (remove_no_event expr')
+          (remove_no_event expr'')
+    | Greater (expr', expr'') ->
+        create_greater
+          (remove_no_event expr')
+          (remove_no_event expr'')
+    | GreaterEqual (expr', expr'') ->
+        create_greater_equal
+          (remove_no_event expr')
+          (remove_no_event expr'')
+    | And exprs -> create_and (List.map remove_no_event exprs)
+    | Or exprs ->  create_or (List.map remove_no_event exprs)
+    | Not expr' -> create_not (remove_no_event expr')
+    | BooleanValue _ | Constant _ | DiscreteVariable _ | Number _ |
+      Parameter _ | TimeVariable | Variable _ | Integer _ | String _ -> expr
+  and remove_no_event_in_argument = function
+    | ScalarArgument expr -> ScalarArgument (remove_no_event expr)
+    | ArrayArgument (dims, exprs) ->
+        ArrayArgument (dims, Array.map remove_no_event exprs) in
+  match nature expr with
     | ArcCosine expr' -> create_arcCosine (rewrite_conditions_in no_event expr')
     | ArcHyperbolicCosine expr' ->
         create_arcHyperbolicCosine (rewrite_conditions_in no_event expr')
@@ -1209,39 +1424,87 @@ let rec rewrite_conditions_in no_event expr =
     | HyperbolicTangent expr' ->
         create_hyperbolicTangent (rewrite_conditions_in no_event expr')
     | Logarithm expr' -> create_logarithm (rewrite_conditions_in no_event expr')
-    | Not expr' -> create_not (rewrite_conditions_in no_event expr')    
+    | Pre expr' -> create_pre (rewrite_conditions_in no_event expr')
     | RationalPower (expr', num) ->
         create_rationalPower (rewrite_conditions_in no_event expr') num
     | Sign expr' -> create_sign (rewrite_conditions_in no_event expr')
     | Sine expr' -> create_sine (rewrite_conditions_in no_event expr')
     | Tangent expr' -> create_tangent (rewrite_conditions_in no_event expr')
-    | Equality (expr1, expr2) ->
-        create_equality
-          (rewrite_conditions_in no_event expr1)
-          (rewrite_conditions_in no_event expr2)
-    | Greater (expr1, expr2) ->
-        create_greater
-          (rewrite_conditions_in no_event expr1)
-          (rewrite_conditions_in no_event expr2)
     | Addition exprs' ->
         create_addition (sort (List.map (rewrite_conditions_in no_event) exprs'))
-    | And exprs' ->
-        create_and (sort (List.map (rewrite_conditions_in no_event) exprs'))
-    | BlackBox ("noEvent", [expr']) -> rewrite_conditions_in true expr'
-    | BlackBox (name, exprs') ->
-        create_blackBox name (List.map (rewrite_conditions_in no_event) exprs')
+    | BlackBox ("noEvent", [ScalarArgument expr']) ->
+        rewrite_conditions_in true expr'
+    | BlackBox (name, args) ->
+        create_blackBox
+          name
+          (List.map (rewrite_conditions_in_argument no_event) args)
     | Multiplication exprs' ->
         create_multiplication (sort (List.map (rewrite_conditions_in no_event) exprs'))
-    | Or exprs' ->
-        create_or (sort (List.map (rewrite_conditions_in no_event) exprs'))
     | PartialDerivative (expr', expr'') ->
         create_partialDerivative
           (rewrite_conditions_in no_event expr')
           (rewrite_conditions_in no_event expr'')
-    | If (expr', expr'', expr''') -> rewrite_if no_event expr' expr'' expr'''
-    | Constant _ | DiscreteVariable _ | Number _ | Parameter _ | TimeVariable |
-      Variable _ -> expr
-    | _ -> assert false
+    | If (expr', expr'', expr''') ->
+        create_if
+          (rewrite_conditions_in no_event expr')
+          (rewrite_conditions_in no_event expr'')
+          (rewrite_conditions_in no_event expr''')
+    | Equality (expr', expr'') when no_event ->
+        create_blackBox
+          "noEvent"
+          [ScalarArgument
+            (create_equality
+              (remove_no_event expr')
+              (remove_no_event expr''))]
+    | Equality (expr', expr'') ->
+        create_equality
+          (remove_no_event expr')
+          (remove_no_event expr'')
+    | Greater (expr', expr'') when no_event ->
+        create_blackBox
+          "noEvent"
+          [ScalarArgument
+            (create_greater
+              (remove_no_event expr')
+              (remove_no_event expr''))]
+    | Greater (expr', expr'') ->
+        create_greater
+          (remove_no_event expr')
+          (remove_no_event expr'')
+    | GreaterEqual (expr', expr'') when no_event ->
+        create_blackBox
+          "noEvent"
+          [ScalarArgument
+            (create_greater_equal
+              (remove_no_event expr')
+              (remove_no_event expr''))]
+    | GreaterEqual (expr', expr'') ->
+        create_greater_equal
+          (remove_no_event expr')
+          (remove_no_event expr'')
+    | And exprs when no_event ->
+        create_blackBox
+          "noEvent"
+          [ScalarArgument (create_and (List.map remove_no_event exprs))]
+    | And exprs -> create_and (List.map remove_no_event exprs)
+    | Or exprs when no_event ->
+        create_blackBox
+          "noEvent"
+          [ScalarArgument (create_or (List.map remove_no_event exprs))]
+    | Or exprs -> create_or (List.map remove_no_event exprs)
+    | Not expr' when no_event ->
+        create_blackBox
+          "noEvent"
+          [ScalarArgument (create_not (remove_no_event expr'))]
+    | Not expr' -> create_not (remove_no_event expr')
+    | BooleanValue _ | Constant _ | DiscreteVariable _ | Number _ |
+      Parameter _ | TimeVariable | Variable _ | Integer _ | String _ -> expr
+  and rewrite_conditions_in_argument no_event = function
+    | ScalarArgument expr ->
+        ScalarArgument (rewrite_conditions_in no_event expr)
+    | ArrayArgument (dims, exprs) ->
+        ArrayArgument
+          (dims, Array.map (rewrite_conditions_in no_event) exprs)
 
 let perform_simplifications max_simplifs model =
   Array.iter
@@ -1251,9 +1514,6 @@ let perform_simplifications max_simplifs model =
   eliminate_explicit_variables max_simplifs model;
   compute_io_dependency model
 
-let compute_structural_index model =
-  failwith "compute_structural_index: not yet implemented"
-
 let find_submodels model =
   let final_index_of_variables = final_index_of_variables model in
   let size =
index cbd6eb5..8698907 100644 (file)
@@ -1,23 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 (** This module contains functions that perform symbolic and topologic
 simplifications over an instantiated Modelica model. *)
@@ -25,11 +26,14 @@ simplifications over an instantiated Modelica model. *)
 (** The type of the records used to store information about parameters. *)
 type parameter_description = {
   mutable main : bool; (** If a parameter is a "main" one, it is not inlined. *)
+  mutable p_type : parameter_type; (** The parameter's type *)
   mutable p_name : string; (** The parameter's user name *)
   mutable p_comment : string; (** The comment associated to the parameter. *)
   mutable value : SymbolicExpression.t;
 }
 
+and parameter_type = IntegerType | StringType | RealType
+
 (** The type of the records used to store information about discrete variables.
 *)
 type discrete_variable_description =
@@ -49,6 +53,9 @@ type variable_description = {
   mutable state : bool; (** [true] = state variable, [false] = algebraic
     variable *)
   mutable v_name : string; (** The variable's user name *)
+  mutable depth_in_hierarchy : int; (** The number of dots in the variable
+    name that is used as a criterion to choose the variables to eliminate
+    (deepest-defined variables are eliminated when possible). *)
   mutable v_comment : string; (** The comment associated to the variable. *)
   mutable start_value : SymbolicExpression.t option;
 }
@@ -90,10 +97,14 @@ type model = {
       reinitializations. *)
   mutable io_dependency : bool; (** [true] = there is a direct dependency
     between inputs and outputs in the model. *)
-  mutable external_functions : (string list * int) list; (** The list of the paths
-    where to find external function bodies and their respective arity. *)
-  trace: string option (** The file where optional tracing information of
+  mutable external_functions :
+    (string list *
+    Instantiation.expression_type list *
+    Instantiation.expression_type list) list; (** The list of the paths
+    where to find external function bodies and their respective signatures. *)
+  trace: string option; (** The file where optional tracing information of
     external function calls is generated *)
+  variables_infos: (string * Compilation.variable_infos) list
 }
 
 and when_expression =
@@ -127,10 +138,6 @@ val perform_simplifications: int -> model -> unit
 appropriate substitutions in order to eliminate at most [max_simplifs] auxiliary
 variables from the model. *)
 
-val compute_structural_index: model -> int
-(** [compute_structural_index model] computes the structural index of the DAE
-system. *)
-
 val find_submodels: model -> int list list
 (** [find_submodels model] splits [model] in dependent submodels such that there
 is no cyclic dependency between them. The result is given as a list of index
@@ -139,8 +146,3 @@ lists (each index corresponding to a variable index). *)
 val print_model: out_channel -> model -> unit
 (** [print_model oc model] prints [model] in an implementation-dependent format
 to [oc]. *)
-
-val is_greater_equal: SymbolicExpression.t -> bool
-(** [is_greater_equal expr] returns [true] if [expr] denotes a greater or equal
-construct, regardless "noEvents" encapsulations. This function is exported by
-Optimization as a utility for convenience. *)
index ddc7975..464c497 100644 (file)
@@ -1,28 +1,29 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 module type CODEGENERATOR =
   sig
     val generate_code: string -> string -> string -> Optimization.model -> bool
-      -> unit
+      -> bool -> string option * string option -> unit
   end
 
 module type S =
@@ -36,9 +37,12 @@ module Make(G: CODEGENERATOR): S =
   struct
 
     let sccs_id =
-      "@(#)Modelicac - Copyright (C) 2003-2004 TNI-Valiosys, 2005 Imagine"
+      "@(#)Modelicac Copyright (C)\n\
+        2003-2004 TNI-Valiosys,\n\
+        2005-2007 Imagine,\n\
+        2007-2009 LMS-Imagine"
 
-    let version = "1.7.3"
+    let version = "1.12.1"
 
     let path = ref ""
 
@@ -50,6 +54,12 @@ module Make(G: CODEGENERATOR): S =
 
     let with_jac = ref false
 
+    let only_outputs = ref false
+
+    let init_in = ref None
+
+    let init_out = ref None
+
     let trace = ref None
 
     let gen_xml = ref false
@@ -58,18 +68,32 @@ module Make(G: CODEGENERATOR): S =
 
     let output = ref ""
 
-    let input = ref ""
+    let inputs = ref []
 
     let max_simplifs = ref max_int
 
     let add_lib_path s =
       directories := !directories @ [s]
 
+    let set_init_in s =
+      if !init_in <> None then
+        failwith "set_init_in: More than one init_in specified";
+      init_in := Some s
+
+    let set_init_out s =
+      if !init_out <> None then
+        failwith "set_init_out: More than one init_out specified";
+      init_out := Some s
+
+(*
     let trace_filename s =
+      if !trace <> None then
+        failwith "trace_filename: More than one trace file specified";
       trace := Some s
+*)
 
-    let check_filename () =
-      if Filename.check_suffix !input "mo" then ()
+    let check_filename filename =
+      if Filename.check_suffix filename "mo" then ()
       else failwith "check_filename: Filename suffix must be 'mo'"
 
     let set_path s =
@@ -80,9 +104,7 @@ module Make(G: CODEGENERATOR): S =
       if !output <> "" then failwith "set_output: More than one output specified";
       output := s
 
-    let set_input s =
-      if !input <> "" then failwith "set_input: More than one input specified";
-      input := s
+    let set_input s = inputs := s :: !inputs
 
     let set_max_simplifs i =
       max_simplifs := i
@@ -91,20 +113,21 @@ module Make(G: CODEGENERATOR): S =
       no_parameter_removal := true;
       keep_variables := true
 
-    let construct_output_filename () =
+    let construct_output_filename id =
       if !output = "" then begin
-        output := Filename.chop_suffix !input "mo";
+        if !gen_xml then
+          output := Printf.sprintf "%s.xml" id
+        else
+          output := Printf.sprintf "%s.c" id;
+        (*output := Filename.chop_suffix !input "mo";*)
         if !compile_only then
-          output := !output ^ "moc"
+          output := Printf.sprintf "%s.moc" id
       end;
       !output
 
     let parse_args () =
       Arg.parse
-        [("-L", Arg.String add_lib_path,
-          "<directory>  Add <directory> to the list of directories to be searched \
-          while linking");
-        ("-c", Arg.Set compile_only, "compile only (do not instantiate)");
+        [("-c", Arg.Set compile_only, "compile only (do not instantiate)");
         ("-o", Arg.String set_output,
           "<outputfile>  Set output file name to <outputfile>");
         ("-hpath", Arg.String set_path,
@@ -117,29 +140,57 @@ module Make(G: CODEGENERATOR): S =
           "Same as -keep-all-variables -no-parameter-removal");
         ("-max-simplifs", Arg.Int set_max_simplifs,
           "<passes> Max number of simplifications");
-        ("-jac", Arg.Set with_jac, "Generate symbolic jacobian matrix");
+        ("-jac", Arg.Set with_jac,
+          "Generate symbolic jacobian matrix
+          (may have no effect depending on target)");
+        ("-only-outputs", Arg.Set only_outputs,
+          "Generate code only for declared outputs
+          (may have no effect depending on target)");
+        ("-with-init-in", Arg.String set_init_in,
+          "<init_input_file>
+          Generate initialization code and use
+          <init_input_file> to get input data
+          (may have no effect depending on target)");
+        ("-with-init-out", Arg.String set_init_out,
+          "<init_output_file>
+          Generate initialization code and use
+          <init_output_file> to generate output data
+          (may have no effect depending on target)");
+(*
         ("-trace", Arg.String trace_filename,
-          "<filename> Generate tracing information for external function calls into \
-          <filename>");
+          "<filename>
+          Generate tracing information for
+          external function calls into <filename>");
+*)
         ("-xml", Arg.Set gen_xml,
-          "Generate an XML version of the model instead of target code")]
+          "Generate an XML version of the model
+          instead of target code");
+        ("-L", Arg.String add_lib_path,
+          "<directory>
+          Add <directory> to the list of directories to be
+          searched in while linking")]
         set_input
         ("usage: modelicac [-c] [-o <outputfile>] <inputfile> [other options]")
 
-    let run () =
-      parse_args ();
-      check_filename ();
-      let ic = open_in !input in
-      Printf.printf "Input file name = %s\n" !input; flush stdout;
+    let compile filename =
+      check_filename filename;
+      let ic = open_in filename in
+      Printf.printf "Input file name = %s\n" filename; flush stdout;
       let lexbuf = Lexing.from_channel ic in
       Printf.printf "Parsing..."; flush stdout;
-      let tree = Parser.parse !input Lexer.token lexbuf in
+      let tree = Parser.parse filename Lexer.token lexbuf in
       Printf.printf " OK\nPrecompiling..."; flush stdout;
-      let root = Precompilation.precompile tree in
+      Precompilation.precompile tree
+
+    let run () =
+      parse_args ();
+      let roots = match !inputs with
+        | [] -> failwith "No input file name specified"
+        | _ -> List.map compile !inputs in
       Printf.printf " OK\nCompiling..."; flush stdout;
       Compilation.paths := !directories;
-      let cu = Compilation.compile_main_class root in
-      let filename = construct_output_filename () in
+      let id, cu = Compilation.compile_main_class roots in
+      let filename = construct_output_filename id in
       if !compile_only then begin
         Printf.printf " OK\nSaving..."; flush stdout;
         Compilation.write_class_file filename cu
@@ -175,7 +226,7 @@ module Make(G: CODEGENERATOR): S =
               Printf.printf "\nOptimizing remaining equations..."; flush stdout;
               Optimization.perform_simplifications !max_simplifs model;
               Printf.printf
-                " OK\n%d variable(s) remaining."
+                "\n%d variable(s) remaining."
                 (Array.fold_left
                   (fun n variable ->
                     if not variable.Optimization.solved then n + 1 else n)
@@ -192,7 +243,14 @@ module Make(G: CODEGENERATOR): S =
             end;
             Printf.printf "Generating code..."; flush stdout;
             if !gen_xml then XMLCodeGeneration.generate_XML filename fun_name model
-            else G.generate_code !path filename fun_name model !with_jac
+            else
+              G.generate_code
+                !path
+                filename
+                fun_name model
+                !with_jac
+                !only_outputs
+                (!init_in, !init_out)
         | Compilation.CompiledFunction _ ->
             failwith "Attempt to generate code for a function"
       end;
index a66077b..4f1efd5 100644 (file)
@@ -1,23 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 (** This module provides the required interface an implementation needs to
 conform to in order to create a new code generator. *)
@@ -25,13 +26,21 @@ conform to in order to create a new code generator. *)
 module type CODEGENERATOR =
   sig
     val generate_code: string -> string -> string -> Optimization.model -> bool
-      -> unit
-    (** [generate_code path filename fun_name model jac] generates the code that
-    allows the numeric simulation of [model]. [path] is the path to the external
+      -> bool -> string option * string option -> unit
+    (** [generate_code path filename fun_name model jac only_outputs
+    init_filenames]
+    generates the code that
+    allows the numeric simulation of [model]. [path] is the path to the
+    external
     functions referenced in [model]. [filename] is the name of the file where
     the code is generated. [fun_name] is the name of the entry point in the
     generated code. [jac] is a flag for which true value indicates that a
-    symbolic jacobian is requested.*)
+    symbolic jacobian is requested. [only_outputs] is set when only declared
+    outputs have to be observed (this saves some useless computations when
+    internal variables need not to be observed). [init_filenames] is the optional
+    names of the XML initialization files (input data, output data) in case
+    separate initialization is required
+    on targets that support separate initialization of models. *)
   end
 
 module type S =
index d04a0e5..1af811d 100644 (file)
@@ -1,37 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
-
-
-(* To be extended like:
-type 'a node =
-  {
-    location : location option ;
-    value : 'a
-  }
-
-and type t =
-  | StoredDefinition of within node * definition node list
-...
-and so on. Hence, location information will be added to the parse tree
-to generate accurate error messages. *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 type t =
   | StoredDefinition of within * definition list
index 4b03e10..21544a7 100644 (file)
@@ -1,23 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 (** This module defines the data structures necessary to hold parse trees built
 by the parser (see Parser module) *)
index e2d1866..17f48ed 100644 (file)
@@ -1,23 +1,24 @@
-/*  Scicos
-*
-*  Copyright (C) INRIA - S. FURIC
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* See the file ./license.txt
-*/
+/*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
 
 /*
  * Parser
@@ -654,13 +655,8 @@ let parse filename token_fun lexbuf =
   try stored_definition_eof token_fun lexbuf with
     | Parsing.Parse_error ->
         let linenum, linebeg =
-          Linenum.for_position filename (Lexing.lexeme_start lexbuf)
-        and linenum', linebeg' =
-          Linenum.for_position filename (Lexing.lexeme_end lexbuf)
-        in
-        let first_char = Lexing.lexeme_start lexbuf - linebeg
-        and first_char' = Lexing.lexeme_end lexbuf - linebeg'
-        in
+          Linenum.for_position filename (Lexing.lexeme_start lexbuf) in
+        let first_char = Lexing.lexeme_start lexbuf - linebeg in
         Printf.eprintf
           "Syntax error at line %d, characters %d to %d\n"
           linenum
index 74ce3c4..9eb2363 100644 (file)
@@ -1,24 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
-
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 (* Precompilation *)
 
index d4a4775..cb4ba1f 100644 (file)
@@ -1,23 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 (** This module eases the compilation phase by sorting elements of the parse
 tree obtained by calling the parsing functions. *)
index a4e1664..b2be767 100644 (file)
@@ -1,23 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 open Num
 open SymbolicExpression
@@ -33,16 +34,40 @@ module ExpressionElement =
 
 module ExpressionTable = Hashtbl.Make(ExpressionElement)
 
+let eq_array nodes nodes' =
+  let l = Array.length nodes in
+  let rec eq_array_from i =
+    i = l || nodes.(i) == nodes'.(i) && eq_array_from (i + 1) in
+  l = Array.length nodes' && eq_array_from 0
+
+module ArrayElement = struct
+  type t = int list * SymbolicExpression.t array
+  let equal (dims, exprs) (dims', exprs') =
+    dims = dims' && eq_array exprs exprs'
+  let hash (dims, exprs) =
+    (Hashtbl.hash dims lxor
+    Array.fold_left
+      (fun acc expr -> acc lsl 2 + hash expr)
+      0x32fb7a88
+      exprs) land max_int
+end
+
+module ArrayStore = Hashtbl.Make(ArrayElement)
+
 type model_info =
   {
     model: model;
-    final_index_of_parameters: int array;
+    final_index_of_integer_parameters: int array;
+    final_index_of_string_parameters: int array;
+    final_index_of_real_parameters: int array;
     final_index_of_variables: int array;
     surfaces: SymbolicExpression.t list;
     occurrence_table: occurrence_record ExpressionTable.t;
     mutable current_index: int;
     mutable max_index: int;
-    code_buffer: Buffer.t
+    code_buffer: Buffer.t;
+    real_array_store_size: int;
+    real_arrays: int ArrayStore.t
   }
 
 and occurrence_record =
@@ -85,8 +110,14 @@ let create_index_array a p =
   Array.iteri (fun i x -> if p x then begin indexes.(i) <- !j; incr j end) a;
   indexes
 
-let final_index_of_parameters model =
-  create_index_array model.parameters (fun parameter -> parameter.main)
+let final_index_of_integer_parameters model =
+  create_index_array model.parameters (fun par -> par.p_type = IntegerType)
+
+let final_index_of_string_parameters model =
+  create_index_array model.parameters (fun par -> par.p_type = StringType)
+
+let final_index_of_real_parameters model =
+  create_index_array model.parameters (fun par -> par.p_type = RealType)
 
 let final_index_of_variables model =
   create_index_array model.equations (fun equation -> not equation.solved)
@@ -99,29 +130,38 @@ let collect_surfaces model =
       ArcHyperbolicTangent expr' | ArcSine expr' | ArcTangent expr' |
       Cosine expr' | Derivative (expr', _) | Exponential expr' | Floor expr' |
       HyperbolicCosine expr' | HyperbolicSine expr' | HyperbolicTangent expr' |
-      Logarithm expr' | Not expr' | RationalPower (expr', _) | Sign expr' |
+      Logarithm expr' | Pre expr' | RationalPower (expr', _) | Sign expr' |
       Sine expr' | Tangent expr' -> surfaces_of expr'
     | BlackBox ("noEvent", _) -> []
-    | Addition exprs' | And exprs' | BlackBox (_, exprs') |
-      Multiplication exprs' | Or exprs' ->
+    | Addition exprs' | Multiplication exprs' ->
         List.fold_left
           (fun surfaces expr -> union surfaces (surfaces_of expr))
           []
           exprs'
-    | Equality (expr', expr'') | Greater (expr', expr'') |
-      PartialDerivative (expr', expr'') ->
+    | BlackBox (_, args) ->
+        List.fold_left
+          (fun surfaces arg -> union surfaces (surfaces_of_argument arg))
+          []
+          args
+    | PartialDerivative (expr', expr'') ->
         union (surfaces_of expr') (surfaces_of expr'')
     | If (expr', expr'', expr''') -> surfaces_of_if expr' expr'' expr'''
-    | TimeVariable | BooleanValue _ | Constant _ | DiscreteVariable _ |
-      Number _ | Parameter _ | Variable _ -> []
+    | Equality _ | Greater _ | GreaterEqual _ |
+      And _ | Or _ | Not _ | TimeVariable | BooleanValue _ | Constant _ |
+      DiscreteVariable _ | Number _ | Parameter _ | Variable _ | Integer _ |
+      String _ -> []
+  and surfaces_of_argument = function
+    | ScalarArgument expr -> surfaces_of expr
+    | ArrayArgument (_, exprs) -> 
+        Array.fold_left
+          (fun surfaces expr -> union surfaces (surfaces_of expr))
+          []
+          exprs
   and surfaces_of_if expr expr' expr'' =
     let surfaces = union (surfaces_of expr') (surfaces_of expr'')
     in match nature expr with
       | BlackBox ("noEvent", _) -> surfaces
-      | Greater _ -> union [expr] (union (surfaces_of expr) surfaces)
-      | Or _ when is_greater_equal expr ->
-          union [expr] (union (surfaces_of expr) surfaces)
-      | _ -> assert false
+      | _ -> union [expr] surfaces
   in
   Array.fold_left
     (fun surfaces equation ->
@@ -131,47 +171,53 @@ let collect_surfaces model =
 
 let rec is_atomic expr = match nature expr with
   | BooleanValue _ | Constant _ | Derivative _ | DiscreteVariable _ | Number _ |
-    Parameter _ | Variable _ -> true
+    Parameter _ | Variable _ | Integer _ | String _ -> true
   | _ -> false
 
-let add_to_occurrence_table modes_on expr table =
+let add_to_occurrence_table modes_on expr model_info =
   let rec add_if_necessary modes_on expr = match nature expr with
-    | BlackBox ("noEvent", [expr']) -> add_if_necessary modes_on expr'
+    | BlackBox ("noEvent", [ScalarArgument expr']) ->
+        add_if_necessary modes_on expr'
     | _ when is_atomic expr -> ()
-    | Or [expr1; expr2] when is_greater_equal expr ->
-        begin match nature expr1, nature expr2 with
-          | Greater (expr', expr''), _ | _, Greater (expr', expr'') ->
-              add_if_necessary modes_on (create_blackBox ">=" [expr'; expr''])
-              (* this is a hack to simulate >= being a primitive expression. *)
-          | _ -> assert false
-        end
     | _ ->
-        try
-          let record = ExpressionTable.find table expr in
+        begin try
+          let record = ExpressionTable.find model_info.occurrence_table expr in
           record.occurrences <- record.occurrences + 1
         with
           | Not_found -> add modes_on expr
+        end
   and add modes_on expr =
-    ExpressionTable.add table expr { occurrences = 1; label = None };
+    ExpressionTable.add
+      model_info.occurrence_table
+      expr
+      { occurrences = 1; label = None };
     match nature expr with
       | ArcCosine expr' | ArcHyperbolicCosine expr' | ArcHyperbolicSine expr' |
         ArcHyperbolicTangent expr' | ArcSine expr' | ArcTangent expr' |
         Cosine expr' | Exponential expr' | Floor expr' |
         HyperbolicCosine expr' | HyperbolicSine expr' |
-        HyperbolicTangent expr' | Logarithm expr' | Not expr' |
+        HyperbolicTangent expr' | Logarithm expr' | Not expr' | Pre expr' |
         RationalPower (expr', _) | Sign expr' | Sine expr' | Tangent expr' ->
           add_if_necessary modes_on expr'
-      | Addition exprs' | And exprs' | BlackBox (_, exprs') |
-        Multiplication exprs' | Or exprs' ->
+      | Addition exprs' | And exprs' | Multiplication exprs' | Or exprs' ->
           List.iter (add_if_necessary modes_on) exprs'
-      | Equality (expr', expr'') | Greater (expr', expr'') ->
+      | BlackBox (_, args) ->
+          List.iter (add_argument_if_necessary modes_on) args
+      | Equality (expr', expr'') | Greater (expr', expr'') |
+        GreaterEqual (expr', expr'') ->
           add_if_necessary modes_on expr'; add_if_necessary modes_on expr''
       | If (expr', expr'', expr''') ->
           add_if_necessary false expr';
           add_if_necessary modes_on expr''; add_if_necessary modes_on expr'''
-      | TimeVariable -> ()
-      | _ -> assert false
-  in add_if_necessary modes_on expr
+      | BooleanValue _ | Constant _ | Derivative _ | DiscreteVariable _ |
+        Number _ | Parameter _ | Variable _ | Integer _ | String _ |
+        TimeVariable -> ()
+      | PartialDerivative _ -> assert false
+  and add_argument_if_necessary modes_on = function
+    | ScalarArgument expr -> add_if_necessary modes_on expr
+    | ArrayArgument (_, exprs) ->
+        Array.iter (add_if_necessary modes_on) exprs in
+  add_if_necessary modes_on expr
 
 let has_multiple_occurrences expr model_info =
   try
@@ -181,7 +227,8 @@ let has_multiple_occurrences expr model_info =
     | Not_found -> false
 
 let rec has_alias_binding expr model_info = match nature expr with
-  | BlackBox ("noEvent", [expr']) -> has_alias_binding expr' model_info
+  | BlackBox ("noEvent", [ScalarArgument expr']) ->
+      has_alias_binding expr' model_info
   | _ ->
       try
         let record = ExpressionTable.find model_info.occurrence_table expr in
@@ -189,6 +236,69 @@ let rec has_alias_binding expr model_info = match nature expr with
       with
         | Not_found -> false
 
+let real_array_store_size model =
+  let rec required_space expr = match nature expr with
+    | BooleanValue _  | Constant _ | DiscreteVariable _ | Number _ |
+      Parameter _ | TimeVariable | Variable _ | Integer _ | String _ -> 0
+    | ArcCosine node | ArcHyperbolicCosine node |
+      ArcHyperbolicSine node | ArcHyperbolicTangent node | ArcSine node |
+      ArcTangent node | Cosine node | Derivative (node, _) |
+      Exponential node | Floor node | HyperbolicCosine node |
+      HyperbolicSine node | HyperbolicTangent node | Logarithm node |
+      Not node | Pre node | RationalPower (node, _) | Sign node | Sine node |
+      Tangent node -> required_space node
+    | Equality (node1, node2) | Greater (node1, node2) |
+      GreaterEqual (node1, node2) | PartialDerivative (node1, node2) ->
+        max (required_space node1) (required_space node2)
+    | If (node1, node2, node3) ->
+        max
+          (required_space node1)
+          (max (required_space node2) (required_space node3))
+    | And nodes | Addition nodes | Multiplication nodes | Or nodes ->
+        List.fold_left (fun acc node -> max acc (required_space node)) 0 nodes
+    | BlackBox (_, args) ->
+        List.fold_left
+          (fun acc arg -> acc + argument_required_space arg)
+          0
+          args
+  and argument_required_space = function
+    | ScalarArgument expr -> required_space expr
+    | ArrayArgument (_, exprs) ->
+        max
+          (Array.length exprs)
+          (Array.fold_left
+            (fun acc expr -> max acc (required_space expr))
+            0
+            exprs) in
+  let option_required_space = function
+    | None -> 0
+    | Some expr -> required_space expr
+  and when_expression_required_space = function
+    | Assign (_, expr) | Reinit (_, expr) -> required_space expr in
+  Array.fold_left
+    (fun acc par -> max acc (required_space par.value))
+    (Array.fold_left
+      (fun acc dvar -> max acc (option_required_space dvar.d_start_value))
+      (Array.fold_left
+        (fun acc var -> max acc (option_required_space var.start_value))
+        (Array.fold_left
+          (fun acc equ -> max acc (required_space equ.expression))
+          (List.fold_left
+            (fun acc (expr, wexprs) ->
+              max
+                (required_space expr)
+                (List.fold_left 
+                  (fun acc wexpr ->
+                    max acc (when_expression_required_space wexpr))
+                  acc
+                  wexprs))
+            0
+            model.when_clauses)
+          model.equations)
+        model.variables)
+      model.discrete_variables)
+    model.parameters
+
 let bufferize_float f model_info =
   let s = Printf.sprintf "%.16g" f in
   if not (String.contains s '.' || String.contains s 'e') then
@@ -197,26 +307,38 @@ let bufferize_float f model_info =
     Printf.bprintf model_info.code_buffer "%s" s
 
 let rec bufferize_rhs model_info tabs modes_on lhs expr =
+  let bufferize_parameter i =
+    let j = model_info.final_index_of_integer_parameters.(i) in
+    if j <> -1 then Printf.bprintf model_info.code_buffer "ipar[%d]" j
+    else
+      let j = model_info.final_index_of_string_parameters.(i) in
+      if j <> -1 then Printf.bprintf model_info.code_buffer "spar[%d]" j
+      else
+        let j = model_info.final_index_of_real_parameters.(i) in
+        if j <> -1 then Printf.bprintf model_info.code_buffer "rpar[%d]" j
+        else assert false in
   let rec precedence expr =
     if has_alias_binding expr model_info then 14
     else match nature expr with
-      | BooleanValue _ | Constant _ -> 14
-      | BlackBox ("noEvent", [expr']) -> precedence expr'
+      | BooleanValue _ | Constant _ | String _ -> 14
+      | BlackBox ("noEvent", [ScalarArgument expr']) -> precedence expr'
       | ArcCosine _ | ArcHyperbolicCosine _ | ArcHyperbolicSine _ |
         ArcHyperbolicTangent _ | ArcSine _ | ArcTangent _ | BlackBox _ |
-        Cosine _ | Derivative _ | Exponential _ | Floor _ | HyperbolicCosine _ |
-        HyperbolicSine _ | HyperbolicTangent _ | DiscreteVariable _ |
-        Logarithm _ | Parameter _ | PartialDerivative _ | Sign _ | Sine _ |
-        Tangent _ | TimeVariable | Variable _ -> 13
+        Cosine _ | Derivative _ | Exponential _ | Floor _ |
+        HyperbolicCosine _ | HyperbolicSine _ | HyperbolicTangent _ |
+        DiscreteVariable _ | Logarithm _ | Parameter _ | PartialDerivative _ |
+        Pre _ | Sign _ | Sine _ | Tangent _ | TimeVariable | Variable _ -> 13
       | Not _ -> 12
       | Multiplication _ | Number (Ratio _) -> 11
       | Addition _ -> 10
       | Greater _ -> 8
-      | Or _ when is_greater_equal expr -> 8
+      | GreaterEqual _ -> 8
       | Equality _ -> 7
       | And _ -> 3
       | Or _ -> 2
       | If _ -> 1
+      | Integer i when i < 0l -> 12
+      | Integer _ -> 14
       | Number num when lt_num num (Int 0) -> 12
       | Number (Int _) | Number (Big_int _) -> 14
       | RationalPower (_, num) when eq_num num (Int (-1)) -> 11
@@ -235,7 +357,8 @@ let rec bufferize_rhs model_info tabs modes_on lhs expr =
     | ArcHyperbolicTangent expr' -> bufferize_unary_function expr "atanh" expr'
     | ArcSine expr' -> bufferize_unary_function expr "asin" expr'
     | ArcTangent expr' -> bufferize_unary_function expr "atan" expr'
-    | BlackBox ("noEvent", [expr']) -> bufferize_expression expr'
+    | BlackBox ("noEvent", [ScalarArgument expr']) ->
+        bufferize_expression expr'
     | BlackBox (name, exprs') -> bufferize_n_ary_function expr name exprs'
     | BooleanValue b ->
         Printf.bprintf model_info.code_buffer "%c" (if b then '1' else '0')
@@ -255,53 +378,39 @@ let rec bufferize_rhs model_info tabs modes_on lhs expr =
     | Floor expr' -> bufferize_unary_function expr "floor" expr'
     | Greater (expr', expr'') ->
         bufferize_infix_operator expr ">" [expr'; expr'']
+    | GreaterEqual (expr', expr'') ->
+        bufferize_infix_operator expr ">=" [expr'; expr'']
     | HyperbolicCosine expr' -> bufferize_unary_function expr "cosh" expr'
     | HyperbolicSine expr' -> bufferize_unary_function expr "sinh" expr'
     | HyperbolicTangent expr' -> bufferize_unary_function expr "tanh" expr'
     | If (expr1, expr2, expr3) -> bufferize_if expr expr1 expr2 expr3
+    | Integer i -> Printf.bprintf model_info.code_buffer "%ld" i
     | DiscreteVariable i when i < 0 ->
         Printf.bprintf model_info.code_buffer "u[%d][0]" (-1 - i)
     | DiscreteVariable i -> Printf.bprintf model_info.code_buffer "z[%d]" i
+    | Pre expr' ->
+        begin match nature expr' with
+          | DiscreteVariable i when i >= 0 ->
+              Printf.bprintf model_info.code_buffer "z[%d]" i
+          | _ -> assert false
+        end
     | Logarithm expr' -> bufferize_unary_function expr "log" expr'
     | Multiplication exprs' -> bufferize_multiplication expr exprs'
     | Not expr' -> bufferize_prefix_operator expr "!" expr'
     | Number num -> bufferize_float (float_of_num num) model_info
-    | Or [expr1; expr2] when is_greater_equal expr ->
-        begin match nature expr1, nature expr2 with
-          | Greater (expr', expr''), _ | _, Greater (expr', expr'') ->
-              bufferize_greater_equal expr expr' expr''
-          | _ -> assert false
-        end
     | Or exprs' -> bufferize_infix_operator expr "||" exprs'
-    | Parameter i ->
-        Printf.bprintf model_info.code_buffer
-          "rpar[%d]"
-          model_info.final_index_of_parameters.(i)
+    | Parameter i -> bufferize_parameter i
     | PartialDerivative (expr', expr'') ->
         bufferize_partial_derivative expr expr' expr''
     | RationalPower (expr', num) -> bufferize_rational_power expr expr' num
     | Sign expr' -> bufferize_unary_function expr "sgn" expr'
     | Sine expr' -> bufferize_unary_function expr "sin" expr'
+    | String s -> Printf.bprintf model_info.code_buffer "\"%s\"" s
     | Tangent expr' -> bufferize_unary_function expr "tan" expr'
     | TimeVariable -> bufferize_n_ary_function expr "get_scicos_time" []
     | Variable i ->
         let j = model_info.final_index_of_variables.(i) in
         Printf.bprintf model_info.code_buffer "x[%d]" j
-  and bufferize_greater_equal expr expr' expr'' =
-    try
-      let record =
-        ExpressionTable.find
-          model_info.occurrence_table
-          (create_blackBox ">=" [expr'; expr''])
-          (* this is a hack to simulate >= being a primitive expression. *)
-      in match record.label with
-        | None ->
-            bufferize_expression_under (precedence expr) expr';
-            Printf.bprintf model_info.code_buffer ">=";
-            bufferize_expression_under (precedence expr) expr''
-        | Some i -> Printf.bprintf model_info.code_buffer "v%d" i
-    with
-      | Not_found -> assert false
   and bufferize_unary_function expr name expr' =
     try
       let record = ExpressionTable.find model_info.occurrence_table expr in
@@ -330,21 +439,49 @@ let rec bufferize_rhs model_info tabs modes_on lhs expr =
         bufferize_expression_under prec expr';
         Printf.bprintf model_info.code_buffer "%s" name;
         bufferize_arguments_under prec name exprs'
-  and bufferize_n_ary_function expr name exprs' =
+  and bufferize_n_ary_function expr name args =
+    let rec bufferize_arguments = function
+      | [] -> ()
+      | [arg] -> bufferize_argument arg
+      | arg :: args ->
+          bufferize_argument arg;
+          Printf.bprintf model_info.code_buffer ", ";
+          bufferize_arguments args
+    and bufferize_argument arg =
+      let rec bufferize_dimensions = function
+        | [] -> assert false
+        | [dim] -> Printf.bprintf model_info.code_buffer "%d" dim
+        | dim :: dims ->
+            Printf.bprintf model_info.code_buffer "%d, " dim;
+            bufferize_dimensions dims in
+      match arg with
+      | ScalarArgument expr -> bufferize_expression_under 0 expr
+      | ArrayArgument (dims, exprs) ->
+          assert (Array.length exprs > 0);
+          begin try
+            let offset =
+              ArrayStore.find model_info.real_arrays (dims, exprs) in
+            Printf.bprintf model_info.code_buffer "&real_buffer[%d], " offset;
+            bufferize_dimensions dims
+          with Not_found -> assert false
+          end in
     try
       let record = ExpressionTable.find model_info.occurrence_table expr in
       match record.label with
-        | None when model_info.model.trace <> None ->
-            Printf.bprintf model_info.code_buffer "%s_trace(" name;
-            bufferize_arguments_under 0 ", " exprs';
-            Printf.bprintf model_info.code_buffer ")"            
+        | Some i -> Printf.bprintf model_info.code_buffer "v%d" i
         | None ->
             Printf.bprintf model_info.code_buffer "%s(" name;
-            bufferize_arguments_under 0 ", " exprs';
+            bufferize_arguments args;
             Printf.bprintf model_info.code_buffer ")"
-        | Some i -> Printf.bprintf model_info.code_buffer "v%d" i
     with
       | Not_found -> assert false
+  and bufferize_expressions_under prec name = function
+    | [] -> ()
+    | [expr'] -> bufferize_expression_under prec expr'
+    | expr' :: exprs' ->
+        bufferize_expression_under prec expr';
+        Printf.bprintf model_info.code_buffer "%s" name;
+        bufferize_expressions_under prec name exprs'
   and bufferize_infix_operator expr name exprs' =
     try
       let record = ExpressionTable.find model_info.occurrence_table expr in
@@ -496,7 +633,10 @@ let rec bufferize_rhs model_info tabs modes_on lhs expr =
   and bufferize_partial_derivative expr expr' expr'' = assert false
   and bufferize_intermediate_variables_if_necessary expr =
     let rec bufferize_children_if_necessary expr = match nature expr with
-      | BlackBox ("noEvent", [expr']) -> bufferize_children_if_necessary expr'
+      | BlackBox ("noEvent", [ScalarArgument expr']) ->
+          bufferize_children_if_necessary expr'
+      | BlackBox (_, args) ->
+          List.iter bufferize_argument_intermediate_variables_if_necessary args
       | ArcCosine expr' | ArcHyperbolicCosine expr' | ArcHyperbolicSine expr' |
         ArcHyperbolicTangent expr' | ArcSine expr' | ArcTangent expr' |
         Cosine expr' | Exponential expr' | Floor expr' |
@@ -504,44 +644,97 @@ let rec bufferize_rhs model_info tabs modes_on lhs expr =
         HyperbolicTangent expr' | Logarithm expr' | Not expr' |
         RationalPower (expr', _) | Sign expr' | Sine expr' | Tangent expr' ->
           bufferize_intermediate_variables_if_necessary expr'
-      | Addition exprs' | And exprs' | BlackBox (_, exprs') |
-        Multiplication exprs' | Or exprs' ->
+      | Addition exprs' | And exprs' | Multiplication exprs' | Or exprs' ->
           List.iter bufferize_intermediate_variables_if_necessary exprs'
-      | Equality (expr1, expr2) | Greater (expr1, expr2) ->
+      | Equality (expr1, expr2) | Greater (expr1, expr2) |
+        GreaterEqual (expr1, expr2) ->
           bufferize_intermediate_variables_if_necessary expr1;
           bufferize_intermediate_variables_if_necessary expr2
       | If (expr1, expr2, expr3) ->
           bufferize_intermediate_variables_if_necessary expr1;
           bufferize_intermediate_variables_if_necessary expr2;
           bufferize_intermediate_variables_if_necessary expr3
-      | TimeVariable -> ()
-      | _ -> assert false
-    in match nature expr with
-      | BlackBox ("noEvent", [expr']) -> bufferize_intermediate_variables_if_necessary expr'
-      | _ ->
-          try
-            let record = ExpressionTable.find model_info.occurrence_table expr in
-            match record.label with
-              | None when record.occurrences > 1 ->
-                  let i = next_index model_info in
-                  bufferize_children_if_necessary expr;
-                  for i = 1 to tabs do
-                    Printf.bprintf model_info.code_buffer "\t"
-                  done;
-                  Printf.bprintf model_info.code_buffer "v%d = " i;
-                  bufferize_expression expr;
-                  Printf.bprintf model_info.code_buffer ";\n";
-                  record.label <- Some i
-              | _ -> bufferize_children_if_necessary expr
-          with
-            | Not_found -> ()
-  in
+      | _ -> ()
+    and bufferize_argument_intermediate_variables_if_necessary = function
+      | ScalarArgument expr ->
+          bufferize_intermediate_variables_if_necessary expr
+      | ArrayArgument (_, exprs) ->
+          Array.iter bufferize_intermediate_variables_if_necessary exprs
+    and bufferize_arrays pointer = function
+      | ScalarArgument _ -> pointer
+      | ArrayArgument (dims, exprs)
+        when ArrayStore.mem model_info.real_arrays (dims, exprs) ->
+          pointer
+      | ArrayArgument (dims, exprs) ->
+          ArrayStore.add model_info.real_arrays (dims, exprs) pointer;
+          Array.iteri
+            (fun i expr ->
+              for i = 1 to tabs do
+                Printf.bprintf model_info.code_buffer "\t"
+              done;
+              Printf.bprintf
+                model_info.code_buffer
+                "real_buffer[%d] = "
+                (pointer + i);
+              bufferize_expression expr;
+              Printf.bprintf model_info.code_buffer ";\n")
+            exprs;
+            pointer + List.fold_left ( * ) 1 dims in
+    match nature expr with
+    | BlackBox ("noEvent", [ScalarArgument expr']) ->
+        bufferize_intermediate_variables_if_necessary expr'
+    | BlackBox (_, args) ->
+        (* Special case of exteral calls: we always generate an intermediate
+           variable in order to avoid nested intermediate array
+           construction *)
+        begin try
+          let record = ExpressionTable.find model_info.occurrence_table expr in
+          match record.label with
+            | None ->
+                let i = next_index model_info in
+                bufferize_children_if_necessary expr;
+                let _ =
+                  List.fold_left
+                    (fun acc arg -> bufferize_arrays acc arg)
+                    0
+                    args in
+                for i = 1 to tabs do
+                  Printf.bprintf model_info.code_buffer "\t"
+                done;
+                Printf.bprintf model_info.code_buffer "v%d = " i;
+                bufferize_expression expr;
+                Printf.bprintf model_info.code_buffer ";\n";
+                record.label <- Some i
+            | _ -> bufferize_children_if_necessary expr
+        with
+          | Not_found -> assert false
+        end
+    | _ ->
+        begin try
+          let record = ExpressionTable.find model_info.occurrence_table expr in
+          match record.label with
+            | None when record.occurrences > 1 ->
+                let i = next_index model_info in
+                bufferize_children_if_necessary expr;
+                for i = 1 to tabs do
+                  Printf.bprintf model_info.code_buffer "\t"
+                done;
+                Printf.bprintf model_info.code_buffer "v%d = " i;
+                bufferize_expression expr;
+                Printf.bprintf model_info.code_buffer ";\n";
+                record.label <- Some i
+            | _ -> bufferize_children_if_necessary expr
+        with
+          | Not_found -> ()
+        end in
+  ArrayStore.clear model_info.real_arrays;
   bufferize_intermediate_variables_if_necessary expr;
   for i = 1 to tabs do
     Printf.bprintf model_info.code_buffer "\t"
   done;
   Printf.bprintf model_info.code_buffer "%s" lhs;
-  bufferize_expression expr
+  bufferize_expression expr;
+  ArrayStore.clear model_info.real_arrays
 
 let bufferize_equations model_info =
   ExpressionTable.clear model_info.occurrence_table;
@@ -551,7 +744,7 @@ let bufferize_equations model_info =
         add_to_occurrence_table
           true
           equation.expression
-          model_info.occurrence_table)
+          model_info)
     model_info.model.equations;
   model_info.current_index <- -1;
   Array.iteri
@@ -563,13 +756,9 @@ let bufferize_equations model_info =
         Printf.bprintf model_info.code_buffer ";\n")
     model_info.model.equations
 
-let bufferize_jacobian model_info =
+let bufferize_jacobian nb_vars model_info =
   let model = model_info.model in
-  let nx =
-    Array.fold_left
-      (fun acc equation -> if not equation.solved then acc + 1 else acc)
-      0
-      model.equations
+  let nx = nb_vars
   and nu = Array.length model.inputs
   and ny =
     Array.fold_left
@@ -688,7 +877,7 @@ let bufferize_jacobian model_info =
           add_to_occurrence_table
             true
             elt
-            model_info.occurrence_table)
+            model_info)
         row)
     jacobian_matrix;
   model_info.current_index <- -1;
@@ -756,7 +945,7 @@ let bufferize_outputs model_info =
         add_to_occurrence_table
           false
           equation.expression
-          model_info.occurrence_table)
+          model_info)
     model_info.model.equations;
   model_info.current_index <- -1;
   Printf.bprintf model_info.code_buffer
@@ -769,7 +958,7 @@ let bufferize_outputs model_info =
         add_to_occurrence_table
           true
           equation.expression
-          model_info.occurrence_table)
+          model_info)
     model_info.model.equations;
   model_info.current_index <- -1;
   Printf.bprintf model_info.code_buffer "\t\t} else {\n";
@@ -777,21 +966,11 @@ let bufferize_outputs model_info =
   Printf.bprintf model_info.code_buffer "\t\t}\n"
 
 let bufferize_surface_expression model_info cond = match nature cond with
-  | Greater (expr, expr') ->
+  | Greater (expr, expr') | GreaterEqual (expr, expr') ->
       add_to_occurrence_table
         false
         (symbolic_sub expr expr')
-        model_info.occurrence_table
-  | Or [expr; expr'] ->
-      assert (is_greater_equal cond);
-      begin match nature expr, nature expr' with
-        | Greater (expr, expr'), _ | _, Greater (expr, expr') ->
-            add_to_occurrence_table
-              false
-              (symbolic_sub expr expr')
-              model_info.occurrence_table
-        | _ -> assert false
-      end
+        model_info
   | _ -> ()
 
 let bufferize_surface_equation model_info i cond =
@@ -800,14 +979,8 @@ let bufferize_surface_equation model_info i cond =
     bufferize_rhs model_info 2 false lhs (symbolic_sub expr expr');
     Printf.bprintf model_info.code_buffer ";\n";
   in match nature cond with
-    | Greater (expr, expr') -> bufferize_surface_equation' expr expr'
-    | Or [expr; expr'] ->
-        assert (is_greater_equal cond);
-        begin match nature expr, nature expr' with
-          | Greater (expr, expr'), _ | _, Greater (expr, expr') ->
-              bufferize_surface_equation' expr expr'
-          | _ -> assert false
-        end
+    | Greater (expr, expr') | GreaterEqual (expr, expr') ->
+        bufferize_surface_equation' expr expr'
     | _ -> ()
 
 let bufferize_when_equations model_info =
@@ -818,7 +991,7 @@ let bufferize_when_equations model_info =
         ExpressionTable.clear model_info.occurrence_table;
         List.iter
           (fun (Assign (_, expr) | Reinit (_, expr)) ->
-            add_to_occurrence_table false expr model_info.occurrence_table)
+            add_to_occurrence_table false expr model_info)
           when_exprs;
         model_info.current_index <- -1;
         List.iter
@@ -851,7 +1024,7 @@ let bufferize_surfaces model_info =
   ExpressionTable.clear model_info.occurrence_table;
   List.iter
     (fun cond ->
-      add_to_occurrence_table false cond model_info.occurrence_table;
+      add_to_occurrence_table false cond model_info;
       bufferize_surface_expression model_info cond)
     model_info.surfaces;
   List.iter
@@ -887,7 +1060,7 @@ let bufferize_surfaces model_info =
         in ();
         Printf.bprintf model_info.code_buffer "\t\t}\n"
 
-let bufferize_initializations model_info =
+let bufferize_initializations init nb_pars nb_dvars nb_vars nb_ders model_info =
   let start_value = function
     | None -> zero
     | Some expr -> expr
@@ -898,14 +1071,14 @@ let bufferize_initializations model_info =
       add_to_occurrence_table
         false
         (start_value discrete_variable.d_start_value)
-        model_info.occurrence_table)
+        model_info)
     model_info.model.discrete_variables;
   Array.iter
     (fun discrete_variable ->
       add_to_occurrence_table
         false
         (start_value discrete_variable.start_value)
-        model_info.occurrence_table)
+        model_info)
     model_info.model.variables;
   Array.iteri
     (fun i discrete_variable ->
@@ -933,14 +1106,169 @@ let bufferize_initializations model_info =
         if variable.v_comment <> "" then
           Printf.bprintf model_info.code_buffer " = %s" variable.v_comment;
         Printf.bprintf model_info.code_buffer " */\n")
-    model_info.model.variables
+    model_info.model.variables;
+  match fst init with
+  | Some xml_filename ->
+      begin
+        if nb_pars > 0 then
+          Printf.bprintf
+            model_info.code_buffer
+            "\t\tif ((*work = scicos_malloc(%d * sizeof(double))) == NULL) \
+            {\n\
+            \t\t\tset_block_error(-16);\n\
+            \t\t\treturn;\n\
+            \t\t}\n"
+            nb_pars;
+        if nb_vars > 0 then
+          Printf.bprintf
+            model_info.code_buffer
+            "\t\tif (read_xml_initial_states(%d, \"%s\", var_ids, x)) {\n\
+            \t\t\tset_block_error(-19);\n\
+            \t\t\treturn;\n\
+            \t\t}\n"
+            nb_vars
+            xml_filename;
+        if nb_dvars > 0 then
+          Printf.bprintf
+            model_info.code_buffer
+            "\t\tif (read_xml_initial_states(%d, \"%s\", disc_var_ids, z)) {\n\
+            \t\t\tset_block_error(-19);\n\
+            \t\t\treturn;\n\
+            \t\t}\n"
+            nb_dvars
+            xml_filename;
+        if nb_ders > 0 then begin
+          Printf.bprintf
+            model_info.code_buffer
+            "\t\tif (read_xml_initial_states(%d, \"%s\", der_ids, der_values)) {\n\
+            \t\t\tset_block_error(-19);\n\
+            \t\t\treturn;\n\
+            \t\t}\n"
+            nb_ders
+            xml_filename;
+          let k = ref 0 in
+          Array.iteri
+            (fun i variable ->
+              if
+                not model_info.model.equations.(i).solved && variable.state
+              then begin
+                let j = model_info.final_index_of_variables.(i) in
+                Printf.bprintf
+                  model_info.code_buffer
+                  "\t\txd[%d] = der_values[%d];\n" j !k;
+                incr k
+              end)
+            model_info.model.variables;
+        end;
+        if nb_pars > 0 then
+          Printf.bprintf
+            model_info.code_buffer
+            "\t\tspars = *work;\n\
+            \t\tif (read_xml_initial_states(%d, \"%s\", par_ids, spars)) {\n\
+            \t\t\tscicos_free(*work);\n\
+            \t\t\t*work = NULL;\n\
+            \t\t\tset_block_error(-19);\n\
+            \t\t\treturn;\n\
+            \t\t}\n"
+            nb_pars
+            xml_filename
+        else
+          Printf.bprintf
+            model_info.code_buffer
+            "\t\t*work = NULL;\n"
+      end
+  | None -> ()
 
-let bufferize_variable_nature model_info =
-  let nb_vars =
-    Array.fold_left
-      (fun acc equation -> if not equation.solved then acc + 1 else acc)
-      0
-      model_info.model.equations in
+let bufferize_variable_store init nb_pars nb_dvars nb_ders model_info =
+  match snd init with
+  | Some xml_filename ->
+      begin
+        if Array.length model_info.model.variables + nb_dvars > 0 then begin
+          ExpressionTable.clear model_info.occurrence_table;
+          Array.iteri
+            (fun i equation ->
+              if equation.solved then
+                add_to_occurrence_table
+                  false
+                  equation.expression
+                  model_info)
+            model_info.model.equations;
+          model_info.current_index <- -1;
+          Array.iteri
+            (fun i equation ->
+              let lhs = Printf.sprintf "all_var_values[%d] = " i in
+              if equation.solved then begin
+                bufferize_rhs model_info 2 false lhs equation.expression;
+                Printf.bprintf model_info.code_buffer ";\n"
+              end else
+                let j = model_info.final_index_of_variables.(i) in
+                Printf.bprintf model_info.code_buffer "\t\t%sx[%d];\n" lhs j)
+            model_info.model.equations;
+          Array.iteri
+            (fun i _ ->
+              let lhs =
+                Printf.sprintf "all_var_values[%d] = "
+                (i + Array.length model_info.model.equations) in
+              Printf.bprintf model_info.code_buffer "\t\t%sz[%i];\n" lhs i)
+            model_info.model.discrete_variables;
+          Printf.bprintf
+            model_info.code_buffer
+            "\t\tif (write_xml_states(%d, \"%s\", all_var_ids, all_var_values)) {\n\
+            \t\t\tset_block_error(-19);\n\
+            \t\t\treturn;\n\
+            \t\t}\n"
+            (Array.length model_info.model.variables)
+            xml_filename
+        end;
+        if nb_ders > 0 then begin
+          let k = ref 0 in
+          Array.iteri
+            (fun i variable ->
+              if
+                not model_info.model.equations.(i).solved && variable.state
+              then begin
+                let j = model_info.final_index_of_variables.(i) in
+                Printf.bprintf
+                  model_info.code_buffer
+                  "\t\tder_values[%d] = xd[%d];\n" !k j;
+                incr k
+              end)
+            model_info.model.variables;
+          Printf.bprintf
+            model_info.code_buffer
+            "\t\tif (write_xml_states(%d, \"%s\", der_ids, der_values)) {\n\
+            \t\t\tset_block_error(-19);\n\
+            \t\t\treturn;\n\
+            \t\t}\n"
+            nb_ders
+            xml_filename
+        end
+      end
+  | None -> ()
+
+let bufferize_work_deallocation init nb_pars model_info =
+  if fst init <> None && nb_pars > 0 then
+    Printf.bprintf
+      model_info.code_buffer
+      "\t\tif (*work != NULL) {\n\
+      \t\t\tspars = *work;\n\
+      \t\t\tfor (i = 0; i < %d; i++) block->rpar[i] = spars[i];\n\
+      \t\t\tscicos_free(*work);\n\
+      \t\t\t*work = NULL;\n\
+      \t\t}\n"
+      nb_pars
+
+let bufferize_parameter_value init nb_pars model_info =
+  if fst init <> None then begin
+    if nb_pars > 0 then
+      Printf.bprintf
+        model_info.code_buffer
+        "\t\tspars = *work;\n\
+        \t\tfor (i = 0; i < %d; i++) block->rpar[i] = spars[i];\n"
+        nb_pars
+  end
+
+let bufferize_variable_nature nb_vars model_info =
   if nb_vars > 0 then begin
     Array.iteri
       (fun i variable ->
@@ -948,7 +1276,7 @@ let bufferize_variable_nature model_info =
         if not equation.solved then begin
           Printf.bprintf
             model_info.code_buffer
-            "\t\tproperty[%d] = %s; /* %s"
+            "\t\tblock->xprop[%d] = %s; /* %s"
             model_info.final_index_of_variables.(i)
             (if variable.state then "1" else "-1")
             variable.v_name;
@@ -959,88 +1287,76 @@ let bufferize_variable_nature model_info =
             " (%s variable) */\n"
             (if variable.state then "state" else "algebraic")
         end)
-      model_info.model.variables;
-    Printf.bprintf model_info.code_buffer "\t\tset_pointer_xproperty(property);\n"
+      model_info.model.variables
   end
 
-
 let rec last = function
   | [] -> failwith "last"
   | [x] -> x
   | _ :: xs -> last xs
 
-let generate_trace_info oc model_info = match model_info.model.trace with
-  | None -> ()
-  | Some filename ->
-      Printf.fprintf oc
-        "#include <stdio.h>\n\
-        \n\
-        \n/* Tracing code */\n";
-      List.iter
-        (fun (name, arity) ->
-          Printf.fprintf oc
-            "\n\
-            double %s_trace("
-            (last name);
-          for i = 1 to arity - 1 do
-            Printf.fprintf oc "double arg%d, " i
-          done;
-          if arity > 0 then Printf.fprintf oc "double arg%d" arity;
-          Printf.fprintf oc
-            ")\n\
-            {\n\
-            \tdouble res;\n\
-            \tFILE *fd;\n\
-            \tfd = fopen(\"%s\",\"a\");\n\
-            \tfprintf(fd, \"%s("
-            filename
-            (last name);
-          for i = 1 to arity - 1 do
-            Printf.fprintf oc "%%g, "
-          done;
-          if arity > 0 then Printf.fprintf oc "%%g";
-          Printf.fprintf oc ")\", ";
-          for i = 1 to arity - 1 do
-            Printf.fprintf oc "arg%d, " i
-          done;
-          if arity > 0 then Printf.fprintf oc "arg%d" arity;
-          Printf.fprintf oc
-            ");\n\
-            \tfclose(fd);\n\
-            \tres = %s("
-            (last name);
-          for i = 1 to arity - 1 do
-            Printf.fprintf oc "arg%d, " i
-          done;
-          if arity > 0 then Printf.fprintf oc "arg%d" arity;
-          Printf.fprintf oc
-            ");\n\
-            \tfd = fopen(\"%s\",\"a\");\n\
-            \tfprintf(fd, \" -> %%g\\n\", res);\n\
-            \tfclose(fd);\n\
-            \treturn res;\n\
-            }\n"
-            filename)
-      model_info.model.external_functions
+let string_of_c_type = function
+  | Instantiation.BooleanType [||] -> "int "
+  | Instantiation.IntegerType [||] -> "int "
+  | Instantiation.RealType [||] -> "double "
+  | Instantiation.RealType dims ->
+      Array.fold_left (fun acc _ -> acc ^ ", int ") "double *" dims
+  | Instantiation.StringType [||] -> "char *"
+  | Instantiation.BooleanType _ | Instantiation.CartesianProduct _ |
+    Instantiation.CompoundType _ | Instantiation.IntegerType _ |
+    Instantiation.StringType _ ->
+      failwith "string_of_c_type: unsupported type"
+
+let generate_c_function_prototype oc name in_types out_types =
+  let rec generate_c_function_input_arguments = function
+    | [] -> ()
+    | [in_type] ->
+        Printf.fprintf oc "%s" (string_of_c_type in_type)
+    | in_type :: in_types ->
+        Printf.fprintf oc "%s, " (string_of_c_type in_type);
+        generate_c_function_input_arguments in_types in
+  match out_types with
+  | [Instantiation.RealType [||]] ->
+      Printf.fprintf oc "\nextern double %s(" name;
+      generate_c_function_input_arguments in_types;
+      Printf.fprintf oc ");\n"
+  | _ -> failwith "generate_c_function_prototype: unsupported function type" 
 
-let generate_code path filename fun_name model with_jac =
+let generate_code path filename fun_name model with_jac _ init =
   let rec to_filename = function
     | [] -> ""
     | [s] -> s
     | s :: ss -> s ^ "/" ^ to_filename ss
-  in
-  let oc = open_out filename in
+  and to_der_id s =
+    let i = try String.index s '[' - 2 with Not_found -> String.length s - 1 in
+    try
+      let n = String.rindex_from s i '.' + 1 in
+      String.sub s 0 n ^ "__der_" ^ String.sub s n (String.length s - n)
+    with Not_found -> "__der_" ^ s
+  and is_derivated expr exprs =
+    let is_derivated' expr' = match nature expr' with
+      | Derivative (expr'', _) -> expr'' == expr
+      | _ -> assert false in
+    List.exists is_derivated' exprs in
+  let oc = open_out filename
+  and oc' = open_out (Filename.chop_extension filename ^ "_incidence_matrix.xml") in
   postprocess_residue model;
   let model_info =
     {
       model = model;
-      final_index_of_parameters = final_index_of_parameters model;
+      final_index_of_integer_parameters =
+        final_index_of_integer_parameters model;
+      final_index_of_string_parameters =
+        final_index_of_string_parameters model;
+      final_index_of_real_parameters = final_index_of_real_parameters model;
       final_index_of_variables = final_index_of_variables model;
       surfaces = collect_surfaces model;
       occurrence_table = ExpressionTable.create 100;
       current_index = -1;
       max_index = -1;
-      code_buffer = Buffer.create 10000
+      code_buffer = Buffer.create 10000;
+      real_array_store_size = real_array_store_size model;
+      real_arrays = ArrayStore.create 13
     }
   in
   let nb_vars =
@@ -1048,7 +1364,21 @@ let generate_code path filename fun_name model with_jac =
       (fun acc equation -> if not equation.solved then acc + 1 else acc)
       0
       model.equations
-  and nb_modes = List.length model_info.surfaces in
+  and nb_dvars = Array.length model.discrete_variables
+  and nb_pars = 
+    Array.fold_left
+      (fun acc parameter -> if parameter.main then acc + 1 else acc)
+      0
+      model.parameters
+  and nb_modes = List.length model_info.surfaces
+  and _, nb_ders =
+    Array.fold_left
+      (fun (i, acc) variable ->
+        i + 1,
+        if not model.equations.(i).solved && variable.state then acc + 1
+        else acc)
+      (0, 0)
+      model.variables in
   Printf.fprintf oc "/*\n\
     number of discrete variables = %d\n\
     number of variables = %d\n\
@@ -1058,7 +1388,7 @@ let generate_code path filename fun_name model with_jac =
     number of zero-crossings = %d\n\
     I/O direct dependency = %s\n\
     */\n\n"
-    (Array.length model.discrete_variables)
+    nb_dvars
     nb_vars
     (Array.length model.inputs)
     (Array.fold_left
@@ -1070,12 +1400,9 @@ let generate_code path filename fun_name model with_jac =
     (if model.io_dependency then "true" else "false");
   Printf.fprintf oc "#include <math.h>\n#include <scicos_block.h>\n";
   List.iter
-    (fun (name, _) ->
-      Printf.fprintf oc
-        "#include \"%s.h\"\n"
-        (String.escaped (Filename.concat path (to_filename name))))
+    (fun (name, in_types, out_types) ->
+      generate_c_function_prototype oc (last name) in_types out_types)
     model.external_functions;
-  generate_trace_info oc model_info;
   Printf.fprintf oc "\n\n/* Utility functions */\n\n";
   Printf.fprintf oc
     "double ipow_(double x, int n)\n\
@@ -1092,7 +1419,7 @@ let generate_code path filename fun_name model with_jac =
      double ipow(double x, int n)\n\
      {\n\
      \t/* NaNs propagation */\n\
-     \tif (x != x || x == 0.0 && n == 0) return exp(x * log((double)n));\n\
+     \tif (x != x || (x == 0.0 && n == 0)) return exp((double)n * log(x));\n\
      \t/* Normal execution */\n\
      \tif (n < 0) return 1.0 / ipow_(x, -n);\n\
      \treturn ipow_(x, n);\n\
@@ -1103,26 +1430,121 @@ let generate_code path filename fun_name model with_jac =
     fun_name;
   Printf.fprintf oc
     "{\n\
+     \tint *ipar = block->ipar;\n\
      \tdouble *rpar = block->rpar;\n\
      \tdouble *z = block->z;\n\
      \tdouble *x = block->x;\n\
      \tdouble *xd = block->xd;\n\
      \tdouble **y = block->outptr;\n\
      \tdouble **u = block->inptr;\n\
+     \tdouble **work = (double **)block->work;\n\
      \tdouble *g = block->g;\n\
      \tdouble *res = block->res;\n\
      \tint *jroot = block->jroot;\n\
      \tint *mode = block->mode;\n\
      \tint nevprt = block->nevprt;\n";
-  if nb_vars > 0 then
-    Printf.fprintf oc "\tint property[%d];\n" nb_vars;
+  if model_info.real_array_store_size > 0 then
+    Printf.fprintf oc "\tdouble real_buffer[%d];\n"
+      model_info.real_array_store_size;
+  if fst init <> None || snd init <> None then begin
+    if nb_pars > 0 then begin
+      Printf.fprintf oc
+        "\tint i;\n\
+        \tdouble *spars;\n\
+        \tchar *par_ids[] =\n\
+        \t\t{\n";
+      let first = ref true in
+      Array.iter
+        (fun parameter ->
+          if parameter.main then begin
+            if !first then first := false else Printf.fprintf oc ",\n";
+            Printf.fprintf oc "\t\t\t\"%s\"" parameter.p_name
+          end)
+        model.parameters;
+      Printf.fprintf oc
+        "\n\
+        \t\t};\n"
+    end;
+    if Array.length model.variables + nb_dvars > 0 then begin
+      Printf.fprintf oc
+        "\tchar *all_var_ids[] =\n\
+        \t\t{\n";
+      let first = ref true in
+      Array.iter
+        (fun variable ->
+          if !first then first := false else Printf.fprintf oc ",\n";
+          Printf.fprintf oc "\t\t\t\"%s\"" variable.v_name)
+        model.variables;
+      Array.iter
+        (fun discrete_variable ->
+          if !first then first := false else Printf.fprintf oc ",\n";
+          Printf.fprintf oc "\t\t\t\"%s\"" discrete_variable.d_v_name)
+        model.discrete_variables;
+      Printf.fprintf oc
+        "\n\
+        \t\t};\n\
+        \tdouble all_var_values[%d];\n"
+        (Array.length model.variables + nb_dvars)
+    end;
+    if nb_vars > 0 then begin
+      Printf.fprintf oc
+        "\tchar *var_ids[] =\n\
+        \t\t{\n";
+      let first = ref true in
+      Array.iteri
+        (fun i variable ->
+          if not model.equations.(i).solved then begin
+            if !first then first := false else Printf.fprintf oc ",\n";
+            Printf.fprintf oc "\t\t\t\"%s\"" variable.v_name
+          end)
+        model.variables;
+      Printf.fprintf oc
+        "\n\
+        \t\t};\n";
+    end;
+    if nb_dvars > 0 then begin
+      Printf.fprintf oc
+        "\tchar *disc_var_ids[] =\n\
+        \t\t{\n";
+      let first = ref true in
+      Array.iter
+        (fun discrete_variable ->
+          if !first then first := false else Printf.fprintf oc ",\n";
+          Printf.fprintf oc "\t\t\t\"%s\"" discrete_variable.d_v_name)
+        model.discrete_variables;
+      Printf.fprintf oc
+        "\n\
+        \t\t};\n";
+    end;
+    if nb_ders > 0 then begin
+      Printf.fprintf oc
+        "\tchar *der_ids[] =\n\
+        \t\t{\n";
+      let first = ref true in
+      Array.iteri
+        (fun i variable ->
+          if not model.equations.(i).solved && variable.state then begin
+            if !first then first := false else Printf.fprintf oc ",\n";
+            Printf.fprintf oc "\t\t\t\"%s\"" (to_der_id variable.v_name)
+          end)
+        model.variables;
+      Printf.fprintf oc
+        "\n\
+        \t\t};\n\
+        \tdouble der_values[%d];\n"
+        nb_ders
+    end
+  end;
   Printf.fprintf oc "\n";
   Printf.bprintf model_info.code_buffer "\tif (flag == 0) {\n";
+  bufferize_parameter_value init nb_pars model_info;
   bufferize_equations model_info;
   Printf.bprintf model_info.code_buffer "\t} else if (flag == 1) {\n";
+  bufferize_parameter_value init nb_pars model_info;
   bufferize_outputs model_info;
   Printf.bprintf model_info.code_buffer
     "\t} else if (flag == 2 && nevprt < 0) {\n";
+  bufferize_parameter_value init nb_pars model_info;
   bufferize_when_equations model_info;
   Printf.bprintf model_info.code_buffer "\t} else if (flag == 4) {\n";
   begin match model.trace with
@@ -1134,19 +1556,25 @@ let generate_code path filename fun_name model with_jac =
           \t\tfclose(fd);\n"
           filename
   end;
-  bufferize_initializations model_info;
+  bufferize_initializations init nb_pars nb_dvars nb_vars nb_ders model_info;
   if with_jac then begin
     Printf.bprintf model_info.code_buffer "\t\tSet_Jacobian_flag(1);\n";
   end;
-  Printf.bprintf model_info.code_buffer
-    "\t} else if (flag == 6) {\n";
+  Printf.bprintf model_info.code_buffer "\t} else if (flag == 5) {\n";
+  bufferize_work_deallocation init nb_pars model_info;
+  bufferize_variable_store init nb_pars nb_dvars nb_ders model_info;
+  Printf.bprintf model_info.code_buffer "\t} else if (flag == 6) {\n";
+  bufferize_parameter_value init nb_pars model_info;
   Printf.bprintf model_info.code_buffer "\t} else if (flag == 7) {\n";
-  bufferize_variable_nature model_info;
+  bufferize_parameter_value init nb_pars model_info;
+  bufferize_variable_nature nb_vars model_info;
   Printf.bprintf model_info.code_buffer "\t} else if (flag == 9) {\n";
+  bufferize_parameter_value init nb_pars model_info;
   bufferize_surfaces model_info;
   if with_jac then begin
     Printf.bprintf model_info.code_buffer "\t} else if (flag == 10) {\n";
-    bufferize_jacobian model_info;
+    bufferize_parameter_value init nb_pars model_info;
+    bufferize_jacobian nb_vars model_info;
   end;
   Printf.bprintf model_info.code_buffer "\t}\n";
   if model_info.max_index >= 0 then begin
@@ -1161,4 +1589,127 @@ let generate_code path filename fun_name model with_jac =
   Buffer.output_buffer oc model_info.code_buffer;
   Printf.fprintf oc "\n\treturn;\n";
   Printf.fprintf oc "}\n";
-  close_out oc
+  Printf.fprintf oc' "<model>\n";
+  Printf.fprintf oc'
+    "\t<model_info>\n\
+    \t\t<number_of_integer_parameters>%d</number_of_integer_parameters>\n\
+    \t\t<number_of_real_parameters>%d</number_of_real_parameters>\n\
+    \t\t<number_of_string_parameters>%d</number_of_string_parameters>\n\
+    \t\t<number_of_discrete_variables>%d</number_of_discrete_variables>\n\
+    \t\t<number_of_continuous_variables>%d</number_of_continuous_variables>\n\
+    \t\t<number_of_continuous_unknowns>%d</number_of_continuous_unknowns>\n\
+    \t\t<number_of_continuous_states>%d</number_of_continuous_states>\n\
+    \t\t<number_of_inputs>%d</number_of_inputs>\n\
+    \t\t<number_of_outputs>%d</number_of_outputs>\n\
+    \t\t<number_of_modes>%d</number_of_modes>\n\
+    \t\t<number_of_zero_crossings>%d</number_of_zero_crossings>\n\
+    \t</model_info>\n"
+    (Array.fold_left max (-1) model_info.final_index_of_integer_parameters + 1)
+    nb_pars
+    (Array.fold_left max (-1) model_info.final_index_of_string_parameters + 1)
+    nb_dvars
+    (Array.length model.variables)
+    nb_vars
+    nb_ders
+    (Array.length model.inputs)
+    (Array.fold_left
+      (fun acc variable -> if variable.output <> None then acc + 1 else acc)
+      0
+      model.variables)
+    nb_modes
+    (List.length model.when_clauses + nb_modes);
+  Printf.fprintf oc' "\t<identifiers>\n";
+  Array.iter
+    (fun par ->
+      if par.main then
+        Printf.fprintf oc' "\t\t<parameter>%s</parameter>\n" par.p_name)
+    model_info.model.parameters;
+  Array.iteri
+    (fun i var ->
+      let equ = model_info.model.equations.(i) in
+      if equ.solved then
+        Printf.fprintf
+          oc'
+          "\t\t<explicit_variable>%s</explicit_variable>\n"
+          var.v_name
+      else
+        Printf.fprintf
+          oc'
+          "\t\t<implicit_variable>%s</implicit_variable>\n"
+          var.v_name)
+    model_info.model.variables;
+  Array.iter
+    (fun s -> Printf.fprintf oc' "\t\t<input>%s</input>\n" s)
+    model_info.model.inputs;
+  Printf.fprintf oc' "\t</identifiers>\n";
+  Printf.fprintf oc' "\t<implicit_relations>\n";
+  Array.iter
+    (fun equ ->
+      if not equ.solved then begin
+        Printf.fprintf oc' "\t\t<implicit_relation>\n";
+        List.iter
+          (fun expr ->
+            match nature expr with
+            | Parameter i when model_info.model.parameters.(i).main ->
+                Printf.fprintf oc'
+                  "\t\t\t<parameter>%s</parameter>\n"
+                  model_info.model.parameters.(i).p_name
+            | Parameter _ -> ()
+            | _ -> assert false)
+          (assignable_parameters_of equ.expression);
+        List.iter
+          (fun expr ->
+            match nature expr with
+            | Variable i when is_derivated expr equ.inner_derivatives ->
+                Printf.fprintf oc'
+                  "\t\t\t<derivative>%s</derivative>\n"
+                  model_info.model.variables.(i).v_name
+            | Variable i ->
+                Printf.fprintf oc'
+                  "\t\t\t<variable>%s</variable>\n"
+                  model_info.model.variables.(i).v_name
+            | _ -> assert false)
+          equ.assignable_variables;
+        Printf.fprintf oc' "\t\t</implicit_relation>\n"
+      end)
+    model_info.model.equations;
+  Printf.fprintf oc' "\t</implicit_relations>\n";
+  Printf.fprintf oc' "\t<outputs>\n";
+  Array.iteri
+    (fun i variable ->
+      match variable.output with
+        | None -> ()
+        | Some j ->
+            Printf.fprintf oc' "\t\t<output>\n";
+            Printf.fprintf oc' "\t\t\t<name>%s</name>\n" variable.v_name;
+            Printf.fprintf oc' "\t\t\t<order>%d</order>\n" j;
+            Printf.fprintf oc' "\t\t\t<dependencies>\n";
+            let inputs, vars =
+              let equ = model_info.model.equations.(i) in
+              if equ.solved then
+                inputs_of equ.expression, variables_of equ.expression
+              else [], [create_variable i] in
+            List.iter
+              (fun expr ->
+                match nature expr with
+                | DiscreteVariable i ->
+                    Printf.fprintf oc' "\t\t\t\t<input>%s</input>\n"
+                      model_info.model.inputs.(-1 - i)
+                | _ -> assert false)
+              inputs;
+            List.iter
+              (fun expr ->
+                match nature expr with
+                | Variable i ->
+                    Printf.fprintf oc'
+                      "\t\t\t\t<variable>%s</variable>\n"
+                      model_info.model.variables.(i).v_name
+                | _ -> assert false)
+              vars;
+              Printf.fprintf oc' "\t\t\t</dependencies>\n";
+              Printf.fprintf oc' "\t\t</output>\n")
+      model_info.model.variables;
+  Printf.fprintf oc' "\t</outputs>\n";
+  Printf.fprintf oc' "</model>\n";
+  close_out oc;
+  close_out oc'
index c524c75..420341e 100644 (file)
@@ -1,31 +1,37 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 (** This module provides functions that generate code for the Scicos target. *)
 
 val generate_code : string -> string -> string -> Optimization.model -> bool
-  -> unit
-(** [generate_code path filename fun_name model jac] generates the code that
-allows the numeric simulation of [model]. [path] is the path to the external
-functions referenced in [model]. [filename] is the name of the file where the
-code is generated. [fun_name] is the name of the entry point in the generated
-code. [jac] is a flag which true value indicates that a symbolic jacobian is
-requested. *)
+  -> bool -> string option * string option -> unit
+(** [generate_code path filename fun_name model jac only_outputs
+     init_filenames]
+generates the
+code that permits the numeric simulation of [model]. [path] is the path to the
+external functions referenced in [model]. [filename] is the name of the file
+where the code is generated. [fun_name] is the name of the entry point in the
+generated code. [jac] is a flag which true value indicates that a symbolic
+jacobian is requested. [only_outputs] indicates that only output variables
+have to be observed (this is the only possibility under Scicos so setting it
+to [false] has no effect on code generation). [init_filenames] gives the
+name of the initialization file so that initialization code is generated. *)
index 1006dcc..883fa16 100644 (file)
@@ -1,25 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
-
-(** Modelicac for Scicos. *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 module Compiler = OptimizingCompiler.Make (ScicosCodeGeneration)
 
index 126f2a5..d6f637e 100644 (file)
@@ -1,24 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
-
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 module type MatrixElement =
     sig
index cc0f0d6..d01501e 100644 (file)
@@ -1,23 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 (** This module implements a sparse representation of square matrices using
 list associations. The retrieval of an element takes O(m) where m is the
index 45ecf82..1eb70d2 100644 (file)
@@ -1,24 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
-
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 open Num
 
@@ -44,7 +44,7 @@ and nature =
   | ArcHyperbolicTangent of t
   | ArcSine of t
   | ArcTangent of t
-  | BlackBox of string * t list
+  | BlackBox of string * argument list
   | BooleanValue of bool
   | Constant of string
   | Cosine of t
@@ -54,10 +54,12 @@ and nature =
   | Exponential of t
   | Floor of t
   | Greater of t * t
+  | GreaterEqual of t * t
   | HyperbolicCosine of t
   | HyperbolicSine of t
   | HyperbolicTangent of t
   | If of t * t * t
+  | Integer of int32
   | Logarithm of t
   | Multiplication of t list
   | Not of t
@@ -65,13 +67,18 @@ and nature =
   | Or of t list
   | Parameter of int
   | PartialDerivative of t * t
+  | Pre of t
   | RationalPower of t * num
   | Sign of t
   | Sine of t
+  | String of string
   | Tangent of t
   | TimeVariable
   | Variable of int
 
+and argument =
+  | ScalarArgument of t
+  | ArrayArgument of int list (* dimensions *) * t array (* flatten array *)
 
 (* Node utilities *)
 
@@ -79,6 +86,31 @@ let nature node = node.nature
 
 let hash node = node.hash
 
+(* Argument utilities *)
+
+let argument_hash = function
+  | ScalarArgument node -> node.hash
+  | ArrayArgument (dims, nodes) ->
+      (Hashtbl.hash dims lxor
+      Array.fold_left
+        (fun acc node -> acc lsl 2 + node.hash)
+        0x32fb7a88
+        nodes) land max_int
+
+(* Array utilities *)
+
+let eq_array nodes nodes' =
+  let l = Array.length nodes in
+  let rec eq_array_from i =
+    i = l || nodes.(i) == nodes'.(i) && eq_array_from (i + 1) in
+  l = Array.length nodes' && eq_array_from 0
+
+let exists_array p xs =
+  let l = Array.length xs in
+  let rec exists_array_from i =
+    i < l && (p xs.(i) || exists_array_from (i + 1)) in
+  exists_array_from 0
+
 (* List utilities *)
 
 let rec eq_list nodes nodes' = match nodes, nodes' with
@@ -224,14 +256,26 @@ let arcTangentNodeSet =
   in NodeSet.create 101 equal hash create
 
 let blackBoxNodeSet =
-  let equal (string, nodeList) node = match node.nature with
-    | BlackBox (name, nodes) -> name = string && eq_list nodeList nodes
+  let rec same_arguments args args' = match args, args' with
+    | [], [] -> true
+    | [], _ :: _ | _ :: _, [] -> false
+    | ScalarArgument node :: args, ScalarArgument node' :: args'
+      when node == node' -> same_arguments args args'
+    | ArrayArgument (dims, nodes) :: args,
+      ArrayArgument (dims', nodes') :: args'
+      when dims = dims' && eq_array nodes nodes' ->
+        same_arguments args args'
+    | _ -> false in
+  let equal (string, argList) node = match node.nature with
+    | BlackBox (name, args) -> name = string && same_arguments argList args
     | _ -> invalid_arg "Argument mismatch."
-  and hash (string, nodes) =
+  and hash (string, args) =
     (GraphNodeSet.hash string +
-    List.fold_left (fun sum elt -> (sum lsl 3) + elt.hash) 0x20a0 nodes) land
-    max_int
-  and create (string, nodes) hash = create_node (BlackBox (string, nodes)) hash
+    List.fold_left
+      (fun sum arg -> (sum lsl 3) + argument_hash arg)
+      0x20a0
+      args) land max_int
+  and create (string, args) hash = create_node (BlackBox (string, args)) hash
   in NodeSet.create 101 equal hash create
 
 let constantNodeSet =
@@ -302,6 +346,17 @@ let greaterNodeSet =
   and create (node1, node2) hash = create_node (Greater (node1, node2)) hash
   in NodeSet.create 101 equal hash create
 
+let greaterEqualNodeSet =
+  let equal (node1, node2) node = match node.nature with
+    | GreaterEqual (leftHandNode, rightHandNode) ->
+        leftHandNode == node1 && rightHandNode == node2
+    | _ -> invalid_arg "Argument mismatch."
+  and hash (node1, node2) =
+    (node1.hash lsl 18) lxor (node2.hash + 0x11e02c02)
+  and create (node1, node2) hash =
+    create_node (GreaterEqual (node1, node2)) hash
+  in NodeSet.create 101 equal hash create
+
 let hyperbolicCosineNodeSet =
   let equal node1 node = match node.nature with
     | HyperbolicCosine node -> node == node1
@@ -339,6 +394,14 @@ let ifNodeSet =
     create_node (If (node1, node2, node3)) hash
   in NodeSet.create 101 equal hash create
 
+let integerNodeSet =
+  let equal i node = match node.nature with
+    | Integer i' -> i' = i
+    | _ -> invalid_arg "Argument mismatch."
+  and hash i = (Hashtbl.hash i lsl 2) lxor 0x11bf004
+  and create i hash = create_node (Integer i) hash
+  in NodeSet.create 101 equal hash create
+
 let logarithmNodeSet =
   let equal node1 node = match node.nature with
     | Logarithm node -> node == node1
@@ -417,6 +480,14 @@ let partialDerivativeNodeSet =
     create_node (PartialDerivative (node1, node2)) hash
   in NodeSet.create 101 equal hash create
 
+let preNodeSet =
+  let equal node1 node = match node.nature with
+    | Pre node -> node == node1
+    | _ -> invalid_arg "Argument mismatch."
+  and hash node1 = (node1.hash lsl 5) lxor 0x100050f0
+  and create node1 hash = create_node (Pre node1) hash
+  in NodeSet.create 101 equal hash create
+
 let rationalPowerNodeSet =
   let equal (node1, num) node = match node.nature with
     | RationalPower (argumentNode, num')  ->
@@ -443,6 +514,14 @@ let sineNodeSet =
   and create node1 hash = create_node (Sine node1) hash
   in NodeSet.create 101 equal hash create
 
+let stringNodeSet =
+  let equal s node = match node.nature with
+    | String s' -> s' = s
+    | _ -> invalid_arg "Argument mismatch."
+  and hash s = (Hashtbl.hash s lsl 6) lxor 0x38a8f002
+  and create s hash = create_node (String s) hash
+  in NodeSet.create 101 equal hash create
+
 let tangentNodeSet =
   let equal node1 node = match node.nature with
     | Tangent node -> node == node1
@@ -537,6 +616,9 @@ let create_floor node =  NodeSet.find_or_add node floorNodeSet
 
 let create_greater node node' = NodeSet.find_or_add (node, node') greaterNodeSet
 
+let create_greater_equal node node' =
+  NodeSet.find_or_add (node, node') greaterEqualNodeSet
+
 let create_hyperbolicCosine node =
   NodeSet.find_or_add node hyperbolicCosineNodeSet
 
@@ -548,6 +630,8 @@ let create_hyperbolicTangent node =
 let create_if node node' node'' =
   NodeSet.find_or_add (node, node', node'') ifNodeSet
 
+let create_integer i = NodeSet.find_or_add i integerNodeSet
+
 let create_logarithm node = NodeSet.find_or_add node logarithmNodeSet
 
 let create_multiplication = function
@@ -572,6 +656,8 @@ let create_parameter i = NodeSet.find_or_add i parameterNodeSet
 let create_partialDerivative node node' =
   NodeSet.find_or_add (node, node') partialDerivativeNodeSet
 
+let create_pre node = NodeSet.find_or_add node preNodeSet
+
 let create_rationalPower node num =
   NodeSet.find_or_add (node, num) rationalPowerNodeSet
 
@@ -579,6 +665,8 @@ let create_sign node = NodeSet.find_or_add node signNodeSet
 
 let create_sine node = NodeSet.find_or_add node sineNodeSet
 
+let create_string s = NodeSet.find_or_add s stringNodeSet
+
 let create_tangent node = NodeSet.find_or_add node tangentNodeSet
 
 let create_timeVariable () = time
@@ -661,8 +749,8 @@ and symbolic_derivative node' =
   and ( / ) = symbolic_div
   and ( ** ) = symbolic_rationalPower
   in match node'.nature with
-    | Number _ | Constant _ | DiscreteVariable _ | Floor _ | Parameter _ |
-      Sign _ -> zero
+    | Integer _ | Number _ | Constant _ | DiscreteVariable _ | Floor _ |
+      Parameter _ | Sign _ | BlackBox (_, []) -> zero
     | BlackBox _ | PartialDerivative _| Variable _ ->
         create_derivative node' one_num
     | Addition nodes ->
@@ -695,13 +783,14 @@ and symbolic_derivative node' =
     | Multiplication (node :: nodes) ->
         let mult = create_multiplication nodes in
         symbolic_derivative node * mult + node * symbolic_derivative mult
+    | Pre node -> create_pre (symbolic_derivative node)
     | RationalPower (node, num) ->
         symbolic_derivative node * create_number num * node ** pred_num num
     | Sine node -> symbolic_derivative node * symbolic_cos node
     | Tangent node -> symbolic_derivative node * (one + node' ** two_num)
     | TimeVariable -> one
-    | And _ | BooleanValue _ | Equality _ | Not _ | Or _ | Greater _ ->
-        invalid_arg "symbolic_derivative"
+    | And _ | BooleanValue _ | Equality _ | Not _ | Or _ | Greater _ |
+      GreaterEqual _ | String _ -> invalid_arg "symbolic_derivative"
 
 and symbolic_div node node' =
   if node' == zero then raise (Infinite_result "Division by zero.")
@@ -719,8 +808,9 @@ and symbolic_exp node =
   else if node == one then e
   else create_exponential node
 
-and symbolic_ge node node' =
-  symbolic_or (symbolic_gt node node') (symbolic_eq node node')
+and symbolic_ge node node' = match node.nature, node'.nature with
+  | Number num, Number num' -> create_booleanValue (ge_num num num')
+  | _ -> create_greater_equal node node'
 
 and symbolic_gt node node' = match node.nature, node'.nature with
   | Number num, Number num' -> create_booleanValue (gt_num num num')
@@ -764,6 +854,7 @@ and symbolic_min node node' = symbolic_if (symbolic_gt node node') node' node
 and symbolic_minus node =
   if node == zero then zero
   else match node.nature with
+    | Integer i -> create_integer (Int32.neg i)
     | Number num -> create_number (minus_num num)
     | Addition nodes ->
         create_addition (
@@ -794,28 +885,14 @@ and symbolic_partial_derivative_with step var node' =
   and ( * ) = symbolic_mult
   and ( / ) = symbolic_div
   and ( ** ) = symbolic_rationalPower in
-  let partial_blackBox_derivatives s args =
-    let dx_of_x x = step * (symbolic_if (symbolic_gt one (symbolic_abs x)) one (symbolic_abs x)) in
-    let rec augmented_arguments_list = function
-      | [] -> []
-      | arg :: args ->
-          (arg + dx_of_x arg :: args) :: List.map (fun aug_args -> arg :: aug_args) (augmented_arguments_list args)
-    and partial_derivatives aug_argss =
-      List.map2
-        (fun aug_args arg -> (create_blackBox s aug_args - create_blackBox s args) / dx_of_x arg)
-        aug_argss
-        args
-    in
-    partial_derivatives (augmented_arguments_list args)
-  in
   let rec partial_derivative node =
     if node == var then one
     else match node.nature with
-      | Number _ | Constant _ | Derivative _ | DiscreteVariable _ | Floor _ |
-        Parameter _ | Sign _ | TimeVariable | Variable _ -> zero
-      | BlackBox (s, nodes) ->
-          let dfs = partial_blackBox_derivatives s nodes in
-          List.fold_left2 (fun acc node df -> acc + partial_derivative node * df) zero nodes dfs
+      | Integer _ | Number _ | Constant _ | Derivative _ | DiscreteVariable _ |
+        Floor _ | Parameter _ | Sign _ | TimeVariable | Variable _ |
+        BlackBox (_, []) -> zero
+      | BlackBox _ ->
+          let node' = replace var (var + step) node in (node' - node) / step
       | PartialDerivative _ ->
           create_partialDerivative var node
       | Addition nodes ->
@@ -838,7 +915,7 @@ and symbolic_partial_derivative_with step var node' =
       | HyperbolicCosine node' -> partial_derivative node' * symbolic_sinh node'
       | HyperbolicSine node' -> partial_derivative node' * symbolic_cosh node'
       | HyperbolicTangent node' ->
-          partial_derivative node' * (one - node' ** two_num)
+          partial_derivative node' * (one - node ** two_num)
       | If (cond, node', node'') ->
           symbolic_if cond (partial_derivative node') (partial_derivative node'')
       | Logarithm node' -> partial_derivative node' / node'
@@ -847,18 +924,25 @@ and symbolic_partial_derivative_with step var node' =
       | Multiplication (node' :: nodes) ->
           let mult = create_multiplication nodes in
           partial_derivative node' * mult + node' * partial_derivative mult
+      | Pre node' -> create_pre (partial_derivative node')
       | RationalPower (node', num) ->
           partial_derivative node' * create_number num * node' ** pred_num num
       | Sine node' -> partial_derivative node' * symbolic_cos node'
       | Tangent node' -> partial_derivative node' * (one + node ** two_num)
-      | And _ | BooleanValue _ | Equality _ | Not _ | Or _ | Greater _ ->
+      | And _ | BooleanValue _ | Equality _ | Not _ | Or _ | Greater _ |
+        GreaterEqual _ | String _ ->
           invalid_arg "partial_derivative : Invalid argument."
   in partial_derivative node'
 
 and symbolic_power node node' = match node'.nature with
+  | Integer i -> symbolic_rationalPower node (num_of_int (Int32.to_int i))
   | Number num' -> symbolic_rationalPower node num'
   | _ -> create_exponential (symbolic_mult node' (symbolic_log node))
 
+and symbolic_pre node = match node.nature with
+  | Number _ -> node
+  | _ -> create_pre node
+
 and symbolic_rationalPower node num' =
   if node == zero && num' = zero_num then
     raise (Infinite_result "Zero raised to zero.")
@@ -1100,17 +1184,20 @@ and output out_channel node =
   let mult_precedence = 50 in
   let rec precedence node = match node.nature with
     | Addition [] | And [] | BooleanValue _ | Constant _ | DiscreteVariable _ |
-      Multiplication [] | Or [] | Parameter _ | TimeVariable | Variable _ ->
+      Multiplication [] | Or [] | Parameter _ | TimeVariable | Variable _ |
+      String _ ->
         1000
     | ArcCosine _ | ArcHyperbolicCosine _ | ArcHyperbolicSine _ |
       ArcHyperbolicTangent _ | ArcSine _ | ArcTangent _ | BlackBox _ |
       Cosine _ | Derivative _ | Exponential _ | Floor _ | HyperbolicCosine _ |
       HyperbolicSine _ | HyperbolicTangent _ | If _ | Logarithm _ | Not _ |
-      PartialDerivative _ | Sign _ | Sine _| Tangent _ -> 10000
+      PartialDerivative _ | Pre _ | Sign _ | Sine _| Tangent _ -> 10000
     | Addition _ -> 10
     | And _ -> 5
     | Equality _ -> 3
     | Multiplication _ -> mult_precedence
+    | Integer i when i < 0l -> 75
+    | Integer _ -> 1000
     | Number (Ratio _) -> mult_precedence
     | Number num when lt_num num zero_num -> 75
     | Number (Int _) | Number (Big_int _)  -> 1000
@@ -1118,6 +1205,7 @@ and output out_channel node =
     | RationalPower (_, num) when lt_num num zero_num -> mult_precedence
     | RationalPower _ -> 100
     | Greater _ -> 9
+    | GreaterEqual _ -> 9
   and output'' node = match node.nature with
     | Addition [] -> output_char' '0'
     | Addition nodes' ->
@@ -1170,11 +1258,9 @@ and output out_channel node =
         output_string' "atanh"; output' (precedence node) node'
     | ArcSine node' -> output_string' "asin"; output' (precedence node) node'
     | ArcTangent node' -> output_string' "atan"; output' (precedence node) node'
-    | BlackBox (name, node' :: nodes') ->
-      output_string' name; output_char' '('; output' 0 node';
-      List.iter (fun elt -> output_string' ", "; output' 0 elt) nodes';
-      output_char' ')'
-    | BlackBox _ -> invalid_arg "Invalid black box node"
+    | BlackBox (name, args) ->
+        output_string' name;
+        output_char' '('; output_arguments args; output_char' ')'
     | BooleanValue b -> output_string' (if b then "true" else "false")
     | Constant s -> output_string' s
     | Cosine node' -> output_string' "cos"; output' (precedence node) node'
@@ -1254,7 +1340,12 @@ and output out_channel node =
             output_char' ')'
       end
     | Not node' -> output_string' "not"; output' (precedence node) node'
-    | Number num -> output_string' (string_of_num num)
+    | Integer i -> output_string' (Printf.sprintf "%ld" i)
+    | Number num ->
+        let s = string_of_float (float_of_num num) in
+        if String.contains s '.' then output_string' s
+        else output_string' (s ^ ".")
+    | String s ->  output_string' (Printf.sprintf "\"%s\"" s)
     | Or [] -> output_string' "false"
     | Or (node' :: nodes') ->
         output' (precedence node) node';
@@ -1266,6 +1357,7 @@ and output out_channel node =
     | PartialDerivative (node', node'') ->
         output_string' "pder("; output' 0 node'';
         output_string' ", "; output' 0 node'; output_char' ')'
+    | Pre node' -> output_string' "pre"; output' (precedence node) node'
     | RationalPower (node', num) when ge_num num zero_num ->
         output' (precedence node) node'; output_string' " ^ ";
         begin match num with
@@ -1290,6 +1382,9 @@ and output out_channel node =
     | Greater (node', node'') ->
         output' (precedence node) node'; output_string' " > ";
         output' (precedence node) node''
+    | GreaterEqual (node', node'') ->
+        output' (precedence node) node'; output_string' " >= ";
+        output' (precedence node) node''
     | Tangent node' -> output_string' "tan"; output' (precedence node) node'
     | TimeVariable -> output_string' "time"
     | Variable i -> output_string' "variable("; output_int' i; output_char' ')'
@@ -1300,56 +1395,152 @@ and output out_channel node =
     if precedence node <= prec then begin
       output_string' "(";  output'' node; output_string' ")"
     end else output'' node
-  in output' 0 node
+  and output_arguments args =
+    let rec output_arguments' = function
+      | [] -> ()
+      | [arg] -> output_argument arg
+      | arg :: args ->
+          output_argument arg; output_string' ", "; output_arguments' args in
+    output_char' '('; output_arguments' args; output_char' ')'
+  and output_argument arg =
+    match arg with
+    | ScalarArgument node -> output' 0 node
+    | ArrayArgument (dims, nodes) -> output_array_argument dims nodes
+  and output_array_argument dims nodes =
+    let rec repeat n printf i =
+      if n = 0 then i
+      else if n = 1 then printf i
+      else
+        let i = printf i in
+        output_string' ", ";
+        repeat (n - 1) printf i in
+    let rec output_array_argument' dim dims i = match dims with
+      | [] -> repeat dim (fun i -> output' 0 nodes.(i); i + 1) i
+      | dim' :: dims ->
+          repeat
+            dim
+            (fun i ->
+              output_char' '{';
+              let i = output_array_argument' dim' dims i in
+              output_char' '}'; i)
+            i in
+    match dims with
+    | [] -> assert false
+    | dim :: dims ->
+        output_char' '{';
+        let _ = output_array_argument' dim dims 0 in ();
+        output_char' '}' in
+  output' 0 node
 
 
 (* Symbolic manipulation helpers *)
 
 and exists p node =
+  let exists_in_argument = function
+    | ScalarArgument node -> exists p node
+    | ArrayArgument (_, nodes) -> exists_array p nodes in
   p node || match node.nature with
     | BooleanValue _  | Constant _ | DiscreteVariable _ | Number _ |
-      Parameter _ | TimeVariable | Variable _ -> false
+      Parameter _ | TimeVariable | Variable _ | Integer _ | String _ -> false
     | ArcCosine node | ArcHyperbolicCosine node |
       ArcHyperbolicSine node | ArcHyperbolicTangent node | ArcSine node |
       ArcTangent node | Cosine node | Derivative (node, _) |
       Exponential node | Floor node | HyperbolicCosine node |
       HyperbolicSine node | HyperbolicTangent node | Logarithm node |
-      Not node | RationalPower (node, _) | Sign node | Sine node |
+      Not node | Pre node | RationalPower (node, _) | Sign node | Sine node |
       Tangent node -> exists p node
     | Equality (node1, node2) | Greater (node1, node2) |
-      PartialDerivative (node1, node2) -> exists p node1 || exists p node2
+      GreaterEqual (node1, node2) | PartialDerivative (node1, node2) ->
+        exists p node1 || exists p node2
     | If (node1, node2, node3) ->
         exists p node1 || exists p node2 || exists p node3
-    | And nodes | Addition nodes | BlackBox (_, nodes) | Multiplication nodes |
-      Or nodes -> List.exists (exists p) nodes
+    | And nodes | Addition nodes | Multiplication nodes | Or nodes ->
+        List.exists (exists p) nodes
+    | BlackBox (_, args) -> List.exists exists_in_argument args
 
 and is_subnode_of node node' = exists (fun node -> node == node') node
 
-and variables_of node = match node.nature with
+and assignable_parameters_of node =
+  let assignable_parameters_of_argument = function
+    | ScalarArgument node -> assignable_parameters_of node
+    | ArrayArgument (_, nodes) ->
+        Array.fold_left
+          (fun acc node -> union (assignable_parameters_of node) acc)
+          []
+          nodes in
+  match node.nature with
+  | BooleanValue _  | Constant _ | DiscreteVariable _ | Number _ | Pre _ |
+    Variable _ | TimeVariable | Integer _ | String _ -> []
+  | Parameter _ -> [node]
+  | ArcCosine node | ArcHyperbolicCosine node |
+    ArcHyperbolicSine node | ArcHyperbolicTangent node | ArcSine node |
+    ArcTangent node | Cosine node | Derivative (node, _) |
+    Exponential node | Floor node | HyperbolicCosine node |
+    HyperbolicSine node | HyperbolicTangent node | Logarithm node |
+    Not node | RationalPower (node, _) | Sign node | Sine node |
+    Tangent node -> assignable_parameters_of node
+  | Equality (node1, node2) | Greater (node1, node2) |
+    GreaterEqual (node1, node2) | PartialDerivative (node1, node2) |
+    If (_, node1, node2) ->
+      union
+        (assignable_parameters_of node1)
+        (assignable_parameters_of node2)
+  | And nodes | Addition nodes | Multiplication nodes | Or nodes ->
+      List.fold_left
+        (fun acc node -> union (assignable_parameters_of node) acc)
+        []
+        nodes
+  | BlackBox (_, args) ->
+      List.fold_left
+        (fun acc arg -> union (assignable_parameters_of_argument arg) acc)
+        []
+        args
+
+and variables_of node =
+  let variables_of_argument = function
+    | ScalarArgument node -> variables_of node
+    | ArrayArgument (_, nodes) ->
+        Array.fold_left
+          (fun acc node -> union (variables_of node) acc)
+          []
+          nodes in
+  match node.nature with
   | BooleanValue _  | Constant _ | DiscreteVariable _ | Number _ | Parameter _ |
-    TimeVariable -> []
+    TimeVariable | Integer _ | String _ -> []
   | Variable _ -> [node]
   | ArcCosine node | ArcHyperbolicCosine node |
     ArcHyperbolicSine node | ArcHyperbolicTangent node | ArcSine node |
     ArcTangent node | Cosine node | Derivative (node, _) |
     Exponential node | Floor node | HyperbolicCosine node |
     HyperbolicSine node | HyperbolicTangent node | Logarithm node |
-    Not node | RationalPower (node, _) | Sign node | Sine node |
+    Not node | Pre node | RationalPower (node, _) | Sign node | Sine node |
     Tangent node -> variables_of node
   | Equality (node1, node2) | Greater (node1, node2) |
-    PartialDerivative (node1, node2) ->
+    GreaterEqual (node1, node2) | PartialDerivative (node1, node2) ->
       union (variables_of node1) (variables_of node2)
   | If (node1, node2, node3) ->
       union
         (variables_of node1)
         (union (variables_of node2) (variables_of node3))
-  | And nodes | Addition nodes | BlackBox (_, nodes) | Multiplication nodes |
-    Or nodes ->
+  | And nodes | Addition nodes | Multiplication nodes | Or nodes ->
       List.fold_left (fun acc node -> union (variables_of node) acc) [] nodes
+  | BlackBox (_, args) ->
+      List.fold_left
+        (fun acc arg -> union (variables_of_argument arg) acc)
+        []
+        args
 
-and assignable_variables_of node = match node.nature with
+and assignable_variables_of node =
+  let assignable_variables_of_argument = function
+    | ScalarArgument node -> assignable_variables_of node
+    | ArrayArgument (_, nodes) ->
+        Array.fold_left
+          (fun acc node -> union (assignable_variables_of node) acc)
+          []
+          nodes in
+  match node.nature with
   | BooleanValue _  | Constant _ | DiscreteVariable _ | Number _ | Parameter _ |
-    TimeVariable -> []
+    Pre _ | TimeVariable | Integer _ | String _ -> []
   | Variable _ -> [node]
   | ArcCosine node | ArcHyperbolicCosine node |
     ArcHyperbolicSine node | ArcHyperbolicTangent node | ArcSine node |
@@ -1359,35 +1550,88 @@ and assignable_variables_of node = match node.nature with
     RationalPower (node, _) | Sign node | Sine node | Tangent node ->
       assignable_variables_of node
   | Equality (node1, node2) | Greater (node1, node2) |
-    PartialDerivative (node1, node2) ->
+    GreaterEqual (node1, node2) | PartialDerivative (node1, node2) ->
       union (assignable_variables_of node1) (assignable_variables_of node2)
   | If (_, node1, node2) ->
       union (* intersection is too pessimistic (since v.1.1.4. *)
         (assignable_variables_of node1)
         (assignable_variables_of node2)
-  | Addition nodes | BlackBox (_, nodes) | Multiplication nodes ->
+  | Addition nodes | Multiplication nodes ->
       List.fold_left
         (fun acc node -> union (assignable_variables_of node) acc)
         []
         nodes
+  | BlackBox (_, args) ->
+      List.fold_left
+        (fun acc arg -> union (assignable_variables_of_argument arg) acc)
+        []
+        args
   | And _ | Or _ | Not _ -> []
 
-and derivatives_of node = match node.nature with
+and derivatives_of node =
+  let derivatives_of_argument = function
+    | ScalarArgument node -> derivatives_of node
+    | ArrayArgument (_, nodes) ->
+        Array.fold_left
+          (fun acc node -> union (derivatives_of node) acc)
+          []
+          nodes in
+  match node.nature with
   | BooleanValue _  | Constant _ | DiscreteVariable _ | Number _ | Parameter _ |
-    TimeVariable | Variable _ -> []
+    TimeVariable | Variable _ | Integer _ | String _ -> []
   | ArcCosine node' | ArcHyperbolicCosine node' |
     ArcHyperbolicSine node' | ArcHyperbolicTangent node' | ArcSine node' |
     ArcTangent node' | Cosine node' | Exponential node' | Floor node' |
     HyperbolicCosine node' | HyperbolicSine node' | HyperbolicTangent node' |
-    Logarithm node' | Not node' | RationalPower (node', _) | Sign node' |
-    Sine node' | Tangent node' -> derivatives_of node'
+    Logarithm node' | Not node' | Pre node' | RationalPower (node', _) |
+    Sign node' | Sine node' | Tangent node' -> derivatives_of node'
   | Derivative _ -> [node]
-  | Equality (node1, node2) | Greater (node1, node2) | If (_, node1, node2) |
+  | Equality (node1, node2) | Greater (node1, node2) |
+    GreaterEqual (node1, node2) | If (_, node1, node2) |
     PartialDerivative (node1, node2) ->
       union (derivatives_of node1) (derivatives_of node2)
-  | And nodes | Addition nodes | BlackBox (_, nodes) | Multiplication nodes |
-    Or nodes ->
+  | And nodes | Addition nodes | Multiplication nodes | Or nodes ->
       List.fold_left (fun acc node -> union (derivatives_of node) acc) [] nodes
+  | BlackBox (_, args) ->
+      List.fold_left
+        (fun acc arg -> union (derivatives_of_argument arg) acc)
+        []
+        args
+
+and inputs_of node =
+  let inputs_of_argument = function
+    | ScalarArgument node -> inputs_of node
+    | ArrayArgument (_, nodes) ->
+        Array.fold_left
+          (fun acc node -> union (inputs_of node) acc)
+          []
+          nodes in
+  match node.nature with
+  | BooleanValue _  | Constant _ | Variable _ | Number _ | Parameter _ |
+    TimeVariable | Integer _ | String _ -> []
+  | DiscreteVariable i when i < 0 -> [node]
+  | DiscreteVariable _ -> []
+  | ArcCosine node | ArcHyperbolicCosine node |
+    ArcHyperbolicSine node | ArcHyperbolicTangent node | ArcSine node |
+    ArcTangent node | Cosine node | Derivative (node, _) |
+    Exponential node | Floor node | HyperbolicCosine node |
+    HyperbolicSine node | HyperbolicTangent node | Logarithm node |
+    Not node | Pre node | RationalPower (node, _) | Sign node | Sine node |
+    Tangent node -> inputs_of node
+  | Equality (node1, node2) | Greater (node1, node2) |
+    GreaterEqual (node1, node2) | PartialDerivative (node1, node2) ->
+      union (inputs_of node1) (inputs_of node2)
+  | If (node1, node2, node3) ->
+      union
+        (inputs_of node1)
+        (union (inputs_of node2) (inputs_of node3))
+  | And nodes | Addition nodes | Multiplication nodes | Or nodes ->
+      List.fold_left (fun acc node -> union (inputs_of node) acc) [] nodes
+  | BlackBox (_, args) ->
+      List.fold_left
+        (fun acc arg -> union (inputs_of_argument arg) acc)
+        []
+        args
 
 and invert_if_possible_with_respect_to node left right =
   let not_null node = match node.nature with
@@ -1409,7 +1653,7 @@ and invert_if_possible_with_respect_to node left right =
   if node == left then Some right
   else match left.nature with
     | BlackBox _ | Cosine _ | Derivative _ | Floor _ | HyperbolicCosine _ |
-      PartialDerivative _ | Sign _ | Sine _ | Tangent _ -> None
+      PartialDerivative _ | Pre _ | Sign _ | Sine _ | Tangent _ -> None
     | Addition nodes ->
         begin match invert_addition_if_possible nodes with
           | None -> None
@@ -1456,30 +1700,37 @@ and invert_if_possible_with_respect_to node left right =
         invert_if_possible_with_respect_to
           node
           node'
-          (symbolic_rationalPower right (minus_num num))
+          (symbolic_rationalPower right (one_num // num))
     | RationalPower _ -> None
     | And _ | Constant _ | BooleanValue _ | Equality _ | Greater _ |
-      DiscreteVariable _ | Not _ | Number _ | Or _ | Parameter _ |
-      TimeVariable | Variable _ ->
+      GreaterEqual _ | DiscreteVariable _ | Not _ | Number _ | Or _ |
+      Parameter _ | TimeVariable | Variable _ | Integer _ | String _ ->
         invalid_arg "invert_if_possible_with_respect_to"
 
 and exists_except_in_conditions p node =
+  let exists_except_in_conditions_argument = function
+    | ScalarArgument node -> exists_except_in_conditions p node
+    | ArrayArgument (_, nodes) ->
+        exists_array (exists_except_in_conditions p) nodes in
   p node || match node.nature with
     | BooleanValue _  | Constant _ | DiscreteVariable _ | Number _ |
-      Parameter _ | TimeVariable | Variable _ -> false
+      Parameter _ | TimeVariable | Variable _ | Integer _ | String _ -> false
     | ArcCosine node | ArcHyperbolicCosine node |
       ArcHyperbolicSine node | ArcHyperbolicTangent node | ArcSine node |
       ArcTangent node | Cosine node | Derivative (node, _) |
       Exponential node | Floor node | HyperbolicCosine node |
       HyperbolicSine node | HyperbolicTangent node | Logarithm node |
-      Not node | RationalPower (node, _) | Sign node | Sine node |
+      Not node | Pre node | RationalPower (node, _) | Sign node | Sine node |
       Tangent node -> exists_except_in_conditions p node
-    | Equality (node1, node2) | Greater (node1, node2) | If (_, node1, node2) |
+    | Equality (node1, node2) | Greater (node1, node2) |
+      GreaterEqual (node1, node2) | If (_, node1, node2) |
       PartialDerivative (node1, node2) ->
         exists_except_in_conditions p node1 ||
         exists_except_in_conditions p node2
-    | And nodes | Addition nodes | BlackBox (_, nodes) | Multiplication nodes |
-      Or nodes -> List.exists (exists_except_in_conditions p) nodes
+    | And nodes | Addition nodes | Multiplication nodes | Or nodes ->
+        List.exists (exists_except_in_conditions p) nodes
+    | BlackBox (_, args) ->
+        List.exists exists_except_in_conditions_argument args
 
 and inversion_difficulty node left right =
   let is_derivative_of_node node' = match node'.nature with
@@ -1498,7 +1749,11 @@ and inversion_difficulty node left right =
     | _ -> 2
 
 and replace node node' node'' =
-  let rec rewrite node'' =
+  let rec rewrite_argument = function
+    | ScalarArgument node -> ScalarArgument (rewrite node)
+    | ArrayArgument (dims, nodes) ->
+        ArrayArgument (dims, Array.map rewrite nodes)
+  and rewrite node'' =
     if node'' == node then node'
     else match node''.nature with
     | Addition nodes -> apply_addition (List.map rewrite nodes)
@@ -1509,13 +1764,14 @@ and replace node node' node'' =
     | ArcHyperbolicTangent node -> symbolic_atanh (rewrite node)
     | ArcSine node -> symbolic_asin (rewrite node)
     | ArcTangent node -> symbolic_atan (rewrite node)
-    | BlackBox (s, nodes) -> apply_blackBox s (List.map rewrite nodes)
+    | BlackBox (s, args) -> apply_blackBox s (List.map rewrite_argument args)
     | Cosine node -> symbolic_cos (rewrite node)
     | Derivative (node, num) -> symbolic_derive (rewrite node) num
     | Equality (node, node') -> symbolic_eq (rewrite node) (rewrite node')
     | Exponential node -> symbolic_exp (rewrite node)
     | Floor node -> symbolic_floor (rewrite node)
     | Greater (node, node') -> symbolic_gt (rewrite node) (rewrite node')
+    | GreaterEqual (node, node') -> symbolic_ge (rewrite node) (rewrite node')
     | HyperbolicCosine node -> symbolic_cosh (rewrite node)
     | HyperbolicSine node -> symbolic_sinh (rewrite node)
     | HyperbolicTangent node -> symbolic_tanh (rewrite node)
@@ -1527,63 +1783,12 @@ and replace node node' node'' =
     | Or nodes -> apply_or (List.map rewrite nodes)
     | PartialDerivative (node, node') ->
         create_partialDerivative (rewrite node) (rewrite node')
+    | Pre node -> symbolic_pre (rewrite node)
     | RationalPower (node, num) -> symbolic_rationalPower (rewrite node) num
     | Sign node -> symbolic_sgn (rewrite node)
     | Sine node -> symbolic_sin (rewrite node)
     | Tangent node -> symbolic_tan (rewrite node)
     | BooleanValue _ | Constant _ | DiscreteVariable _ | Number _ |
-      Parameter _ | TimeVariable | Variable _ -> node''
+      Parameter _ | TimeVariable | Variable _ | Integer _ | String _ -> node''
   in
   rewrite node''
-
-(*and replace node node' node'' =
-  let rec rewrite node =
-    if node.count = !global_count then
-      node.replacement
-    else
-      let node' = replace' node in
-      node.count <- !global_count;
-      node.replacement <- node';
-      node'
-  and replace' node = match node.nature with
-    | Addition nodes -> apply_addition (List.map rewrite nodes)
-    | And nodes -> apply_and (List.map rewrite nodes)
-    | ArcCosine node -> symbolic_acos (rewrite node)
-    | ArcHyperbolicCosine node -> symbolic_acosh (rewrite node)
-    | ArcHyperbolicSine node -> symbolic_asinh (rewrite node)
-    | ArcHyperbolicTangent node -> symbolic_atanh (rewrite node)
-    | ArcSine node -> symbolic_asin (rewrite node)
-    | ArcTangent node -> symbolic_atan (rewrite node)
-    | BlackBox (s, nodes) -> apply_blackBox s (List.map rewrite nodes)
-    | Cosine node -> symbolic_cos (rewrite node)
-    | Derivative (node, num) -> symbolic_derive (rewrite node) num
-    | Equality (node, node') -> symbolic_eq (rewrite node) (rewrite node')
-    | Exponential node -> symbolic_exp (rewrite node)
-    | Floor node -> symbolic_floor (rewrite node)
-    | Greater (node, node') -> symbolic_gt (rewrite node) (rewrite node')
-    | HyperbolicCosine node -> symbolic_cosh (rewrite node)
-    | HyperbolicSine node -> symbolic_sinh (rewrite node)
-    | HyperbolicTangent node -> symbolic_tanh (rewrite node)
-    | If (node, node', node'') ->
-        symbolic_if (rewrite node) (rewrite node') (rewrite node'')
-    | Logarithm node -> symbolic_log (rewrite node)
-    | Multiplication nodes -> apply_multiplication (List.map rewrite nodes)
-    | Not node -> symbolic_not (rewrite node)
-    | Or nodes -> apply_or (List.map rewrite nodes)
-    | PartialDerivative (node, node') ->
-        create_partialDerivative (rewrite node) (rewrite node')
-    | RationalPower (node, num) -> symbolic_rationalPower (rewrite node) num
-    | Sign node -> symbolic_sgn (rewrite node)
-    | Sine node -> symbolic_sin (rewrite node)
-    | Tangent node -> symbolic_tan (rewrite node)
-    | BooleanValue _ | Constant _ | DiscreteVariable _ | Number _ |
-      Parameter _ | TimeVariable | Variable _ -> node.replacement
-  in
-  incr global_count;
-  assert (!global_count <> 0);
-  node.count <- !global_count;
-  node.replacement <- node';
-  let rewritten_node = rewrite node'' in
-  node.replacement <- node;
-  rewritten_node
-*)
index 87cfe29..8116dd8 100644 (file)
@@ -1,23 +1,24 @@
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
+(*
+ *  Modelicac
+ *
+ *  Copyright (C) 2005 - 2007 Imagine S.A.
+ *  For more information or commercial use please contact us at www.amesim.com
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *)
 
 (** This module provides the data structures and functions that are necessary
 to perform the symbolic manipulations involved in the transformation of Modelica
@@ -41,7 +42,7 @@ type nature =
     | ArcHyperbolicTangent of t
     | ArcSine of t
     | ArcTangent of t
-    | BlackBox of string * t list (* BlackBox (name, expressions) *)
+    | BlackBox of string * argument list
     | BooleanValue of bool
     | Constant of string
     | Cosine of t
@@ -51,10 +52,12 @@ type nature =
     | Exponential of t
     | Floor of t
     | Greater of t * t
+    | GreaterEqual of t * t
     | HyperbolicCosine of t
     | HyperbolicSine of t
     | HyperbolicTangent of t
     | If of t * t * t
+    | Integer of int32
     | Logarithm of t
     | Multiplication of t list
     | Not of t
@@ -62,14 +65,20 @@ type nature =
     | Or of t list
     | Parameter of int
     | PartialDerivative of t * t (* PartialDerivative (variable, expression) *)
+    | Pre of t
     | RationalPower of t * num
     | Sign of t
     | Sine of t
+    | String of string
     | Tangent of t
     | TimeVariable
     | Variable of int
 (** The type of the nature of an expression. *)
 
+and argument =
+  | ScalarArgument of t
+  | ArrayArgument of int list (* dimensions *) * t array (* flatten array *)
+(** The type of the arguments of functions. *)
 
 (* Node utilities *)
 
@@ -180,9 +189,9 @@ val create_arcTangent: t -> t
 (** [create_arcTangent expr] returns an object representing the arc tangent of
 the expression represented by [expr]. *)
 
-val create_blackBox: string -> t list -> t
-(** [create_blackBox name exprs] returns an object representing a black box
-function application expression. [name] is the name of the function and [exprs]
+val create_blackBox: string -> argument list -> t
+(** [create_blackBox name args] returns an object representing a black box
+function application expression. [name] is the name of the function and [args]
 is the list of the object representing the arguments of the function. *)
 
 val create_booleanValue: bool -> t
@@ -222,6 +231,11 @@ val create_greater: t -> t -> t
 'greater than' relation involving the expressions represented by [expr] and
 [expr'] in that order. *)
 
+val create_greater_equal: t -> t -> t
+(** [create_greater_equal expr expr'] returns an object representing the
+'greater than' relation involving the expressions represented by [expr] and
+[expr'] in that order. *)
+
 val create_hyperbolicCosine: t -> t
 (** [create_hyperbolicCosine expr] returns an object representing the hyperbolic
 cosine of the expression represented by [expr]. *)
@@ -240,8 +254,11 @@ condition is the expression represented by [expr] and first alternative the
 expression represented by [expr'] and second alternative the expression
 represented by [expr'']. *)
 
+val create_integer: int32 -> t
+(** [create_integer i] returns an object representing the integer [i]. *)
+
 val create_logarithm: t -> t
-(** [create_integerPart expr] returns an object representing the logarithm of the
+(** [create_logarithm expr] returns an object representing the logarithm of the
 expression represented by [expr]. *)
 
 val create_multiplication: t list -> t
@@ -271,6 +288,10 @@ partial derivative of the expression represented by [expr'] with respect to the
 variable represented by [expr]. If [expr] does not represent a variable,
 Invalid_argument is raised. *)
 
+val create_pre: t -> t
+(** [create_pre expr] returns an object representing the 'previous value' of
+the expression represented by [expr]. *)
+
 val create_rationalPower: t -> num -> t
 (** [create_rationalPower expr num] returns an object representing the expression
 represented by [expr] raised to the power of the rational number represented by
@@ -285,6 +306,9 @@ val create_sine: t -> t
 (** [create_sine expr] returns an object representing the sine of the expression
 represented by [expr]. *)
 
+val create_string: string -> t
+(** [create_string s] returns an object representing the string [s]. *)
+
 val create_tangent: t -> t
 (** [create_tangent expr] returns an object representing the tangent of the
 expression represented by [expr]. *)
@@ -340,10 +364,10 @@ val symbolic_atanh: t -> t
 (** [symbolic_abs expr] returns an object that represents the result of applying
 the hyperbolic arc tangent function to the expression represented by [expr]. *)
 
-val symbolic_blackBox: string -> t list -> t
-(** [symbolic_blackBox name exprs] returns an object that represents the
+val symbolic_blackBox: string -> argument list -> t
+(** [symbolic_blackBox name args] returns an object that represents the
 result of applying the black box function named [name] to the expressions
-represented by the objects of the list [exprs]. *)
+represented by the objects of the list [args]. *)
 
 val symbolic_cos: t -> t
 (** [symbolic_cos expr] returns an object that represents the result of applying
@@ -476,6 +500,10 @@ raising the expression represented by [expr] to the power of the expression
 represented by [expr']. Raise Infinite_result if both [expr] and [num] represent
 zero.*)
 
+val symbolic_pre: t -> t
+(** [symbolic_pre expr] returns an object that represents the result of
+applying the 'pre' operator to the expression represented by [expr]. *)
+
 val symbolic_rationalPower: t -> num -> t
 (** [symbolic_rationalPower expr num] returns an object that represents the
 result of raising the expression represented by [expr] to the power of the
@@ -526,10 +554,10 @@ val apply_and: t list -> t
 the 'and' function to the expressions represented by the objects in the list
 [exprs]. *)
 
-val apply_blackBox: string -> t list -> t
-(** [apply_blackBox name exprs] returns an object that represents the result
+val apply_blackBox: string -> argument list -> t
+(** [apply_blackBox name args] returns an object that represents the result
 of applying the black box function named [name] to the expressions represented
-by the objects in the list [exprs]. *)
+by the objects in the list [args]. *)
 
 val apply_max: t list -> t
 (** [apply_max exprs] returns an object that represents the result of applying
@@ -565,6 +593,11 @@ val is_subnode_of: t -> t -> bool
 (** [is_subnode_of node node'] returns [true] if [node'] appears as a subnode
 in the internal representation of [node] viewed as a tree. *)
 
+val assignable_parameters_of: t -> t list
+(** [assignable_parameters_of node] returns the parameters that, considered as
+variables, might be selected by the Hungarian method applied to [node] as a
+list of symbolic expressions. *)
+
 val variables_of: t -> t list
 (** [variables_of node] returns the variables that appear in [node] as a list of
 symbolic expressions. *)
@@ -577,6 +610,10 @@ val derivatives_of: t -> t list
 (** [derivatives_of node] returns the derivatives that appear in [node] as a list
 of symbolic expressions. *)
 
+val inputs_of: t -> t list
+(** [inputs_of node] returns the inputs that appear in [node] as a list of
+symbolic expressions. *)
+
 val invert_if_possible_with_respect_to: t -> t -> t -> t option
 (** [invert_if_possible_with_respect_to node left right] returns [Some node'] if
 a way to rewrite the equation [left] = [right] as [node] = ... by applying
old mode 100755 (executable)
new mode 100644 (file)
index d32fff2..68eee80
-
-(*  Scicos *)
-(* *)
-(*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr> *)
-(* *)
-(* This program is free software; you can redistribute it and/or modify *)
-(* it under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation; either version 2 of the License, or *)
-(* (at your option) any later version. *)
-(* *)
-(* This program is distributed in the hope that it will be useful, *)
-(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
-(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *)
-(* GNU General Public License for more details. *)
-(* *) 
-(* You should have received a copy of the GNU General Public License *)
-(* along with this program; if not, write to the Free Software *)
-(* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *)
-(*  *)
-(* See the file ./license.txt *)
-
-
-type 'a tree = Leaf of (string * 'a) | Node of string * 'a tree list
-
-let rec insert path x ts =
-  let rec insert' s path' = function
-    | [] -> [Node (s, insert path' x [])]
-    | Node (s', ts'') :: ts' when s = s' -> Node (s', insert path' x ts'') :: ts'
-    | t' :: ts' -> t' :: insert' s path' ts'
-  in match path with
-    | [s] -> Leaf (s, x) :: ts
-    | s :: path' -> insert' s path' ts
-    | [] -> assert false
-
-let cut_on_dot s =
-  let rec cut_on_dot' i =
-    if i = String.length s then s, None
-      else if s.[i] = '.' then String.sub s 0 i, Some (String.sub s (i + 1) (String.length s - i - 1))
-      else cut_on_dot' (i + 1)
-  in cut_on_dot' 0
-
-let rec split name =
-  let s, name_opt = cut_on_dot name in
-  match name_opt with
-    | None -> [s]
-    | Some name' -> s :: split name'
-
-type element =
-  {
-    kind: element_kind;
-    id: string;
-    comment: string;
-    initial_value: SymbolicExpression.t option;
-    output: bool
-  }
-
-and element_kind =
-  | Input
-  | Parameter
-  | Variable
-  | DiscreteVariable
-
-let build_tree model =
-  let bool_of_option = function
-    | None -> false
-    | Some _ -> true
-  in
-  let (_, ts) =
-    Array.fold_left
-      (fun (i, ts) s ->
-        i + 1,
-        insert
-          (split s) 
-          {
-            kind = Input;
-            id = s;
-            comment = "";
-            initial_value = Some SymbolicExpression.zero;
-            output = false
-          }
-          ts)
-      (0, [])
-      model.Optimization.inputs in
-  let (_, ts) =
-    Array.fold_left
-      (fun (i, ts) par ->
-        i + 1,
-        insert
-          (split par.Optimization.p_name)
-          {
-            kind = Parameter;
-            id = par.Optimization.p_name;
-            comment = par.Optimization.p_comment;
-            initial_value = Some par.Optimization.value;
-            output = false
-          }
-          ts)
-      (0, ts)
-      model.Optimization.parameters in
-  let (_, ts) =
-    Array.fold_left
-      (fun (i, ts) v