Middelhoek.com

ModelCompiler

In college, I build a graphical calculator in BASIC on the original Apple ][. Formulas that were entered as a string would be directed through the interpreter and executed. At some point I wanted to port the calculator to Pascal, another forgotten language. Since Pascal is compiled I had to find a different solution for evaluating the equations, preferably a compile-once, use-often method.

The strategy I chose was to convert the formula to Reverse Polish Notation, an old classic. The evaluator was written in assembly and used the processor stack for speed. Then when ParX needed a model compiler I revisited this design.

The parser and the basic data structure for the parse tree were sound, and could be extended to handle the more general case needed for ParX: multiple equations, intermediate variables and conditional evaluation.

Then it was time for the pièce de résistance: analytical first-order derivatives. Most optimization and root-finding algorithms gain speed and reliability when derivatives are made available, and ParX is no exception. Mathematical analysis provides the rules for determining the derivatives for all operators and special functions. So all we have to do is build parallel parse trees for each derivative, and prune the results to eliminate superfluous operations. It sounds straightforward, but it is still a lot of code.

The ModelCompiler was originally developed as a stand-alone application that could feed several other design tools.

In 2016, the ModelCompiler was ported from C99 to Objective-C, and integrated in ParX. In the transition it gained a number of long desired features: full Unicode support, a wider range of variable names, special numbers and physical constants, and unit-strings for the variables and parameters.

The old C99 version of the ModelCompiler is now open source software under the GPLv3 licence. The source code can be found on GitHub as part of the ParXCL project, the command line version of ParX.

The ModelCompiler is now encapsulated in a library as a portable SPM package.

Model Specification Language

The models are described in a text file that specifies its interface variables, parameters and equations between them, in a flexible format. For the details of the specification language visit: Model Specification Language.

As an example: the model for a MOS transistor as proposed by Shichman and Hodges.


                                    
                                        

ModelCompiler API

The ModelCompiler Class initializer reads from a model-definition file, which has usually the file extension .parx. Parsing errors are returned in a NSError object that contains a description of the error, and the line number at which the error occurred.

The compiled code is made available as a ModelCode object.


                                    
                                        

The ModelInterpreter Class initializer accepts a ModelCode object. The model is then evaluated for the given input by evaluateForVar:.