LCOV - code coverage report
Current view: top level - builds/barbot/Cosmos/src/ModelGenerator - expressionStruct.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 115 263 43.7 %
Date: 2021-06-16 15:43:28 Functions: 17 18 94.4 %

          Line data    Source code
       1             : /*******************************************************************************
       2             :  *                                                                             *
       3             :  * Cosmos:(C)oncept et (O)utils (S)tatistique pour les (Mo)deles               *
       4             :  * (S)tochastiques                                                             *
       5             :  *                                                                             *
       6             :  * Copyright (C) 2009-2012 LSV & LACL                                          *
       7             :  * Authors: Paolo Ballarini BenoƮt Barbot & Hilal Djafri                       *
       8             :  * Website: http://www.lsv.ens-cachan.fr/Software/cosmos                       *
       9             :  *                                                                             *
      10             :  * This program is free software; you can redistribute it and/or modify        *
      11             :  * it under the terms of the GNU General Public License as published by        *
      12             :  * the Free Software Foundation; either version 3 of the License, or           *
      13             :  * (at your option) any later version.                                         *
      14             :  *                                                                             *
      15             :  * This program is distributed in the hope that it will be useful,             *
      16             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of              *
      17             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               *
      18             :  * GNU General Public License for more details.                                *
      19             :  *                                                                             *
      20             :  * You should have received a copy of the GNU General Public License along     *
      21             :  * with this program; if not, write to the Free Software Foundation, Inc.,     *
      22             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.                 *
      23             :  * file expressionStruct.cpp                                                   *
      24             :  * Created by Benoit Barbot on 17/04/14.                                       *
      25             :  *******************************************************************************
      26             :  */
      27             : 
      28             : 
      29             : #include <cmath>
      30             : #include <sstream>
      31             : 
      32             : #include "expressionStruct.hpp"
      33             : 
      34             : using namespace std;
      35             : 
      36        6118 : std::ostream& text_output::operator<<(std::ostream& os, const expr& e)
      37             : {
      38        6118 :   switch (e.t) {
      39             :   case Empty:
      40           0 :     break;
      41         953 :   case UnParsed: os << e.stringVal << " ";
      42         953 :     break;
      43           0 :   case ColouredPlaceHolder: os << "COLOURED ";
      44           0 :     break;
      45          23 :   case Bool: os  << e.boolVal << " ";
      46          23 :     break;
      47        1318 :   case Int: os << e.intVal << " ";
      48        1318 :     break;
      49        3395 :   case Real: os << e.realVal << " ";
      50        3395 :     break;
      51          40 :   case PlaceName: os << " Marking.P->_PL_" << e.stringVal << " ";
      52          40 :     break;
      53          60 :   case ColorVarName: os << " bl.P->" << e.stringVal << ".c0 ";
      54          60 :     break;
      55          91 :   case Constant: os  << e.stringVal << " ";
      56          91 :     break;
      57           0 :   case Ceil: os << " ceil(" << *(e.lhs) << ") ";
      58           0 :     break;
      59           0 :   case Floor: os << " floor(" << *(e.lhs) << ") ";
      60           0 :     break;
      61           0 :   case Exp: os << " exp(" << *(e.lhs) << ") ";
      62           0 :     break;
      63           0 :   case Plus: os << " (" << *(e.lhs) << " + " << *(e.rhs) << ") ";
      64           0 :     break;
      65          40 :   case Times: os << " (" << *(e.lhs) << " * " << *(e.rhs) << ") ";
      66          40 :     break;
      67           0 :   case Minus: os << " (" << *(e.lhs) << " - " << *(e.rhs) << ") ";
      68           0 :     break;
      69          10 :   case Div: os << " (" << *(e.lhs) << " / (double) " << *(e.rhs) << ") ";
      70          10 :     break;
      71           0 :   case Min: os << " min(" << *(e.lhs) << ", " << *(e.rhs) << ") ";
      72           0 :     break;
      73           0 :   case Max: os << " max(" << *(e.lhs) << ", " << *(e.rhs) << ") ";
      74           0 :     break;
      75          40 :   case Pow: os << " pow(" << *(e.lhs) << ", " << *(e.rhs) << ") ";
      76          40 :     break;
      77           0 :   case Neg: os << " !(" << *(e.lhs) << ") ";
      78           0 :     break;
      79           0 :   case And: os << " (" << *(e.lhs) << " && " << *(e.rhs) << ") ";
      80           0 :     break;
      81          68 :   case Or: os << " (" << *(e.lhs) << " || " << *(e.rhs) << ") ";
      82          68 :     break;
      83          80 :   case Eq: os << " (" << *(e.lhs) << " == " << *(e.rhs) << ") ";
      84          80 :     break;
      85           0 :   case Neq: os << " (" << *(e.lhs) << " != " << *(e.rhs) << ") ";
      86           0 :     break;
      87           0 :   case Leq: os << " (" << *(e.lhs) << " <= " << *(e.rhs) << ") ";
      88           0 :     break;
      89           0 :   case Sl: os << " (" << *(e.lhs) << " < " << *(e.rhs) << ") ";
      90           0 :     break;
      91           0 :   case Geq: os << " (" << *(e.lhs) << " >= " << *(e.rhs) << ") ";
      92           0 :     break;
      93           0 :   case SG: os << " (" << *(e.lhs) << " > " << *(e.rhs) << ") ";
      94           0 :     break;
      95           0 :   case In: os << " contains(" <<*(e.lhs) <<" , " << *(e.rhs) << ") ";
      96           0 :     break;
      97           0 :   case NotIn: os << " !contains((" << *(e.lhs) <<" , " << *(e.rhs) << ") ";
      98           0 :     break;
      99           0 :   case ListContinuation: os << *(e.lhs) << " , " << *(e.rhs);
     100           0 :     break;
     101           0 :   case Var: os << e.lhs->stringVal; break;
     102           0 :   case Lambda: os << "([] (auto "<< e.lhs->stringVal << "){" << *(e.rhs) << "})"; break;
     103           0 :   case App: os << "("<<  e.lhs->stringVal << "(" << *(e.rhs) << "))"; break;
     104             : 
     105             :   }
     106        6118 :   return os;
     107             : }
     108             : 
     109          54 : bool operator< (const expr &lhs, const expr &rhs){
     110          54 :     if(lhs.is_concrete() && rhs.is_concrete()){
     111          54 :         return lhs.get_real() < rhs.get_real();
     112             :     }
     113           0 :     if( lhs.t == Bool && rhs.t == Bool)return lhs.boolVal < rhs.boolVal;
     114             :     
     115           0 :     return true;
     116             : }
     117             : 
     118          55 : bool operator== (const expr &lhs, const expr &rhs){
     119          55 :     return (lhs.t == rhs.t
     120          55 :             && (lhs.t != Bool || lhs.boolVal == rhs.boolVal)
     121          55 :             && (lhs.t != Int || lhs.intVal == rhs.intVal)
     122          55 :             && (lhs.t != Real || lhs.realVal == rhs.realVal)
     123         165 :             && ((lhs.t == Bool || lhs.t == Int || lhs.t == Real)
     124          55 :                 && lhs.stringVal == rhs.stringVal
     125          55 :                 && lhs.lhs == rhs.lhs
     126          55 :                 && lhs.rhs == rhs.rhs)
     127          55 :             );
     128             : }
     129          55 : bool operator!= (const expr &lhs, const expr &rhs){
     130          55 :     return !(lhs == rhs);
     131             : }
     132             : 
     133             : 
     134        1519 : string expr::to_string()const {
     135             :   using namespace text_output;
     136        3038 :   stringstream ss;
     137        1519 :   ss << *this;
     138        3038 :   return ss.str();
     139             : }
     140             : 
     141         152 : std::ostream& xml_output::operator<<(std::ostream& os, const expr& e){
     142         152 :   switch (e.t) {
     143             :   case Empty:
     144           0 :     break;
     145           0 :   case UnParsed: os << "<attribute name=\"expr\"><attribute name=\"unParsed\">"<< e.stringVal << "</attribute></attribute>";
     146           0 :     break;
     147           0 :   case ColouredPlaceHolder: os << "<attribute name=\"expr\"><attribute name=\"unParsed\">COLOURED</attribute></attribute>";
     148           0 :     break;
     149           0 :   case Bool: os << "<attribute name=\"expr\"><attribute name=\"boolValue\">"<< boolalpha << e.boolVal << "</attribute></attribute>";
     150           0 :     break;
     151         128 :   case Int:  os << "<attribute name=\"expr\"><attribute name=\"intValue\">"<< e.intVal << "</attribute></attribute>";
     152         128 :     break;
     153           0 :   case Real: os << "<attribute name=\"expr\"><attribute name=\"numValue\">"<< e.realVal << "</attribute></attribute>";
     154           0 :     break;
     155           0 :   case PlaceName: os << "<attribute name=\"expr\"><attribute name=\"name\">"<< e.stringVal << "</attribute></attribute>";
     156           0 :     break;
     157          24 :   case Constant: os << "<attribute name=\"expr\"><attribute name=\"name\">"<< e.stringVal << "</attribute></attribute>";
     158          24 :     break;
     159             :   case Plus:
     160           0 :     os << "<attribute name=\"expr\"><attribute name=\"function\"><attribute name=\"+\">" << e.lhs << e.rhs;
     161           0 :     os << "</attribute></attribute></attribute>";
     162           0 :     break;
     163             :   case Times:
     164           0 :     os << "<attribute name=\"expr\"><attribute name=\"function\"><attribute name=\"*\">" << e.lhs << e.rhs;
     165           0 :     os << "</attribute></attribute></attribute>";
     166           0 :     break;
     167             :   case Minus:
     168           0 :     os << "<attribute name=\"expr\"><attribute name=\"function\"><attribute name=\"-\">"<< e.lhs << e.rhs;
     169           0 :     os << "</attribute></attribute></attribute>";
     170           0 :     break;
     171             : 
     172             :   case Div:
     173           0 :     os << "<attribute name=\"expr\"><attribute name=\"function\"><attribute name=\"/\">"<< e.lhs << e.rhs;
     174           0 :     os << "</attribute></attribute></attribute>";
     175           0 :     break;
     176             :   default:
     177           0 :     cerr << "PrintXML Not yet implemented";
     178           0 :     exit(EXIT_FAILURE);
     179             :   }
     180         152 :   return os;
     181             : }
     182             : 
     183         372 : double expr::get_real()const{
     184         372 :   if(t==Int) return (double)intVal;
     185         258 :   else if(t==Real) return realVal;
     186           0 :   else return NAN;
     187             : 
     188             : }
     189          22 : expType expr::mix(const expr &le,const expr &re)const{
     190          22 :   const auto l=le.t;
     191          22 :   const auto r=re.t;
     192          22 :   if (l == Int && r ==Int)return Int;
     193           6 :   else if ((l == Real && r ==Int)|| (l == Int && r == Real)|| (l == Real && r ==Real))
     194           6 :     return Real;
     195           0 :   else if(le.is_concrete() && re.is_concrete())
     196           0 :     return Bool;
     197           0 :   else return Plus;
     198             : }
     199             : 
     200        1677 : bool expr::is_concrete()const{
     201        1677 :   return (t== Int || t == Real || t==boolVal);
     202             : }
     203             : 
     204          96 : bool expr::empty()const{
     205          96 :   return (t==Empty || (t==UnParsed && stringVal.empty()));
     206             : }
     207             : 
     208           0 : bool expr::is_zero()const{
     209           0 :   return empty() || (t== Int && intVal == 0) || ( t == Real && realVal == 0.0);
     210             : }
     211             : 
     212         100 : void expr::rewrite( function<void(expr&)> f){
     213         100 :   switch (t) {
     214             :   case Constant:
     215             :   case Empty:
     216             :   case UnParsed:
     217             :   case PlaceName:
     218             :   case Bool:
     219             :   case Int:
     220             :   case Real:
     221             :   case Var:
     222             :   case Lambda:
     223             :   case ColouredPlaceHolder:
     224             :   case ColorVarName:
     225             :     // 0-ary
     226          63 :     f(*this);
     227          63 :     break;
     228             : 
     229             :   case App:
     230             :     //unary right
     231           0 :     rhs->rewrite(f);
     232           0 :     f(*this);
     233           0 :     break;
     234             :     
     235             :   case Ceil:
     236             :   case Floor:
     237             :   case Neg:
     238             :   case Exp:
     239             :     //unary left
     240           0 :     lhs->rewrite(f);
     241           0 :     f(*this);
     242           0 :     break;
     243             :     
     244             :   case In:
     245             :   case NotIn:
     246             :   case Plus:
     247             :   case Times:
     248             :   case Minus:
     249             :   case Div:
     250             :   case Min:
     251             :   case Max:
     252             :   case Pow:
     253             :   case And:
     254             :   case Or:
     255             :   case Eq:
     256             :   case Neq:
     257             :   case Leq:
     258             :   case Sl:
     259             :   case Geq:
     260             :   case SG:
     261             :   case ListContinuation:
     262             :     //binary
     263          37 :     lhs->rewrite(f);
     264          37 :     rhs->rewrite(f);
     265          37 :     f(*this);
     266          37 :     break;
     267             :   }
     268         100 : }
     269             :   
     270             : 
     271         469 : void expr::eval(const map<string,int> &intconst,const map<string,double> &realconst){
     272         469 :   switch (t) {
     273             :   case Constant:
     274             :     {
     275          11 :       const auto it = intconst.find(stringVal);
     276          11 :       if(it != intconst.end()){
     277          11 :         t=Int;
     278          11 :         intVal = it->second;
     279             :       }else{
     280           0 :         const auto it = realconst.find(stringVal);
     281           0 :         if(it != realconst.end()){
     282           0 :           t=Real;
     283           0 :           realVal = it->second;
     284             :         }
     285             :       }
     286             :     }
     287          11 :     break;
     288             :   case Empty:
     289             :   case UnParsed:
     290             :   case PlaceName:
     291             :   case Bool:
     292             :   case Int:
     293             :   case Real:
     294             :   case Var:
     295             :   case Lambda:
     296             :   case ColouredPlaceHolder:
     297             :   case In:
     298             :   case NotIn:
     299             :   case ColorVarName:
     300         436 :     break;
     301             :   case App:
     302           0 :     rhs->eval(intconst,realconst);
     303           0 :     break;
     304             :   case ListContinuation:
     305           0 :     lhs->eval(intconst,realconst);
     306           0 :     rhs->eval(intconst,realconst);
     307           0 :     break;
     308             :   case Ceil:
     309             :   case Floor:
     310             :   case Neg:
     311             :   case Exp:
     312           0 :     lhs->eval(intconst,realconst);
     313           0 :     if (lhs->t==Int){
     314           0 :       expr tmp = *lhs;
     315           0 :       *this= tmp;
     316           0 :     } else if(lhs->t==Real){
     317           0 :       if(t==Floor)intVal = (int)floor(lhs->realVal);
     318           0 :       else intVal=(int)ceil(lhs->realVal);
     319           0 :       t= Int;
     320           0 :       lhs.reset();
     321           0 :     } else if(lhs->t==Bool){
     322           0 :       t=Bool;
     323           0 :       boolVal = !lhs->boolVal;
     324           0 :       lhs.reset();
     325             :     }
     326           0 :     break;
     327             :   case Plus:
     328             :   case Times:
     329             :   case Minus:
     330             :   case Div:
     331             :   case Min:
     332             :   case Max:
     333             :   case Pow:
     334             :   case And:
     335             :   case Or:
     336             :   case Eq:
     337             :   case Neq:
     338             :   case Leq:
     339             :   case Sl:
     340             :   case Geq:
     341             :   case SG:
     342          22 :     lhs->eval(intconst,realconst);
     343          22 :     rhs->eval(intconst,realconst);
     344          22 :     expType t2=mix(*rhs,*lhs);
     345          22 :     if(t2==Int) {
     346          16 :       switch (t) {
     347          16 :       case Plus: intVal = lhs->intVal + rhs->intVal;
     348          16 :         break;
     349           0 :       case Times: intVal = lhs->intVal * rhs->intVal;
     350           0 :         break;
     351           0 :       case Minus: intVal = lhs->intVal - rhs->intVal;
     352           0 :         break;
     353           0 :       case Div: intVal = lhs->intVal / rhs->intVal;
     354           0 :         break;
     355           0 :       case Min: intVal = min(lhs->intVal,rhs->intVal);
     356           0 :         break;
     357           0 :       case Max: intVal = max(lhs->intVal,rhs->intVal);
     358           0 :         break;
     359           0 :       case Pow: intVal = (lhs->intVal)^(rhs->intVal);
     360           0 :         break;
     361             :       default:
     362           0 :         break;
     363             :       }
     364          16 :       t = Int;
     365          16 :       lhs.reset();
     366          16 :       rhs.reset();
     367           6 :     } else if (t2==Real ){
     368           6 :       switch (t) {
     369           0 :       case Plus: realVal = lhs->get_real() + rhs->get_real();
     370           0 :         break;
     371           6 :       case Times: realVal = lhs->get_real() * rhs->get_real();
     372           6 :         break;
     373           0 :       case Minus: realVal = lhs->get_real() - rhs->get_real();
     374           0 :         break;
     375           0 :       case Div: realVal = lhs->get_real() / rhs->get_real();
     376           0 :         break;
     377           0 :       case Min: realVal = min(lhs->get_real(),rhs->get_real());
     378           0 :         break;
     379           0 :       case Max: realVal = max(lhs->get_real(),rhs->get_real());
     380           0 :         break;
     381           0 :       case Pow: realVal = pow(lhs->get_real(),rhs->get_real());
     382           0 :         break;
     383             :       default:
     384           0 :         break;
     385             :       }
     386           6 :       t = Real;
     387           6 :       lhs.reset();
     388           6 :       rhs.reset();
     389           0 :     } else if (t2 == Bool){
     390           0 :       switch (t) {
     391           0 :       case And: boolVal = lhs->boolVal && rhs->boolVal;
     392           0 :         break;
     393           0 :       case Or: boolVal = lhs->boolVal || rhs->boolVal;
     394           0 :         break;
     395           0 :       case Eq: boolVal = lhs->get_real() == rhs->get_real();
     396           0 :         break;
     397           0 :       case Leq: boolVal = lhs->get_real() <= rhs->get_real();
     398           0 :         break;
     399           0 :       case Sl: boolVal = lhs->get_real() < rhs->get_real();
     400           0 :         break;
     401           0 :       case Geq: boolVal = lhs->get_real() >= rhs->get_real();
     402           0 :         break;
     403           0 :       case SG: boolVal = lhs->get_real() > rhs->get_real();
     404           0 :         break;
     405             :       default:
     406           0 :         break;
     407             :       }
     408           0 :       t = Bool;
     409           0 :       lhs.reset();
     410           0 :       rhs.reset();
     411             :     }
     412          22 :     break;
     413             :   }
     414         469 : }
     415             : 
     416             : 
     417             : 
     418          64 : void expr::eval(){
     419          64 :   eval(map<string,int>(), map<string,double>());
     420          64 : }
     421             : 
     422        5711 : void expr::get_places(set<string> & acset)const{
     423        5711 :   if(t==PlaceName)acset.insert(stringVal);
     424        5711 :   if(lhs.use_count()>0)lhs->get_places(acset);
     425        5711 :   if(rhs.use_count()>0)rhs->get_places(acset);
     426        5711 : }
     427             : 
     428        3243 : bool expr::is_markDep()const{
     429        6486 :   set<string> accset;
     430        3243 :   get_places(accset);
     431        6486 :   return !accset.empty();
     432         105 : }

Generated by: LCOV version 1.13