LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/uf - eq_proof.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 1 100.0 %
Date: 2026-04-20 10:41:59 Functions: 1 1 100.0 %
Branches: 0 0 -

           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                 :            :  * A proof as produced by the equality engine.
      11                 :            :  */
      12                 :            : 
      13                 :            : #include "cvc5_private.h"
      14                 :            : #include "expr/node.h"
      15                 :            : #include "theory/uf/equality_engine_types.h"
      16                 :            : 
      17                 :            : namespace cvc5::internal {
      18                 :            : 
      19                 :            : class CDProof;
      20                 :            : 
      21                 :            : namespace theory {
      22                 :            : namespace eq {
      23                 :            : 
      24                 :            : /**
      25                 :            :  * An equality proof.
      26                 :            :  *
      27                 :            :  * This represents the reasoning performed by the Equality Engine to derive
      28                 :            :  * facts, represented in terms of the rules in MergeReasonType. Each proof step
      29                 :            :  * is annotated with the rule id, the conclusion node and a vector of proofs of
      30                 :            :  * the rule's premises.
      31                 :            :  **/
      32                 :            : class EqProof
      33                 :            : {
      34                 :            :  public:
      35                 :    9713548 :   EqProof() : d_id(MERGED_THROUGH_REFLEXIVITY) {}
      36                 :            :   /** The proof rule for concluding d_node */
      37                 :            :   MergeReasonType d_id;
      38                 :            :   /** The conclusion of this EqProof */
      39                 :            :   Node d_node;
      40                 :            :   /** The proofs of the premises for deriving d_node with d_id */
      41                 :            :   std::vector<std::shared_ptr<EqProof>> d_children;
      42                 :            :   /**
      43                 :            :    * Debug print this proof on debug trace c with tabulation tb.
      44                 :            :    */
      45                 :            :   void debug_print(const char* c, unsigned tb = 0) const;
      46                 :            :   /**
      47                 :            :    * Debug print this proof on output stream os with tabulation tb.
      48                 :            :    */
      49                 :            :   void debug_print(std::ostream& os, unsigned tb = 0) const;
      50                 :            : 
      51                 :            :   /** Add to proof
      52                 :            :    *
      53                 :            :    * Converts EqProof into ProofNode via a series of steps to be stored in
      54                 :            :    * CDProof* p.
      55                 :            :    *
      56                 :            :    * This method can be seen as a best-effort solution until the EqualityEngine
      57                 :            :    * is updated to produce ProofNodes directly, if ever. Note that since the
      58                 :            :    * original EqProof steps can be coarse-grained (e.g. without proper order,
      59                 :            :    * implicit inferences related to disequelaties) and are phrased over curried
      60                 :            :    * terms, the transformation requires significant, although cheap (mostly
      61                 :            :    * linear on the DAG-size of EqProof), post-processing.
      62                 :            :    *
      63                 :            :    * An important invariant of the resulting ProofNode is that neither its
      64                 :            :    * assumptions nor its conclusion are predicate equalities, i.e. of the form
      65                 :            :    * (= t true/false), modulo symmetry. This is so that users of the converted
      66                 :            :    * ProofNode don't need to do case analysis on whether assumptions/conclusion
      67                 :            :    * are either t or (= t true/false).
      68                 :            :    *
      69                 :            :    * @param p a pointer to a CDProof to store the conversion of this EqProof
      70                 :            :    * @return the node that is the conclusion of the proof as added to p.
      71                 :            :    */
      72                 :            :   Node addToProof(CDProof* p) const;
      73                 :            : 
      74                 :            :  private:
      75                 :            :   /**
      76                 :            :    * As above, but with a cache of previously processed nodes and their results
      77                 :            :    * (for DAG traversal). The caching is in terms of the original conclusions of
      78                 :            :    * EqProof.
      79                 :            :    *
      80                 :            :    * @param p a pointer to a CDProof to store the conversion of this EqProof
      81                 :            :    * @param visited a cache of the original EqProof conclusions and the
      82                 :            :    * resulting conclusion after conversion.
      83                 :            :    * @param assumptions the assumptions of the original EqProof (and their
      84                 :            :    * variations in terms of symmetry and conversion to/from predicate
      85                 :            :    * equalities)
      86                 :            :    * @return the node that is the conclusion of the proof as added to p.
      87                 :            :    */
      88                 :            :   Node addToProof(CDProof* p,
      89                 :            :                   std::unordered_map<Node, Node>& visited,
      90                 :            :                   std::unordered_set<Node>& assumptions) const;
      91                 :            : 
      92                 :            :   /** Removes all reflexivity steps, i.e. (= t t), from premises. */
      93                 :            :   void cleanReflPremises(std::vector<Node>& premises) const;
      94                 :            : 
      95                 :            :   /** Expand coarse-grained transitivity steps for disequalities
      96                 :            :    *
      97                 :            :    * Currently the equality engine can represent disequality reasoning in a
      98                 :            :    * rather coarse-grained manner with EqProof. This is always the case when the
      99                 :            :    * transitivity step contains a disequality, (= (= t t') false) or its
     100                 :            :    * symmetric, as a premise.
     101                 :            :    *
     102                 :            :    * There are two cases. In the simplest one the general shape of the EqProof
     103                 :            :    * is
     104                 :            :    *  (= t1 t2) (= t3 t2) (= (t1 t3) false)
     105                 :            :    *  ------------------------------------- EQP::TR
     106                 :            :    *             false = true
     107                 :            :    *
     108                 :            :    * which is expanded into
     109                 :            :    *                                          (= t3 t2)
     110                 :            :    *                                          --------- SYMM
     111                 :            :    *                                (= t1 t2) (= t2 t3)
     112                 :            :    *                                ------------------- TRANS
     113                 :            :    *   (= (= t1 t3) false)                (= t1 t3)
     114                 :            :    *  --------------------- SYMM    ------------------ TRUE_INTRO
     115                 :            :    *   (= false (= t1 t3))         (= (= t1 t3) true)
     116                 :            :    *  ----------------------------------------------- TRANS
     117                 :            :    *             false = true
     118                 :            :    *
     119                 :            :    * by explicitly adding the transitivity step for inferring (= t1 t3) and its
     120                 :            :    * predicate equality. Note that we differentiate (from now on) the EqProof
     121                 :            :    * rules ids from those of ProofRule by adding the prefix EQP:: to the former.
     122                 :            :    *
     123                 :            :    * In the other case, the general shape of the EqProof is
     124                 :            :    *
     125                 :            :    *  (= (= t1 t2) false) (= t1 x1) ... (= xn t3) (= t2 y1) ... (= ym t4)
     126                 :            :    * ------------------------------------------------------------------- EQP::TR
     127                 :            :    *         (= (= t4 t3) false)
     128                 :            :    *
     129                 :            :    * which is converted into
     130                 :            :    *
     131                 :            :    *   (= t1 x1) ... (= xn t3)      (= t2 y1) ... (= ym t4)
     132                 :            :    *  ------------------------ TR  ------------------------ TR
     133                 :            :    *   (= t1 t3)                    (= t2 t4)
     134                 :            :    *  ----------- SYMM             ----------- SYMM
     135                 :            :    *   (= t3 t1)                    (= t4 t2)
     136                 :            :    *  ---------------------------------------- CONG
     137                 :            :    *   (= (= t3 t4) (= t1 t2))                         (= (= t1 t2) false)
     138                 :            :    *  --------------------------------------------------------------------- TR
     139                 :            :    *           (= (= t3 t4) false)
     140                 :            :    *          --------------------- MACRO_SR_PRED_TRANSFORM
     141                 :            :    *           (= (= t4 t3) false)
     142                 :            :    *
     143                 :            :    * whereas the last step is only necessary if the conclusion has the arguments
     144                 :            :    * in reverse order than expected. Note that the original step represents two
     145                 :            :    * substitutions happening on the disequality, from t1->t3 and t2->t4, which
     146                 :            :    * are implicitly justified by transitivity steps that need to be made
     147                 :            :    * explicity. Since there is no sense of ordering among which premisis (other
     148                 :            :    * than (= (= t1 t2) false)) are used for which substitution, the transitivity
     149                 :            :    * proofs are built greedly by searching the sets of premises.
     150                 :            :    *
     151                 :            :    * If in either of the above cases then the conclusion is directly derived
     152                 :            :    * in the call, so only in the other cases we try to build a transitivity
     153                 :            :    * step below
     154                 :            :    *
     155                 :            :    * @param conclusion the conclusion of the (possibly) coarse-grained
     156                 :            :    * transitivity step
     157                 :            :    * @param premises the premises of the (possibly) coarse-grained
     158                 :            :    * transitivity step
     159                 :            :    * @param p a pointer to a CDProof to store the conversion of this EqProof
     160                 :            :    * @param assumptions the assumptions (and variants) of the original
     161                 :            :    * EqProof. These are necessary to avoid cyclic proofs, which could be
     162                 :            :    * generated by creating transitivity steps for assumptions (which depend on
     163                 :            :    * themselves).
     164                 :            :    * @return True if the EqProof transitivity step is in either of the above
     165                 :            :    * cases, symbolizing that the ProofNode justifying the conclusion has already
     166                 :            :    * been produced.
     167                 :            :    */
     168                 :            :   bool expandTransitivityForDisequalities(
     169                 :            :       Node conclusion,
     170                 :            :       std::vector<Node>& premises,
     171                 :            :       CDProof* p,
     172                 :            :       std::unordered_set<Node>& assumptions) const;
     173                 :            : 
     174                 :            :   /** Expand coarse-grained transitivity steps for theory disequalities
     175                 :            :    *
     176                 :            :    * Currently the equality engine can represent disequality reasoning of theory
     177                 :            :    * symbols in a rather coarse-grained manner with EqProof. This is the case
     178                 :            :    * when EqProof is
     179                 :            :    *            (= t1 c1) (= t2 c2)
     180                 :            :    *  ------------------------------------- EQP::TR
     181                 :            :    *             (= (t1 t2) false)
     182                 :            :    *
     183                 :            :    * which is converted into
     184                 :            :    *
     185                 :            :    *   (= t1 c1)        (= t2 c2)
     186                 :            :    *  -------------------------- CONG  --------------------- MACRO_SR_PRED_INTRO
     187                 :            :    *   (= (= t1 t2) (= c1 t2))           (= (= c1 c2) false)
     188                 :            :    *  --------------------------------------------------------- TR
     189                 :            :    *           (= (= t1 t2) false)
     190                 :            :    *
     191                 :            :    * @param conclusion the conclusion of the (possibly) coarse-grained
     192                 :            :    * transitivity step
     193                 :            :    * @param premises the premises of the (possibly) coarse-grained
     194                 :            :    * transitivity step
     195                 :            :    * @param p a pointer to a CDProof to store the conversion of this EqProof
     196                 :            :    * @return True if the EqProof transitivity step is the above case,
     197                 :            :    * indicating that the ProofNode justifying the conclusion has already been
     198                 :            :    * produced.
     199                 :            :    */
     200                 :            :   bool expandTransitivityForTheoryDisequalities(Node conclusion,
     201                 :            :                                                 std::vector<Node>& premises,
     202                 :            :                                                 CDProof* p) const;
     203                 :            : 
     204                 :            :   /** Builds a transitivity chain from equalities to derive a conclusion
     205                 :            :    *
     206                 :            :    * Given an equality (= t1 tn), and a list of equalities premises, attempts to
     207                 :            :    * build a chain (= t1 t2) ... (= tn-1 tn) from premises. This is done in a
     208                 :            :    * greedy manner by finding one "link" in the chain at a time, updating the
     209                 :            :    * conclusion to be the next link and the premises by removing the used
     210                 :            :    * premise, and searching recursively.
     211                 :            :    *
     212                 :            :    * Consider for example
     213                 :            :    * - conclusion: (= t1 t4)
     214                 :            :    * - premises:   (= t4 t2), (= t2 t3), (= t2 t1), (= t3 t4)
     215                 :            :    *
     216                 :            :    * It proceeds by searching for t1 in an equality in the premises, in order,
     217                 :            :    * which is found in the equality (= t2 t1). Since t2 != t4, it attempts to
     218                 :            :    * build a chain with
     219                 :            :    * - conclusion (= t2 t4)
     220                 :            :    * - premises (= t4 t2), (= t2 t3), (= t3 t4)
     221                 :            :    *
     222                 :            :    * In the first equality it finds t2 and also t4, which closes the chain, so
     223                 :            :    * that premises is updated to (= t2 t4) and the method returns true. Since
     224                 :            :    * the recursive call was successful, the original conclusion (= t1 t4) is
     225                 :            :    * justified with (= t1 t2) plus the chain built in the recursive call,
     226                 :            :    * i.e. (= t1 t2), (= t2 t4).
     227                 :            :    *
     228                 :            :    * Note that not all the premises were necessary to build a successful
     229                 :            :    * chain. Moreover, note that building a successful chain can depend on the
     230                 :            :    * order in which the equalities are chosen. When a recursive call fails to
     231                 :            :    * close a chain, the chosen equality is dismissed and another is searched for
     232                 :            :    * among the remaining ones.
     233                 :            :    *
     234                 :            :    * This method assumes that premises does not contain reflexivity premises.
     235                 :            :    * This is without loss of generality since such premises are spurious for a
     236                 :            :    * transitivity step.
     237                 :            :    *
     238                 :            :    * @param conclusion the conclusion of the transitivity chain of equalities
     239                 :            :    * @param premises the list of equalities to build a chain with
     240                 :            :    * @return whether premises successfully build a transitivity chain for the
     241                 :            :    * conclusion
     242                 :            :    */
     243                 :            :   bool buildTransitivityChain(Node conclusion,
     244                 :            :                               std::vector<Node>& premises) const;
     245                 :            : 
     246                 :            :   /** Reduce a congruence EqProof into a transitivity matrix
     247                 :            :    *
     248                 :            :    * Given a congruence EqProof of (= (f a0 ... an-1) (f b0 ... bn-1)), reduce
     249                 :            :    * its justification into a matrix
     250                 :            :    *
     251                 :            :    *   [0]   -> p_{0,0} ... p_{m_0,0}
     252                 :            :    *   ...
     253                 :            :    *   [n-1] -> p_{0,n} ... p_{m_n-1,n-1}
     254                 :            :    *
     255                 :            :    * where f has arity n and each p_{0,i} ... p_{m_i, i} is a transitivity chain
     256                 :            :    * (modulo ordering) justifying (= ai bi).
     257                 :            :    *
     258                 :            :    * Congruence steps in EqProof are binary, representing reasoning over curried
     259                 :            :    * applications. In the simplest case the general shape of a congruence
     260                 :            :    * EqProof is:
     261                 :            :    *                                     P0
     262                 :            :    *              ------- EQP::REFL  ----------
     263                 :            :    *       P1        []               (= a0 b0)
     264                 :            :    *  ---------   ----------------------- EQP::CONG
     265                 :            :    *  (= a1 b1)             []                        P2
     266                 :            :    *  ------------------------- EQP::CONG        -----------
     267                 :            :    *             []                               (= a2 b2)
     268                 :            :    *          ------------------------------------------------ EQP::CONG
     269                 :            :    *                  (= (f a0 a1 a2) (f b0 b1 b2))
     270                 :            :    *
     271                 :            :    * where [] stands for the null node, symbolizing "equality between partial
     272                 :            :    * applications".
     273                 :            :    *
     274                 :            :    * The reduction of such a proof is done by
     275                 :            :    * - converting the proof of the second CONG premise (via addToProof) and
     276                 :            :    *   adding the resulting node to row i of the matrix
     277                 :            :    * - recursively reducing the first proof with i-1
     278                 :            :    *
     279                 :            :    * In the above case the transitivity matrix would thus be
     280                 :            :    *   [0] -> (= a0 b0)
     281                 :            :    *   [1] -> (= a1 b1)
     282                 :            :    *   [2] -> (= a2 b2)
     283                 :            :    *
     284                 :            :    * The more complex case of congruence proofs has transitivity steps as the
     285                 :            :    * first child of CONG steps. For example
     286                 :            :    *                                     P0
     287                 :            :    *              ------- EQP::REFL  ----------
     288                 :            :    *     P'          []            (= a0 c)
     289                 :            :    *  ---------   ----------------------------- EQP::CONG
     290                 :            :    *  (= b0 c)             []                               P1
     291                 :            :    * ------------------------- EQP::TRANS             -----------
     292                 :            :    *            []                                     (= a1 b1)
     293                 :            :    *         ----------------------------------------------------- EQP::CONG
     294                 :            :    *                          (= (f a0 a1) (f b0 b1))
     295                 :            :    *
     296                 :            :    * where when the first child of CONG is a transitivity step
     297                 :            :    * - the premises that are CONG steps are recursively reduced with *the same*
     298                 :            :    *   argument i
     299                 :            :    * - the other premises are processed with addToProof and added to the i row
     300                 :            :    *   in the matrix
     301                 :            :    *
     302                 :            :    * In the above example the corresponding transitivity matrix is
     303                 :            :    *   [0] -> (= a0 c), (= b0 c)
     304                 :            :    *   [1] -> (= a1 b1)
     305                 :            :    *
     306                 :            :    * The remaining complication is when the conclusion is an equality of n-ary
     307                 :            :    * applications of *different* arities. Then there necessarily is a
     308                 :            :    * transitivity step as a first child a CONG step whose conclusion is an
     309                 :            :    * equality of n-ary applications of different arities. For example
     310                 :            :    *
     311                 :            :    *             P0                              P1
     312                 :            :    * -------------------------- EQP::TRANS  -----------
     313                 :            :    *     (= (f a0 a1) (f b0))                (= a2 b1)
     314                 :            :    * -------------------------------------------------- EQP::CONG
     315                 :            :    *              (= (f a0 a1 a2) (f b0 b1))
     316                 :            :    *
     317                 :            :    * will be first reduced with i = 2 (maximal arity among the original
     318                 :            :    * conclusion's applications), adding (= a2 b1) to row 2 after processing
     319                 :            :    * P1. The first child is reduced with i = 1. Since it is a TRANS step whose
     320                 :            :    * conclusion is an equality of n-ary applications with mismatching arity, P0
     321                 :            :    * is processed with addToProof and the result is added to row 1. Thus the
     322                 :            :    * transitivity matrix is
     323                 :            :    *   [0] ->
     324                 :            :    *   [1] -> (= (f a0 a1) (f b0))
     325                 :            :    *   [2] -> (= a2 b1)
     326                 :            :    *
     327                 :            :    * The empty row 0 is used by the original caller of reduceNestedCongruence to
     328                 :            :    * compute that the above congruence proof's conclusion is
     329                 :            :    *   (= (f (f a0 a1) a2) (f (f b0) b1))
     330                 :            :    *
     331                 :            :    * @param i the i-th argument of the congruent applications, initially being
     332                 :            :    * the maximal arity among conclusion's applications.
     333                 :            :    * @param conclusion the original congruence conclusion
     334                 :            :    * @param transitivityMatrix a matrix of equalities with each row justifying
     335                 :            :    * an equality between the congruent applications
     336                 :            :    * @param p a pointer to a CDProof to store the conversion of this EqProof
     337                 :            :    * @param visited a cache of the original EqProof conclusions and the
     338                 :            :    * resulting conclusion after conversion.
     339                 :            :    * @param assumptions the assumptions (and variants) of the original EqProof
     340                 :            :    * @param isNary whether conclusion is an equality of n-ary applications
     341                 :            :    */
     342                 :            :   void reduceNestedCongruence(
     343                 :            :       unsigned i,
     344                 :            :       Node conclusion,
     345                 :            :       std::vector<std::vector<Node>>& transitivityMatrix,
     346                 :            :       CDProof* p,
     347                 :            :       std::unordered_map<Node, Node>& visited,
     348                 :            :       std::unordered_set<Node>& assumptions,
     349                 :            :       bool isNary) const;
     350                 :            : 
     351                 :            : }; /* class EqProof */
     352                 :            : 
     353                 :            : }  // Namespace eq
     354                 :            : }  // Namespace theory
     355                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14