LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/parser - symbol_table.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 216 265 81.5 %
Date: 2026-03-20 10:41:15 Functions: 46 49 93.9 %
Branches: 86 158 54.4 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * This file is part of the cvc5 project.
       3                 :            :  *
       4                 :            :  * Copyright (c) 2009-2026 by the authors listed in the file AUTHORS
       5                 :            :  * in the top-level source directory and their institutional affiliations.
       6                 :            :  * All rights reserved.  See the file COPYING in the top-level source
       7                 :            :  * directory for licensing information.
       8                 :            :  * ****************************************************************************
       9                 :            :  *
      10                 :            :  * Convenience class for scoping variable and type declarations
      11                 :            :  * (implementation).
      12                 :            :  */
      13                 :            : 
      14                 :            : #include "parser/symbol_table.h"
      15                 :            : 
      16                 :            : #include <cvc5/cvc5.h>
      17                 :            : 
      18                 :            : #include <ostream>
      19                 :            : #include <string>
      20                 :            : #include <unordered_map>
      21                 :            : #include <utility>
      22                 :            : 
      23                 :            : #include "base/check.h"
      24                 :            : #include "context/cdhashmap.h"
      25                 :            : #include "context/cdhashset.h"
      26                 :            : #include "context/context.h"
      27                 :            : 
      28                 :            : namespace cvc5::internal::parser {
      29                 :            : 
      30                 :            : using context::CDHashMap;
      31                 :            : using context::CDHashSet;
      32                 :            : using context::Context;
      33                 :            : using std::copy;
      34                 :            : using std::endl;
      35                 :            : using std::ostream_iterator;
      36                 :            : using std::pair;
      37                 :            : using std::string;
      38                 :            : using std::vector;
      39                 :            : 
      40                 :            : /** Overloaded type trie.
      41                 :            :  *
      42                 :            :  * This data structure stores a trie of expressions with
      43                 :            :  * the same name, and must be distinguished by their argument types.
      44                 :            :  * It is context-dependent.
      45                 :            :  *
      46                 :            :  * Using the argument allowFunVariants,
      47                 :            :  * it may either be configured to allow function variants or not,
      48                 :            :  * where a function variant is function that expects the same
      49                 :            :  * argument types as another.
      50                 :            :  *
      51                 :            :  * For example, the following definitions introduce function
      52                 :            :  * variants for the symbol f:
      53                 :            :  *
      54                 :            :  * 1. (declare-fun f (Int) Int) and
      55                 :            :  *    (declare-fun f (Int) Bool)
      56                 :            :  *
      57                 :            :  * 2. (declare-fun f (Int) Int) and
      58                 :            :  *    (declare-fun f (Int) Int)
      59                 :            :  *
      60                 :            :  * 3. (declare-datatypes ((Tup 0)) ((f (data Int)))) and
      61                 :            :  *    (declare-fun f (Int) Tup)
      62                 :            :  *
      63                 :            :  * 4. (declare-datatypes ((Tup 0)) ((mkTup (f Int)))) and
      64                 :            :  *    (declare-fun f (Tup) Bool)
      65                 :            :  *
      66                 :            :  * If function variants is set to true, we allow function variants
      67                 :            :  * but not function redefinition. In examples 2 and 3, f is
      68                 :            :  * declared twice as a symbol of identical argument and range
      69                 :            :  * types. We never accept these definitions. However, we do
      70                 :            :  * allow examples 1 and 4 above when allowFunVariants is true.
      71                 :            :  *
      72                 :            :  * For 0-argument functions (constants), we always allow
      73                 :            :  * function variants.  That is, we always accept these examples:
      74                 :            :  *
      75                 :            :  * 5.  (declare-fun c () Int)
      76                 :            :  *     (declare-fun c () Bool)
      77                 :            :  *
      78                 :            :  * 6.  (declare-datatypes ((Enum 0)) ((c)))
      79                 :            :  *     (declare-fun c () Int)
      80                 :            :  *
      81                 :            :  * and always reject constant redefinition such as:
      82                 :            :  *
      83                 :            :  * 7. (declare-fun c () Int)
      84                 :            :  *    (declare-fun c () Int)
      85                 :            :  *
      86                 :            :  * 8. (declare-datatypes ((Enum 0)) ((c))) and
      87                 :            :  *    (declare-fun c () Enum)
      88                 :            :  */
      89                 :            : class OverloadedTypeTrie
      90                 :            : {
      91                 :            :  public:
      92                 :      28645 :   OverloadedTypeTrie(Context* c, bool allowFunVariants = false)
      93                 :      28645 :       : d_overloaded_symbols(new (true) CDHashSet<Term, std::hash<Term>>(c)),
      94                 :      28645 :         d_allowFunctionVariants(allowFunVariants)
      95                 :            :   {
      96                 :      28645 :   }
      97                 :      28596 :   ~OverloadedTypeTrie() { d_overloaded_symbols->deleteSelf(); }
      98                 :            : 
      99                 :            :   /** is this function overloaded? */
     100                 :            :   bool isOverloadedFunction(Term fun) const;
     101                 :            : 
     102                 :            :   /** Get overloaded constant for type.
     103                 :            :    * If possible, it returns a defined symbol with name
     104                 :            :    * that has type t. Otherwise returns null expression.
     105                 :            :    */
     106                 :            :   Term getOverloadedConstantForType(const std::string& name, Sort t) const;
     107                 :            : 
     108                 :            :   /**
     109                 :            :    * If possible, returns a defined function for a name
     110                 :            :    * and a vector of expected argument types. Otherwise returns
     111                 :            :    * null expression.
     112                 :            :    */
     113                 :            :   Term getOverloadedFunctionForTypes(const std::string& name,
     114                 :            :                                      const std::vector<Sort>& argTypes) const;
     115                 :            :   /** called when obj is bound to name, and prev_bound_obj was already bound to
     116                 :            :    * name Returns false if the binding is invalid.
     117                 :            :    */
     118                 :            :   bool bind(const string& name, Term prev_bound_obj, Term obj);
     119                 :            : 
     120                 :            :  private:
     121                 :            :   /** Marks expression obj with name as overloaded.
     122                 :            :    * Adds relevant information to the type arg trie data structure.
     123                 :            :    * It returns false if there is already an expression bound to that name
     124                 :            :    * whose type expects the same arguments as the type of obj but is not
     125                 :            :    * identical to the type of obj.  For example, if we declare :
     126                 :            :    *
     127                 :            :    * (declare-datatypes () ((List (cons (hd Int) (tl List)) (nil))))
     128                 :            :    * (declare-fun cons (Int List) List)
     129                 :            :    *
     130                 :            :    * cons : constructor_type( Int, List, List )
     131                 :            :    * cons : function_type( Int, List, List )
     132                 :            :    *
     133                 :            :    * These are put in the same place in the trie but do not have identical type,
     134                 :            :    * hence we return false.
     135                 :            :    */
     136                 :            :   bool markOverloaded(const string& name, Term obj);
     137                 :            :   /** the null expression */
     138                 :            :   Term d_nullTerm;
     139                 :            :   // The (context-independent) trie storing that maps expected argument
     140                 :            :   // vectors to symbols. All expressions stored in d_symbols are only
     141                 :            :   // interpreted as active if they also appear in the context-dependent
     142                 :            :   // set d_overloaded_symbols.
     143                 :            :   class TypeArgTrie
     144                 :            :   {
     145                 :            :    public:
     146                 :            :     // children of this node
     147                 :            :     std::map<Sort, TypeArgTrie> d_children;
     148                 :            :     // symbols at this node
     149                 :            :     std::map<Sort, Term> d_symbols;
     150                 :            :   };
     151                 :            :   /** for each string with operator overloading, this stores the data structure
     152                 :            :    * above. */
     153                 :            :   std::unordered_map<std::string, TypeArgTrie> d_overload_type_arg_trie;
     154                 :            :   /** The set of overloaded symbols. */
     155                 :            :   CDHashSet<Term, std::hash<Term>>* d_overloaded_symbols;
     156                 :            :   /** allow function variants
     157                 :            :    * This is true if we allow overloading (non-constant) functions that expect
     158                 :            :    * the same argument types.
     159                 :            :    */
     160                 :            :   bool d_allowFunctionVariants;
     161                 :            :   /** get unique overloaded function
     162                 :            :    * If tat->d_symbols contains an active overloaded function, it
     163                 :            :    * returns that function, where that function must be unique
     164                 :            :    * if reqUnique=true.
     165                 :            :    * Otherwise, it returns the null expression.
     166                 :            :    */
     167                 :            :   Term getOverloadedFunctionAt(const TypeArgTrie* tat,
     168                 :            :                                bool reqUnique = true) const;
     169                 :            : };
     170                 :            : 
     171                 :    6283953 : bool OverloadedTypeTrie::isOverloadedFunction(Term fun) const
     172                 :            : {
     173                 :    6283953 :   return d_overloaded_symbols->find(fun) != d_overloaded_symbols->end();
     174                 :            : }
     175                 :            : 
     176                 :          6 : Term OverloadedTypeTrie::getOverloadedConstantForType(const std::string& name,
     177                 :            :                                                       Sort t) const
     178                 :            : {
     179                 :            :   std::unordered_map<std::string, TypeArgTrie>::const_iterator it =
     180                 :          6 :       d_overload_type_arg_trie.find(name);
     181         [ +  - ]:          6 :   if (it != d_overload_type_arg_trie.end())
     182                 :            :   {
     183                 :          6 :     std::map<Sort, Term>::const_iterator its = it->second.d_symbols.find(t);
     184         [ +  - ]:          6 :     if (its != it->second.d_symbols.end())
     185                 :            :     {
     186                 :          6 :       Term expr = its->second;
     187                 :            :       // must be an active symbol
     188         [ +  - ]:          6 :       if (isOverloadedFunction(expr))
     189                 :            :       {
     190                 :          6 :         return expr;
     191                 :            :       }
     192         [ -  + ]:          6 :     }
     193                 :            :   }
     194                 :          0 :   return d_nullTerm;
     195                 :            : }
     196                 :            : 
     197                 :        836 : Term OverloadedTypeTrie::getOverloadedFunctionForTypes(
     198                 :            :     const std::string& name, const std::vector<Sort>& argTypes) const
     199                 :            : {
     200                 :            :   std::unordered_map<std::string, TypeArgTrie>::const_iterator it =
     201                 :        836 :       d_overload_type_arg_trie.find(name);
     202         [ +  - ]:        836 :   if (it != d_overload_type_arg_trie.end())
     203                 :            :   {
     204                 :        836 :     const TypeArgTrie* tat = &it->second;
     205         [ +  + ]:       2152 :     for (unsigned i = 0; i < argTypes.size(); i++)
     206                 :            :     {
     207                 :            :       std::map<Sort, TypeArgTrie>::const_iterator itc =
     208                 :       1316 :           tat->d_children.find(argTypes[i]);
     209         [ +  - ]:       1316 :       if (itc != tat->d_children.end())
     210                 :            :       {
     211                 :       1316 :         tat = &itc->second;
     212                 :            :       }
     213                 :            :       else
     214                 :            :       {
     215         [ -  - ]:          0 :         Trace("parser-overloading")
     216                 :          0 :             << "Could not find overloaded function " << name << std::endl;
     217                 :            : 
     218                 :            :         // no functions match
     219                 :          0 :         return d_nullTerm;
     220                 :            :       }
     221                 :            :     }
     222                 :            :     // we ensure that there is *only* one active symbol at this node
     223                 :        836 :     return getOverloadedFunctionAt(tat);
     224                 :            :   }
     225                 :          0 :   return d_nullTerm;
     226                 :            : }
     227                 :            : 
     228                 :        515 : bool OverloadedTypeTrie::bind(const string& name, Term prev_bound_obj, Term obj)
     229                 :            : {
     230 [ -  + ][ -  + ]:        515 :   Assert(prev_bound_obj != obj);
                 [ -  - ]
     231                 :        515 :   bool retprev = true;
     232         [ +  + ]:        515 :   if (!isOverloadedFunction(prev_bound_obj))
     233                 :            :   {
     234                 :            :     // mark previous as overloaded
     235                 :        362 :     retprev = markOverloaded(name, prev_bound_obj);
     236                 :            :   }
     237                 :            :   // mark this as overloaded
     238                 :        515 :   bool retobj = markOverloaded(name, obj);
     239 [ +  - ][ +  + ]:        515 :   return retprev && retobj;
     240                 :            : }
     241                 :            : 
     242                 :        877 : bool OverloadedTypeTrie::markOverloaded(const string& name, Term obj)
     243                 :            : {
     244         [ +  - ]:        877 :   Trace("parser-overloading") << "Overloaded function : " << name;
     245         [ +  - ]:       1754 :   Trace("parser-overloading")
     246 [ -  + ][ -  - ]:        877 :       << " with type " << obj.getSort() << ", obj is " << obj << std::endl;
     247                 :            :   // get the argument types
     248                 :        877 :   Sort t = obj.getSort();
     249                 :        877 :   Sort rangeType = t;
     250                 :        877 :   std::vector<Sort> argTypes;
     251         [ +  + ]:        877 :   if (t.isFunction())
     252                 :            :   {
     253                 :        196 :     argTypes = t.getFunctionDomainSorts();
     254                 :        196 :     rangeType = t.getFunctionCodomainSort();
     255                 :            :   }
     256         [ +  + ]:        681 :   else if (t.isDatatypeConstructor())
     257                 :            :   {
     258                 :        140 :     argTypes = t.getDatatypeConstructorDomainSorts();
     259                 :        140 :     rangeType = t.getDatatypeConstructorCodomainSort();
     260                 :            :   }
     261         [ +  + ]:        541 :   else if (t.isDatatypeSelector())
     262                 :            :   {
     263                 :        189 :     argTypes.push_back(t.getDatatypeSelectorDomainSort());
     264                 :        189 :     rangeType = t.getDatatypeSelectorCodomainSort();
     265                 :            :   }
     266                 :            :   // add to the trie
     267                 :        877 :   TypeArgTrie* tat = &d_overload_type_arg_trie[name];
     268         [ +  + ]:       1621 :   for (unsigned i = 0; i < argTypes.size(); i++)
     269                 :            :   {
     270                 :        744 :     tat = &(tat->d_children[argTypes[i]]);
     271                 :            :   }
     272                 :            : 
     273                 :            :   // check if function variants are allowed here
     274 [ +  - ][ +  + ]:        877 :   if (d_allowFunctionVariants || argTypes.empty())
                 [ +  + ]
     275                 :            :   {
     276                 :            :     // they are allowed, check for redefinition
     277                 :        352 :     std::map<Sort, Term>::iterator it = tat->d_symbols.find(rangeType);
     278         [ +  + ]:        352 :     if (it != tat->d_symbols.end())
     279                 :            :     {
     280                 :          2 :       Term prev_obj = it->second;
     281                 :            :       // if there is already an active function with the same name and expects
     282                 :            :       // the same argument types and has the same return type, we reject the
     283                 :            :       // re-declaration here.
     284         [ +  - ]:          2 :       if (isOverloadedFunction(prev_obj))
     285                 :            :       {
     286         [ +  - ]:          2 :         Trace("parser-overloading") << "...existing overload" << std::endl;
     287                 :          2 :         return false;
     288                 :            :       }
     289         [ -  + ]:          2 :     }
     290                 :            :   }
     291                 :            :   else
     292                 :            :   {
     293                 :            :     // they are not allowed, we cannot have any function defined here.
     294                 :        525 :     Term existingFun = getOverloadedFunctionAt(tat, false);
     295         [ -  + ]:        525 :     if (!existingFun.isNull())
     296                 :            :     {
     297         [ -  - ]:          0 :       Trace("parser-overloading")
     298                 :          0 :           << "...existing fun (no variant)" << std::endl;
     299                 :          0 :       return false;
     300                 :            :     }
     301         [ +  - ]:        525 :   }
     302         [ +  - ]:        875 :   Trace("parser-overloading") << "...update symbols" << std::endl;
     303                 :            : 
     304                 :            :   // otherwise, update the symbols
     305                 :        875 :   d_overloaded_symbols->insert(obj);
     306                 :        875 :   tat->d_symbols[rangeType] = obj;
     307                 :        875 :   return true;
     308                 :        877 : }
     309                 :            : 
     310                 :       1361 : Term OverloadedTypeTrie::getOverloadedFunctionAt(
     311                 :            :     const OverloadedTypeTrie::TypeArgTrie* tat, bool reqUnique) const
     312                 :            : {
     313                 :       1361 :   Term retExpr;
     314                 :       1361 :   for (std::map<Sort, Term>::const_iterator its = tat->d_symbols.begin();
     315         [ +  + ]:       2197 :        its != tat->d_symbols.end();
     316                 :        836 :        ++its)
     317                 :            :   {
     318                 :        836 :     Term expr = its->second;
     319         [ +  - ]:        836 :     if (isOverloadedFunction(expr))
     320                 :            :     {
     321         [ +  - ]:        836 :       if (retExpr.isNull())
     322                 :            :       {
     323         [ -  + ]:        836 :         if (!reqUnique)
     324                 :            :         {
     325                 :          0 :           return expr;
     326                 :            :         }
     327                 :            :         else
     328                 :            :         {
     329                 :        836 :           retExpr = expr;
     330                 :            :         }
     331                 :            :       }
     332                 :            :       else
     333                 :            :       {
     334                 :            :         // multiple functions match
     335                 :          0 :         return d_nullTerm;
     336                 :            :       }
     337                 :            :     }
     338         [ +  - ]:        836 :   }
     339                 :       1361 :   return retExpr;
     340                 :       1361 : }
     341                 :            : 
     342                 :            : class SymbolTable::Implementation
     343                 :            : {
     344                 :            :  public:
     345                 :      28645 :   Implementation()
     346                 :      28645 :       : d_context(),
     347                 :      28645 :         d_dummySortTerms(&d_context),
     348                 :      28645 :         d_exprMap(&d_context),
     349                 :      28645 :         d_typeMap(&d_context),
     350                 :      28645 :         d_overload_trie(&d_context)
     351                 :            :   {
     352                 :      28645 :   }
     353                 :            : 
     354                 :      28596 :   ~Implementation() {}
     355                 :            : 
     356                 :            :   bool bind(const string& name, Term obj, bool doOverload);
     357                 :            :   bool bindDummySortTerm(const std::string& name, Term t);
     358                 :            :   void bindType(const string& name, Sort t);
     359                 :            :   void bindType(const string& name, const vector<Sort>& params, Sort t);
     360                 :            :   bool isBound(const string& name) const;
     361                 :            :   bool isBoundType(const string& name) const;
     362                 :            :   Term lookup(const string& name) const;
     363                 :            :   Sort lookupType(const string& name) const;
     364                 :            :   Sort lookupType(const string& name, const vector<Sort>& params) const;
     365                 :            :   size_t lookupArity(const string& name);
     366                 :            :   void popScope();
     367                 :            :   void pushScope();
     368                 :            :   size_t getLevel() const;
     369                 :            :   void reset();
     370                 :            :   void resetAssertions();
     371                 :            :   //------------------------ operator overloading
     372                 :            :   /** implementation of function from header */
     373                 :            :   bool isOverloadedFunction(Term fun) const;
     374                 :            : 
     375                 :            :   /** implementation of function from header */
     376                 :            :   Term getOverloadedConstantForType(const std::string& name, Sort t) const;
     377                 :            : 
     378                 :            :   /** implementation of function from header */
     379                 :            :   Term getOverloadedFunctionForTypes(const std::string& name,
     380                 :            :                                      const std::vector<Sort>& argTypes) const;
     381                 :            :   //------------------------ end operator overloading
     382                 :            :  private:
     383                 :            :   /** The context manager for the scope maps. */
     384                 :            :   Context d_context;
     385                 :            :   /** The set of dummy sort terms we have bound. */
     386                 :            :   CDHashSet<Term> d_dummySortTerms;
     387                 :            : 
     388                 :            :   /** A map for expressions. */
     389                 :            :   CDHashMap<string, Term> d_exprMap;
     390                 :            : 
     391                 :            :   /** A map for types. */
     392                 :            :   using TypeMap = CDHashMap<string, std::pair<vector<Sort>, Sort>>;
     393                 :            :   TypeMap d_typeMap;
     394                 :            : 
     395                 :            :   //------------------------ operator overloading
     396                 :            :   /** the null term */
     397                 :            :   Term d_nullTerm;
     398                 :            :   /** The null sort */
     399                 :            :   Sort d_nullSort;
     400                 :            :   // overloaded type trie, stores all information regarding overloading
     401                 :            :   OverloadedTypeTrie d_overload_trie;
     402                 :            :   /** bind with overloading
     403                 :            :    * This is called whenever obj is bound to name where overloading symbols is
     404                 :            :    * allowed. If a symbol is previously bound to that name, it marks both as
     405                 :            :    * overloaded. Returns false if the binding was invalid.
     406                 :            :    */
     407                 :            :   bool bindWithOverloading(const string& name, Term obj);
     408                 :            :   //------------------------ end operator overloading
     409                 :            : }; /* SymbolTable::Implementation */
     410                 :            : 
     411                 :    1118638 : bool SymbolTable::Implementation::bind(const string& name,
     412                 :            :                                        Term obj,
     413                 :            :                                        bool doOverload)
     414                 :            : {
     415 [ -  + ][ -  + ]:    1118638 :   Assert(!obj.isNull()) << "cannot bind to a null Term";
                 [ -  - ]
     416         [ +  - ]:    2237276 :   Trace("sym-table") << "SymbolTable: bind " << name << " to " << obj
     417                 :    1118638 :                      << ", doOverload=" << doOverload << std::endl;
     418         [ +  + ]:    1118638 :   if (doOverload)
     419                 :            :   {
     420         [ +  + ]:     418655 :     if (!bindWithOverloading(name, obj))
     421                 :            :     {
     422                 :          4 :       return false;
     423                 :            :     }
     424                 :            :   }
     425                 :    1118634 :   d_exprMap.insert(name, obj);
     426                 :            : 
     427                 :    1118634 :   return true;
     428                 :            : }
     429                 :            : 
     430                 :          1 : bool SymbolTable::Implementation::bindDummySortTerm(const std::string& name,
     431                 :            :                                                     Term t)
     432                 :            : {
     433         [ -  + ]:          1 :   if (!bind(name, t, false))
     434                 :            :   {
     435                 :          0 :     return false;
     436                 :            :   }
     437                 :            :   // remember that it is a dummy sort term
     438                 :          1 :   d_dummySortTerms.insert(t);
     439                 :          1 :   return true;
     440                 :            : }
     441                 :            : 
     442                 :    1586042 : bool SymbolTable::Implementation::isBound(const string& name) const
     443                 :            : {
     444                 :    1586042 :   return d_exprMap.find(name) != d_exprMap.end();
     445                 :            : }
     446                 :            : 
     447                 :    6282605 : Term SymbolTable::Implementation::lookup(const string& name) const
     448                 :            : {
     449                 :    6282605 :   CDHashMap<string, Term>::const_iterator it = d_exprMap.find(name);
     450         [ +  + ]:    6282605 :   if (it == d_exprMap.end())
     451                 :            :   {
     452                 :         11 :     return d_nullTerm;
     453                 :            :   }
     454                 :    6282594 :   Term expr = it->second;
     455         [ +  + ]:    6282594 :   if (isOverloadedFunction(expr))
     456                 :            :   {
     457                 :        842 :     return d_nullTerm;
     458                 :            :   }
     459                 :    6281752 :   return expr;
     460                 :    6282594 : }
     461                 :            : 
     462                 :     205186 : void SymbolTable::Implementation::bindType(const string& name, Sort t)
     463                 :            : {
     464                 :     205186 :   d_typeMap.insert(name, make_pair(vector<Sort>(), t));
     465                 :     205186 : }
     466                 :            : 
     467                 :      12619 : void SymbolTable::Implementation::bindType(const string& name,
     468                 :            :                                            const vector<Sort>& params,
     469                 :            :                                            Sort t)
     470                 :            : {
     471         [ -  + ]:      12619 :   if (TraceIsOn("sort"))
     472                 :            :   {
     473         [ -  - ]:          0 :     Trace("sort") << "bindType(" << name << ", [";
     474         [ -  - ]:          0 :     if (params.size() > 0)
     475                 :            :     {
     476                 :          0 :       copy(params.begin(),
     477                 :          0 :            params.end() - 1,
     478         [ -  - ]:          0 :            ostream_iterator<Sort>(Trace("sort"), ", "));
     479         [ -  - ]:          0 :       Trace("sort") << params.back();
     480                 :            :     }
     481         [ -  - ]:          0 :     Trace("sort") << "], " << t << ")" << endl;
     482                 :            :   }
     483                 :            : 
     484                 :      12619 :   d_typeMap.insert(name, make_pair(params, t));
     485                 :      12619 : }
     486                 :            : 
     487                 :     434269 : bool SymbolTable::Implementation::isBoundType(const string& name) const
     488                 :            : {
     489                 :     434269 :   return d_typeMap.find(name) != d_typeMap.end();
     490                 :            : }
     491                 :            : 
     492                 :     625162 : Sort SymbolTable::Implementation::lookupType(const string& name) const
     493                 :            : {
     494                 :     625162 :   TypeMap::const_iterator it = d_typeMap.find(name);
     495         [ +  + ]:     625162 :   if (it == d_typeMap.end())
     496                 :            :   {
     497                 :          1 :     return d_nullSort;
     498                 :            :   }
     499                 :     625161 :   std::pair<std::vector<Sort>, Sort> p = it->second;
     500         [ -  + ]:     625161 :   if (p.first.size() != 0)
     501                 :            :   {
     502                 :          0 :     std::stringstream ss;
     503                 :          0 :     ss << "type constructor arity is wrong: `" << name << "' requires "
     504                 :          0 :        << p.first.size() << " parameters but was provided 0";
     505                 :          0 :     throw Exception(ss.str());
     506                 :          0 :   }
     507                 :     625161 :   return p.second;
     508                 :     625161 : }
     509                 :            : 
     510                 :       1583 : Sort SymbolTable::Implementation::lookupType(const string& name,
     511                 :            :                                              const vector<Sort>& params) const
     512                 :            : {
     513                 :       1583 :   TypeMap::const_iterator it = d_typeMap.find(name);
     514         [ +  + ]:       1583 :   if (it == d_typeMap.end())
     515                 :            :   {
     516                 :          2 :     return d_nullSort;
     517                 :            :   }
     518                 :       1581 :   std::pair<std::vector<Sort>, Sort> p = it->second;
     519         [ +  + ]:       1581 :   if (p.first.size() != params.size())
     520                 :            :   {
     521                 :          1 :     std::stringstream ss;
     522                 :          1 :     ss << "type constructor arity is wrong: `" << name.c_str() << "' requires "
     523                 :          1 :        << p.first.size() << " parameters but was provided " << params.size();
     524                 :          1 :     throw Exception(ss.str());
     525                 :          1 :   }
     526         [ -  + ]:       1580 :   if (p.first.size() == 0)
     527                 :            :   {
     528                 :          0 :     Assert(p.second.isUninterpretedSort());
     529                 :          0 :     return p.second;
     530                 :            :   }
     531         [ +  + ]:       1580 :   if (p.second.isDatatype())
     532                 :            :   {
     533 [ -  + ][ -  + ]:        533 :     Assert(p.second.getDatatype().isParametric())
                 [ -  - ]
     534                 :          0 :         << "expected parametric datatype";
     535                 :        533 :     return p.second.instantiate(params);
     536                 :            :   }
     537                 :            :   bool isUninterpretedSortConstructor =
     538                 :       1047 :       p.second.isUninterpretedSortConstructor();
     539         [ -  + ]:       1047 :   if (TraceIsOn("sort"))
     540                 :            :   {
     541         [ -  - ]:          0 :     Trace("sort") << "instantiating using a sort "
     542         [ -  - ]:          0 :                   << (isUninterpretedSortConstructor ? "constructor"
     543                 :          0 :                                                      : "substitution")
     544                 :          0 :                   << std::endl;
     545         [ -  - ]:          0 :     Trace("sort") << "have formals [";
     546                 :          0 :     copy(p.first.begin(),
     547                 :          0 :          p.first.end() - 1,
     548         [ -  - ]:          0 :          ostream_iterator<Sort>(Trace("sort"), ", "));
     549         [ -  - ]:          0 :     Trace("sort") << p.first.back() << "]" << std::endl << "parameters   [";
     550                 :          0 :     copy(params.begin(),
     551                 :          0 :          params.end() - 1,
     552         [ -  - ]:          0 :          ostream_iterator<Sort>(Trace("sort"), ", "));
     553         [ -  - ]:          0 :     Trace("sort") << params.back() << "]" << endl
     554                 :          0 :                   << "type ctor    " << name << std::endl
     555                 :          0 :                   << "type is      " << p.second << std::endl;
     556                 :            :   }
     557                 :            :   Sort instantiation = isUninterpretedSortConstructor
     558                 :            :                            ? p.second.instantiate(params)
     559         [ +  + ]:       1047 :                            : p.second.substitute(p.first, params);
     560         [ +  - ]:       1047 :   Trace("sort") << "instance is  " << instantiation << std::endl;
     561                 :            : 
     562                 :       1047 :   return instantiation;
     563                 :       1581 : }
     564                 :            : 
     565                 :          0 : size_t SymbolTable::Implementation::lookupArity(const string& name)
     566                 :            : {
     567                 :          0 :   std::pair<std::vector<Sort>, Sort> p = (*d_typeMap.find(name)).second;
     568                 :          0 :   return p.first.size();
     569                 :          0 : }
     570                 :            : 
     571                 :     327909 : void SymbolTable::Implementation::popScope()
     572                 :            : {
     573                 :            :   // should not pop beyond level one
     574         [ +  + ]:     327909 :   if (d_context.getLevel() == 0)
     575                 :            :   {
     576                 :          1 :     throw ScopeException();
     577                 :            :   }
     578                 :     327908 :   d_context.pop();
     579                 :     327908 : }
     580                 :            : 
     581                 :     352877 : void SymbolTable::Implementation::pushScope() { d_context.push(); }
     582                 :            : 
     583                 :         16 : size_t SymbolTable::Implementation::getLevel() const
     584                 :            : {
     585                 :         16 :   return d_context.getLevel();
     586                 :            : }
     587                 :            : 
     588                 :         83 : void SymbolTable::Implementation::reset()
     589                 :            : {
     590         [ +  - ]:         83 :   Trace("sym-table") << "SymbolTable: reset" << std::endl;
     591                 :         83 :   this->SymbolTable::Implementation::~Implementation();
     592                 :         83 :   new (this) SymbolTable::Implementation();
     593                 :         83 : }
     594                 :            : 
     595                 :         13 : void SymbolTable::Implementation::resetAssertions()
     596                 :            : {
     597         [ +  - ]:         13 :   Trace("sym-table") << "SymbolTable: resetAssertions" << std::endl;
     598                 :            :   // pop all contexts
     599         [ +  + ]:         32 :   while (d_context.getLevel() > 0)
     600                 :            :   {
     601                 :         19 :     d_context.pop();
     602                 :            :   }
     603                 :         13 :   d_context.push();
     604                 :         13 : }
     605                 :            : 
     606                 :    6282594 : bool SymbolTable::Implementation::isOverloadedFunction(Term fun) const
     607                 :            : {
     608                 :    6282594 :   return d_overload_trie.isOverloadedFunction(fun);
     609                 :            : }
     610                 :            : 
     611                 :          6 : Term SymbolTable::Implementation::getOverloadedConstantForType(
     612                 :            :     const std::string& name, Sort t) const
     613                 :            : {
     614                 :          6 :   return d_overload_trie.getOverloadedConstantForType(name, t);
     615                 :            : }
     616                 :            : 
     617                 :        836 : Term SymbolTable::Implementation::getOverloadedFunctionForTypes(
     618                 :            :     const std::string& name, const std::vector<Sort>& argTypes) const
     619                 :            : {
     620                 :        836 :   return d_overload_trie.getOverloadedFunctionForTypes(name, argTypes);
     621                 :            : }
     622                 :            : 
     623                 :     418655 : bool SymbolTable::Implementation::bindWithOverloading(const string& name,
     624                 :            :                                                       Term obj)
     625                 :            : {
     626                 :     418655 :   CDHashMap<string, Term>::const_iterator it = d_exprMap.find(name);
     627         [ +  + ]:     418655 :   if (it != d_exprMap.end())
     628                 :            :   {
     629                 :        773 :     const Term& prev_bound_obj = (*it).second;
     630                 :            :     // Only bind if the object is different. Note this means we don't
     631                 :            :     // catch errors due to repeated function symbols when using
     632                 :            :     // --no-fresh-declarations.
     633                 :            :     // Note this is currently necessary to avoid rebinding symbols in
     634                 :            :     // the symbol manager.
     635         [ +  + ]:        773 :     if (prev_bound_obj != obj)
     636                 :            :     {
     637                 :            :       // If the previous overloaded symbol was a dummy symbol denoting a sort
     638                 :            :       // (as tracked by d_dummySortTerms), we fail unconditionally
     639                 :            :       // in this case.
     640         [ +  + ]:        517 :       if (d_dummySortTerms.find(prev_bound_obj) != d_dummySortTerms.end())
     641                 :            :       {
     642                 :          2 :         return false;
     643                 :            :       }
     644                 :        515 :       return d_overload_trie.bind(name, prev_bound_obj, obj);
     645                 :            :     }
     646                 :            :   }
     647                 :     418138 :   return true;
     648                 :            : }
     649                 :            : 
     650                 :          0 : bool SymbolTable::isOverloadedFunction(Term fun) const
     651                 :            : {
     652                 :          0 :   return d_implementation->isOverloadedFunction(fun);
     653                 :            : }
     654                 :            : 
     655                 :          6 : Term SymbolTable::getOverloadedConstantForType(const std::string& name,
     656                 :            :                                                Sort t) const
     657                 :            : {
     658                 :          6 :   return d_implementation->getOverloadedConstantForType(name, t);
     659                 :            : }
     660                 :            : 
     661                 :        836 : Term SymbolTable::getOverloadedFunctionForTypes(
     662                 :            :     const std::string& name, const std::vector<Sort>& argTypes) const
     663                 :            : {
     664                 :        836 :   return d_implementation->getOverloadedFunctionForTypes(name, argTypes);
     665                 :            : }
     666                 :            : 
     667                 :      28562 : SymbolTable::SymbolTable() : d_implementation(new SymbolTable::Implementation())
     668                 :            : {
     669                 :      28562 : }
     670                 :            : 
     671                 :      28513 : SymbolTable::~SymbolTable() {}
     672                 :    1118637 : bool SymbolTable::bind(const string& name, Term obj, bool doOverload)
     673                 :            : {
     674                 :    1118637 :   return d_implementation->bind(name, obj, doOverload);
     675                 :            : }
     676                 :            : 
     677                 :          1 : bool SymbolTable::bindDummySortTerm(const std::string& name, cvc5::Term t)
     678                 :            : {
     679                 :          1 :   return d_implementation->bindDummySortTerm(name, t);
     680                 :            : }
     681                 :            : 
     682                 :     205186 : void SymbolTable::bindType(const string& name, Sort t)
     683                 :            : {
     684                 :     205186 :   d_implementation->bindType(name, t);
     685                 :     205186 : }
     686                 :            : 
     687                 :      12619 : void SymbolTable::bindType(const string& name,
     688                 :            :                            const vector<Sort>& params,
     689                 :            :                            Sort t)
     690                 :            : {
     691                 :      12619 :   d_implementation->bindType(name, params, t);
     692                 :      12619 : }
     693                 :            : 
     694                 :    1586042 : bool SymbolTable::isBound(const string& name) const
     695                 :            : {
     696                 :    1586042 :   return d_implementation->isBound(name);
     697                 :            : }
     698                 :     434269 : bool SymbolTable::isBoundType(const string& name) const
     699                 :            : {
     700                 :     434269 :   return d_implementation->isBoundType(name);
     701                 :            : }
     702                 :    6282605 : Term SymbolTable::lookup(const string& name) const
     703                 :            : {
     704                 :    6282605 :   return d_implementation->lookup(name);
     705                 :            : }
     706                 :     625162 : Sort SymbolTable::lookupType(const string& name) const
     707                 :            : {
     708                 :     625162 :   return d_implementation->lookupType(name);
     709                 :            : }
     710                 :            : 
     711                 :       1583 : Sort SymbolTable::lookupType(const string& name,
     712                 :            :                              const vector<Sort>& params) const
     713                 :            : {
     714                 :       1583 :   return d_implementation->lookupType(name, params);
     715                 :            : }
     716                 :          0 : size_t SymbolTable::lookupArity(const string& name)
     717                 :            : {
     718                 :          0 :   return d_implementation->lookupArity(name);
     719                 :            : }
     720                 :     327909 : void SymbolTable::popScope() { d_implementation->popScope(); }
     721                 :     352877 : void SymbolTable::pushScope() { d_implementation->pushScope(); }
     722                 :         16 : size_t SymbolTable::getLevel() const { return d_implementation->getLevel(); }
     723                 :         83 : void SymbolTable::reset() { d_implementation->reset(); }
     724                 :         13 : void SymbolTable::resetAssertions() { d_implementation->resetAssertions(); }
     725                 :            : 
     726                 :            : }  // namespace cvc5::internal::parser

Generated by: LCOV version 1.14