LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/expr - skolem_manager.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 1 100.0 %
Date: 2026-02-04 12:23:02 Functions: 1 1 100.0 %
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * Top contributors (to current version):
       3                 :            :  *   Andrew Reynolds, Kshitij Bansal, Morgan Deters
       4                 :            :  *
       5                 :            :  * This file is part of the cvc5 project.
       6                 :            :  *
       7                 :            :  * Copyright (c) 2009-2025 by the authors listed in the file AUTHORS
       8                 :            :  * in the top-level source directory and their institutional affiliations.
       9                 :            :  * All rights reserved.  See the file COPYING in the top-level source
      10                 :            :  * directory for licensing information.
      11                 :            :  * ****************************************************************************
      12                 :            :  *
      13                 :            :  * Skolem manager utility.
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "cvc5_private.h"
      17                 :            : 
      18                 :            : #ifndef CVC5__EXPR__SKOLEM_MANAGER_H
      19                 :            : #define CVC5__EXPR__SKOLEM_MANAGER_H
      20                 :            : 
      21                 :            : #include <cvc5/cvc5_skolem_id.h>
      22                 :            : 
      23                 :            : #include <string>
      24                 :            : 
      25                 :            : #include "expr/internal_skolem_id.h"
      26                 :            : #include "expr/node.h"
      27                 :            : 
      28                 :            : namespace cvc5::internal {
      29                 :            : 
      30                 :            : class ProofGenerator;
      31                 :            : 
      32                 :            : /**
      33                 :            :  * A manager for skolems that can be used in proofs. This is designed to be
      34                 :            :  * a trusted interface for constructing variables of SKOLEM type, where one
      35                 :            :  * must provide information that characterizes the skolem. This information
      36                 :            :  * may either be:
      37                 :            :  * (1) the term that the skolem purifies (`mkPurifySkolem`)
      38                 :            :  * (2) an identifier (`mkSkolemFunction`) and a set of "cache values", which
      39                 :            :  * can be seen as arguments to the skolem function. These are typically used for
      40                 :            :  * implementing theory-specific inferences that introduce symbols that
      41                 :            :  * are not interpreted by the theory (see SkolemId enum).
      42                 :            :  *
      43                 :            :  * Note that (1) is a special instance of (2), where the purification skolem
      44                 :            :  * for t is equivalent to calling mkSkolemFunction on SkolemId::PURIFY
      45                 :            :  * and t.
      46                 :            :  *
      47                 :            :  * If a variable cannot be associated with any of the above information,
      48                 :            :  * the method `mkDummySkolem` may be used, which always constructs a fresh
      49                 :            :  * skolem variable.
      50                 :            :  *
      51                 :            :  * It is implemented by mapping terms to an attribute corresponding to their
      52                 :            :  * "original form" as described below. Hence, this class does not impact the
      53                 :            :  * reference counting of skolem variables which may be deleted if they are not
      54                 :            :  * used.
      55                 :            :  *
      56                 :            :  * To handle purification of witness terms, notice that the purification
      57                 :            :  * skolem for (witness ((x T)) P) is equivalent to the skolem function:
      58                 :            :  *    (QUANTIFIERS_SKOLEMIZE (exists ((x T)) P) 0)
      59                 :            :  * In other words, the purification for witness terms are equivalent to
      60                 :            :  * the skolemization of their corresponding existential. This is currently only
      61                 :            :  * used for eliminating witness terms coming from algorithms that introduce
      62                 :            :  * them, e.g. BV/set instantiation. Unifying these two skolems is required
      63                 :            :  * for ensuring proof checking succeeds for term formula removal on witness
      64                 :            :  * terms.
      65                 :            :  *
      66                 :            :  * The use of purification skolems and skolem functions avoid having to reason
      67                 :            :  * about witness terms. This avoids several complications. In particular,
      68                 :            :  * witness terms in most contexts should be seen as black boxes, converting
      69                 :            :  * something to a witness term may have unintended consequences e.g. variable
      70                 :            :  * shadowing. In contrast, converting to original form does not have these
      71                 :            :  * complications. Furthermore, having original form greatly simplifies
      72                 :            :  * reasoning in the proof in certain external proof formats, in particular, it
      73                 :            :  * avoids the need to reason about identifiers for introduced variables for
      74                 :            :  * the binders of witness terms.
      75                 :            :  */
      76                 :            : class SkolemManager
      77                 :            : {
      78                 :            :  public:
      79                 :            :   SkolemManager(NodeManager* nm);
      80                 :      72382 :   ~SkolemManager() {}
      81                 :            :   /**
      82                 :            :    * Make purification skolem. This skolem is unique for each t, which we
      83                 :            :    * implement via an attribute on t. This attribute is used to ensure to
      84                 :            :    * associate a unique skolem for each t.
      85                 :            :    *
      86                 :            :    * Notice that a purification skolem is trivial to justify (via
      87                 :            :    * SKOLEM_INTRO), and hence it does not require a proof generator.
      88                 :            :    *
      89                 :            :    * Notice that we do not convert t to original form in this call. Thus,
      90                 :            :    * in very rare cases, two Skolems may be introduced that have the same
      91                 :            :    * original form. For example, let k be the skolem introduced to eliminate
      92                 :            :    * (ite A B C). Then, asking for the purify skolem for:
      93                 :            :    *  (ite (ite A B C) D E) and (ite k D E)
      94                 :            :    * will return two different Skolems.
      95                 :            :    *
      96                 :            :    * @param t The term to purify
      97                 :            :    * @return The purification skolem for t
      98                 :            :    */
      99                 :            :   static Node mkPurifySkolem(Node t);
     100                 :            :   /**
     101                 :            :    * Make skolem function. This method should be used for creating fixed
     102                 :            :    * skolem functions of the forms described in SkolemId. The user of this
     103                 :            :    * method is responsible for providing a proper type for the identifier that
     104                 :            :    * matches the description of id.
     105                 :            :    * This can be done from the function
     106                 :            :    * `SkolemManager::getTypeFor`.
     107                 :            :    * Skolem functions are useful for modelling
     108                 :            :    * the behavior of partial functions, or for theory-specific inferences that
     109                 :            :    * introduce fresh variables.
     110                 :            :    *
     111                 :            :    * A skolem function is not given a formal semantics in terms of a witness
     112                 :            :    * term, nor is it a purification skolem, thus it does not fall into the two
     113                 :            :    * categories of skolems above. This method is motivated by convenience, as
     114                 :            :    * the user of this method does not require constructing canonical variables
     115                 :            :    * for witness terms.
     116                 :            :    *
     117                 :            :    * The returned skolem is an ordinary skolem variable that can be used
     118                 :            :    * e.g. in APPLY_UF terms when tn is a function type.
     119                 :            :    *
     120                 :            :    * Notice that we do not insist that tn is a function type. A user of this
     121                 :            :    * method may construct a canonical (first-order) skolem using this method
     122                 :            :    * as well.
     123                 :            :    *
     124                 :            :    * @param id The identifier of the skolem function
     125                 :            :    * @param cacheVal A cache value. The returned skolem function will be
     126                 :            :    * unique to the pair (id, cacheVal). This value is required, for instance,
     127                 :            :    * for skolem functions that are in fact families of skolem functions,
     128                 :            :    * e.g. the wrongly applied case of selectors.
     129                 :            :    * @return The skolem function.
     130                 :            :    */
     131                 :            :   Node mkSkolemFunction(SkolemId id, Node cacheVal = Node::null());
     132                 :            :   /**
     133                 :            :    * Same as above, with multiple cache values.
     134                 :            :    * @param id The identifier of the skolem function
     135                 :            :    * @param cacheVals A vector of cache values.
     136                 :            :    * @return The skolem function.
     137                 :            :    */
     138                 :            :   Node mkSkolemFunction(SkolemId id,
     139                 :            :                         const std::vector<Node>& cacheVals);
     140                 :            :   /**
     141                 :            :    * Same as above, with multiple cache values and an internal skolem id.
     142                 :            :    * This will call mkSkolemFunction where the (external) id is
     143                 :            :    * SkolemId::INTERNAL. The type is provided explicitly.
     144                 :            :    */
     145                 :            :   Node mkInternalSkolemFunction(InternalSkolemId id,
     146                 :            :                                 TypeNode tn,
     147                 :            :                                 const std::vector<Node>& cacheVals = {});
     148                 :            :   /**
     149                 :            :    * Is k a skolem function? Returns true if k was generated by the above
     150                 :            :    * call.
     151                 :            :    */
     152                 :            :   static bool isSkolemFunction(TNode k);
     153                 :            :   /**
     154                 :            :    * Is k a skolem function? Returns true if k was generated by the above
     155                 :            :    * call. Updates the arguments to the values used when constructing it.
     156                 :            :    */
     157                 :            :   static bool isSkolemFunction(TNode k, SkolemId& id, Node& cacheVal);
     158                 :            :   /**
     159                 :            :    * @param k The skolem.
     160                 :            :    * @return skolem function id for k.
     161                 :            :    */
     162                 :            :   SkolemId getId(TNode k) const;
     163                 :            :   /**
     164                 :            :    * @param k The skolem.
     165                 :            :    * @return The list of skolem indices for k.
     166                 :            :    */
     167                 :            :   std::vector<Node> getIndices(TNode k) const;
     168                 :            :   /**
     169                 :            :    * @param k The skolem.
     170                 :            :    * @return the internal skolem function id, for skolem k whose id is
     171                 :            :    * SkolemId::INTERNAL.
     172                 :            :    */
     173                 :            :   InternalSkolemId getInternalId(TNode k) const;
     174                 :            :   /**
     175                 :            :    * Create a skolem constant with the given name, type, and comment. This
     176                 :            :    * should only be used if the definition of the skolem does not matter.
     177                 :            :    * The definition of a skolem matters e.g. when the skolem is used in a
     178                 :            :    * proof.
     179                 :            :    *
     180                 :            :    * @param prefix the name of the new skolem variable is the prefix
     181                 :            :    * appended with a unique ID.  This way a family of skolem variables
     182                 :            :    * can be made with unique identifiers, used in dump, tracing, and
     183                 :            :    * debugging output.  Use SKOLEM_EXACT_NAME flag if you don't want
     184                 :            :    * a unique ID appended and use prefix as the name.
     185                 :            :    * @param type the type of the skolem variable to create
     186                 :            :    * @param flags an optional mask of bits from SkolemFlags to control
     187                 :            :    * skolem behavior
     188                 :            :    */
     189                 :            :   Node mkDummySkolem(const std::string& prefix,
     190                 :            :                      const TypeNode& type,
     191                 :            :                      SkolemFlags flags = SkolemFlags::SKOLEM_DEFAULT);
     192                 :            :   /** Returns true if n is a skolem that stands for an abstract value */
     193                 :            :   bool isAbstractValue(TNode n) const;
     194                 :            :   /**
     195                 :            :    * Convert to original form, which recursively replaces all skolems terms in
     196                 :            :    * n by the term they purify.
     197                 :            :    *
     198                 :            :    * @param n The term or formula to convert to original form described above
     199                 :            :    * @return n in original form.
     200                 :            :    */
     201                 :            :   static Node getOriginalForm(Node n);
     202                 :            :   /**
     203                 :            :    * Convert to unpurified form, which returns the term that k purifies. This
     204                 :            :    * is literally the term that was passed as an argument to mkPurify on the
     205                 :            :    * call that created k. In contrast to getOriginalForm, this is not
     206                 :            :    * recursive w.r.t. skolems, so that the term purified by k may itself
     207                 :            :    * contain purification skolems that are not expanded.
     208                 :            :    *
     209                 :            :    * @param k The skolem to convert to unpurified form
     210                 :            :    * @return the unpurified form of k.
     211                 :            :    */
     212                 :            :   static Node getUnpurifiedForm(Node k);
     213                 :            :   /**
     214                 :            :    * Get the number of indices for a skolem id.
     215                 :            :    * @param id The skolem id.
     216                 :            :    * @return The number of indices for the skolem id.
     217                 :            :    */
     218                 :            :   size_t getNumIndicesForSkolemId(SkolemId id) const;
     219                 :            :   /**
     220                 :            :    * Is the given skolem identifier commutative, in the sense that its
     221                 :            :    * arguments can be reordered? If this method returns true, then
     222                 :            :    * we sort the arguments to the skolem upon construction via the API.
     223                 :            :    */
     224                 :            :   static bool isCommutativeSkolemId(SkolemId id);
     225                 :            :  private:
     226                 :            :   /** The associated node manager. */
     227                 :            :   NodeManager* d_nm;
     228                 :            :   /** Cache of skolem functions for mkSkolemFunction above. */
     229                 :            :   std::map<std::tuple<SkolemId, TypeNode, Node>, Node> d_skolemFuns;
     230                 :            :   /** Backwards mapping of above */
     231                 :            :   std::map<Node, std::tuple<SkolemId, TypeNode, Node>> d_skolemFunMap;
     232                 :            : 
     233                 :            :   /**
     234                 :            :    * A counter used to produce unique skolem names.
     235                 :            :    *
     236                 :            :    * Note that it is NOT incremented when skolems are created using
     237                 :            :    * SKOLEM_EXACT_NAME, so it is NOT a count of the skolems produced
     238                 :            :    * by this node manager.
     239                 :            :    */
     240                 :            :   size_t d_skolemCounter;
     241                 :            :   /** Same as mkSkolemFunction, with explicit type */
     242                 :            :   Node mkSkolemFunctionTyped(SkolemId id,
     243                 :            :                              TypeNode tn,
     244                 :            :                              Node cacheVal = Node::null());
     245                 :            :   /** Same as above, with multiple cache values and explicit Type */
     246                 :            :   Node mkSkolemFunctionTyped(SkolemId id,
     247                 :            :                              TypeNode tn,
     248                 :            :                              const std::vector<Node>& cacheVals);
     249                 :            :   /**
     250                 :            :    * Create a skolem constant with the given name, type, and comment.
     251                 :            :    *
     252                 :            :    * This method is intentionally private. To create skolems, one should
     253                 :            :    * call a public method from SkolemManager for allocating a skolem in a
     254                 :            :    * proper way, or otherwise use SkolemManager::mkDummySkolem.
     255                 :            :    */
     256                 :            :   Node mkSkolemNode(Kind k,
     257                 :            :                     const std::string& prefix,
     258                 :            :                     const TypeNode& type,
     259                 :            :                     SkolemFlags flags = SkolemFlags::SKOLEM_DEFAULT);
     260                 :            :   /** Get type for skolem */
     261                 :            :   TypeNode getTypeFor(SkolemId id, const std::vector<Node>& cacheVals);
     262                 :            : };
     263                 :            : 
     264                 :            : }  // namespace cvc5::internal
     265                 :            : 
     266                 :            : #endif /* CVC5__EXPR__PROOF_SKOLEM_CACHE_H */

Generated by: LCOV version 1.14