ALLO and SAMO, Language for Modeling and Optimisation System

ALLO , SAMO A Language and Integrated System for Modeling and Optimisation
ALLO and SAMO ...
1. Introduction 18. Variables Restrictions
2. Historic 19. Operators
3. ALLO Facilities 20. Intrinsec ALLO Functions
4. SAMO, Advanced System Modeling ... 21. Relational Operators
5. Languages or Mathematical Modeling ... 22. Expresions
6. Example of ALLO model 23. Linear simbolic Expresions
7. Extract from the MPS generated file 24. Repetitive Blocks
8. Extract from the optimization report 25, Structure of ALLO program
9. Extract with non-zero variables from ... 26. Sintax of ALLO program, model
10. ALLO Characters Set 27. Statements
11. The elements of ALLO language 28. Variabile Model Statement
12. ALLO Keywords 29. Obiective Function Statement
13. Constants 30. Obiective Function Selection Statement
14. Masive 31. Restriction Model Statement
15. Variables 32. ALLO Language Sintax
16. Variables Model 33. LPTR Language
17. Variables Obiective Function 34. LPTR language Sintax

       ALLO - Algebraic Language for Linear Optimisation is a linear mathematical modeling language, the only language of its kind in the country. The language together with its translator were completed and implemented in 1995 by the National Institute for Research and Development in Informatics (ICI, ROMÂNIA) within the Modeling and Optimization Laboratory led by Dr. eng., Mat., CP1, Neculai Andrei.
       ALLO allows easy modeling of
linear modeling problems in a form close to the algebraic description. More importantly, it allows prototyping of practical or theoretical problems. A prototype together with the concrete data instantiates a concrete model.
       The translator instantiates the prototype into a model and translates it into the equivalent
MPS form (MPS wiki) that has been the standard input file recognized by any well-known optimizer for decades. It solves the problem and provides a unique solution if any. ALLO stands out for its simple syntax, close to the algebraic mathematical language and even the FORTRAN (EN) / FORTRAN (RO) programming language. ALLO has a small number of reserved keywords.
       We can say that, at the time of its creation, ALLO was in the top ten similar languages ​​in the world, most of which were made commercially in several countries with a tradition in research in any strategic field.

Historic

       The idea to create the ALLO language was had by two research mathematicians from ICI, specialists in mathematical optimization problems. These are Dr. mat., CP1, Cornel Resteanu and Dr. eng., Mat., CP1, Neculai Andrei who did not give up the project and overcame all obstacles through an iron will. At the beginning, they appealed (by contract) to the Department of Informatics within the
Faculty of Mathematics and Informatics, University of Bucharest. After a while they received a printed work. After 1990 he went to Germany for an internship at Humboldt. He called Matt to him. Mircea Bărbulescu, employee in ICI. There they made a first form of the grammar of the ALLO language, after which Mircea Bărbulescu made it in the Borland C language. It is about the lexical-syntactic analyzer without the expression part due to the short time and his departure as an assistant at Fac. Mathematics, University of Bucharest and from here to Canada.
       Left alone on his return from Germany, Neculai Andrei co-opted for the project Mat., CP3, Gheorghe Borcan with a master's degree in Formal Languages and Compilation Construction Techniques (Fac. Mat., Univ. Bucharest) who had ,previous, important contribution to the resumption and continuation of the LPTR project.    Because at that time the two did not have a PC, they started to design the second phase of the translator. He first finalized the form (a reverse and mixed polish) that had to be produced by the lexical-syntactic analyzer, including for the area of expression not yet programmed. After that they designed the model translation process in MPS format.
       Meanwhile, Neculai Andrei received a PC from the Humboldt Foundation in Germany, and Mircea Bărbulescu recommended a former student of Informatics (Faculty of Mathematics, University of Bucharest), namely Cristian Dubălaru who was employed in ICI. He did the Borland C language programs on expression and completed the exit from step one, then left ICI because of the salary. To speed things up, the second step was taken by Gheorghe Borcan in FORTRAN. He also took care of some error corrections in step one.
        Thus in 1995 we had the first version of the ALLO translator.
        During this period Gheorghe Borcan took care of the adaptation of an old solver (received over ten years ago by NA, compiled and executed on the
FELIX C256 computer with French operating system SIRIS, see the history of Romanian computers) and compilation (with the only compiler available ) to be executable (now called Dsolver) on a PC with the WINDOWS 3.1 operating system. He also recompiled the routines (about 100) from the MINOS package (received by N.A. from Stanford University, California, USA). The package was created, compiled, tasked and executed on an operating system other than ours. At the first compilation he found multiple errors that seemed insurmountable because changing the routines would have been not only a serious job but also risky. Eventually he found a correct solution that allowed tests (performed by N.A.) with nonlinear problems because the package also had this feature in addition to the one related to linear problems.
       Moreover, he completed the SAMO system (Advanced Modeling and Optimization System, a system started by Cristian Dubălaru in
Visual Basic) which integrated a Text Editor, ALLO Translator, Dsolver Optimizer as well as a solution viewer. There are several such trading systems in the world.
Solving a linear optimization problem was much easier for SAMO. So I was able to test the translator on several hundred models.
       The most interesting prototype model was related to CETSUD Bucharest. A CETSUD instantiated model has thousands of variables and thousands of restrictions! Prof. Univ. Alexandru Badea (Politehnica Bucharest) specialist in thermal power plants had a decisive contribution to this prototype. He provided us (in a first linear approximation although the more precise model is nonlinear) with the equations of boilers, turbines, balloons, etc. as well as the central cost / profit equations. It is a first in the country to have access to a global vision of the operation of such a plant. This would not have been possible without the existence of the ALLO translator, the DSolver and even more of SAMO.
        After about three years from the first tests and after hundreds of modeling experiments, the ALLO language reached version one by restoring syntax and semantics. 17 implicit functions have been introduced in language that considerably increase the force of language expression.
         Version 1 of the ALLO language was made entirely by Gheorghe Borcan who also implemented the translator consisting of the two components Pas1 (in C) and Pas2 (in Fortran).
          Here is a list (RO) / list (EN) with category programming languages.
       The grammar of the ALLO language was brought to the form that meets the criterion LL1

ALLO Language facilities

  • algebraic language;
  •  FOR - cycle usable in defining auxiliary variables, model variables, objective function variables and constraint variables;
  • SUM - operator in any calculable or symbolic expression;
  • Test conditions in the definition of auxiliary variables and model variables that are boundary conditions;
  • Dynamic domains computable only in the context of the "execution" of the expression in which they are quoted;
  •  Reference to variable initialization data that can be in a data file attached to the prototype and managed by the translator. This feature allows you to easily write a prototype for a particular problem. A model results from the concretization of the attached data file. The data referred to in the prototype are subjected together to the translation process;
  •  Recognizes 17 intrinsic functions that amplify the force of dynamic expression;
  •  ALLO allows auxiliary variables of whole or real type, model variables, objective function variables and constraint variables to be declared as masses of vectors, matrices, three - dimensional variables, etc. This not only makes it easier to write a complex model but also allows you to model large problems;
  • Comments in the model.

    SAMO - Advanced Modeling and Optimization System

           An IDE (Integrated Development Environment) for the SAMO system was started by mat. Cristian Dubălaru in Visual Basic at the indications of CP3., Mat. Gheorghe Borcan who completed it and with the help of which he tested hundreds of models.
           SAMO has a built-in Text Editor (to make it easier to write templates and correct them in the compilation process, etc.). ALLO Translator, Dsolver Optimizer as well as a solution viewer.
         Solving a linear optimization problem is much easier by SAMO. Thus, the translator could be tested on several hundred models.
         Like the ALLO translator, we believe that it is the first system of this kind developed in our country as a result of special efforts in times when such objectives are disregarded by many IT decision-makers who were unfortunately in positions beyond them.

    Functions

  • Text file manager;
  • Editing text files related to models written in ALLO language;
  • Checking the correctness of ALLO models and translating them into standard MPS format;
  • Viewing ALLO translator results;
  • Solving ALLO models using the integrated optimizer;
  • Viewing optimizer results.

    A SAMO image with the CETSUD prototype file in process working

    IDE SAMO

    Operating system

           The ALLO translator and the SAMO system survived on the WINDOWS 3.1, WINDOWS 95 and WINDOWS Vista operating systems. When switching to each of these systems, it was necessary to recompile and redo the tasks starting from compatible compilers on these systems. Given the sources in Borland C, Fortran and Visual Basic, the transition was not easy. The required compilers had to be changed to be compatible on that system. For this reason, some source components had to be rebuilt. Portability of programs on various operating systems is still an unresolved issue.

    Mathematical Modeling Systems or Languages

           1. AIMMS - Advanced Interactive Multidimensional Modeling System. In AIMMS you can model problems: Linear, Quadratic, Nonlinear, Mixed with integers and others. It has a complex IDE For solving AIMMS launches multiple solvents.
           2
    AMPL - A Mathematical Programming Language. In AMPL you can model problems: Linear, Quadratic, Nonlinear, Mixed with integers and others.
       Multiple solvers accept the input of what results from the AMPL translator
           3.
    GAMS - General Algebraic Modeling System. GAMS is one of the oldest and most complex language and modeling and optimization system. Problems can be modeled in GAMS: Linear, Quadratic, Nonlinear, Mixed with integers and others. For solution GAMS launches from IDE multiple solvers. It has a complex IDE. See 
              
    GAMS Development Corporation, GAMS Software GmbH, GAMS World
           4. LINGO. In LINGO you can model problems: Linear, Quadratic, Nonlinear, Mixed with integers and others. It has a complex IDE and to solve the problem LINGO launches multiple solvents.
           5.
    MPL - Mathematical Programming Language.  Problems can be modeled in the MPL system: Linear, Quadratic, Nonlinear. It has a complex IDE. To solve this, the MPL system launches multiple solvents.
           6.
    TOMLAB / TOMLAB (Wiki). It is a modeling platform for solving optimization problems written in the complex MATLAB language. Problems can be modeled and solved: Linear, Quadratic, Nonlinear, Mixed with integers, etc.
             See MATLAB language (Oficial),  MATLAB (Wiki)
    Example of problem with ALLO Model

        A company with several production / storage centers delivers the products to certain markets / customers according to their requirements. To meet the demand of a market, the company can deliver products from several centers. Transport costs, market demand and the production (or storage) capacity of the centers are known. For simplification, the products are given in conventional units because here the transport costs and the capacity of the centers are significant.

        Customer satisfaction is required as well as minimizing transportation costs.

    MODEL Transport

    /*-----------------------------------------------------------------------*/
    /*                      Created: 27 Oct 1997                             */
    /*-----------------------------------------------------------------------*/
    /*
    Prototype of a transport / delivery model produced from               */
    /*
    several centersat more markets / customers.A company                  */
    /*
    with several productioncenters delivers the products                  */
    /*
     to some markets according to their requirements.                     */
    /* Is required minimizing transportation costs
                               */
    /*-----------------------------------------------------------------------*/

    FILE ftr="translpl.dat"  /* Prototype instantiation file */

    INTEGER
      nrcp READ ftr IS nrcp>0; /* Number of production centers */
      nrmk READ ftr IS nrmk>0  /* Number of markets */
    RANGE
      cp=[1,nrcp]; /* Domain internal code for production centers */
      mk=[1,nrmk]  /* Domain internal code for delivery markets  */
    REAL
      /* Production capacities in conventional units */
      A[cp] READ ftr IS FOR[c In cp] a[c]>0.0;

      /* Market demands in conventional units */
      B[mk] READ ftr IS FOR[m IN mk] b[m]>0.0;

      /* Transport cost per conventional unit */
      CT[cp,mk] READ ftr IS For[c IN cp,m IN mk] CT[c,m]>=0.0

    VARIABLES
      x[cp,mk] /* x[j,k], The quantity transported from center j to market k */

       /* The condition is not necessary being supplemented by restrictions */
       /* x[cp,mk] IS FOR [j IN cp, k IN mk] x[j,k] <= A[j] */

    OBJECTIVES
      /* The total cost for transporting products delivered to markets */
      cost IS cost:= SUM[c IN cp,m IN mk]( CT[c,m]*x[c,m])
     
    MINIMIZE cost

    CONSTRAINTS
      /* The quantity transported from one center to all markets */
      /* it cannot exceed the existing quantity in that center */
      rcap[cp] IS FOR[c IN cp] rcap[c]:= SUM[m IN mk] (X(c,m)) <= A[c] ;

      /* An additional restriction for discussion. The quantity delivered to all markets in each */
      /* center must do not be zero so as not to block products and dynamically free up space */
      /* rcapnz[cp] IS FOR[c IN cp] rcapnz[c]:= SUM[m IN mk] (X(c,m)) >= 0.7*A[c] ;*/

      /* The quantity delivered to a market from all centers */
      /* it must meet the minimum required by that market */
      rdem[mk] IS FOR[m IN mk] rdem[m]:= SUM[c IN cp] (X[c,m]) >= B[m]

    END

    Transport prototype instantiation data file

    /* translpl.dat------------------------------------------*/
    /*               Created: 27 Oct 1997                     */
    /*--------------------------------------------------------*/

       /* nrcp  */ 10
      /* nrmk  */  6
        /* A[cp] */ 134.0,120.0,301.0,400.0,290.0,398.0,678.0,456.0,1729.0,456.0;
      /* B[mk] */ 923.0,45.0,78.98,300.0,589.0,678.0;

      /* CT[cp,mk] */
      /* centre */ /* 1     2     3     4     5    6 piata */
      /*  1 */       5.0,  4.0,  6.0,  7.0,  8.0, 4.5,
      /*  2 */      10.0,  0.0, 12.0, 23.0,  5.0, 6.5,
      /*  3 */      11.0,  8.0, 13.0, 17.0,  2.0, 7.8,
      /*  4 */       5.0,  5.0, 10.0, 34.0, 10.0, 4.0,
      /*  5 */      18.0,  0.0,  0.0, 11.0, 17.0, 2.3,
      /*  6 */       7.0,  9.0,  9.0, 34.0, 23.0, 9.9,
      /*  7 */      12.0, 10.0, 14.0,  0.0,  8.0, 2.0,
      /*  8 */       4.0, 77.0, 11.0,  0.0,  9.0, 1.0,
      /*  9 */      16.0, 16.0, 12.0,  8.0, 12.0, 5.6,
      /* 10 */      23.0, 67.0,  2.0, 12.0,  4.0, 7.7;


    /* eof translpl.dat--*/

    Extract from the MPS file generated by the ALLO translator that is input to Dsolver

    NAME Transport
    ROWS
    N cost min
    L rcap1
    L rcap2
    L rcap3
    L rcap4
    L rcap5
    L rcap6
    L rcap7
    L rcap8
    L rcap9
    L rcap10
    G rdem1
    G rdem2
    G rdem3
    G rdem4
    G rdem5
    G rdem6
    COLUMNS
    x1 cost 5.00000
    x1 rcap1 1.00000
    x1 rdem1 1.00000
    x2 cost 4.00000
    x2 rcap1 1.00000
    x2 rdem2 1.00000
    x3 cost 6.00000
    x3 rcap1 1.00000
    x3 rdem3 1.00000
                   ... omitted from the exposure
    x58 cost 12.0000
    x58 rcap10 1.00000
    x58 rdem4 1.00000
    x59 cost 4.00000
    x59 rcap10 1.00000
    x59 rdem5 1.00000
    x60 cost 7.70000
    x60 rcap10 1.00000
    x60 rdem6 1.00000
    RHS
    RHS1 rcap1 134.000
    RHS1 rcap2 120.000
    RHS1 rcap3 301.000
    RHS1 rcap4 400.000
    RHS1 rcap5 290.000
    RHS1 rcap6 398.000
    RHS1 rcap7 678.000
    RHS1 rcap8 456.000
    RHS1 rcap9 1729.00
    RHS1 rcap10 456.000
    RHS1 rdem1 923.000
    RHS1 rdem2 45.0000
    RHS1 rdem3 78.9800
    RHS1 rdem4 300.000
    RHS1 rdem5 589.000
    RHS1 rdem6 678.000
    RANGES
    BOUNDS
    ENDATA

    Extract from optimizer report after resolution
    ===================================
    Name of the problem  : Transport
    Minimize the function : cost

    Synopsis of original matrix
    --------------------------------
    No. constraints                        =  16
    No. structural variables            =  60
    No. non-zeros elements           = 120
    Density of non-zeros in matrix = 12.50%
    No. unity elements                 = 120
    Density of unity elements       = 12.50%


    Row section
    ---------------
    No. less than or equal      = 10
    No. greater than or equal =  6

    Column section
    -------------------
    No. normal variables = 60
    -----------------------------------------

    ... omit iterations to a feasible solution

    Feasible Solution found in 21 iterations

    ...omit iterations to an optimal solution

    Optimal Solution found in 15 iterations
    Objective function value = 7376.266

    ... omitted about satisfying the restrictions in the optimal solution

    Extract with linearized and non-zero variables from the optimal solution

    NoVar Name AT    Value
     1     x1  bs .134000D+03
     8     x8  bs .450000D+02
    17     x17 bs .301000D+03
    19     x19 bs .400000D+03
    27     x27 bs .789800D+02
    30     x30 bs .211020D+03
    31     x31 bs .219800D+02
    40     x40 bs .300000D+03
    42     x42 bs .378000D+03
    43     x43 bs .367020D+03
    48     x48 bs .889800D+02
    59     x59 bs .288000D+03
    --------------------------

         Let us remember that these are the variables:
        x[cp,mk] /* x[j,k] The quantity transported from center j to market k */
        cp = [1,10] și mk = [1,6] , so there are 60 variables linearized as from the matrix x [10,6] thus:
        row 1: x1-x6,    row 2: x7-x12,  row 3: x13-x18, row 4: x19-x24, row 5:  x25-x30
        row 6: x31-x36,row 7: x37-x42,row 8: x43-x48,  row 9: x49-x54, row10: x55-x60
      So:
        x1  =x[1,1]=134.0, x8  =x[2,2]= 45.0,   x17=x[3,5]=301.0,  x19=x[4,1] =400.0
        x27=x[5,3]= 78.98,x30=x[5,6]=211.02, x31=x[6,1]= 21.98, x40=x[7,4] =300.0
        x42=x[7,6]=378.0, x43=x[8,1]=367.02, x48=x[8,6]= 88.98, x59=x[10,5]=288.0

       x[j,k] The quantity transported from center j to market k

    x[10,6] Markets
    Centers 1 2 3 4 5 6
    1 134.0          
    2   45.0        
    3         301.0  
    4 400.0          
    5     78.98     211.02
    6 21.98          
    7       300.0   378.0
    8 367.02         88.98
    9            
    10         288.0 

           It is noted that from center 9 no products are delivered to markets. In order to deliver from here as well (in order not to reach the activity block) we should put another condition in the model. For example, we want the sum of deliveries from any center to be greater than a certain part of the capacity. Here is a variant that changes the situation. But usually the objective function will have a higher value than the previous one:
      rcapnz[cp] IS FOR[c IN cp] rcapnz[c]:= SUM[m IN mk] (X(c,m)) >= 0.7*A[c] 

        Objective function = 13495.68

    x[10,6] Markets
    Centers 1 2 3 4 5 6
    1 93.80          
    2   84.0        
    3         269.8  
    4 280.0          
    5   124.02 78.98      
    6 278.6          
    7       474.6    
    8 270.6     48.60    
    9           1210.3
    10         319.2  

    ALLO character set

           The ALLO language is built on a character set called the language alphabet. Based on the alphabet, tokens or words of the language are constructed (according to lexical rules) which are elements of the set called the vocabulary of the language. Some words will be used frequently by any user of the language. They form the set of reserved words or the set of keywords with a special role in the syntactic and semantic construction of what we call source program or prototype / source model.  

          The other words are not known, but are constructed by those who use this language. The vocabulary would be an infinite lot but there are restrictions on word length limitation. With the alphabet and vocabulary we can create complex assemblies from the instructions and finally we can create the assembly with the highest semantic load called program. Of course with the observance of some syntactic and semantic rules because otherwise it will not be validated by an assembler, translator, interpreter or compiler.

            We have seen above a global structure of an ALLO program. Seen only through the prism of the alphabet, a program is a finite string of characters recognized by the translator. This string can be the result of a mix of file strings decided by the main file that refers to the others. Everything is coordinated by the ALLO translator. Below is the alphabet or character set recognized by the ALLO language:

    Clasa Cod ASCII Simbol Descriere
    Litere 065-090 A- Z Mari
      097-122 a - z Mici
    Cifre 048-057 0- 9 Cifrele zecimale
    Caractere 013 <CR> Sfârșit linie sursă
            control 010 <LF> Linie nouă "solicitare"
                linie sursă  013,010 <CR><LF> Linie nouă
    Caractere 009 <TAB> Butonul TAB de regulă = 8 x SP
                    spațiere 032 <SP> Caracterul blank sau spațiu
    Comentarii 047,042 /* Început Comentariu
      042,047 */ Sfârșit Comentariu
    Legatură în nume 095 _ Caracterul de subliniere
    Delimitatori 046 . Punct zecimal
      034 " Ghilimele duble delimitator șir
      044 , Virgulă, separă elemente în listă
      059 ; Sfârșit instrucțiune, definiție,etc.
    Paranteze 040 ( Început expresie sau listă
      041 ) Sfârșit expresie sau listă
      091 [ Început domeniu, FOR / SUM
    093 ] Sfârșitul lor
      123 { Început listă instrucțiuni sau ...
      125 } Sfârșit  listă instrucțiuni sau ...
    Operatori 043 + Plus binar
      045 - Minus binar sau unar
      042 * Înmulțiere
              aritmetici 047 / Împărțire
    Operatori 060 <  
      061 =  
      062 >  
      060 061 <= Mai mic sau egal
      062,061 >= Mai mare sau egal
      060,062 <> Diferit de ceva
               relaționali  073,078 IN Se află într-un interval, mulțime...
    Op. de definire, 061 = Stânga este egală cu dreapta
    condiționare, 058,061 := Operator de definire
    atribuire valori 073,083 IS Operatorul este ...

    Observation

           1. The IN operator can be written in any combination of uppercase / lowercase letters as desired by the modeler. This also applies to the IS operator but also to any reserved word.

           2. The difference between the operator: = and the IS operator is that the first refers to the definition of a mass component (with the role of objective function name, constraint name) while IS announces the beginning of the definition of an auxiliary variable of mass type or the condition of validation of an auxiliary variable (scalar or solid-type), announces the boundary condition of a model variable (scalar or massive-type), and finally announces the beginning of the body defining an objective function or constraint (scalar or massive type).

           3. The set of characters <CR> <SP> <TAB>,:; {} [] () + - * / <=> is a special set whose elements signal the beginning or end of words / tokens recognized by the lexical analyzer of the ALLO translator. These tokens are part of the language vocabulary only if they comply with the construction rules imposed by the language.

    Elements of the ALLO language

        Based on the alphabet and vocabulary, new vocabulary words or more and more complex assemblies are built up to the assembly with maximum syntactic and semantic load called program or model. The basics of the ALLO language are :

    • comments;
    • names or identifiers; 
    • constants; 
    • arrays; 
    • indices; 
    • variables; 
    • arithmetic operators; 
    • function operators; 
    • parenthesis; 
    • delimiters; 
    • expressions; 
    • list of function call parameters; 
    • dimensions list; 
    • index list; 
    • cycling assembly; 
    • statements; 
    • statements list; 
    •  conditions list; 
    • sections; 
    • program

            Below we will detail each of the basic elements in the construction of a model presented above.

    Comments

           Comments are especially useful in any language. In ALLO comments are accepted anywhere in the source files related to a prototype / model.

           An ALLO comment is a sequence of characters in the ALLO set that is nested at the beginning and end of the comment. After the comment is opened, the lexical analyzer scans the string until it encounters the closing sequence. If necessary, the <CR> <LF> source line end sequence is exceeded when a comment continues on multiple lines. This fact is useful not only in explaining the model but also for a possible troubleshooting. Comments and space areas are unproductive elements with the role of design and explanation of the source model.

    Name

           The name is an essential element in the construction of any ALLO prototype / model being a vocabulary element, a token identifiable by the ALLO lexical analyzer. Names are formed using letters, numbers, and an underscore character that links two or more components to which the user assigns a meaning. Of course, no one is stopping us from pasting these names and not using this link. It depends on your preference. However, the use of character is often useful because it highlights the components.

           A valid name starts only with a letter that can be followed by: a letter, a number, the underscore link character. The length must not exceed the maximum allowed case solved by truncation.

    Details of the metalanguage used in defining the ALLO syntax

    ::= tells us that its left element is constructed as follows (or is by definition);

    | is a separator from the list items. Any element can participate in the construction of the respective complex assembly;

         Space between two metalanguage elements or between a metalanguage element and an atom (eg link character _) means the concatenation operation between two strings. A metalanguage element means a class / set of possible assemblies (strings on the alphabet) constructed with the rules of that element.

      lambda is the symbol for the null element relative to the character or string concatenation operation. It is an empty string that has no character being of zero length.

    Sintax

    nume ::= litera | nume litera | nume cifra | nume _ 
    litera ::= any element of the set of letters from the character set (this and the next do not respect the meta.)
    cifra ::= any element of the digits set

    Examples : nrfprod, fprod, ump, xprod, cost_prod, st_cost, per_1

    Keywords ALLO

    Nr Name Description
    01 MODEL Begin  model
    02 END End  model
    03 VARIABLES Begin variables section
    04 OBJECTIVES Begin of the objective functions section
    05 CONSTRAINTS Begin restrictions section
    06 FILE Begin statementdefining secondary files with data
    07 RANGE Begin statement defining whole or real domains
    08 INTEGER Begin statement defining integer auxiliary variables
    09 REAL Begin statement defining real auxiliary variables
    10 READ Command to read initialization data from the secondary file
    11 IN Begin condition of belonging to a domain of values
    12 IS Global definition clause
    13 FOR Begin cycling sequence
    14 SUM Begin cycling SUM sequence
    15 MINIMIZE Begin objective function selection statement sense Minimize
    16 MAXIMIZE Begin objective function selection statement sense Maximize
    Intermediate actions such as functions
    17 ABS The absolute value
    18 AND Logical AND
    19 APX Raising power with base a variable
    20 ATR Value change function for some auxiliary variables
    21 DIP The positive difference
    22 IFP Positivity test with selected value return
    23 IFS Logical test with selected value return
    24 LOR Logic OR
    25 LOG Decimal logarithm
    26 MAX Maximum of two values
    27 MIN Minimum of two values
    28 MOD The remainder of the division of two integers
    29 NOT Logical NOT
    30 SEARCH Search existence value with return result and where it is
    31 SIG The sign of value or variabile
    32 SQR Second order root
    33 XOR Or exclusively

    Remarks

           The words in the table above are reserved. They can also be used in combined capitalization as the user wishes. All (including the resulting combinations) can no longer be used as variable names. Those in the range [17,33] are names of default functions that must be called according to their definition with respect to the number of arguments and the required type.

    Constante

        Constants are necessary elements for any programming or specialized language. In the ALLO language they are used either directly in the construction of a model or indirectly by the fact that they serve to initialize auxiliary variables that are used in that construction. ALLO allows the construction and use of the following types of constants: integer | real | domain / range | string of characters.

    Integer constant

           An integer constant is a sequence of decimal digits in front of which the + or - sign can appear. ALLO allows integer constants in the single word value range, i.e. [-32768, + 32767]. For higher values there are real constants or integer variables that can be assigned with the desired expression.

    Sintax
    secv_cifra ::= cifra | cifra secv_cifra
    numar_intreg ::= semn secv_cifra 
    semn ::= - | + | lambda

    Exemple: 3457,  -15481,  +12 , -32768,  +32767

    Real Constant

           Real constants are composed of the sign, integer part, decimal point, fractional part possibly followed by an exponent. It consists of the letter E or is followed by an integer with or without a sign. The approximate value range of such a constant is the negative range [- 3.4028235E + 38, - 1.1754944E-38] plus the positive range [1.1754944E-38, 3.4028235E + 38] and of course the value 0 as a mandatory element in operations.

    Sintax 
    numar_real ::= semn p_int . p_frac exponent 
    p_int ::= secv_cifra | lambda 
    p_frac ::= secv_cifra | lambda 
    exponent ::= lambda | E numar_intreg | e numar_intreg

    Observatii.

        1. p_int may be missing when p_frac is present and vice versa. but I can't miss it at the same time.
        2. As can be seen from the exponent, the presence of lambda is not mandatory.
        3. exponent is relatively within the limit of two useful decimal places.

    Exemple : .517,  -32.7564,  +3. 0.342E-15,  -2.51e+9,  -3.4028235E+38

    Domain constants

           There are elements of the ALLO language that define an interval on the real axis or in the set of integers. They contain the two sizes that define such an interval: the lower edge and the upper edge. These quantities are enclosed in square brackets and are separated by a comma. The quantities can be real or integer constants but can also be arithmetic expressions calculable at the point where the domain constant appears and is used as the initialization quantity of a domain variable or as an ad hoc domain.
           The type resulting from the evaluation of an arithmetic expression is integer if the operands are all integers, otherwise it is the real type. Real domain constants are usually used in double boundary clauses when no previously defined domain variables are used. Depending on the context, it is assessed whether the constant represents an integer domain or a real domain even if the evaluation result of the margin expressions contradicts the type. For example in a cycling clause a constant is evaluated with integer edges so it must represent an integer interval. Also in a size list a constant is evaluated at an integer range. If a constant initializes a domain variable whose use is not yet known then for the domain the two values ​​are kept: integer range and real range.

           In ALLO, field constants are allowed that can only be evaluated in a certain context and whose value may differ depending on the value of some cycling indices that participate in the margin expressions. This is the case for so-called dynamic field constants that support their re-evaluation every time the cycle to which they belong is initialized.

    Sintax

    const_domeniu ::= [ expr_aritm , expr_aritm ]

    Exemple : [ -2, 17],  [ 34.5, 70.18],  [ m/2, 3*n ] , [ a+3.2*(k+1), b+18.65 ]

        Observație.

           Integer auxiliary variables m and n must be defined in advance for the expressions to be calculable at the time of meeting this field. Also a and b are auxiliary variables whose values are already known and k is a cycling index in a FOR clause in whose instruction block this domain constant appears, so in this cycle the expressions are calculable.

    Strings of characters

           They consist of one or more characters of the ALLO alphabet delimited by a pair of double quotation marks which thus can no longer be included in any string. Strings are used to define the external file identification specification under the DOS operating system. Such a specification may contain only the name and type separated by a period, in which case the file is searched in the translator's working directory, or it may also contain the path in which case it is searched in accordance with it.

    Sintax

    sir ::= " secv_car " 
    secv_car ::= car | car secv_car 
    car ::= caracter ASCII recunoscut de ALLO (text comentariu)

    Exemple : "e:\lpmodels\allo\prod.dat" "cetsud.dat" "twood.dat"

    Massive

           Massifs are special creations of a programming language and more. They consist of one or more identical cells / objects organized according to a known dimensional rule that allows the identification of the place occupied (in this structure) by each object. Massifs are characterized by a list of dimensions, by the space allocated to each cell and by the rule of allocation or retrieval of each cell. One-dimensional massifs are known as vectors, those with two dimensions as matrices. Three-dimensional massifs are called three-dimensional massifs, with n-dimensional massive dimensions.

    Sintax 
    masiv ::= nume_masiv [ l_dim ] 
    nume_masiv ::= nume

    Exemple : storcost [rmat] ump [rmat,fprod] xsmat[rmat,perpext]

    Dimension list

           As I said, a massif is marked by a list of dimensions that define its size, its shape. A dimension of a massif is a domain of integers that has a number of elements given by the difference between the top edge and the bottom edge after which one must be added. This number participates in the calculation of the total number of elements of the array as the product of all numbers associated with the dimensions. A classical dimension represents a domain [1, n] so that the number of elements represented by this dimension is n-1 + 1 = n, even the upper edge. A whole and one-dimensional whole domain can be put in biunivocal correspondence with such a classical domain.

    Sintax

    l_dim ::= dim | dim , l_dim 
    dim ::= domeniu 
    domeniu ::= const_domeniu | var_domeniu 
    var_domeniu ::= nume

    Exemple de listă dimensiuni:  [1,10] , rmat, / rmat,  fprod / (fără cele două /)

        Observație

        [1,10] is a domain constant, the others are constructed by domain names that should be defined before using them elsewhere or in this list.

    Allocation method

             In ALLO the linearization of a massif is done "on lines" in which the last index increases faster until the end and is restored at the beginning not before increasing it with 1 on the previous one, etc.
            A two-dimensional domain, the first domain [1, m] and the second domain [1, n]) is viewed similarly to the matrix [m, n] i.e. the elements in the order of line 1, ... line m each line having n elements as long as it has a column.
            The elements of the matrix are arranged as follows: a [1,1], ... a [1, n], ... a [m, 1], ... a [m, n]. The allocation formula is place (a [i, j]) = (i-1) * n + j. The place of the first element is place (a [1,1]) = 1 and of the last is place (a [m, n]) = (m-1) * n + n = m * n that is equal to the number of elements of the matrix .

            A three-dimensional massif, a [m, n, p] is regarded as a cube consisting of m * n * p identical cubes or consisting of p floors of cubes each floor being a matrix of cubes a [m, n]. So the cube a [i, j, k] is on the floor k at the intersection of line i with column j.
            The allocation formula is given by place (a [i, j, k]) = ((i-1) * n + j-1) * p + k. We see that the place of the first element is place (a [1,1,1] = 1 and the place of the last is place (a [m, n, p]) = ((m-1) * n + n-1) * p + p = (m * n -1) * p + p = m * n * p, ie equal to the number of elements of the massif.

           In ALLO auxiliary variables of integer or real type, model variables, objective function variables and constraint variables can be declared as masses of vector, matrix, three - dimensional variables, etc. This makes it easier to write a large, complex model.

    Reference to a massive element

          We saw that a massif is a collection of cells / objects of the same type organized according to a known allocation procedure. Access to such a cell / object is made by invoking the name of that massif and a list of index expressions whose number of elements coincides with the number of dimensions of the massif. This is the so-called reference to that element in the massif on the basis of which we access it.
           The expression index is an arithmetic expression that can be calculated when used in the reference list of a solid element. Calculate its value, convert it (if necessary) to an integer value and then perform the domain membership test. The same is done with any index expression in a list of index expressions. After this, the linearized index is calculated, which represents the place of the referred element. Based on the place, the address from the beginning can also be calculated by multiplying (place -1) with the unit of allocation of the variable type.

    Sintax

    ref_element_masiv ::= nume_masiv [ l_expr_ind ] 
    l_expr_ind ::= expr_ind | expr_ind , l_expr_ind 
    expr_ind ::= expr_aritm

    Exemple : ump [r,f], storcost[r], xprod[f,p]

                  Rprd [ATR(opczindl[j],h) + ATR((h-1)/nrprod+1,m)+h-(m-1)*nrprod , f]

    Observație

           The index expressions in the first three examples above are simple invoking the name of auxiliary variable r, f, p. In the last example the first index expression is a complicated arithmetic expression in which two intermediate actions occur. ATR (opczindl [j], h) is the function that assigns to h the calculated value of the vector element opczindl [j]. Then this value of h enters the calculation of the expression that is assigned to m and then the value of the expression h- (m-1) * nrprod is calculated which converted to the integer is the first reference index of Rprd, the second being m with the calculated value immediately before but which must eventually be converted to the whole.

    Variables 

           ALLO language variables are the basic elements in the construction of a model. Except for the INDEX type (implicitly recognized from the context) all must have a statement / definition. In terms of size we have two types of variables: scalar variables and compound variables with one or more dimensions. Scalar variables are defined by name, type and possibly a value. Compound variables are defined by name, type, size list and possibly list of values. The elements of the compound variables are accessible by name and the list of indices possibly resulting from a list of index expressions. Based on this list and the list of dimensions, the linear place of the element is calculated and thus the value or a linearized scalar name is calculated. Details on this subject are in the description of the massifs.
         By purpose, ALLO language variables can be grouped into four groups that correspond to the four sections of a source model auxiliary; variables of the model; objective function variables; variable restrictions.

    Auxiliary variables

           Auxiliary variables together with constants help to build the model by: coefficients, facilitating the expression of relationships and constraints, etc. All auxiliary variables must have a value at the time of their use. This category includes the following types: integer; index ; real ; domain ; file name.

    Integer auxiliary variables

           These variables can be scalar or compound, vectors, matrices, etc. A scalar variable is represented in complementary code with sign and on four bytes. A value in the range [- 2147483648, 2147483647] can be assigned to such a variable.
           An integer auxiliary variable must appear in an INTEGER statement that contains its entire declaration.
           Integer auxiliary variables are frequently used in the construction of integer domains required in the definition of massifs or in instructions containing FOR or SUM cycling sequences. They are also used in index expressions, for other purposes but not as cycling indices.

    Sintax

    var_intreg ::= var_intreg_scalara | var_intreg_masiv
    var_intreg_scalara ::= nume
    var_intreg_masiv ::= masiv

        Exemple : nrfprod, nrperp, opczindl [opcze]

        Observation. All quoted variables are integers if they are in an INTEGER statement in that model.

    Index auxiliary variables

        They are only of the scalar type by name and are not the subject of an explicit statement. They are considered as whole and can participate in index expressions, coefficient expressions, or even in the definition of dynamic domains that can be evaluated only in a certain context of execution of an instruction. An index variable is present as a cycling index in the FOR and SUM sequences. At that time this index must not be used by another FOR or SUM. So its purpose is precise until the end of the operation in which it is involved after which it can be reused.

    Sintax

    var_indice ::= nume

    Exemple : j, k, k1, m, n,  r, f, p

        Observation. There is a certain simplicity in the role of the index auxiliary variable, but we can also use more complicated names.

    Real auxiliary variables

           Real auxiliary variables can be scalar or compound (vectors, matrices, etc.). A scalar variable is represented by a floating point with a sign and four bytes. The approximate value range of such a variable is the negative range [- 3.4028235E + 38, - 1.1754944E-38] plus the value 0 and the positive range [1.1754944E-38, 3.4028235E + 38].

          A real variable must appear in a REAL statement that contains its entire statement. Real auxiliary variables are used in the construction of coefficient expressions or real domains used as model variable boundary domains or model constraint variables.

    Sintax

    var_real ::= var_real_scalara | var_real_masiv
    var_real_scalara ::= nume
    var_real_masiv ::= masiv

    Exemple : prodmax, storcost [rmat] , ump [rmat,fprod] , profdc [fprod,perp]

         Observation. All quoted variables are real only if they are included in a REAL statement.

    Domain auxiliary variables

           Auxiliary domain variables are scalar-type only and are used as size domains, cycling domains, or model variable boundary domains or model constraint variables. The first two types have integer values and the other real ones. A domain variable has two values. One value represents the lower edge and the other the upper edge. Because the subsequent use of this field is not known (because the translator makes a single pass through the source text) these values are retained as real values but also as integer values. Such a variable can represent an interval on the real axis or on the integer axis.

         A domain variable must appear in a RANGE statement that contains its entire definition.

    Sintax

    var_domeniu ::= nume

    File name auxiliary variables 

           The ALLO language allows the definition of such variables whose value is a DOS file specification. The definition is made by the FILE statement which also means the default Open to be prepared to satisfy the first variable in a READ statement that refers to this name.
           Such a variable is used as a reference to the auxiliary file it represents and from which assignment data for other auxiliary variables can be taken. ALLO allows access to multiple auxiliary files simultaneously with the main file with the basic text of the model.

    Sintax

    var_fisier ::= nume

    Exemple : fpp, fdist, fcsd

        Observation. These names must appear in the FILE statement. They are chosen as desired, simpler if they are required in the model.

    Model variable

            The variables of the model to be optimized are all defined after the auxiliary variables section. The date type associated with such a variable is only the actual type. If in the definition is not the boundary clause then the variable is assumed to be positive. If it has the lower boundary clause then its range is up to infinite plus. If it has only the upper margin clause then this margin must be strictly positive and the range considered for this variable is from zero to this value. If the clause is double bounded then the domain can be negative, positive or mixed only if it is correctly represented by the edges, ie the lower edge <= the upper edge. The result of processing the boundary clause can be found in the BOUNDS section of the resulting MPS file.
           Thus, before the name (possibly linearized) appear FX (fixed variables, generic for x = wave), LO (x <= wave), UP (x> = wave). If the variable is constrained to a range then it appears twice in BOUNDS for each edge with LO and UP respectively.

           A model variable can be scalar or compound (vector, matrix, etc.) which allows us to use general (strong) instructions to define both boundary clauses and constraints.

           Scalar pattern variables appear in the MPS file with their names when it is at most eight characters long. Otherwise the name is the result of truncating to the first 8 characters. For compound variables there is a need to encrypt the linearized index of the referred cell in the name. This is done on as many characters as needed on the back up to the eight allowed. That is why the user must choose his generic name shorter than 8 characters and correlated with the respective size. Otherwise inconsistencies may occur on the same representation of final names because the translator does not do this check. This procedure seemed to us the best at the time. Otherwise, it would have been necessary to build a very useful dictionary in the recovery operation, of the optimizer solution, in terms of the original names with non-linearized clues.

    Sintax

    var_model ::= var_model_scalara | var_model_masiv
    var_model_scalara ::= nume
    var_model_masiv ::= masiv

    Exemple : xprod [fprod,perp], xsmat[rmat,perpext], Rprd[prod,fact],

    XRZP [hrze] , XIRZP [hrz] , XORZP [hrz] , XAF

    Variables Functions Objective

           These variables allow the definition of objective functions in the objective functions section. They can be scaled or compound. At the end of this section, a single scalar function or component can be selected in the MINIMIZE / MAXIMIZE statement. The result of processing an objective function definition can be found in the MPS file in the ROWS and COLUMNS sections.
           Type N (No restriction) appears in the line in the ROWS section of the selected function. If there are more than N with us, the objective function also has MAX / MIN from the selection instruction. This is related to the SAMO Solver and is a small change to the MPS standard. Usually solvers (not having the information) assume and minimize. The conscious user, if he wants maximization, builds the objective function with - (right side) and then - (at the value given by the solver) is the maximum value.

    Sintax

    var_fobj ::= var_fobj_scalara | var_fobj_masiv
    var_fobj_scalara ::= nume
    var_fobj_masiv ::= masiv

    Exemple : profit | cost

    Restriction variables

           Constraint variables are names for the constraint lines in the model necessary for its understanding, for the form to be solved by the solver (in our case the MPS) and for the form of the solution (provided by the solver) necessary in its interpretation for the real decision-making process. They can be scaled or compounded as defined in the model restrictions section. The result of processing a restriction can be found in the MPS file in the ROWS, COLUMNS, RHS (Right Hand Section) sections and possibly in the RANGES section if the restriction had a double border clause.
           In ROWS appear in front of the name (linearized if necessary) one of the letters E (constraint equal to the constant calculated and brought to the right of the sign), L (in case <=), E (in case =), G (in case > =). In these situations the constant appears by name in the RHS section. If we have a domain, the upper edge appears in the RHS and the lower one is in the RANGES section. In this case in ROWS L always appears in front of the name.
           For the names generated in the MPS file to be correct, the same rules set out for the model variables apply.

    Sintax

    var_restr ::= var_restr_scalara | var_restr_masiv
    var_restr_scalara ::= nume
    var_restr_masiv ::= masiv

    Exemple : limprod [perp] , pmbal [rmat,perp] , rtlim | DRZP [hrz]

    Operators

        Operators act on one or more operands to produce a value, an action, and a value, a domain limitation for certain model variables or constraints. ALLO language operators are in the categories: arithmetic; function; relational; symbolic border.

    Aritmetic operators

           Arithmetic operators are used in the construction of arithmetic and symbolic expressions. In arithmetic expressions it acts on an operand or two operands producing a new operand that further participates in the evaluation of the expression. In a symbolic expression they can be in an arithmetic expression coefficient, operator on symbolic expression or operator on two symbolic expressions producing a new operand of type symbolic expression. We have unary operators and binary operators, additive or multiplicative.

    Sintaxa

    opr_aritm ::= opr_unar | opr_binar
    opr_unar ::= -
    opr_binar ::= - | + | * | /
    opr_adit ::= + | -
    opr_mult ::= * | /

    Function operators

           Function operators are invoked by the name of the default function recognized by the language and the ALLO translator. They act on the call parameters a closed list between two round brackets following the name. The result of the execution of that function is an operand that further participates in the calculation of that expression. Before the execution of the function, all parameters from left to right are evaluated, resulting in a list of concrete values with the type of each. The correctness of the call is checked as number of parameters and as type. If everything was correct, the respective operand results, otherwise the error is signaled.

    Sintaxa

    opr_fun ::= ABS | AND | APX | ATR | DIP | IFP | IFS | LOR | LOG |
                     MAX | MIN | MOD | NOT | SEARCH | SIG | SQR | XOR

    apel_fun ::= opr_fun ( l_param_act )
    l_param_act ::= expr_aritm | expr_aritm , l_param_act

        Observatie. Numele de operatori funcție se pot scrie cu litere mici sau chiar în combinație mari cu mici.

    Example function call:  ATR(rtl[d,w]*((d-1)*nrwhse+w),h) , ABS(a[j,k]+5.3] , SEARCH(h,rtindl[1],find) ,
                                       Ifp(rpc[f,p],0,1,0) , Ifs(rtl[d,w],1,0) , And(Ifp(dctrs[d]-whses[w],1,0,1),
                                       Ifp(sc[w,d]-huge,1,0,0)) , Max(a,b)

    Functions recognized by the ALLO translator

    Nr Nume Descriere parametri Descriere rezultat
    1 ABS

    Întreg sau real

    Întoarce valoarea absolută de același tip
    2 AND Doi INT cu val 0 sau 1 Întoarce 1 dacă p1=p2=1, rest 0
    3 APX Doi INT/R, p1 strict pozitiv Ridicarea la putere. Rezultat întreg dacă ambii sunt întregi
    4 ATR p1 val/variabilă INT/reală, p2 var. întreagă/reală  descrierea mai jos
           este echivalentul instrucțiunii p2=p1 după eventuală conversie la tipul p2. În plus întoarce ca operand valoarea întreagă 0 
    5 DIP Doi reali / întregi descrierea mai jos 
           Dacă p1 <= p2 întoarce 0 altfel întoarce valoarea p1-p2. Tipul rezultatului este întreg dacă ambii au fost întregi 
    6 IFP Patru reali / întregi
    (p1,p2,p3,p4)
    Rezultatul întors are tipul parametrului selectat. Dacă p1 < 0 atunci p2, dacă p1 = 0 atunci p3, altfel p4
    7 IFS Trei, p1 întreg cu 0 / 1 (p1,p2,p3) Rezultatul are tipul argumentului selectat. Dacă p1 = 1 atunci p2, dacă p1 = 0 atunci p3
    8 LOR Doi întregi cu valori 0/1 Întoarce 1 dacă măcar unul are val 1altfel 0
    9 LOG Un întreg/real strict pozitiv Întoarce ca real logaritmul zecimal
    10 MAX Doi reali / întregi Întoarce maximul lor eventual convertit la real dacă unul a fost real
    11 MIN Doi reali / întregi Întoarce minimul lor eventual convertit la real dacă unul a fost real
    12 MOD Doi întregi >= 1 Întoarce restul împărțirii întregi p1/p2
    13 NOT Un întreg cu 0 / 1 Întoarce 1/0 dacă p a fost respectiv  0/1
    14 SEARCH (p1,p2,p3) toți de același tip, real/intreg Descrierea mai jos
              p1 este căutat în vectorul p2. p3 este o variabilă scalară întreagă. p2 este privit liniarizat dacă este matrice, masiv. Se caută primul loc unde valoarile sunt egale și întoarce locul. Dacă operația a avut succes funcția întoarce ca operand valoarea 1 altfel 0. Dacă a avut eșec p3 primește totuși valoarea 1
    15 SIG Un parametru p Dacă p < 0 întoarce -1, dacă p = 0 întoarce 0, altfel 1
    16 SQR Un întreg/real >=0 Întoarce radicalul pătrat convertit la tipul parametrului
    17 XOR Doi întregi (p1,p2) cu 0 / 1 Întoarce 1 dacă numai un p= 1 în rest 0

    Relational operators

           They are used in relational expressions necessary for the validation of auxiliary variables of integer or real type that may be subject to restrictions. The result is 1 (true) or 0 (false) depending on whether or not the relationship was fulfilled.

    Sintaxa

    opr_rel ::= < | <= | = | >= | > | <>

    Symbolic variable boundary operators

           Model variables can only receive values if they are in a certain domain. This request is marked in the MPS file in the BOUNDS section. Thus the optimizer takes into account the condition in the process of finding an optimal solution. And model constraint variables may be subject to similar conditions. Conditioning is obtained by using symbolic boundary operators from variable boundary clauses or model restrictions.

    Sintaxa

    opr_marg ::= <= | = | >= | IN

        Observation. In case = we have a fixed value model variable (FX in the BOUNDS section). A model constraint is a constraint with equality (E in the ROWS section).

         IN determines membership in a domain with finite real margins.

         The operators <= or >= say that the model variable / model restriction variable is allowed to take the respective value as well. There is no strict case in standard modeling. For the model variable the operators <= or> = transmit UP or LO in the BOUNDS section. For the model restriction variable the operators <= or> = transmit L or G in the ROWS section.

    Parenthesis

           The ALLO language uses three pairs of parentheses: round brackets () ; square brackets [] ; brackets {}

           Round brackets are used in the construction of complex expressions or in the construction of default function calls. The parenthesed expression is calculated as a value and becomes an operand. If it is the case of a default function call, the values ​​of the parameters are calculated, after which the function that possibly performs an action but produces an operand used in the calculation is "called".
           Square brackets are used in defining massifs (size list is between []), in reference to a mass element (index list is between []), as well as in the construction of FOR and SUM blocks. Depending on the context of use, the size list is evaluated and retained, the index expressions are evaluated based on which the linearized index, start evaluation and control of the cycling operations in the respective block are calculated.
           Brackets are used in delimiting an instruction block from the same definition of a variable as well as for framing the list of initialization expressions of an auxiliary variable of solid or integer type. If the list is read from a secondary file then these parentheses have been removed for practical reasons.

    Sintaxa

    p_rotunda ::= ( | )
    p_dreapta ::= [ | ]
    p_acolada ::= { | }

    Expressions

           The basic element of the ALLO language is the expression which is absent from almost all instructions except the instructions for structuring the model into sections. We have the following types of expressions: arithmetic; relational; symbolic.

    Arithmetic expresions

           Arithmetic expressions are constructions with operands, operators and round brackets. As operands can be integer or real constants, integer or real type auxiliary variables, references to integer elements of integer or real variables, implicit function calls. The result of evaluating an arithmetic expression is an operand, real or integer value.
           The evaluation of an expression is done from left to right and based on the priorities of the operators and parentheses. An operator acts on one or more operands that must be evaluated before its operation. Multiplicative operators have priority over additive ones. Minus unar has priority over binary operators. The index operator first requests the evaluation of the index expressions on the basis of which the linearized index is calculated, which allows access to the value of the referred element. The default function operator first requests the evaluation of the list of parameters after which the function is launched. The binary arithmetic operator with the same type of operands results in an operand of the same type. If it has an integer and a real the result is a real operand. The evaluation of arithmetic expressions is the one adopted by established programming languages.
           In the parsing process the ALLO translator brings the expression to a mixed form based on a postfixed Polish form in which the round brackets were abolished and in which the function and reference operators are not according to the corresponding lists but remained in front in their place.

    Sintaxa

    expr_aritm ::= termen rest_suma
    termen ::= factor rest_produs
    rest_suma ::= lambda | opr_adit rest_suma
    rest_produs ::= opr_mult factor rest_produs | lambda
    factor ::= numar | ref_var_aux | apel_fun | ( expr_aritm ) | SUM [ l_expr_apart ] ( expr_aritm )
    ref_var_aux ::= ref_var_intreaga | ref_var_reala
    ref_var_intreg ::= var_intreg_scalara| ref_element_masiv_intreg
    ref_var_real ::= var_real_scalara | ref_element_masiv_real

    Examples : (d-1)*nrwhse+w ; h-(m-1)*nrprod ; ATR(h+IFS(rtl[d,w],1,0),h) ;

                   SUM[f IN fact,p IN prod](Ifp(rpc[f,p],0,1,0)) ; +2.3 ; N ; 5 * M .

    Validation condition expressions

        These expressions are constructions based on two arithmetic expressions linked by a relational operator. The result of evaluating such an expression is an integer value 0 or 1 with the meaning of false or true. The two arithmetic expressions are first evaluated and compared. These expressions are used in the instructions for defining auxiliary variables of integer or real type, namely in the validation clause.

    Sintaxa

    expr_cond_valid ::= expr_aritm opr_rel expr_aritm

    Exemple : prodmax > 0.0 | omin[f] <= omax[f] | nrdctr < nrwhse

    Linear symbolic expressions

           Symbolic linear expressions are expressions constructed and evaluated in a similar way to arithmetic expressions. But here also appear variable scalar model operands or references to massive elements. In multiplicative binary operators we cannot have symbolic expressions simultaneously because the resulting expression would no longer be a linear thing signaled by the translator in the evaluation process. Objective function variables or constraint variables have nothing to do with a symbolic expression. They can receive a linear symbolic expression as a value.

    Sintaxa

    expr_simb ::= termen_simb rest_suma_simb
    termen_simb ::= factor_simb rest_produs_simb
    rest_suma_simb ::= lambda | opr_adit rest_suma_simb
    rest_produs_simb ::= lambda|opr_mult factor_simb rest_produs_simb
    factor_simb ::= numar|ref_var_aux| ref_var_model| apel_fun | ( expr_simb ) | SUM [ l_expr_apart ] ( expr_simb )

    Exemple :

        Sum[f In fprod,p In perp](profdc[f,p]*xprod[f,p]) , xsmat[r,p] - Sum[f In fprod](ump[r,f] * xprod[f,p])

    Repetitive blocks

           Repetitive blocks are ALLO semantic constructions that allow us to repeat (with other parameters related to the cycle) the instructions or operations in their body. This feature is especially useful in concentrated model writing even for large processes / systems. Blocks have a header defining one or more cycles simultaneously. A cycle is defined by a cycling index as well as an entire domain in which it is allowed to evolve with the default step 1. To initiate a cycle, the cycling range is evaluated (there are dynamic domains with expressions that include variable cycling indexes that are active / have value only in this context) after which the cycling index is initialized with the value of the lower edge of the range.
           After initializing the index, the instructions in the body of the respective cycle are executed. At the end of this body it increases by 1 index and compares with the upper edge of the cycling range. If the value of the index does not exceed it, the execution of the body is resumed. Otherwise it is considered that the execution of the cycle has been exhausted and the inactive status is set to this index which can be reused further.
           In the case of cycles with multiple indices, before body execution, the operations are performed similarly for each index and attached field. The left index rises the fastest. When it has a value above the maximum, it is set to the starting value (lower edge of the range) and the previous index is increased, etc. After the whole list has been processed, the body is executed.
           In ALLO we have two repetitive blocks signaled by the keywords
    FOR and SUM briefly described below.

    FOR block

           It allows the resumption of a group of instructions that form the body of the cycle whose beginning and end are perceived by syntax. If the body has several instructions it starts with {and ends with}. Each instruction in the body ends with; except for the last whose end is recognized by}.

    Sintaxa

    antet_for ::= FOR [ l_expr_apart ]
    l_expr_apart ::= expr_apart | expr_apart , l_expr_apart
    expr_apart ::= var_indice IN domeniu

    Exemplu : FOR [p IN perp] | FOR [r IN rmat, f IN fprod]

    SUM block

        It allows the resumption of the process of summing an expression between two round brackets that form the body of the cycle. The SUM block is particularly useful in expressing very large symbolic expressions that can be concentrated to the maximum. The summation process starts with the value 0.0 to which is added what results in each repeated pass over the expression (which is reclassified and added) until the cycle is exhausted.

    Sintaxa

    antet_sum ::= SUM [ l_expr_apart ]
    l_expr_apart ::= expr_apart | expr_apart , l_expr_apart
    expr_apart ::= var_indice IN domeniu

    Exemplu : SUM[r IN rmat] , SUM [f IN fprod, p IN perp]

    Statements

        ALLO language instructions are special assemblies with complex semantics that define the sections of a model and each variable used in each section of the model. The instruction categories are: model structuring; preparation of auxiliary data; defining model variables; defining objective functions; objective function selection and optimization direction specification; defining model restrictions.

    Statements for model structuring

        Their role is to create a sectional structure of an ALLO model. Apart from the template statement, all others are defined only by those keywords that indicate the destination of the next section or end of the template. Each section appears only once.

    Sintaxa

    instr_struct_model ::= MODEL nume_model | VARIABLES | OBJECTIVES | CONSTRAINTS | END
    nume_model ::= nume

    Sintax of program / model ALLO

           Below is the syntactic scheme of an optimization model written in ALLO language. Syntax is free in white areas consisting of spaces, tabs, empty source lines. Also reserved words are not case sensitive and can be used as desired. Any ALLO name behaves the same.
           An ALLO program is a concatenation of the four sections with everything related to them and in the required order. Each section is a concatenation of one or more section-specific instructions that are separated by a semicolon token. The exception is the last statement in each section because its end is indicated by the following keyword. For this reason, all instructions in the auxiliary variables section do not need a semicolon because each statement begins with a keyword that also indicates the end of the previous statement.

    Sintaxa

    Program ::= MODEL nume_model

           sect_var_aux

    VARIABLES
           sect_var_model

    OBJECTIVES
           sect_var_fobj

    CONSTRAINTS
           sect_var_restr

    END

    Secțiunea variabile auxiliare

    sect_var_aux ::= s_instr
    s_instr ::= instr | instr s_instr
    instr ::= instr_file | instr_domeniu |instr_integer | instr_real

    Secțiunea variabile model

    sect_var_model ::= s_instr_var_model
    s_instr_var_model ::= instr_var_model | instr_var_model ; s_instr_var_model
    instr_var_model ::= var_model proced_cond_marg

    Secțiunea variabile funcții obiectiv

    sect_var_fobj ::= s_instr_fobj instr_select_fobj
    s_instr_fobj ::= instr_fobj | instr_fobj ; s_instr_fobj
    instr_fobj ::= var_fobj
    IS proced_def_fobj

    instr_select_fobj ::= MINIMIZE ref_fobj | MAXIMIZE ref_fobj

    Secțiunea variabile restricții

    sect_var_restr ::= s_instr_restr
    s_instr_restr ::= instr_restr | instr_restr ; s_instr_restr
    instr_restr ::= var_restr
    IS proced_def_restr

    Statements for preparation of auxiliary data

           They allow us to define the auxiliary variables needed in the construction of any model. We have a specific instruction for each type of date. Each statement begins with the appropriate keyword. The INTEGER and REAL statements are the same except for the keyword. Here is the type of instructions: FILLE; RANGE; INTEGER; REAL.

    FILE statement

            We can define auxiliary variables of type FILE whose value is a file specification string recognized by the DOS operating system. The file is secondary with data attached to the model prototype in the main file. Access to it is done by invoking the variable name (internal name for the file) in the READ command from the instructions for defining the auxiliary variables of type INTEGER or REAL if they have the initialization data in the associated file. Through an instruction we can define several secondary files separated by a semicolon character. A secondary file is opened by default for access to the current data in them. This statement can appear anywhere in the section.

    Sintaxa

    instr_file ::= FILE s_decl_file
    s_decl_file ::= decl_file | decl_file ; s_decl_file
    decl_file ::= var_fisier = spec_fisier_dos
    spec_fisier_dos ::= sir
    sir ::= " secv_car "
    secv_car ::= car | car secv_car
    car ::= caracter ASCII recunoscut de ALLO (text comentariu)

    Exemple : FILE fpp = "prodplan.dat" , FILE fcsd="cetsud.dat"

    RANGE statement

        Allows you to define one or more RANGE variables (integer or real range domain). Through an instruction we can define several fields separated by the semicolon character. The domain constant must be calculable at the time of definition in the sense that both edge expressions must be calculable. If they contain other auxiliary variables of integer or real type they must be previously defined and of course initialized. This statement can appear anywhere in the section.

    Sintaxa

    instr_domeniu ::= RANGE s_decl_domeniu
    s_decl_domeniu ::= decl_domeniu | decl_domeniu ; s_decl_domeniu
    decl_domeniu ::= var_domeniu = const_domeniu

    Exemple : RANGE fprod = [1,nrfprod] ; rmat = [1,nrrmat ]

        Observation. Above we have defined two fields in a single statement that can be written even on several source lines. Each domain could be defined in a separate statement. It is assumed that the auxiliary variables nrfprod and nrmat are already known when reaching the RANGE statement so the margin expressions are all calculable. These values must also be greater than or equal to 1 due to the lower edge present and the constant 1.

    INTEGER statement

           Allows the definition of one or more auxiliary variables of integer, scalar or massive type. If they are multiple then their definitions must be separated by a semicolon token. Each definition is composed of three components, the first of which is mandatory because it has the name and size of the variable. The second component is dedicated to the initialization of the variable that can be done even by reading the data from a secondary file from the pointer that was reached at the time of the READ command. Component three deals with validation. If it is not component two, for dimensioned variables it is interpreted as a data assignment procedure for some (even all) elements of the mass. In this case only the relational operator = which is reinterpreted as the assignment operator can appear in the validation sequence. That is why only the references to the massive element can stand in front of it.

    Sintaxa

    instr_integer ::= INTEGER s_decl_integer
    s_decl_integer ::= decl_integer | decl_integer ; s_decl_integer
    decl_integer ::= var_integer part_init part_valid
    part_init ::= lambda | READ var_fisier | = val_init
    val_init ::= expr_aritm | { l_expr_aritm }
    l_expr_aritm ::= expr_aritm | expr_aritm , l_expr_aritm
    part_valid ::= lambda | IS proced_valid
    proced_valid ::= expr_cond_valid | FOR [ l_expr_apart ] proced_valid | { s_proced_valid }
    s_proced_valid ::= proced_valid | proced_valid ; s_proced_valid
    l_expr_apart ::= expr_apart | expr_apart , l_expr_apart
    expr_apart ::= var_indice IN domeniu
    expr_cond_valid ::= expr_aritm opr_rel expr_aritm

    Examples:

    INTEGER M = 10 ; N = 23

    INTEGER V[ [3,5] ] ={1,2,3}

    INTEGER nrfprod READ fpp IS nrfprod >0 ;

          nrperp READ fpp IS nrperp >0

        Observation. In the first instruction the auxiliary variables M and N are defined with the initialization values 10 respectively 23. In the second instruction we defined a vector with indices in the range [3,5] whose initial values are V [3] = 1, V [ 4] = 2 and V [5] = 3. In the last instruction, two scalar auxiliary variables are defined. For each variable the value is read from the fpp file and validated by the condition after the IS keyword.

    REAL statement

        Everything that has been said about the INTEGER type auxiliary variables remains valid here as well. From the syntax part_init and part_valid are defined exactly as in the previous syntax. Only the following are added to them:

    Sintaxa

    instr_real ::= REAL s_decl_real
    s_decl_real ::= decl_real | decl_real ; s_decl_real
    decl_real ::= var_real part_init part_valid

    Exemple :

    REAL ump [rmat,fprod] READ fpp IS FOR [r IN rmat,f IN fprod] ump[r,f]>= 0.0

        Observation. Above is defined a single matrix auxiliary variable whose values are taken from the fpp file. Each initialization value of the matrix element cannot be a negative number because it does not allow the validation clause in the body of the FOR block that cycles on two indices of the rmat and fprod domains.

    Model variable definition statement

           It allows us to define symbolic variables, basic elements that participate in symbolic expressions in the definition of objective function variables and model constraint variables. A model variable has a name, a dimensional list if it is of massive type as well as a possible boundary condition. Model variables have no initial value. As an initial value we can consider the condition value if it exists and which consists of the code of the boundary operator and of one or two values that represent the lower edge or the upper edge as an admissible range of values. We have a two-value domain when the operator is IN. Model variables will receive values only in the optimization process that tries to determine an optimal solution. This process is independent of the model analysis, validation and translation process in standard MPS format.

    The statement  are separated by a semicolon character, except for the last.

    Sintaxa

    instr_var_model ::= var_model  part_cond_marg
    part_cond_marg ::= lambda | IS proced_marg
    proced_marg ::= ref_var_model  cond_var_model  |  FOR [ l_expr_apart ] proced_marg | { s_proced_marg }
    ref_var_model ::=var_model_scalara | ref_element_masiv_var_model
    cond_var_model ::= opr_marg expr_marg_var
    expr_marg_var ::= expr_aritm | domeniu
    s_proced_marg ::= proced_marg | proced_marg ; s_proced_marg

    Examples : xprod [fprod,perp] , xsmat[rmat,perpext] IS FOR[r IN rmat] xsmat[r,1] <= stinimax[r]

        Observation. The first statement defines a matrix model variable that contains no boundary clause in which all elements are assumed in the real positive domain. The second statement defines a variable that contains a boundary clause for all components that have the index 1 on the second dimension and are required not to exceed the upper limit with value in the stinimax vector the first dimensional index. The clause is with the FOR block which has only one component: xsmat [r, 1] <= stinimax [r].

    Objective function variable definition statement

           An objective function variable has a name, a dimensional list (if it is of massive type) as well as a part of definition with symbolic expression.

            The instructions for defining objective function variables are separated from each other by the semicolon character. An exception is the last statement that ends before a MINIMIZE / MAXIMIZE keyword.

    Sintaxa

    instr_fobj ::= var_fobj IS proced_def_fobj
    proced_def_fobj ::= ref_fobj := expr_simb | FOR [ l_expr_apart ] proced_def_fobj | { s_proced_def_fobj }
    s_proced_def_fobj ::= proced_def_fobj | proced_def_fobj ; s_proced_def_fobj
    ref_fobj ::= var_fobj_scalara|ref_element_masiv_var_fobj

    Exemplu: fobj IS fobj :=  SUM[f IN fprod,p IN perp](profdc[f,p]*xprod[f,p])

        Observation. Above we have a scalar variable function objective fobj as a sum of symbolic expressions.

    Objective function selection statement

           This instruction, the last in the objective functions section allows not only the selection of the objective function (considered by the optimizer) but also the type of problem. The ALLO translator puts min / max on the line corresponding to this function in the ROWS section of the resulting MPS file but also N in front of the name. The other objective functions (if any) do not influence the solution. The reference to the function to be optimized consists in quoting the name of a scalar variable or of a reference element from the objective type variable of massive type.

    Sintaxa

    instr_select_fobj ::= MINIMIZE ref_fobj | MAXIMIZE ref_fobj

    Exemple : MAXIMIZE profit , MINIMIZE cost

    Restriction variable definition statement

           The basic structure of a linear model consists of model constraints that provide the model matrix. In the ALLO language, each restriction also has a name required by the MPS standard. On the other hand, a model constraint variable can be a massive one that facilitates the work of defining the model.
           The definition of restrictions is done with the instruction below which includes the name definition part with a possible sizing followed by the IS keyword and the concrete definition procedure. If we have a massive type restriction variable, only those lines resulting from the massive cells cited as the reference in the definition procedure that can be performed by the FOR or SUM block will be part of the model.
        The
    statements are separated by a semicolon character, except for the last statement. This is before the END statement that ends both the model restrictions section and the ALLO model.

    Sintaxa

    instr_restr ::= var_restr IS proced_defrestr
    proced_defrestr ::= ref_var_restr := expr_simb opr_marg expr_marg_restr | FOR [ l_expr_apart ] proced_defrestr | { s_proced_defrestr }
    s_proced_defrestr ::= proced_defrestr | proced_defrestr ; s_proced_defrestr
    ref_var_restr ::= var_restr_scalara | ref_element_masiv_restr
    expr_marg_restr ::= expr_simb | domeniu

    Examples: limprod [perp] IS FOR [p IN perp] limprod[p]:= SUM[f IN fprod](xprod [f,p]) <= prodmax;

         Observation. The statement defines a vector constraint variable called limprod. The definition of each component is in the body of a FOR cycle and contains a symbolic expression made with the SUM operator plus a higher boundary condition.

    Structure of ALLO program / model

        The model has a structure marked by the keywords MODEL, VARIABLES, OBJECTIVES, CONSTRAINTS, END

    MODEL nume_model
            section of auxiliary variables with statements:
    FILE | RANGE | INTEGER | REAL

    VARIABLES
            section of model variables model

    OBJECTIVES
            section of objective functions with the last selection instruction MINIMIZE | MAXIMIZE ...

    CONSTRAINS
            section of model restrictions

    END

    Section of auxiliary variables

           Starts with the MODEL statement and ends before the VARIABLES statement. It is dedicated to defining and preparing all the data needed to build the model in the last three sections: the model variables section, the objective functions section and the constraints section.
           Here you can define secondary files invoked by the main file through the READ command that allows the assignment of data to auxiliary variables. Here you can define whole or real domains needed in defining any mass, in defining the margins of some variables or constraints, and in the FOR or SUM blocks.
           Also here the scalar or massive auxiliary variables of whole or real type are defined and initialized. Their values ​​can be changed by calling intrinsic functions such as ATR, SEARCH, etc. There are four types of auxiliary variables: FILE, RANGE, INTEGER, REAL that have a specific definition instruction. The instructions can be used as desired or necessary regardless of the order between them.

    Section of model variables

           It is signaled by the VARIABLES statement and holds up to the OBJECTIVES statement. All model variables are defined here. A boundary condition may appear in a definition / instruction. If the variable does not appear, it is considered positive (from 0 to + infinity) For the massive type variable, the rest of the elements in the massif (if any) that were not invoked in the boundary condition are considered positive model variables.

    Section of objective function

           Start with the OBJECTIVES statement and stick to CONSTRAINTS. Here are defined all the objective functions from which we select only one (scalar or solid element reference) for model optimization. Both the function definitions and the selection instruction have an equivalent in the MPS file by marking, in the ROWS section, all functions with N in front of the name (linearized if they come from solid) and with MIN or MAX after the name of the selected function. Of course, the names of the objective functions are also invoked in the COLUMNS section. All objectively unselected functions do not influence the solution. A new selection can be easily made by changing the selection instruction, generating a new MPS, etc.

        The section ends with the selection statement which is mandatory if we want to solve the problem.

    Section of model restriction

           Start with the CONSTRAINTS statement and continue to the END statement that ends the ALLO text. all model restrictions are defined in this section. Simple equal or non-equal constraints and double-bounded restrictions can be defined. They produce a line in the RHS and RANGES section of the resulting MPS file. All constraints produce lines in the ROWS section marked with E, L or G. Of course the names of the constraint functions are also invoked in the COLUMNS section of the MPS.

    Sintax ALLO

    Metalimbaj pentru Sintaxa ALLO

    ::= tells us that its left element is constructed as follows (or is by definition);

    | is a separator from the list items. Any element can participate in the respective assembly;

         Space between two metalanguage elements or between a metalanguage element and an atom (eg link character _) means the concatenation operation between two strings. A metalanguage element means a class / set of possible assemblies (strings on the alphabet) constructed with the rules of that element.

      lambda is the symbol for the null element relative to the character or string concatenation operation. It is an empty string that has no character being of zero length.

          Gramar of ALLO language was brought to the form that meets the criterion LL1

    Begin of ALLO sintax

    nume ::= litera | nume litera | nume cifra | nume _
    litera ::= any letter from the leters set (this and the following do not respect the metalanguage)
    cifra ::= any digit from the digits set

    var_intreg ::= var_intreg_scalara | var_intreg_masiv
    var_intreg_scalara ::= nume
    var_intreg_masiv ::= masiv
    var_indice ::= nume
    var_real ::= var_real_scalara | var_real_masiv
    var_real_scalara ::= nume
    var_real_masiv ::= masiv
    var_domeniu ::= nume
    var_fisier ::= nume
    var_model ::= var_model_scalara | var_model_masiv
    var_model_scalara ::= nume
    var_model_masiv ::= masiv
    var_fobj ::= var_fobj_scalara | var_fobj_masiv
    var_fobj_scalara ::= nume
    var_fobj_masiv ::= masiv
    var_restr ::= var_restr_scalara | var_restr_masiv
    var_restr_scalara ::= nume
    var_restr_masiv ::= masiv

    secv_cifra ::= cifra | cifra secv_cifra
    numar_intreg ::= semn secv_cifra
    semn ::= - | + | lambda
    numar_real ::= semn p_int . p_frac exponent
    p_int ::= secv_cifra | lambda
    p_frac ::= secv_cifra | lambda
    exponent ::= lambda | E numar_intreg | e numar_intreg

    const_domeniu ::= [ expr_aritm , expr_aritm ]

    sir ::= " secv_car "
    secv_car ::= car | car secv_car
    car ::= caracter ASCII recunoscut de ALLO (text comentariu)

    masiv ::= nume_masiv [ l_dim ]
    nume_masiv ::= nume
    l_dim ::= dim | dim , l_dim
    dim ::= domeniu
    domeniu ::= const_domeniu | var_domeniu
    ref_element_masiv ::= nume_masiv [ l_expr_ind ]
    l_expr_ind ::= expr_ind | expr_ind , l_expr_ind
    expr_ind ::= expr_aritm

    opr_aritm ::= opr_unar | opr_binar
    opr_unar ::= -
    opr_binar ::= - | + | * | /
    opr_adit ::= + | -
    opr_mult ::= * | /

    opr_fun ::= ABS | AND | APX | ATR | DIP | IFP | IFS | LOR | LOG | MAX | MIN |
                     MOD | NOT | SEARCH | SIG | SQR | XOR

    opr_rel ::= < | <= | = | >= | > | <>

    opr_marg ::= <= | = | >= | IN

    Program ::= MODEL nume_model
               sect_var_aux
    VARIABLES

               sect_var_model
    OBJECTIVES

               sect_var_fobj
    CONSTRAINTS

               sect_var_restr
    END

    sect_var_aux ::= s_instr
    s_instr ::= instr | instr s_instr
    instr ::= instr_file | instr_domeniu | instr_integer | instr_real

    instr_file ::= FILE s_decl_file
    s_decl_file ::= decl_file | decl_file ; s_decl_file
    decl_file ::= var_fisier = spec_fisier_dos
    spec_fisier_dos ::= sir

    instr_domeniu ::= RANGE s_decl_domeniu
    s_decl_domeniu ::= decl_domeniu | decl_domeniu ; s_decl_domeniu
    decl_domeniu ::= var_domeniu = const_domeniu

    instr_integer ::= INTEGER s_decl_integer
    s_decl_integer ::= decl_integer | decl_integer ; s_decl_integer
    decl_integer ::= var_integer part_init part_valid
    part_init ::= lambda | READ var_fisier | = val_init
    val_init ::= expr_aritm | { l_expr_aritm }
    l_expr_aritm ::= expr_aritm | expr_aritm , l_expr_aritm
    part_valid ::= lambda | IS proced_valid
    proced_valid ::= expr_cond_valid | FOR [ l_expr_apart ] proced_valid | { s_proced_valid }
    s_proced_valid ::= proced_valid | proced_valid ; s_proced_valid
    l_expr_apart ::= expr_apart | expr_apart , l_expr_apart
    expr_apart ::= var_indice IN domeniu
    expr_cond_valid ::= expr_aritm opr_rel expr_aritm

    instr_real ::= REAL s_decl_real
    s_decl_real ::= decl_real | decl_real ; s_decl_real
    decl_real ::= var_real part_init part_valid

    sect_var_model ::= s_instr_var_model
    s_instr_var_model ::= instr_var_model | instr_var_model ; s_instr_var_model
    instr_var_model ::= var_model part_cond_marg
    part_cond_marg ::= lambda | IS proced_marg
    proced_marg ::= ref_var_model cond_var_model | FOR [ l_expr_apart ] proced_marg | { s_proced_marg }
    ref_var_model ::= var_model_scalara | ref_element_masiv_var_model
    cond_var_model ::= opr_marg expr_marg_var
    expr_marg_var ::= expr_aritm | domeniu
    s_proced_marg ::= proced_marg | proced_marg ; s_proced_marg

    sect_var_fobj ::= s_instr_fobj instr_select_fobj
    s_instr_fobj ::= instr_fobj | instr_fobj ; s_instr_fobj
    instr_fobj ::= var_fobj IS proced_def_fobj
    proced_def_fobj ::= ref_fobj := expr_simb | FOR [ l_expr_apart ] proced_def_fobj | { s_proced_def_fobj }
    s_proced_def_fobj ::= proced_def_fobj | proced_def_fobj ; s_proced_def_fobj
    ref_fobj ::= var_fobj_scalara | ref_element_masiv_fobj

    instr_select_fobj ::= MINIMIZE ref_fobj | MAXIMIZE ref_fobj

    sect_var_restr ::= s_instr_restr
    s_instr_restr ::= instr_restr | instr_restr ; s_instr_restr
    instr_restr ::= var_restr IS proced_defrestr
    proced_defrestr ::= ref_var_restr := expr_simb opr_marg expr_marg_restr | FOR [ l_expr_apart ] proced_defrestr | { s_proced_defrestr }
    s_proced_defrestr ::= proced_defrestr | proced_defrestr ; s_proced_defrestr
    ref_var_restr ::= var_restr_scalara | ref_element_masiv_restr
    expr_marg_restr ::= expr_simb | domeniu
    expr_aritm ::= termen rest_suma
    termen ::= factor rest_produs
    rest_suma ::= lambda | opr_adit rest_suma
    rest_produs ::= opr_mult factor rest_produs | lambda
    factor ::= numar | ref_var_aux | apel_fun | ( expr_aritm ) | SUM [ l_expr_apart ] ( expr_aritm )
    ref_var_aux ::= ref_var_intreg | ref_var_real
    ref_var_intreg ::= var_intreg_scalara | ref_element_masiv_intreg
    ref_var_real ::= var_real_scalara | ref_element_masiv_real
    expr_simb ::= termen_simb rest_suma_simb
    termen_simb ::= factor_simb rest_produs_simb
    rest_suma_simb ::= lambda | opr_adit rest_suma_simb
    rest_produs_simb ::= lambda | opr_mult factor_simb rest_produs_simb
    factor_simb ::= numar | ref_var_aux | ref_var_model | apel_fun | ( expr_simb ) | SUM [ l_expr_apart ] ( expr_simb )
    apel_fun ::= opr_fun ( l_param_act )
    l_param_act ::= expr_aritm | expr_aritm , l_param_act

    LPTR Language

           In the 1975s the ICI Institute (founded in 1970) was tasked with compiling a compiler for RTL - Real Time Language (designed and developed by Imperial Chemical Industries Limited, London) to equip minicomputers Independent 100 and Coral. The RTL compiler was implemented on the American minicomputers DEC - PDP 11 with RSX 11 operating system, a family of multi-user operating systems made in the 1970s. Two PDPs were bought by Romania, both without the RTL compiler due to the embargo imposed.
           Having no specialists, in 1977 the ICI institute concluded a contract with the
    Faculty of Automation and Computers Politehnica Bucharest. The Polytechnic team consisted of two specialists then assistants / lecturers who worked with students. The team leader was Prof. Univ. Dr. eng. Luca Dan Șerbănați may (since then and until today) be the first specialist in the country in this field. After two years they designed the similar language RTL, called LPTR - Real Time Programming Language. They finalized the LL1 type grammar and in the pseudocode they performed most of the lexical-syntactic analysis routines.

           Due to limited human resources and lack of technical resources (PDP 11 with Macro 11 assembler) the faculty handed over the project to the ICI institute. In addition to filling the gaps in the project followed the hardest part related to semantic analysis, code generation, programming also in Macro 11, testing, etc. The institute still did not have specialists in the field (with some exceptions) because only in 1974 it hired dozens of graduates specialized in mathematics, computer science, computers, cybernetics but not in the construction of compilers. To continue the LPTR project, a team was formed (out of 8 employees from the Computing Center) led by Mat. Petre Preoteasa.
          The compiler had to be programmed in the Macro 11 assembly language (learned on the fly by team members) existing in ICI on a single PDP with few terminals and many employees requesting them. After taking over the project, multiple design shortcomings were found, etc. one of which seemed insurmountable, which would have led to the resumption of the project almost from the beginning. A solution was found that saved the work done. However, the compiler was not made for several reasons, to which were added the social changes, the disinterest in research, the overclassification by PCs of minicomputers, a fact that closed the subject forever. From this project remained the experience of some but also the grammar of the interesting LPTR language.

        The first team designed the compiler in one step (no return to correct / complete some information gathered by reading the source text only). Along the way, the ICI team ran into several problems that were impossible to solve in a single pass due to the complexity of this language with a nested dynamic block structure and a mechanism for recursive procedures. The attributes of some identifiers could not be established from the first pass over the text of a source program. As an example, there were contexts in which a jump instruction could not specify / decide whether the identifier involved represents a constant label following in the text or a label variable that will be declared.

        Fortunately Mat. Gheorghe Borcan found a continuation solution that preserved most of the work done (especially by the first team) until this phase. It was the result of specialization through the master's degree in formal languages ​​and compilation writing techniques and more. The solution was also agreed by the Politehnica team. As a result, the concept of implementation was revived by introducing a new step that would be in fact the first step in the source text. Some essential routines (missing from the project) were designed that finalized the mechanism of operation and understanding (by the whole team) of this compiler. Thus, the functional structure of the compiler was finalized, as well as the mandatory linking structure at that time due to the internal memory limit (for execution) imposed by the PDP-11M minicomputer, RSX-11M operating system. ICI had a copy to which the LPTR team (from the Computing Center) had limited access because the minicomputer belonged to the Research Department! The first step was exceptionally programmed in Macro 11 by the brilliant Mat. Vasile Coardoș who left us prematurely.

        Due to the ALLO language, in Feb.1998, we returned to the LPTR grammar, processing and testing the form below that meets the LL1 condition. It is based on the grammar of the LPTR project with some modifications. I hope it will be useful for students from the profile faculties and not only.

    A LL1 gramar of LPTR language

    The metalanguage used is similar to that of ALLO

    Recognized characters:

    litera ::= A - Z, a - z ! any from two intervales
    cifra ::= 0 - 9 ! any from interval
    eol ::= ! Ascii cod 13 followed by Ascii cod 10
    cartitle ::= any character other than these four: "'", '"', ";", eol

    Ignored characters: Ascii Cod(9) - Ascii Cod(13) ! any from interval

    Comments are left and right bordered by character "%"

    /*-----------------Tokens results from the Lexical Analyzer------------------------*/

    nrop ::= cifra
    title ::= cartitle { cartitle }
    id ! it is similar to a name and must start with a letter

    /*-------------Keyword tokens are capitalized------------------*/

    intreg real fractie sir
    MODE ENDMODUL ENT EXT
    SVC ARRAY DATA ENDDATA
    PROC ENDPROC STACK REF
    LABEL WHILE plumi FOR
    BY TOK REP IF
    THEN ELSEIF ELSE ENDIF
    ABS AND BIN BLOCK
    ENDBLOCK BYTE CODE DO
    FRAC GOTO HEX INT
    LAND LENGTH LET LOR
    MOD NEV NOT OCT
    OF OPTION OR REAL
    RETURN RTL SHA SHL
    SLA SLL SRA SRL
    SWITCH TITLE VAL secvcod
    altopbin altopun oplog et
    idtipinreg tipobisnuit comparator  

    /*------------------------------- Productions ---------------------------*/

    Modul ::= Unitmodul Lum ENDMODUL
    Unitmodul ::= [ Descrcontext | MODE id "(" Speci id Lsp ")" |
      Let | Titlu | Optiune | ENT Sectneet ]
    Let ::= LET id "=" { Letitem } ";"
    Letitem ::= id | Numar | sir | Separator
    Separator ::= ":=" | ":/" | "//" | "<=" | ">=" | ":=:" | ":#:" | "(" | ")" |
       "*" | "/" | "+" | "-" | "," | "." | ":" | "<" | "=" | ">" | "#"
    Titlu ::= TITLE title
    Optiune ::= OPTION "(" nrop ")" [ id { "," id} ]
    Lum ::= [ ";" Unitmodul Lum ]
    Descrcontext ::= EXT Dc1 | SVC Dc2
    Speci ::= Tipelem | ARRAY "(" intreg Lintreg ")" Tipelem
    Lsp ::= [ "," Rlsp id Lsp ]
    Sectneet ::= DATA id Ldecl ENDDATA | STACK id intreg |
      PROC id "(" Lpar ")" Tiprez ";" Corpbloc ENDPROC
    Dc1 ::= STACK id Listid | Dc2
    Dc2 ::= DATA id ";" Declfvi Ldfvi ENDDATA |
      PROC "(" Listtipel ")" Tiprez id Listid
    Tipelem ::= tipobisnuit | Tipprogram | REF Altmod
    Lintreg ::= [ "," intreg Lintreg ]
    Rlsp ::= [ Speci ]
    Ldecl ::= [ ";" Idecl id Inel1 Linitel1 Ldecl ]
    Lpar ::= [ Tipelem id Ltipelem ]
    Tiprez ::= [ Tipelem ]
    Corpbloc/td> ::= Lsd Secv
    Listid ::= [ "," id Listid ]
    Declfvi ::= [ Idecl id Listid ]
    Ldfvi ::= [ ";" Declfvi Ldfvi ]
    Listtipel ::= [ Tipelem Greseala ]
    Tipprogram ::= LABEL | STACK | PROC "(" Listtipel ")" Tiprez
    Altmod ::= tipobisnuit | Tipprogram | ARRAY Listdim Tipt | idtipinreg
    Idecl ::= Tipelem | ARRAY "(" intreg Lintreg ")" Tipt | idtipinreg
    Inel1 ::= [ ":=" Rinel1 ]
    Linitel1 ::= [ "," id Inel1 Linitel1 ]
    Ltipelem ::= [ "," Tiprez id Ltipelem ]
    Lsd ::= [ Tipelem id Inel2 Linitel2 ";" Lsd ]
    Secv ::= Etichete Instrneet Linstr
    Greseala ::= [ "," Tipelem Greseala ]
    Listdim ::= [ "(" Listvirg ")" ]
    Tipt ::= Tipelem | idtipinreg
    Rinel1 ::= Irinel1 | id Cinel1
    Etichete ::= [ et ":" Etichete ]
    Instrneet ::= [ BLOCK Corpbloc ENDBLOCK |
      Iciclucont TOK Expr DO Corpbloc REP | GOTO Expr |
      IF Cond THEN Secv Lelseif Else ENDIF | RETURN Int |
      SWITCH Expr OF id Listid | VAL id Lconstr ":=" Rval |
      WHILE Cond DO Secv REP | id Exec | secvcod ]
    Linstr ::= [ ";" Secv ]
    Listvirg ::= [ "," Listvirg ]
    Irinel1 ::= Numar | plumi Numar | sir | "(" Ivali1 "," Livali1 ")"
    Cinel1 ::= Lconstr1 | ":=" Rinel1
    Iciclucont ::= [ FOR id ":=" Expr By ]
    Expr ::= Nuvar Sfexpr | id Restexpr Sfexpr | Opun Expr
    Cond ::= Expr comparator Expr Restcond
    Lelseif ::= [ ELSEIF Cond THEN Secv Lelseif ]
    Else ::= [ ELSE Secv ]
    Int ::= [ "(" Expr ")" ]
    Lconstr ::= [ "." id Lconstr | "(" Expr Lexpr ")" Lconstr ]
    Rval ::= VAL id Lconstr ":=" Rval | Nuvar Sfexpr | Opun Expr | id Rv1
    Exec ::= ":=" Rval | "." id Exec | "(" Rexec ")"
    Numar ::= fractie | intreg | real
    Ivali1 ::= Irinel1 Vali
    Livali1 ::= [ "," Ivali1 Livali1 ]
    By ::= [ BY Expr ]
    Nuvar ::= Numar | sir | "(" Expr ")" |
      IF Cond THEN Expr Rec ELSE Expr ENDIF
    Sfexpr ::= [ Opbin Expr ]
    Restexpr ::= [ "." id Restexpr | "(" Reste ]
    Opun ::= tipobisnuit | plumi | altopun
    Restcond ::= [oplog Cond ]
    Lexpr ::= [ "," Expr Lexpr ]
    Rv1 ::= [ Opbin Expr | ":=" Rval | "(" Rv2 | "." id Rv1 ]
    Rexec ::= ")" | Expr Lexpr ")" Rex
    Vali ::= [ "(" intreg ")" ]
    Lconstr1 ::= [ "." id Lconstr1 | "(" intreg ")" Lconstr1 ]
    Rec ::= [ ELSEIF Cond THEN Expr Rec ]
    Opbin ::= plumi | altopbin
    Reste ::= ")" | Expr Lexpr ")" Restexpr
    Rv2 ::= ")" Sfexpr | Expr Lexpr ")" Rv1
    Rex ::= [ Exec ]
    Inel2 ::= [ ":=" Rpval2 ]
    Linitel2 ::= [ "," id Inel2 Linitel2 ]
    Rpval2 ::= Opun Expr | Nuvar Sfexpr | id Rvp2
    Rvp2 ::= ":=" Rpval2 | Rvp3
    Rvp3 ::= [ Opbin Expr | "(" Rvp4 | "." id Rvp3 ]
    Rvp4 ::= ")" Sfexpr | Expr Lexpr ")" Rvp3

    End LPTR language gramar